Information Security
Code Injection 본문
[ Code Injection ]
-프로세스에 독립 실행 코드를 삽입한 후 실행하는 기법
-CreateRemoteThread() API를 이용하여 원격 스레드 형태로 실행하므로 Thread 인젝션이라고도 한다.
Windows 메시지 박스를 출력하는 간단한 코드이다.
Ollydbg에서 ThreadProc()를 확인한다.
PUSH 명령어로 MessageBox() API의 문자열 주소를 스택에 저장하고 있다.
1000781C, 10007828 주소는 DLL의 데이터(.rdata) 섹션 영역에 정의된 문자열을 가리킨다.
CALL 명령어의 100060E4 주소는 MessageBox() API의 IAT이다.
DLL 코드에서 사용되는 모든 데이터(파라미터, IAT 등)는 DLL의 데이터(.rdata) 섹션에 위치한다.
이 코드를 DLL로 만들고 다른 프로세스에 삽입하면 코드와 데이터가 같이 메모리에 존재하여 정상적으로 실행이 된다.
하지만 DLL이 아닌 코드(10001000~10001016)만 다른 프로세스에 삽입한다면, 정상적으로 실행되지 않을 것이다.
다른 프로세스에는 1000781C, 10007828, 100060E4에 참조할 데이터가 없기 때문이다.
그래서 Code injection을 위해서는 참조할 데이터까지 인젝션해야 한다.
실습은 간단하다. notepad를 실행시키고, CodeInjection.exe를 실행시키면 notepad에 코드가 인젝션되어 메시지 박스가 출력된다.
이제 Code 인젝션을 위해 구현된 CodeInjection.exe를 봅시다.
위의 코드는 메인 함수에서 호출되는 InjectCode() 함수의 일부분이다. ThreadProc() 스레드 함수에 파라미터로 전달될 값들을 THREAD_PARAM 구조체를 이용하여 셋팅하고 있다.
그리고 API를 호출하여 상대방 프로세스에 메모리를 할당(VirtualAllocExec)하고 데이터(THREAD_PARAM)와 코드(ThreadProc)를 각각 인젝션(WriteProcessMemory)한다. 그리고 원격 스레드를 실행(CreateRemoteThread)시킨다.
이 코드가 인젝션할 코드 ThreadProc()이다.
모든 데이터를 직접 API를 호출하거나 문자열을 정의하지 않고(하드코딩된 주소의 데이터를 참조하지 않고) THREAD_PARM 구조체에 접근해서 사용하고 있다.
코드가 인젝션된 상태의 notepad를 Ollydbg로 보면, ThreadProc()을 확인할 수 있다.
[EBP+8]는 ThreadProc()의 파라미터 lParam으로, InjectCode()에서 열심히 셋팅했던 THREAD_PARAM 구조체를 가리킨다.
이를 ESI에 옮겨 놓고 함수들을 호출할 때 ESI를 기준으로 값에 접근하여 사용한다.
[ESP+8]의 값 960000으로 찾아가보면, THREAD_PARAM 구조체가 나온다.
이렇게 Code 인젝션이 어떻게 구현되는지 살펴 보았다.
Code 인젝션을 사용하는 이유는 DLL로 만들지 않고 코드만 인젝션하기 때문에 메모리를 조금만 차지하고, 흔적을 찾기도 어렵고, 쉽고 편리하게 구현할 수 있기 때문이다.
'Reverse Engineering' 카테고리의 다른 글
Debug 방식의 API 후킹 (0) | 2019.07.04 |
---|---|
PE 패치를 이용한 DLL 로딩 (0) | 2019.06.21 |
DLL Ejection (0) | 2019.06.21 |
DLL Injection - Remote Thread 생성 & 레지스트리 이용 (0) | 2019.06.20 |
Windows Message Hooking (0) | 2019.06.17 |