DLL Injection
1.DLL(Dynamic Link Library) 파일이란?
먼저 Library는 함수,데이터,타입들의 여러가지 프로그래밍 요소들의 집합니다. 자주사용되는 함수를 미리 만들어서 모아놓은것을 Library라고 한다.
library는 정적링크 (Static link library) 와 동적링크(Dynamic Link) 방식이 있는데 동적링크 방식을 사용한 것이 DLL이다.
정적링크 방식을 사용하면 컴파일할때 라이브러리 코드를 실행파일에 복사하기 떄문에 한번컴파일하게되면 라이브러리파일 없이도 실행이 가능하다.
동적링크 방식을 사용하면 실행파일 실행시에 라이브러리에 실행파일이 연결된다. 실행파일에는 라이브러리에있는 함수의 정보만 포함되고 실제함수의
코드는 복사되지 않기때문에 실행파일이 작아진다. 또 필요할때 가져다가 사용하기때문에 메모리사용에 효율적이다.
ex> 워드프로그램을 이용하여 문서작업을 할때에는 프린터를 이용하지 않기때문에 프린트관련 라이브러리는 메모리에 적재되지 않는다. 만약
사용자가 문서를 출력하고자 한다면 그때 프린트 관련 라이브러리가 메모리에 적재, 실행된다.
2. DLL Injection ?
다른 프로세스에 특정 DLL파일을 강제로 삽입하는것.
DLL Injection의 원리는 외부에서 다른프로세스가 LoadLibrary() API를 호출하도록 하는것이기때문에 일반적인 DLL loading과
마찬가지로 강제 삽입된 DLL의 DllMain() 함수가 실행된다.
아래 사진은 notepad.exe프로세스에 임의로 만든 DLL파일을 강제로 삽입했을때 notepade.exe 프로세스의 구조이다.
3. DLL Injection 을 사용하는 목적
프로세스에 삽입된 DLL파일은 프로세스 메모리에 대한 정당한 접근권한을 가지기 때문에 사용자가 원하는 모든일을 수행할수 있다.
이런점을 이용 해서 버그패치,기능추가 등등 다양한곳에 이용할수 있지만 대부분 악의적인 용도(악성코드)로 사용된다.
ex> 유해 프로그램,사이트 차단프로그램 , API Hooking, 악성코드 등등
4. 구현방법
4-1 AppInit_DLLs
쉬운방법으로는 AppInit_DLLs를 이용하는 방법이 있다.
windows에서 기본으로 제공하는 레지스트리 키 중에 AppInit_DLLs 라는 것이 있는데 AppInit_DLLs 값에 인젝션을 원하는 DLL의 경로를 써주고
재부팅하면 Windows는 재부팅하면서 실행되는 모든 프로세스에 해당 DLL을 인젝션 시킨다.
이방법은 가장쉬운 방법중 하나지만 부팅시 실행되는 모든 프로세스에 해당DLL을 인젝션 시키기 때문에
DLL파일에 문제가 있다면 윈도우를 다시 설치해야할수도 있다.
실습전에 철저한 테스트가 필요하다.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs |
4-2. CreateRemoteThread() API 이용.
아래는 인젝션 시킬 myhack.dll의 소스코드이다
[출처] Appinit_Dlls 로 구현한 환경변수 설정 DLL|작성자 techshare
DLL이 프로세스에 삽입되면 DllMain() 함수가 호출된다.
DllMain()의 내용을 보면 DLL이 로딩될때(DLL_PROCESS_ATTACH) 스레드(ThreadProc)를 실행한다.
실행된 ThreadProc()은 URLDownloadToFile() 함수를 실행해서 네이버 메인화면을 다운받는다.
아래는 DLL파일을 프로세스에 Injection 시켜줄 프로그램과 소스코드이다.
main에서는 두개의 함수를 호출하고있다.
함수내부에 대해 간단하게 설명하자면,
1. FindProcessID()
processName(notepade.exe)를 가지고 PID(Process ID)를 구하는 함수이다.
hSnapShot 은 프로세스의 상태를 저장하기위한 핸들러이고
PROCESSENTRY32 는 프로세스의 정보를 저장할 구조체이다.
CreateToolhelp32Snapshot()함수는 현재 모든 프로세스의 상태를 스냅한다.
Process32First : 첫번째 프로세스의 상태를 저장한다.
do~while 구문에서는 프로세스 이름을 현재 스냅한 프로세스의 이름과 비교하여 프로세스ID를 저장한다
Process32Next : 다음프로세스의 상태를 저장한다.
원하는 프로세스 ID를 반환하고 종료한다.
2.InjectDll()
OpenProcess()함수를 이용해 FindProcessID() 함수에서 얻어온 PID를 가지고
notepad.exe 프로세스를 제어하기위한 핸들을 구한다.
VirtualAllocEx() 함수를 이용해서 해당 프로세스의 메모리 공간에 버퍼를 할당한다. pRemoteBuf 에는 버퍼의 주소가 저장된다.
WriteProcessMemory() : 할당받은 버퍼의 주소를 이용해서 삽입할 DLL 경로를 써준다.
notepad.exe 에 로딩된 kernel32.dll 에서 LoadLibrary() 를 호출하기위해 주소를 가져와야한다.
그런데 소스코드( GetProcAddress() ) 에서는 InjectDll.exe.에 로딩된 kernel32.dll의 loadLibrary()의 주소를 가져오고있는데
모든 프로세스에서 kernel32.dll은 같은 주소에 로딩되기 때문에
notepad.exe에 로딩된 kernel.dll의 주소 = InjectDll.exe 에 로딩된 kernel32.dll의 주소가 된다.
마지막으로 notepad.exe가 LoadLibrary를 호출하게 하면 된다.
하지만 windows에는 그런API를 제공하지않는다.
이것을 CreateRemoteThread()로 대체할 수 있다.
(CreateRemoteThread() : 다른프로세스에게 스레드를 실행시키게 하는 함수.)
ThreadProc() 와 LoadLibrary() 는 모두 4byte의 인수값을 받고 4byte값을 리턴하는데
CreateRemoteThread() 는 이것을 보고 아이디어를 얻어서 사용되는 방법이다.
CreateRemoteThread()의
4번째 인수에는 생성할 Thread 함수의 주소가 들어가는데
여기에 notepad.exe의 LoadLibrary()의 주소가 들어간다.
5번째 인수에는 생성된 Thread함수에 전달될 변수가 들어가야한다.
여기에 myhack.dll의 경로가 들어가게된다.
이렇게되면
CreateRemoteThread()는 notepad.exe 가 LoadLibrary() 를 호출하도록 한것이다.
참조
http://bhnbhn.tistory.com/186
http://www.opensource.apple.com/source/OpenSSL098/OpenSSL098-32/src/ms/tlhelp32.h
http://www.reversecore.com/
http://keybreak.tistory.com/
'네트워크및보안&해킹 > 보안&해킹' 카테고리의 다른 글
[시스템해킹]버퍼오버플로우 실습 (329) | 2015.08.28 |
---|---|
CrackMe2 문제풀이 (6) | 2015.07.17 |
CrackMe 문제풀이 (리버싱 기초) (6) | 2015.06.08 |
리버스 엔지니어링 (3) | 2015.06.08 |
버퍼오버플로우 (928) | 2015.06.08 |