본문 바로가기
리버싱/기타

Code Injection from BlackEnergy

by 즉흥 2016. 10. 12.
728x90
반응형

BlackEnergy라는 악성코드를 분석하다가 코드 인젝션을 재미있게 하는 코드를 발견해서 정리해서 올려본다.


지금까지 분석해본 악성코드는 CreateProcess API 함수를 이용하여 suspend로 프로세스를 실행한 뒤에 보통 이미지 베이스에 MZ부터 쭉 인젝션 하고 ResumeThread API를 호출했었는데, 이 악성코드는 같은 방법으로 프로세스를 실행하지만 특정 주소에 코드를 인젝션 한 뒤에 쓰레드 컨텍스트를 수정하고 ResumeThread API 함수를 호출한다.




1. CreateProcess API 호출



6번째 인자(Creation_Flags)가 4(Create_Suspended)임을 알 수 있다.




mssrv32.exe(악성코드)의 자식 프로세스(svchost.exe)가 생김.




2. WriteProcessMemory API 호출



CreateProcess API의 10번 째 인자는 PROCESS_INFORMATION구조체로, 이름 그대로 프로세스에 대한 정보를 담고 있는 구조체이다. CreateProcess API 함수가 정상적으로 실행되었을 경우, 자식 프로세스의 정보가 담긴다.



1
2
3
4
5
6
typedef struct _PROCESS_INFORMATION {
  HANDLE hProcess;
  HANDLE hThread;
  DWORD  dwProcessId;
  DWORD  dwThreadId;
} PROCESS_INFORMATION, *LPPROCESS_INFORMATION;
cs


PROCESS_INFORMATION 구조체는 위와 같이 구성되어 있다.




WriteProcessMemory API를 호출하여 자식 프로세스의 0x15110000에 코드를 쓴다.


0x78은 자식 프로세스의 HANDLE 값이다.


ReadProcessMemory API를 호출해서 악성코드 자기 자신에 있는 코드를 읽어오는 부분은 생략했다.




3. ThreadContext 수정 및 ResumeThread API 호출



GetThreadContext API를 호출하여 자식 프로세스의 ThreadContext를 가져온다.



0x74는 자식 프로세스의 쓰레드 핸들이다. CreateProcess API 호출 당시 PROCESS_INFORMATION 구조체에 저장된다.



ThreadContext는 아래와 같이 구성되어 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
typedef struct _CONTEXT {
    DWORD ContextFlags;
    DWORD   Dr0;
    DWORD   Dr1;
    DWORD   Dr2;
    DWORD   Dr3;
    DWORD   Dr6;
    DWORD   Dr7;
    FLOATING_SAVE_AREA FloatSave;
    DWORD   SegGs;
    DWORD   SegFs;
    DWORD   SegEs;
    DWORD   SegDs;
    DWORD   Edi;
    DWORD   Esi;
    DWORD   Ebx;
    DWORD   Edx;
    DWORD   Ecx;
    DWORD   Eax;
    DWORD   Ebp;
    DWORD   Eip;
    DWORD   SegCs;              // MUST BE SANITIZED
    DWORD   EFlags;             // MUST BE SANITIZED
    DWORD   Esp;
    DWORD   SegSs;
    BYTE    ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];
} CONTEXT;
cs

WinNT.h에 정의되어 있음.




ThreadContext.eip를 수정(mov dowrd ptr ss:[ebp-378], edx) 후에 SetThreadContext API로 세팅해주고, ResumeThread API로 쓰레드 재시작.



728x90
반응형

댓글