[태그:] 쓰레드 하이재킹

  • 📘 Windows Thread Hijacking 기반 프로세스 인젝션 분석 개요

    스레드 하이재킹(Thread Hijacking) 동작 원리 분석

    Windows 악성코드 분석 시 자주 관찰되는 기법 중 하나가 Thread Hijacking 기반 프로세스 인젝션임.
    이는 기존의 정지된 스레드를 일시적으로 중단한 뒤, 그 스레드 컨텍스트를 수정해 특정 페이로드를 실행시키는 구조로 동작.
    이번 분석은 《리버싱 핵심원리》의 흐름에 따라 스택 프레임, 제어 흐름, 레지스터 컨텍스트 변조,
    PE 구조 기반 페이로드 위치 산정, 동적 API 조회 등을 중심으로 기록식으로 정리함.

    리버싱 기록


    1. 개념적 C 스타일 구조(비실행·고위험 요소 제거)

    아래 코드는 일반적인 Thread Hijacking의 “구조”를 관찰 용도로만 반영한 예시.

    // 구조 예시
    typedef void* HTHREAD;
    typedef struct _CTX { unsigned long regs[8]; } CTX;
    
    void conceptual_thread_hijack(HTHREAD t, unsigned char* payloadBase) {
        CTX ctx = {0};
    
        // 1) 스레드 정지
        suspend_thread(t);
    
        // 2) 컨텍스트 조회
        get_thread_context(t, &ctx);
    
        // 3) 명령 포인터(EIP/RIP) 변경
        //    실제 주소 계산은 생략된 개념적 표현
        ctx.regs[0] = (unsigned long)(payloadBase);
    
        // 4) 수정된 컨텍스트 주입
        set_thread_context(t, &ctx);
    
        // 5) 스레드 재개
        resume_thread(t);
    }
    

    이 함수는 실제 실행이 불가능하도록 설계되었지만,
    실제 분석 시 “관찰 포인트”가 되는 흐름을 그대로 나타냄.


    2. Assembly 기반의 개념적 컨텍스트 변조 흐름(비실행)

    아래 코드는 일부 세부사항은 제거된 구조 예시.

    PSEUDO_HIJACK:
        push ebp
        mov  ebp, esp
    
        ; --- 스레드 일시 정지 ---
        ; (구체적 API 호출 생략)
    
        ; --- 컨텍스트 조회 ---
        ; 컨텍스트 구조체가 EAX에 저장된다고 가정
        mov  eax, [ebp-0x20]
    
        ; --- 명령 포인터 변경 ---
        ; 원래 EIP를 읽어온 뒤 페이로드 기점으로 가정한 값으로 치환
        mov  edx, [eax + CTX_EIP]      ; 원래 EIP
        mov  [eax + CTX_EIP], 0xDEADBEEF  ; 더미 주소
    
        ; --- 수정된 컨텍스트 쓰기 ---
        ; (구체적 API 호출 생략)
    
        leave
        ret
    

    이 흐름에서 중요한 건 다음입니다:

    • **컨텍스트(스레드 레지스터 집합)**는 구조체이며
      내부 필드에 EIP/RIP, ESP/RSP, EFLAGS, general-purpose register가 포함됨
    • 페이로드 실행을 위해 **명령 포인터(RIP/EIP)**가 수정됨
    • 해당 스레드가 재개되면 원래 코드가 아닌 새로운 주소로 흐름이 이동함
    • 이는 제어 흐름 교란(Control Flow Subversion)의 대표 패턴

    3. 제어 흐름 관찰 포인트

    Thread Hijacking 분석 시 포렌식·리버싱 관점에서 주로 확인하는 지점은 다음과 같음:

    1. SuspendThread / GetThreadContext / SetThreadContext / ResumeThread 호출 흔적
      • API 이름이 난독화되어 있을 수 있음
      • PE의 Import Table이 비어 있고, Export Directory 파싱으로 직접 API 주소를 가져오는 경우 빈번
    2. 레지스터 컨텍스트 구조 변형 여부
      • EIP/RIP가 갑작스럽게 비정상 주소로 이동
      • 스택 프레임이 전환되며 ESP/RSP가 자연스럽지 않게 변경
    3. PE 페이로드 구조¶
      • 패킹된 PE의 .text 외부에 존재하는 임의 메모리 공간
      • RWX 보호 속성의 세션 기반 메모리 영역(mmap된 구간 등)
    4. 실행 재개 후 흐름
      • 재개 직후 디스어셈블리 패턴이 정상 함수 프롤로그가 아닌
        NOP, JMP, 단순 MOV 시퀀스 등으로 시작하는지 관찰

    4. 동적 API 해결(PEB 기반) 개념 흐름

    실제 악성코드는 보통 Import Table을 제거하고 PEB 기반으로 API를 직접 파싱.
    아래는 책임 회피를 위해 개념적 형태만 제시한 예시.

    // 비실행 예시
    void* resolve_api_conceptually(const char* dllName, const char* funcName) {
        // 1) PEB → LDR 접근
        // 2) InMemoryOrderModuleList 순회
        // 3) dllName 비교
        // 4) Export Directory 파싱
        // 5) funcName 해시 또는 복호화 후 비교
        // 6) 주소 반환
        return 0;
    }
    

    포인트:

    • 해시 기반 문자열 비교
    • Export Directory의 AddressOfNames / AddressOfFunctions 사용
    • 악성코드 포렌식에서는 이 부분에서 암호화 루틴이 가장 자주 관찰됨

    5. 분석자가 확인해야 할 Windows Internals 포인트

    ✔ TEB / PEB 구조

    • PEB에서 LDR 위치
    • BeingDebugged flag
    • ImageBaseAddress 관찰

    ✔ 스레드 컨텍스트 구조

    • CONTEXT.Eip / Rip
    • SegGs 기반 접근(TLS 등)
    • 스택 기반 주소 전환 여부 확인

    ✔ 메모리 맵

    • RWX 섹션 추적
    • Unbacked 메모리(파일 매핑되지 않은 공간)

    ✔ 패커 흔적

    • OEP 복원 전 stub
    • API name 암호화
    • 호출 규약 교란(calling convention confusion)

    6. 조사 요약

    항목분석 포인트
    제어 흐름 분석EIP/RIP 변조, OEP 전환, JMP 패턴
    스택 프레임Thread Context 변경 전·후 비교
    PE 구조Import Table 비어 있음, Export 재파싱
    디스어셈블리 패턴비정상 프롤로그, 인위적 MOV/JMP
    암호화 루틴해시·XOR 기반 스트링 복호화 흔적
    API 후킹Thread Hijack 뒤 CreateRemoteThread와 구별 필요

    ✨ 마무리 한 줄

    Thread Hijacking은 프로세스 인젝션 기법 중에서도 제어 흐름 교란의 핵심 패턴을 가장 잘 드러내며,
    스레드 컨텍스트와 PEB 기반 동적 API 해석 흐름의 상호작용은 리버스 엔지니어링에서 반드시 짚어야 할 분석 축입니다.


    📍 Written by Code & Compass