COMMENTS (0)
댓글은 익명으로 작성되며, 삭제 비밀번호를 설정하면 본인만 삭제할 수 있습니다. 비밀번호를 설정하지 않은 댓글은 누구나 삭제할 수 있습니다.
Thread Execution Hijacking(T1055.003) 분석. 기존 스레드의 실행 주소를 바꿔 셸코드를 실행하는 기법의 구조, DLL/PE Injection과의 비교, Lumma Stealer/Zloader 사례, 2025년 Waiting Thread Hijacking 진화까지.
댓글은 익명으로 작성되며, 삭제 비밀번호를 설정하면 본인만 삭제할 수 있습니다. 비밀번호를 설정하지 않은 댓글은 누구나 삭제할 수 있습니다.
DLL Injection은 디스크에 파일을 남긴다. PE Injection은 새 스레드를 생성한다. 두 기법 모두 EDR이 탐지할 수 있는 흔적을 남긴다.
Thread Execution Hijacking은 이 둘의 약점을 모두 제거한다. 디스크에 아무것도 쓰지 않고, 새 스레드도 만들지 않는다. 이미 실행 중인 스레드를 잠시 멈추고, 실행 주소를 바꾼 뒤, 다시 풀어주는 것이다.
Lumma Stealer가 2024년 1월 이 기법으로 PNG 파일에 숨긴 셸코드를 주입했다. Zloader는 msiexec.exe의 스레드를 납치하여 직접 syscall로 EDR 후킹까지 우회했다. 2025년에는 Check Point Research가 더 진화한 변종인 Waiting Thread Hijacking을 발견했다. SuspendThread 호출 자체를 생략하는 기법이다.
Thread Execution Hijacking은 6단계 API 호출로 구성된다.
1단계: 스레드 탐색
CreateToolhelp32Snapshot으로 대상 프로세스의 스레드 목록을 가져온다. Thread32First와 Thread32Next로 순회하며 적절한 스레드를 선택한다.
2단계: 스레드 정지
OpenThread로 대상 스레드의 핸들을 획득한다. 필요한 권한은 THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME이다. SuspendThread로 스레드를 정지시킨다. 정지된 동안 스레드는 어떤 코드도 실행하지 않는다.
3단계: 메모리 할당과 셸코드 주입
VirtualAllocEx로 대상 프로세스에 실행 가능한 메모리를 할당한다. WriteProcessMemory로 셸코드를 이 영역에 쓴다.
4단계: 실행 주소 변경
GetThreadContext로 현재 CPU 레지스터 상태를 가져온다. x64에서는 RIP(명령 포인터), x86에서는 EIP를 셸코드 주소로 변경한다. SetThreadContext로 변경된 레지스터를 적용한다.
5단계: 실행 재개
ResumeThread로 스레드를 다시 실행한다. 스레드는 원래 코드가 아니라 공격자의 셸코드를 실행한다.
| 비교 항목 | DLL/PE Injection | Thread Hijacking |
|---|---|---|
| 디스크 파일 | DLL은 필요, PE는 불필요 | 불필요 |
| 새 스레드 생성 | 둘 다 생성 | 기존 스레드 재사용 |
| 모듈 목록 등록 | DLL만 등록 | 없음 |
| 탐지 난이도 | DLL 낮음, PE 중간 | 높음 |
| 구현 복잡도 | DLL 낮음, PE 높음 | 중간 |
공격자가 Thread Hijacking을 선택하는 상황:
EDR이 CreateRemoteThread를 감시하는 환경에서, 이미 실행 중인 정상 프로세스(예: explorer.exe, svchost.exe)에 코드를 주입해야 할 때 선택한다. DLL Injection은 파일을 남기고, PE Injection은 새 스레드를 만든다. 둘 다 탐지될 위험이 있을 때 Thread Hijacking이 남는다.
핵심 차이는 새 스레드를 만들지 않는다는 점이다. EDR은 CreateRemoteThread 호출을 프로세스 인젝션의 핵심 지표로 감시한다. Thread Hijacking은 이 API를 사용하지 않는다.
DLL Injection(T1055.001)은 LoadLibrary를 호출하므로 DLL 로드 이벤트가 기록된다. PE Injection(T1055.002)은 디스크 파일은 없지만 CreateRemoteThread로 새 스레드를 만든다. Thread Hijacking은 둘 다 하지 않는다.
인코딩된 PNG 파일에 셸코드를 숨긴 뒤, Thread Hijacking으로 explorer.exe에 주입했다. 정적 탐지를 우회하기 위해 페이로드를 이미지 파일로 위장한 것이다. 감염되면 브라우저 비밀번호, 암호화폐 지갑, 세션 쿠키를 탈취한다. Lumma Stealer는 2025년 5월 Microsoft가 도메인 2,300개를 압수할 때까지 인포스틸러 시장 1위를 유지했으며, 전 세계 39만 대 이상의 Windows PC가 감염된 것으로 추정된다.
msiexec.exe의 스레드를 납치하여 CyberMesh.exe를 주입했다. 주목할 점은 GetContextThread와 SetContextThread를 직접 syscall로 호출했다는 것이다. 유저모드 API를 거치지 않으면 EDR의 인라인 후킹을 우회할 수 있다. ACRStealer(#321)가 ntdll을 디스크에서 재로드한 것과 같은 목적이다.
Check Point Research가 2025년에 발견한 진화형이다. 기존 Thread Hijacking의 가장 큰 약점인 SuspendThread/ResumeThread 호출을 완전히 제거했다.
기존 방식의 문제:
SuspendThread와 ResumeThread는 EDR이 감시하는 API다. 특히 다른 프로세스의 스레드를 정지시키는 행위는 의심스럽다.
Waiting Thread Hijacking의 차이:
SuspendThread를 호출하지 않는다 (스레드가 이미 멈춰있으므로)SetThreadContext 대신 스택의 리턴 주소를 덮어쓴다필요한 권한도 THREAD_SET_CONTEXT가 아닌 THREAD_GET_CONTEXT만으로 충분하다. 여러 상용 EDR을 우회한 것으로 보고됐다.
Sysmon Event ID 10(ProcessAccess)으로 크로스 프로세스 핸들 획득을 감시한다.
<Sysmon schemaversion="4.90">
<EventFiltering>
<RuleGroup groupRelation="or">
<ProcessAccess onmatch="include">
<GrantedAccess condition="is">0x0012</GrantedAccess>
</ProcessAccess>
</RuleGroup>
</EventFiltering>
</Sysmon>
0x0012는 THREAD_SET_CONTEXT(0x0010) | THREAD_SUSPEND_RESUME(0x0002)를 합친 값이다. 다른 프로세스의 스레드에 이 권한으로 접근하면 Thread Hijacking을 시도하는 것일 수 있다.
title: Thread Execution Hijacking 의심 행위 탐지
status: experimental
description: 크로스 프로세스 스레드 컨텍스트 변경 권한 획득 탐지
date: 2026-04-09
references:
- https://attack.mitre.org/techniques/T1055/003/
logsource:
category: process_access
product: windows
detection:
selection:
GrantedAccess|contains:
- '0x0012'
- '0x001F'
filter_system:
SourceImage|endswith:
- '\csrss.exe'
- '\lsass.exe'
- '\svchost.exe'
condition: selection and not filter_system
level: high
테스트 ID: 578025d5-faa9-4f6d-8390-aae527d503e1
$notepad = Start-Process notepad -passthru
Start-Process "$PathToAtomicsFolder\T1055.003\bin\InjectContext.exe"
Start-Sleep -Seconds 5
Stop-Process $notepad.id
notepad.exe의 스레드를 납치하여 msfvenom MessageBox 셸코드를 주입한다. 성공하면 "Atomic Red Team" 캡션의 메시지 박스가 나타난다.
Thread Execution Hijacking은 프로세스 인젝션 12가지 변종 중 탐지가 가장 어려운 기법 중 하나다. 디스크 파일 없음, 새 스레드 없음, 모듈 목록 변경 없음. EDR이 주로 감시하는 3가지 지표를 모두 회피한다.
방어 우선순위:
THREAD_SET_CONTEXT 권한을 포함한 크로스 프로세스 접근을 모니터링한다Microsoft-Windows-Kernel-Process 프로바이더로 스레드 컨텍스트 변경을 커널 레벨에서 탐지한다WriteProcessMemory 호출은 리턴 주소 덮어쓰기를 의미하며, 정상적인 프로세스 간 통신에서는 발생하지 않는다AI 활용 안내 이 글은 AI(Claude)의 도움을 받아 작성되었습니다. 인용된 통계와 사례는 참고 자료에 명시된 출처에 근거하며, 설명을 위한 일부 표현은 각색되었습니다.
면책 조항 본 글은 보안 인식 제고를 위한 교육 목적으로 작성되었습니다. 언급된 공격 기법을 실제로 시도하는 행위는 「정보통신망법」, 「형법」 등에 따라 처벌받을 수 있으며, 본 블로그는 이에 대한 법적 책임을 지지 않습니다.
KW_PROTECT_0