본문 바로가기

CAT-Security/미분류

Code injection (1) - Basic

Code injection 이란 말그대로 code를 상대방 프로세스에 넣어 버리는 것 입니다.

Dll injection에서 한단계 복잡하게 된 기술로서 주로 악성코드, 바이러스, 쉘코드등에 사용 됩니다.

Dll은 백신에 탐지가 잘 되서, 좀더 복잡한 code injection을 많이 사용 합니다.

code injection은 dll inejction과 달리 완전한 형태의 pe이미지를 가지고 하는것 이 아닌

데이터와 코드만을 가지고 상대방 프로세스에 주입시킨후, 상대방 api주소를 구한뒤 원격으로 실행 시키는것이기 때문에 기법이 dll보다는 살짝 어렵다고 알려져 있습니다.

다른프로세스 메모리에 접근할 때 사용되는 api 입니다.

Openprocess

주입할 대상 process에 대한 핸들을 얻는다.

VirtualAllocEx

대상 process 내의 메모리를 할당 한다.

WirteprocessMemory

할당된 메모리에 기록 한다.

CreateRemoteThread

대상 Process에 Thread를 생성 한다. LoadLibrary를 호출 합니다.

그림으로 표현하면 다음과 같습니다. 순서대로 1,2,3으로 진행 됩니다.

8.jpg

소스 분석

Main 소스 부분 입니다.

1.jpg

argv로 해당 프로세스의 PID를 얻어서 그것으로 InjectCode의 함수의 인자로 넣습니다.

이때의 해당 프로세스는 내것이 아닌 상대방 프로세스 입니다.

2.jpg

_THREAD_PARAM의 부분이 바로 인젝션의 스트링값이 저장될 공간 입니다.

LoadLibraryA(), GetProcAddress()

"user32.dll", "MessageBoxA"

"www.lapislazull.tistory.com", "lazull"

등을 가져와서 쓸수 있게 선언 하는 부분 입니다.

나머지 단순 C언어 문법 부분 입니다.

3.jpg

hMod 부분

pPram->pFunc[0] -> kernel32!LoadLibraryA()

pParam->szBuf[0] -> "user32.dll"

LoadLibrary("user32.dll") 이 만들어 지는 부분 입니다.


pFunc 부분

pPram -> pFunc[1] -> Kernel32!GetProcAddress()

pParam->szBuf[1] -> "MessageBoxA"

GetprocAddress("MessageBoxA")이 만들어 지는 부분 입니다.


그리고 마지막 코드는

pFunc(NULL, www.lapislazull.tistory.com, "lazull", MB_OK) 부분 입니다.


ThreadProc 함수의 전체 코드는 다음과 같습니다.

hMod = LoadLibrary("user32.dll");

pFunc = GetprocAddress("MessageBoxA");

pFunc(NULL, www.lapislazull.tistory.com, "lazull", MB_OK);

이 함수 코드의 개념이 중요 합니다.


Code Injection 기법의 핵심은 독립 실행 코드를 인젝션 하는 것 입니다.

그러기 위해서는 코드와, 데이터를 같이 인젝션을 시켜야 합니다.

그리고 인젝션 하는 코드는 데이터를 정확히 참조 할 수 있어야 합니다.

위 함수의 경우 직접 API를 호출하지않고 문자열도 직접 정의해서 사용하지않습니다.

그저 넘어온 인자인 THREAD_PARAM 구조체에서 가져다 사용 하고 있습니다.

4.jpg


일반적인 프로그램의 소스의 경우 바로 이렇게 됩니다.

코드인젝션의 코드를 다른프로세스에 그대로 인젝션 한다면 정상적으로 실행되지 않습니다.

그 이유는 코드에서 사용되는 주소의 내용이 상대방 프로세스에 없기 때문 입니다.

따라서 주소에 해당하는 문자열과 API주소를 같이 인젝션 해야 합니다.(그래서 위와같은 코드를 쓰는것)

그 뒤 인젝션된 코드에서 데이터의 주소를 정확히 참조하도록 프로그래밍 되어야 합니다.

이와 같은 조건을 만족하기 위해서 해당 함수안에 있는 dll의 주소를 가져와 mesaages함수의 주소를 구하고 넣은 문자열등을 인자값으로 받아와서 호출하게 하는 것 입니다.

LoadLibraryA()와 GetprocAddress()만 있으면 모든 라이브러리 함수를 호출 할 수 있습니다.

이유는 대부분의 유저모드 프로세스는 kernel32.dll을 로딩하므로 LoadLibraryA(), GetProcAddress()의 주소를 직접 넘기는 것은 크게 무리가 없습니다. 다만 저 dll을 로딩하지 안흔 프로세스도 있긴 합니다.

OS가 달라지면 같은 모듈이라도 주소가 달라지게 됩니다.


5.jpg

6.jpg

7.jpg

전체적인 구조

OpenProcess()

// data : THREAD_PARAM

VirtualAllocEx()

WriteProcessMemory()

//code :ThreadProc()

VirtualAllocEx()

WriteprocessMemory()

createRemoteThread()

이와 같습니다.

상대방 프로세스에 data와 code를 각각 메모리 할당하고 인젝션 해주는것 입니다.

그리고 마지막으로 CreateRemoteThread() API를 이용해서 원격 스레드를 실행 시키는 것 입니다.

'CAT-Security > 미분류' 카테고리의 다른 글

[api]모달과 모달리스의 차이  (0) 2013.03.25
Callback(콜백 함수) 정리  (0) 2013.01.17
Python으로 레이싱 갤러리 사진 긁어 오기  (1) 2012.12.20
python 공부 자료  (0) 2012.12.20
kernel object 와 handle 정리  (2) 2012.11.29