본문으로 건너뛰기

Process / Module — 프로세스·모듈 확인 ​

게임 프로세스에 로드된 모듈과 스레드·핸들·메모리 영역을 검사해 인젝션·할로잉 흔적을 찾는다. 프로세스 상태는 라이브 SS에서만 유효하며, 프로세스 종료나 재부팅으로 증발한다.

왜 중요한가 ​

디스크 아티팩트(PF, USN, BAM)는 과거를 보여 준다. 프로세스·모듈 확인은 지금 메모리에 무엇이 올라가 있는지 보여 준다. 두 축을 맞춰야 "파일이 있었고, 실행됐고, 지금도 동작 중이다"까지 도달할 수 있다.

유저모드 치트는 어떤 형태로든 다른 프로세스의 주소 공간을 건드린다. LoadLibrary 경유의 고전 DLL 인젝션부터 수동 매핑·할로잉·리플렉티브 로딩까지, 기법이 정교해질수록 모듈 목록에 안 잡히도록 설계된다. 그래서 이 카드의 핵심 질문은 "모듈 목록에 뭐가 있나"가 아니라 "기법이 쓰였다면 잔류물이 어디에 남는가"다.

동시에 이 축은 오탐이 잦다. 게임·안티치트·오버레이·GPU 스택·백신이 정상적으로도 수십 개의 DLL과 훅을 만든다. pe-sieve 계열 히트는 단서이지 판정이 아니다.

무엇인가 ​

항목설명
대상라이브 프로세스 트리 + 로드된 모듈 + 스레드 + 핸들 + 메모리 영역
도구System Informer(프로세스 트리·모듈·스레드·메모리 탭), Process Explorer, tasklist /m, listdlls
보조pe-sieve 계열(단서 생성기로만), Sysmon 이벤트(배포된 경우에만)
메모리 문자열DPS·PcaSvc·DcomLaunch를 호스팅하는 svchost, csrss.exe, explorer.exe 같은 프로세스의 메모리 문자열. 전용 파서는 DPS-Analyzer·pcasvc-executed·process-parser·JARParser. 아래 절
MITRE 참조T1055 Process Injection 계열, T1620 Reflective Code Loading
한계라이브 SS 전용. 프로세스 종료 후에는 디스크 축만 남는다

System Informer에서 실제로 여는 뷰는 다섯 개다. 프로세스 트리는 부모-자식 관계를 보여 주고, 모듈 탭(프로세스 더블클릭 → Modules)은 그 프로세스가 로드한 DLL 전체다. 스레드 탭은 각 스레드의 시작 주소와 상태를 보여 주는데, 시작 주소가 로드된 어떤 모듈에도 속하지 않으면 인젝션 리드(판정 전 재검증이 필요한 단서, 용어집)다. 메모리 탭은 커밋된 영역의 보호 속성(EXECUTE_READWRITE 등)과 매핑 유형(Private/Mapped/Image)을 보여 준다. 핸들 탭은 무관한 프로세스가 게임 프로세스를 연 흔적을 잡는다.

tasklist /m은 "이 DLL을 로드한 프로세스 전부"를 뒤집어 보는 용도로 빠르고, listdlls는 특정 프로세스의 로드 모듈을 텍스트로 뽑을 때 쓴다. 둘 다 스크린샷보다 복붙 가능한 텍스트가 남아 증거 패키지에 넣기 좋다.

pe-sieve 계열 도구는 프로세스 메모리를 스캔해 임플란트·패치된 코드·교체된 이미지를 보고한다. 결과물은 반드시 리드 목록으로만 취급한다. 이 도구들은 "이 영역이 의심스러운 형태다"까지만 말해 주고, "치트다"라고는 말해 주지 않는다. JIT 컴파일러, AV 훅, 안티치트 자체 보호 루틴이 모두 같은 모양으로 보고된다.

Sysmon이 배포돼 있으면 이벤트 8(CreateRemoteThread)·10(ProcessAccess)·7(ImageLoaded)이 인젝션의 직접 신호다. 레지스트리 경유 설정 변경은 12–14가 받친다. 대부분의 개인 PC에는 Sysmon이 없으므로 부재를 증거로 읽지 않는다.

SS에서 어떻게 쓰나 ​

  1. T+28에 System Informer 프로세스 트리를 열어 게임·안티치트·오버레이 기준선을 먼저 식별한다.
  2. 게임 프로세스의 모듈 목록에서 비벤더·무서명 DLL을 확인한다. 특히 Temp·AppData·Downloads 같은 사용자 쓰기 가능 경로에서 로드된 모듈에 주목한다.
  3. 스레드 탭에서 시작 주소가 로드된 모듈 밖에 있는 스레드를 찾는다.
  4. 메모리 탭에서 Private이면서 실행 가능한 영역을 본다. 파일 미매핑 + 실행 가능 조합이 수동 매핑·리플렉티브 계열의 모양이다.
  5. PEB·이미지 경로 불일치(경로는 정상 exe인데 내용이 다르다)가 보이면 R3-MEM 분기 기준 충족으로 기록한다.
  6. pe-sieve를 돌렸다면 히트 하나하나에 "정상 설명이 성립하는가"를 먼저 적용하고, 남은 것만 디스크 축과 교차한다.
  7. 서비스·셸 프로세스의 메모리 문자열을 읽고, 그 프로세스의 시작 시각을 부팅 시각과 비교한다. 방법은 다음 절에 있다.

서비스와 프로세스의 메모리 문자열 ​

실행 중인 시스템 서비스와 셸 프로세스는 자기 메모리에 최근 다룬 실행 파일의 경로와 날짜 같은 문자열을 쌓아 둔다. 이 문자열을 읽어 Prefetch·BAM·USN 같은 디스크 축과 이름·경로·시각을 맞춰 보는 것이 이 검사다. 디스크의 기록을 지워도 다른 프로세스 메모리에 남은 경로는 따로 지워야 하므로, 디스크 축과 다른 관찰 지점이 된다. 대신 프로세스가 끝나면 함께 사라지는 기록이라 라이브 SS에서만 쓸 수 있다.

대상별로 남는 문자열 ​

대상본래 역할메모리에 남는 것읽는 도구
DPS (Diagnostic Policy Service, dps.dll을 싣는 svchost)Windows 구성 요소의 문제 감지·해결을 맡는 진단 서비스\Device\HarddiskVolumeN\…\*.exe 형태의 장치 경로, !!파일명.exe!날짜!… 형태의 구조화된 항목DPS-Analyzer, System Informer
PcaSvc (Program Compatibility Assistant Service)사용자가 설치·실행한 프로그램을 지켜보며 알려진 호환성 문제를 감지한다드라이브 문자로 시작하는 파일 경로pcasvc-executed, System Informer
explorer.exeWindows 셸(바탕 화면·작업 표시줄·파일 탐색기)TRACE,로 시작하는 PCA 클라이언트 기록 블록. 그 밖의 판독 관행은 아래 CommunitySystem Informer, pcasvc-executed
DcomLaunch (DCOM Server Process Launcher)개체 활성화 요청에 따라 COM·DCOM 서버를 띄운다-jar가 들어간 명령줄 문자열JARParser, System Informer
csrss.exeWin32 하위 시스템의 사용자 모드 부분. 콘솔 창과 스레드 생성·삭제를 맡는다무엇을 찾는지, 두 인스턴스 중 어느 쪽을 여는지는 아래 CommunitySystem Informer
DiagTrack (Connected User Experiences and Telemetry)진단·사용 데이터 수집\Device\HarddiskVolumeN\… 형태의 파일 경로process-parser
AppInfo (Application Information)추가 관리자 권한이 필요한 앱 실행을 돕는다(UAC 승격)드라이브 문자로 시작하는 .exe 경로process-parser
Dnscache (DNS Client)조회한 DNS 이름을 캐시한다최근 조회한 도메인 이름ipconfig /displaydns

형식마다 읽는 법이 다르다. DPS의 장치 경로는 드라이브 문자 대신 볼륨 장치 이름으로 적혀 있어, DPS-Analyzer는 이를 C:\ 같은 경로로 바꾼 뒤 서명 상태와 현재 존재 여부를 붙여 출력한다. 지금 디스크에 없는 경로는 dps-full-notfound-executables.txt로 따로 나온다. !!로 시작하는 항목은 파일명과 날짜 필드를 담고, DPS-Analyzer는 같은 파일명에 서로 다른 날짜가 붙은 항목(dps-suspicious-results.txt)과 exe가 들어가지 않은 장치 경로(dps-modified-extension.txt)를 따로 모은다. Echo 핸드북은 이 DPS 기록을 "실행된 실행 파일과 그 컴파일 시각"으로 보여 주고, explorer의 PCA 클라이언트 기록을 "explorer를 마지막으로 재시작한 뒤 실행된 파일"로 보여 준다. pcasvc-executed는 TRACE, 블록을 모든 프로세스 메모리에서 찾고, PcaSvc 호스트에서는 드라이브 경로 문자열을 뽑는다. JARParser가 DcomLaunch에서 뽑는 -jar 문자열은 java -jar 형태로 JAR를 실행한 명령줄이다.

csrss.exe는 Win32 하위 시스템이 항상 떠 있어야 하는 핵심 프로세스라 재시작으로 메모리를 비울 수 없다. DNS 캐시는 메모리 문자열을 뒤지기보다 ipconfig /displaydns로 직접 읽는다. 캐시는 최근 조회 결과를 담는 것이라 휘발성이 높고, ipconfig /flushdns로 비울 수 있다.

어느 문자열이든 그 경로가 해당 프로세스의 메모리를 거쳤다는 기록이다. 누가 언제 실행했는지는 디스크 축과 맞춰 봐야 정해진다.

읽는 법 ​

  1. 대상 PID를 찾는다. 서비스는 tasklist /svc /fi "services eq DPS"처럼 서비스 이름으로 호스팅 svchost의 PID를 찾는다. PcaSvc·DcomLaunch·DiagTrack·AppInfo도 같은 방식이다. System Informer에서 svchost의 속성을 열면 Services 탭에 그 프로세스가 호스팅하는 서비스가 나온다.
  2. System Informer를 관리자 권한으로 실행하고 대상 프로세스의 속성(Properties)을 연다. 권한 때문에 메모리가 열리지 않는 시스템 프로세스가 있다. 열리지 않으면 그 사실을 기록한다.
  3. Memory 탭에서 Strings를 연다. 빌드에 따라 탭의 버튼으로 있거나 Options 메뉴 안의 Strings...로 있다. 최소 길이(Minimum length), 검색할 영역(Private·Image·Mapped), 유니코드 옵션(대화 상자의 Detect Unicode·Extended Unicode, 새 창에서는 Options 메뉴의 Unicode·Extended character set)을 정한다. 최소 길이가 짧을수록 잡음이 늘고, 영역을 줄이면 놓치는 문자열이 생긴다.
  4. Filter로 좁힌다. Contains로 제보된 이름과 확장자(.exe·.dll·.jar)를 찾고, Regex로 ^[A-Z]:\\.+\.exe$ 같은 드라이브 경로 형태를 거른다. 둘 다 대소문자를 무시하는 옵션이 있다.
  5. 결과를 텍스트로 저장해 05-process/에 둔다. 파일 이름에 프로세스 이름·PID·검사 시각을 넣고, 최소 길이·영역·필터 설정을 함께 적는다. DPS-Analyzer·pcasvc-executed·process-parser·JARParser의 출력 파일도 같은 폴더에 둔다.

서비스 시작 시각과 부팅 시각 ​

문자열은 그 프로세스가 시작된 뒤에 쌓인 것만 담는다. 호스트 프로세스가 다시 뜨면 이전 메모리의 문자열은 남지 않으므로, 문자열이 비었거나 얇으면 그 프로세스가 언제 시작됐는지부터 본다.

  • 부팅 시각: (Get-CimInstance Win32_OperatingSystem).LastBootUpTime
  • 서비스 호스트의 PID: Get-CimInstance Win32_Service -Filter "Name='DPS'" | Select-Object Name,ProcessId
  • 그 프로세스의 시작 시각: Get-CimInstance Win32_Process -Filter "ProcessId=<PID>" | Select-Object Name,CreationDate. System Informer 속성의 General 탭 Started 칸도 시작 시각을 보여 준다.

서비스 호스트의 시작 시각이 부팅 시각보다 한참 늦다면 재시작 흔적으로 보고 리드에 적는다. System 로그에서 그 서비스의 7036(서비스 상태 변경)을 필터링하면 정지·실행 시각이 나온다. explorer.exe는 로그온 때 뜨므로 로그온 시각과 비교한다.

Windows 10 1703부터 RAM이 3.5GB를 넘는 PC에서는 서비스가 대부분 각자의 svchost에서 돈다. 이 구성에서는 서비스를 재시작하면 호스트 프로세스도 새로 떠 시작 시각이 바뀐다. RAM이 3.5GB 이하이거나 분리하지 않는 서비스처럼 여러 서비스가 한 호스트를 나눠 쓰면, 서비스만 재시작돼도 호스트 시작 시각은 그대로다. 이때는 7036 기록으로 판단한다.

늦은 시작에는 정상 사유도 있다. 수동·트리거 시작 서비스는 필요할 때 뜨고, 업데이트·설치 프로그램과 서비스 복구 설정도 서비스를 다시 띄운다. 시작 유형(sc qc)과 7036 전후 맥락을 같이 적는다.

한계 ​

  • 휘발성: 재부팅이나 재시작이면 문자열이 사라진다. 사후 수집 세션에는 이 관찰 지점이 없다.
  • 문자열만으로 실행이 증명되지 않는다: 형식마다 뜻이 다르고, 경로가 메모리에 남은 것과 사용자가 그 파일을 실행한 것은 다른 진술이다. 디스크 축의 실행 기록과 이름·경로·시각이 맞을 때만 무게를 둔다.
  • 대부분은 정상 사용 흔적이다: 게임·런처·설치 프로그램·업데이트 경로가 대다수다. 제보 이름, 사용자 쓰기 경로, 무서명, 디스크 부재에 해당하는 것만 추린다.
  • 검사 도구도 문자열을 남긴다: System Informer·DPS-Analyzer·스캐너를 실행하면 그 경로가 DPS·PCA 문자열에 새로 들어간다. 도구마다 실행 시각을 적어 두고 결과에서 가려낸다.
  • 꺼진 서비스는 대상이 없다: 서비스가 비활성이면 그 프로세스 자체가 없다. 서비스 상태를 먼저 기록한다.

문자열 검사를 피하는 방법과 남는 흔적 ​

기법공격자가 하는 일남는 흔적
서비스 재시작으로 비우기DPS·PcaSvc 같은 서비스나 explorer.exe를 재시작해 메모리를 새로 띄운다호스트 프로세스 시작 시각이 부팅(explorer는 로그온) 시각보다 한참 늦다. System 7036의 정지→실행 기록, 재시작에 쓴 명령(sc·net)의 PF·BAM
서비스 스레드 정지호스트는 그대로 두고 기록 스레드만 Suspend해 새 문자열이 쌓이지 않게 한다시작 시각은 정상인데 디스크 축에 있는 최근 실행이 문자열에 없다. 스레드 상태 판독은 Prefetch·Anti-forensics 카드의 "서비스 스레드 정지" 행에 있다
문자열 제거 로더로드한 뒤 자기 메모리에서 탐지용 문자열을 지운다로더가 지우는 것은 자기 쪽 문자열이다. DPS·PcaSvc 같은 다른 프로세스에 남은 로더 실행 경로는 별개이고, 구조 지표는 Memory 카드의 "문자열 제거 로딩" 행이 본다
편집 도구로 덮어쓰기System Informer 같은 도구의 메모리 편집 창으로 대상 프로세스의 문자열을 직접 지운다편집 도구의 실행 기록(PF·BAM·DPS 문자열). System Informer의 메모리 편집 창 제목은 이름.exe (PID) (0x시작 - 0x끝) 형식이다

인젝션 기법과 남는 흔적 ​

기법이 정교할수록 "모듈 목록에 나타난다"는 가정이 깨진다. 각 기법이 어디에 잔류물을 남기는지를 알아야 "없다"와 "안 보인다"를 구분할 수 있다. 모듈 목록의 "이름"도 같은 함정이다. 시스템·드라이버 DLL 이름을 베낀 모듈은 목록에서 정상으로 보이지만, 실제 위치·서명 상태·백킹 파일(모듈이 매핑된 디스크 파일)에서 위장이 드러난다.

기법공격자가 하는 일남는 흔적
고전 DLL 인젝션OpenProcess → VirtualAllocEx → WriteProcessMemory → CreateRemoteThread로 대상에 DLL 경로를 쓰고 LoadLibrary를 원격 호출한다 (T1055.001)모듈 목록에 실제로 나타나는 계열이다. 비벤더·무서명 DLL + 사용자 경로가 1차 리드. 인젝터 exe의 PF·BAM, DLL 파일의 USN CREATE, Sysmon 8·10·7이 보조다
수동 매핑LoadLibrary를 거치지 않고 PE를 직접 메모리에 매핑·재배치·import 해결한다. OS 로더의 모듈 목록(PEB LDR)에 올라가지 않는다모듈 탭에는 없는데 메모리 탭에 파일 미매핑 실행 영역 + MZ·PE 구조가 있다. ldrmodules 불일치는 R3-MEM에서 확인한다. 매퍼 자체는 exe라 PF·BAM에 남는다
프로세스 할로잉정상 exe를 suspended 상태로 만든 뒤 이미지를 통째로 교체하고 재개한다 (T1055.012)프로세스 경로는 notepad.exe·svchost.exe인데 메모리 안의 코드는 다른 바이너리고, 스레드 시작 주소도 그 바이너리를 가리킨다. 비정상 부모-자식 관계, PEB 이미지 경로와 실제 코드 영역 불일치가 잡힌다. Volatility hollowprocesses·pe-sieve가 겨냥하는 대표 패턴
APC 인젝션대상 스레드의 APC 큐에 코드 실행을 등록한다 (T1055.004). 새 스레드를 만들지 않아 스레드 카운트로는 안 잡힌다기존 스레드의 호출 스택에 모듈 밖 프레임이 낀다. 큐잉 직전의 프로세스 접근(Sysmon 10)과 메모리 쓰기 흔적이 보조다. 라이브 스냅샷에서 잡기 어려워 메모리 축 의존도가 높다
스레드 하이재킹실행 중인 스레드를 Suspend하고 컨텍스트를 바꿔 RIP를 악성 코드로 돌린 뒤 Resume한다 (T1055.003)스레드 시작 주소는 정상 모듈인데 현재 실행 위치·스택 프레임이 로드된 모듈 밖이다. SI 스레드 탭에서 파일 미매핑 주소를 가리키는 프레임이 리드다
리플렉티브 DLLDLL이 자기 자신을 로드하는 로더를 내장해 디스크 경유 없이 메모리에서 올라간다 (T1620)unbacked(파일에 매핑되지 않은, 용어집) 실행 영역 + MZ 헤더(malfind류 패턴). 디스크에 DLL이 없는데 기능은 동작 중이라면 "로더 실행 기록(PF·BAM) + 현재 기능" 두 축이 필요하다
IAT 훅로드된 모듈의 import 주소 테이블 엔트리를 자기 코드 주소로 덮어쓴다파일은 정상인데 메모리 상의 IAT가 디스크 이미지와 다르다. 모듈 무결성 비교(메모리 vs 디스크)로만 잡힌다. 오버레이·AV가 정상적으로도 같은 행위를 해서 FP가 매우 높다
인라인 훅ntdll·게임 함수의 프롤로그를 jmp/call로 패치한다함수 선두 바이트가 디스크 이미지와 불일치한다. pe-sieve가 "hooked"로 보고한다. 안티치트·AV·오버레이가 같은 패턴이라 단독 의미가 약하다
DLL 사이드로딩·하이잭정상 exe가 로드할 DLL을 같은 이름의 비정상 DLL로 교체하거나, exe 옆 검색 우선 폴더에 둔다. 서명된 정상 exe가 악성 DLL을 대신 로드한다 (T1574.001·T1574.002)모듈 이름은 정상인데 로드 경로가 기대 위치(System32·설치 폴더)가 아니다. 서명 없는 동명 DLL, 교체된 DLL의 USN rename·write 체인. hijacklibs 같은 공개 목록이 하이잭 가능한 DLL 이름을 가린다
LdrLoadDll 스텁대상 프로세스에 심은 코드가 OS 내부 로더 함수(LdrLoadDll)를 호출해 모듈을 올린다. ExtremeInjector 같은 다기법 인젝터가 제공하는 방식이다모듈 목록에는 나타나지만 stub이 실행된 파일 미매핑 영역·원격 스레드 생성 흔적(Sysmon 8·10)이 남는다. 인젝터 exe는 PF·BAM에 남는다
이미지 교체 변종hasherezade의 PE 인젝션 PoC 계열(process ghosting·transacted hollowing·process overwriting·process doppelganging·module overloading)이 정상 프로세스를 띄우고 내용을 페이로드로 바꾼다프로세스 이름·경로는 정상인데 실제 이미지와 불일치한다. unbacked 실행 영역, PEB·VAD 불일치, 일부 변종이 남기는 잔여 임시 파일. pe-sieve·hollows_hunter가 겨냥하는 패턴이다
드라이버 모듈명 위장치트 DLL을 GPU 드라이버 모듈명(atig6pxx.dll·aticfx64.dll)으로 바꿔 javaw 같은 게임 프로세스의 모듈 목록에서 드라이버처럼 보이게 한다이름은 정상이어도 위치·서명·환경이 아니다. 정품은 System32·드라이버 설치 경로에서 유효 서명과 함께 로드되고, NVIDIA·Intel GPU 환경의 AMD 드라이버 DLL은 환경과 모순된다
rundll 없는 DLL 실행전용 로더가 rundll32·regsvr32를 거치지 않고 DLL을 직접 호출한다rundll32의 PF·BAM 부재는 부정 증거가 아니다. 대상 프로세스의 모듈 목록과 로더 자체의 실행 기록(PF·BAM)이 남는다

공통 원칙: 기법이 디스크를 건드리지 않아도 로더·인젝터는 exe로 먼저 실행됐어야 한다. "인젝터의 PF·BAM + 프로세스 내 잔류물" 조합이 이 카드의 표준 증거 모양이다.

정상 vs 이상 ​

구분정상이상
모듈MS·벤더 서명, 게임·설치 폴더, 알려진 오버레이무서명 + 사용자 경로 + 치트 네이밍, 또는 모듈 목록에 없는데 실행 영역 존재
스레드시작 주소가 로드된 모듈 내부시작 주소·스택 프레임이 파일 미매핑 영역
프로세스 구조표준 부모-자식PEB·경로 불일치(할로잉 의심), 게임이 무관한 exe의 부모
핸들·접근게임이 자체 리소스 접근무관 프로세스가 게임에 높은 권한으로 접근
무결성메모리 모듈 = 디스크 이미지IAT·프롤로그 불일치(단, 오버레이·AV와 구분 필요)
모듈 이름모듈명과 경로·서명·환경이 정합시스템·드라이버 이름인데 경로·서명 불일치, GPU 환경과 모순되는 드라이버 모듈명
서비스 문자열게임·런처·설치 프로그램·업데이트 경로, 서명된 실행 파일제보 이름, 사용자 쓰기 경로의 무서명 exe, 지금 디스크에 없는 exe, 같은 파일명에 날짜가 다른 DPS 항목
호스트 시작 시각부팅 직후(explorer.exe는 로그온 직후)부팅보다 한참 늦은 시작과 7036 정지·실행 기록, 그와 함께 비어 있는 문자열

오탐 ​

  • 오버레이 인젝션: Discord·Steam·NVIDIA 오버레이는 게임 프로세스에 정상 주입된다. 벤더 서명과 설치 여부로 가린다.
  • 그래픽·입력 스택: GPU 드라이버, 입력 장치 DLL, MSI Afterburner/RTSS 계열의 훅.
  • 백신·EDR: 사용자모드 훅과 모니터링 DLL을 거의 모든 프로세스에 넣는다.
  • 안티치트 자체: 자체 보호 루틴이 인젝션 탐지 패턴을 만든다. 안티치트를 치트로 판정하지 않는다.
  • 개발 PC의 디버거: Visual Studio·x64dbg가 연결된 상태는 같은 신호를 낸다.
  • pe-sieve 히트: JIT·AV·안티치트 훅이 같은 보고를 만든다. 히트는 리드이며, FP 베이스라인과 디스크 교차 없이 무게를 두지 않는다.
  • 검사 도구가 만든 문자열: System Informer·DPS-Analyzer·스캐너를 실행하면 그 경로가 서비스 문자열에 새로 들어간다. 도구 실행 시각을 기록해 결과에서 가려낸다.
  • 정상적인 늦은 시작: 수동·트리거 시작 서비스, 업데이트나 서비스 복구로 다시 뜬 호스트, 충돌 뒤 다시 뜬 explorer.exe. 시작 유형과 7036 맥락으로 가린다.

교차 검증 ​

교차 카드확인 내용
R3-SIG의심 모듈 경로의 서명 상태와 경로 위생
R3-PF/BAM로더·인젝터 exe의 실행 기록, 제보 시간대와의 정렬
R3-USN드롭된 DLL의 CREATE·DELETE, 인젝터 파일의 존재 이력
R3-MEMPEB·경로 불일치, unbacked 실행 영역이 보이면 분기
R3-PF/BAM·PCA메모리 문자열의 이름·경로·시각이 PF·BAM 실행 기록, PCA 파일 기록(BAM / Registry·Windows 흔적)과 맞는지
R3-AF서비스 재시작·스레드 정지 정황. 호스트 시작 시각, 7036, 스레드 상태
MITRE T1055기법 프레이밍. Confirmed 단독 근거가 아니다

프로세스·모듈 소견만으로는 Confirmed를 내리지 않는다. 라이브 관찰(모듈·스레드·메모리)이 한 축이고, 디스크 타임라인(인젝터 실행·DLL 생성)이 다른 축이다. 둘이 같은 스토리로 수렴해야 한다. 서비스 메모리 문자열도 라이브 관찰 축에 속한다. 문자열 여러 개가 같은 경로를 가리켜도 디스크 축 없이는 한 축이다.

증거 캡처 ​

05-process/ 폴더에 둔다.

  1. 프로세스 트리 전체 스크린샷(부모-자식이 보이게)
  2. 비Microsoft·비벤더 필터를 건 모듈 목록 + 의심 모듈의 경로·서명 상태
  3. 이상 스레드의 시작 주소·스택, 파일 미매핑 실행 영역의 메모리 탭 화면
  4. pe-sieve를 썼다면 출력 원문 + 각 히트의 정상 설명 검토 메모
  5. Sysmon 배포 시 관련 이벤트(8·10·7) export
  6. 서비스·프로세스 문자열 검사 결과(txt): 프로세스 이름·PID·시작 시각, 최소 길이·영역·필터 설정, 검사 시각. 전용 파서를 썼다면 출력 파일 원본
  7. 부팅 시각과 대상 호스트 시작 시각 메모. 재시작이 의심되면 7036 필터 화면을 함께 두고 06-af/에도 적는다

흔한 실수 ​

  • pe-sieve 히트 하나로 Confirmed를 내린다. 이 도구는 단서 생성기다.
  • 무서명 DLL 하나로 판정한다. 정당한 무서명 소프트웨어가 너무 많다.
  • 안티치트 자체 보호·오버레이를 치트로 판정한다.
  • 모듈 목록만 보고 "없다"고 끝낸다. 수동 매핑·리플렉티브 계열은 모듈 목록에 나타나지 않는다. 메모리·스레드 탭을 봐야 한다.
  • 라이브 SS 없이 프로세스 증거를 주장한다. 프로세스가 꺼지면 이 축의 증거도 사라진다.
  • 메모리 문자열 하나로 실행을 확정한다. 형식마다 뜻이 다르고, 디스크 축과 맞아야 한다.
  • 문자열이 비어 있는데 호스트 시작 시각을 보지 않는다. 방금 다시 뜬 프로세스는 원래 비어 있다.

Community SS 커뮤니티에서 "injector stub"·"manual map loader"·"steam hideloader" 같은 이름의 로더가 반복 언급된다. 공통 패턴은 로더 exe는 디스크에 남고(=PF·BAM에 잡히고) 페이로드만 메모리에 간다는 것이다. 모듈 목록이 깨끗해도 로더의 실행 기록과 파일 미매핑 실행 영역이 같이 있으면 같은 가설을 지지하는 두 축이다.

다기법 인젝터(ExtremeInjector 등)가 "표준·manual map·thread hijacking·LdrLoadDll stub" 4종 세트로 유통된다는 보고도 반복된다. 각각이 남기는 모듈 목록·메모리 시그니처는 위 표의 개별 기법과 같다. "정규식·prefetch 파서를 전부 우회한다"고 스스로 밝힌 클라이언트 사례(slinky)는 저널 없는 파일 시스템 + 유니코드 폴더명 + 정상 모듈명 rename의 조합이었다. 회피용으로 만든 이름·경로 패턴 자체가 정상 베이스라인에 없는 모양이라, 조합의 각 조각은 해당 축의 카드가 잡는다.

서비스·프로세스 메모리 문자열 검사는 Minecraft·FiveM SS 가이드가 공통으로 다루는 기본 점검이다. 가이드들의 판독 관행은 이렇다. csrss.exe는 보통 두 개가 떠 있는데, 개인 바이트(private bytes)가 적은 쪽에서 .exe 전체 경로를, 많은 쪽에서 .dll 경로와 확장자를 바꾼 실행 파일 경로를 찾는다. explorer.exe에서는 pcaclient로 최근 실행 경로를 찾고, file:///로 셸에서 열어 본 경로를 보되 이쪽은 실행 증거로 쓰지 않는다. DPS에서는 !!로 시작하면서 .exe로 끝나지 않는 항목과 exe가 없는 장치 경로를 걸러 확장자를 바꿔 실행한 파일을 찾는다. PcaSvc에서는 점 없이 jar로 검색해 확장자를 바꾼 JAR 실행까지 잡는다. 최소 길이는 가이드마다 4에서 6 사이로 다르다.

같은 이름의 도구가 DPS에 서로 다른 컴파일 시각으로 두 번 이상 보이면, 정상 도구 이름을 빌린 다른 파일을 의심하는 강한 신호로 다룬다. explorer.exe의 PCA 클라이언트 기록이 비어 있는데 explorer가 방금 시작됐다면 흔적을 지우려고 재시작한 것으로 본다. System Informer의 메모리 편집 창으로 문자열을 지우면 그 창 제목(이름.exe (PID) (0x… - 0x…))이 dwm.exe·explorer.exe·taskhostw.exe 메모리에 남는다고 보고 ) (0x로 검색한다. 게임 프로세스(javaw.exe)의 문자열에서 치트 모듈 이름과 키 바인딩 패턴을 찾는 전용 도구도 쓰이고, SearchIndexer.exe·ctfmon.exe를 보조 대상으로 드는 가이드도 있다.

Sources ​

Next ​