Information Security

DLL Injection - Remote Thread 생성 & 레지스트리 이용 본문

Reverse Engineering

DLL Injection - Remote Thread 생성 & 레지스트리 이용

leeeeye321 2019. 6. 20. 14:17

[ DLL Injection ]

-실행 중인 프로세스에 LoadLibrary() API를 스스로 호출하도록 명령하여 원하는 DLL을 로딩시키는 것

-삽입된 DLL은 이미 프로세스에 로딩되어 있는 다른 DLL과 마찬가지로 프로세스 메모리에 대한 권한을 가지게 된다.


DLL이 로딩되면 DLLMain() 함수가 실행되는데, 이 switch 문에 기능을 개선하거나 버그를 패치하는 등의 사용자가 원하는 코드를 넣을 수 있다. 


1. 원격 스레드 생성하여 DLL 인젝션 구현하기 - CreateRemoteThread()

(리버싱 핵심 원리 https://reversecore.com/104)

notepad.exe에 myhack.dll을 인젝션하는 실습을 할 것이다. 


myhack.dll이 로딩되면 OutputDebugString()에 의해 해당 문자열을 출력되어 dll이 인젝션되었음을 확인할 수 있고, CreateThread() 함수 호출로 TreadProc 스레드를 실행된다. 


ThreadProc의 내용은, URLDownloadToFile() API를 이용하여 DEF_URL(http://www.naver.com/index.html)을 다운받는 것이다.


InjectDll.exe는 DLL 인젝션 유틸리티이다. 코드가 생소하므로 자세히 공부합시다.


OpenProcess()를 이용하여 PROCESS_ALL_ACCESS 권한을 가진 notepad.exe 프로세스 핸들을 얻는다. 이제 이 핸들(hProcess)를 이용하여 해당 프로세스를 제어할 수 있다.


우리는 notepad.exe에게 인젝션 할 dll의 경로를 알려줘야 한다. 일단 VirtualAllocEx()로 해당 프로세스 메모리에 경로 길이만큼의 버퍼를 할당한다. 리턴 값(pRemoteBuf)은 notepad.exe에 할당된 버퍼 주소이다.


그리고 WriteProcessMemory()로 할당한 버퍼에 경로(szDllPath)를 써준다.


우리는 LoadLibraryW를 호출하기 위해 주소를 얻어야 한다.

kernel32.dll(그 외 Windows 핵심 DLL도)은 프로세스마다 같은 주소에 로딩되기 때문에 굳이 notepad.exe에 로딩된 임포트 주소를 구하지 않아도 된다. DLL Injection이 바로 이 취약점을 이용한 것이다.

InejctDll.exe에 로딩되어 있는 kernel32.dll가 소유한 LoadLibraryW()의 주소를 얻는다.


이제 notepad.exe에 LoadLibrary() API를 스스로 호출하도록 명령해야 한다.

우리는 이를 위해 다른 프로세스에게 스레드를 실행시켜주는 함수 CreateRemoteThread()를 사용할 것이다.


* LoadLibrary() API를 호출하도록 해야 하는데 스레드를 실행시키는 함수를 사용하는 이유는,

이렇게 ThreadProc()과 LoadLibrary()가 함수 형태가 똑같기 때문이라고 한다.


CreateRemoteThread() API의 파라미터는 어떻게 설정할까? 

lpStartAddress에는 스레드 함수 주소 -> LoadLibrary()의 주소 pThreadProc,

lpParameter에는 스레드 파라미터 주소 -> 인젝션할 DLL 경로의 주소 pRemoteBuf을 넣고 호출하면 된다.

이렇게 소스 코드들을 살펴 보았으니 실습을 해봅시다. 


 

* DebugView - 시스템에서 실행되는 프로세스들이 출력하는 모든 디버그 문자열을 가로채서 보여주는 유틸리티이다.

이것으로 인젝션의 성공을 확인할 수 있다.

 

1900은 notepad.exe의 PID이다. Dbgview를 실행시켜 놓고, InjectDll.exe를 실행하여 notepad.exe로 DLL 인젝션을 시도한다.

 

DebugView을 확인해보면, 문자열이 출력되어 있다. 이는 myhack.dll 인젝션이 성공하여 DllMain() 함수의 OutputDebugString() API가 호출된 것이다.

 

Process Explorer에서 notepad.exe에 로딩된 dll 목록을 확인했다. 역시 myhack.dll을 확인할 수 있다.


notepad.exe에 인젝션된 myhack.dll이 제 기능을 수행하여 index.html이 다운로드되었다.

 

Naver 페이지 확인


2. 레지스트리 이용하여  DLL 인젝션 구현하기 - AppInit-DLLs

User32.dll은 프로세스에 로딩될 때 레지스트리 항목 AppInt_DLLs를 읽어서 값이 존재하면 LoadLibrary()를 이용하여 사용자 DLL을 로딩한다. 이를 이용하여 AppInt_DLLs에 인젝션을 원하는 DLL의 경로를 입력하고 재부팅을 하면, User32.dll이 로딩된 모든 프로세스에 해당 DLL이 인젝션된다. 그럼 이제 실습을 해봅시다.


myhack2.dll은 자신을 로딩한 프로세스가 notepad.exe이면 IE를 숨김 모드(SW_HIDE)로 실행한다.

실습 파일을 준비하고, cmd에서 레지스트리 에디터 regedit.exe를 실행한다.


AppInit_DLLs가 있는 곳으로 찾아간다. 아래에 나온 긴 경로를 따라 가세요.


값을 인젝션할 dll의 경로로 변경하고 변경 사항을 적용하기 위해서 시스템을 재부팅한다. 


재부팅이 되었으면 Process Explorer에서 모든 프로세스에 myhackk2.dll이 인젝션된 것을 확인한다.


notepad를 실행하면 notepad에도 인젝션된다. iexplore.exe가 숨김 속성으로 실행된 것도 확인한다.

이렇게 DLL INJECTION을 두 가지 방법으로 구현해 보았다. 다음에는 DLL EJECTION을 알아 봅시다.

'Reverse Engineering' 카테고리의 다른 글

PE 패치를 이용한 DLL 로딩  (0) 2019.06.21
DLL Ejection  (0) 2019.06.21
Windows Message Hooking  (0) 2019.06.17
EAT(Export Address Table)  (0) 2019.06.12
IAT(Import Address Table)  (0) 2019.06.12