물먹는산세베리아

DLL Ejection 본문

Waregame & CTF/Reversing

DLL Ejection

suntall 2021. 11. 13. 22:15

DLL 이젝션(DLL Ejection)이란?

프로세스에 강제로 삽입한 DLL을 빼내는 기법으로, DLL 인젝션의 동작 원리와 기본 동작 원리는 같다.

대상 프로세스로 하여금 FreeLibrary() API를 호출하도록 만든다.

* DLL 인젝션은 LoadLibrary() API 호출

 

DLL 이젝션 과정

CreateRemoteThread()의 lStartAddresss 파라미터에 FreeLibrary() API 주소를 넘기고, lpParameter 파라미터에 이젝션할 DLL의 HANDLE을 넘겨준다.

 

1. 프로세스에 로딩된 DLL 정보 구하기

//dwPID = notepad 프로세스 ID
//TH32CS_SNAPMODULE 파라미터를 이용해서 notepad 프로세스에 로딩된 DLL 이름을 얻음
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);

CreateToolhelp32napshot() API를 이용하면 프로세스에 로딩된 모듈 정보를 얻을 수 있다.

 

2. 대상 프로세스 핸들 구하기

if(!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE< dwPID)))
{
    _tprintf(L"OpenProcess(%d) failed!!! [%d]\n", dwPID, GetLastError());
    return FALSE;
}

OpenProcess()

프로세스 ID를 이용해 대상 프로세스(notepad)의 프로세스 핸들을 구한다. 

 

3. FreeLibrary() API 주소 구하기

    hModule = GetModuleHandle(L"kernel32.dll");
    pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hModule, "FreeLibrary");

GetModulerHandle(), GetProcAddress()

notepad 프로세스로 하여금 스스로 FreeLibrary() API를 호출하게 하려면 FreeLibrary() 주소를 알아야 한다. 위 코드를 통해 EjectDll.exe 프로세스에 로딩된 Kernel32!FreeLibrary 주소를 얻어오는 걸 보면  FreeLibrary주소가 모든 프로세스에 대해 동일하다는 점을 알 수 있다.

 

4. 대상 프로세스에 스레드를 실행시킴

 hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, me.modBaseAddr, 0, NULL);

 

pThreadProc 파라미터는 FreeLibrary() API의 주소이고, me.modBaseAddr 파라미터는 이젝션하기 ㄹ원하는 DLL의 로딩주소이다. 스레드 함수로 FreeLibrary함수를 지정해 스레드 파라미터에 DLL 로딩 주소를 넘겨주면 대상 프로세스에서는 FreeLibrary() API가 성공적으로 호출한다. (CreateRemoteThread()는 원래 외부 프로세스에 스레드 함수를 실행시키는 것이 목적인데 여기서 스레드 함수는 FreeLibrary()가 된다.)

 

전체코드

 

GitHub - oo7-0310/SWING_reversing_study

Contribute to oo7-0310/SWING_reversing_study development by creating an account on GitHub.

github.com

 

'Waregame & CTF > Reversing' 카테고리의 다른 글

LAB 6-3 분석  (0) 2021.11.20
[dream.io]rev 7, 8  (0) 2021.11.13
DLL Injection  (0) 2021.11.13
패킹, UPX, notepad 언패킹  (0) 2021.10.06
[dreamhack.io] rev-basic-3  (0) 2021.10.06