티스토리 뷰

Reversing/Reversing Tech

[Reversing] DLL Injection

정짱 정뚱띵 2020. 2. 4. 05:33

[Reversing] DLL Injection


  1. CreateRemoteThread() API을 이용한 인젝션 

DLL 인젝션을 하기위해서는 CreateRemoteThread()을 이용하여 스레드를 생성하는 것이 아니라 LoadLibraryA()을 호출해야 된다. 즉, LoadLibraryA()을 실행 시켜 CreateRemoteTh 

read()의 인자에 인젝션 할 DLL의 경로를 적어 프로세스가 스스로 LoadLibrary()을 호출하는 것이다. 

이러한 방법이 가능한 이유를 살펴보면 먼저 CreateRemoteThread()의 인자 중 (LPTHREA 

D_START_ROUTINE)llBaseAddress는 llBaseAddress가 가르키는 함수 호출 시 전달할 인자를 지정하는데 그게 ThreadProc 콜백 함수이다. 그런데 ThreadProcLoadLibrary는 함수 원형이 같아 return 전달 인자를 4bte씩 받게 되어 해당 방법이 가능한 걸 확인 할 수 있다. 


 //option 1: CreateRemoteThread 

case 1: 

{ 

hThread = CreateRemoteThread(hProcessNULL0, (LPTHREAD_START_ROUTINE)llBaseAddresslpBaseAddress0, (LPDWORD)(&ThreadId)); 

if (hThread == NULL) 

{ 

ErrorExit(TEXT("CreateRemoteThread")); 

} 

break; 

} 


  1. NtCreateThreadEx(), RtlCreateUserThread() API을 이용한 인젝션 

먼저 NtCreateThreadEx()는 CreateRemoteThread() 함수의 내부에서 최종적으로 호출하는 함수이다.  

(CreateRemoteThread() → CreateRemoteThreadEx() → NtCreateThreadEx()) 

Windows OS 버전에 따라 사용하는 API가 달라지는데 Windows7 이후로 CreateRemote

Thread() API을 이용한 인젝션에 제한이 생기면서 ntdll.dll에 있는 NtCreateThreadEx() API을 사용하게 되었다고 한다. 확인 시 Windows OS 버전(Windows 10)에 따라 NtCreateTh 

readEx() 사용이 안되는 것을 확인 하였다. 때문에 RtlCreateUserThread()을 사용을 권장한다.  

(RtlCreateUserThread() → NtCreateThreadEx()) 


 //option 2: NtCreateThreadEx 

case 2: 

{ 

prototype_NtCreateThreadEx pfnNtCreateThreadEx = NULL; 

PVOID pvEncodedPtr = NULL; 

GetFunctionAddressFromDll("ntdll.dll""NtCreateThreadEx", (PVOID *)&pfnNtCreateThreadEx); 

pfnNtCreateThreadEx(&hThread, GENERIC_ALL, NULLhProcess, (LPTHREAD_START_ROUTINE)llBaseAddresslpBaseAddress, FALSE, NULLNULLNULLNULL); 

if (hThread == NULL) 

{ 

ErrorExit(TEXT("NtCreateThreadEx")); 

} 

break; 

} 

//option 3: RtlCreateUserThread 

case 3: 

{ 

prototype_RtlCreateUserThread pfnRtlCreateUserThread = NULL; 

PVOID pvEncodedPtr = NULL; 

GetFunctionAddressFromDll("ntdll.dll""RtlCreateUserThread", (PVOID *)&pfnRtlCreateUserThread); 

pfnRtlCreateUserThread(hProcessNULL0000llBaseAddresslpBaseAddress&hThreadNULL); 

if (hThread == NULL) 

{ 

ErrorExit(TEXT("RtlCreateUserThread")); 

} 

break; 

} 


  1. DLL Injection 정리 

마지막으로는 Msg_box(DLL) 소스코드와 DLL Injection 실행 화면 단계에 대해 기술하였다. 

 // Msg_box.cpp(DLL 소스코드) 

#include "stdafx.h" 

BOOL APIENTRY Msg_box( HMODULE hModule, 

                       DWORD  ul_reason_for_call, 

                       LPVOID lpReserved 

 ) 

{ 

switch (ul_reason_for_call) 

{ 

    case DLL_PROCESS_ATTACH: { 

        MessageBox(nullptrL"injection success"L"dll injection", MB_OK); 

    } 

case DLL_THREAD_ATTACH: 

case DLL_THREAD_DETACH: 

case DLL_PROCESS_DETACH: 

break; 

} 

return TRUE; 

} 


대상 프로세스의 핸들을 얻은 뒤 버퍼를 할당을 한다. 이후 인젝션 할 데이터를 삽입한 후 상황에 따른 API를 이용하여 인젝션이 진행되는 것을 확인 할 수 있다. 


OpenProcess() 대상 프로세스 핸들 Get

VirtualAllocEx() 대상 프로세스 버퍼 할당

WriteProcessMemory() 데이터 삽입

Kernel32.dll 핸들 Get

Ntdll.dll 핸들 Get

GetProcAddress() → LoadLibrary() Address Get

Windos OS Version 따라 API 결정

CreateRemoteThread()

실행 & DLL 로드

NtCreateThreadEx()/

RtlCreateUserThread()

실행 & DLL 로드

 1 – DLL Injection 단계


각 옵션에 따라 성공 유무를 확인 할 수 있었으며, Windows OS Version에 따라 (그림 1)와 같은 성공 문구와 Msg_box.dll이 추가되는 걸 확인 할 수 있었다. 

 

그림 1 – DLL Injection 실행 화면 


첨부파일

댓글
공지사항
«   2020/02   »
            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 28 29
Total
138,729
Today
2