Code injection using Dll injection Why do I write this document? 어느날갑자기는아니고진작에익혔으면문서화해놓았어야했는데 3~4 주전에소스만만들어놓고개인사정이있어서보류하다가작성한다. 이문서는개인적으로 Dll injection 과 Code injection 에대해서이해한내용을기록한문서이기에틀린내용이있을지도모르니주의 하시기바란다. 그리고첨부된소스에대한설명은하지않는다. 그이유는이미 Reversecore 님께서보다훨씬높은수준의강의로 Blog 에공개가되어있고이론적으로 이해하고있으면나중에소스를봐도활용하는데큰문제가없다고여기기때문이다. 그나저나이문서만들때예쁘게해보려고워드 2010 만지작거리는재미도있다. 그리고어차피 보고서같은문서라글자체만윤고딕을써줘도이렇게미려하게나오는구나. 요즘 MacBook 이눈앞에아른거리는데 (iwork) 워드도괜찮은소프트였군!! 제대로안써보고 iwork 의미려함만좇았었는데더열심히써줘야겠다. -2011 년 7 월 16 일한여름의토요일밤에서일요일새벽으로넘어가는시점에서 - 혹시모를질문은 mailto:appff@naver.com - 영남대학교컴퓨터공학과김정민 What is the Dll injection? 먼저 Code injection 을하려면 Dll injection 이필요하므로먼저 Dll injection 부터이야기하겠다. 일반적으로윈도우는한프로세스가다른프로세스에게접근하는것을허용하지않는다. 가장 쉬운예를들면그것은커널오브젝트일것이다. 정확히는 Kernel Object 에접근할수있게해주는 HANDLE 값이다. 이 HANDLE 값은각프로세스마다고유한 HANDLE TABLE 로관리해서특정프로세스의 Editor Control 윈도우의 HANDLE 이 3 이라는고유값을가지더라도 그것이다른프로세스의 HANDLE TABLE 의 3 이라는값과같은 Kernel Object 를나타낸다는 보장은없다. ( 때에따라같은 Kernel Object 를나타내게할수도있다.) 그러나프로그래머들은종종자신이만든프로그램이다른프로그램을제어해야할경우가있다. 이럴때바로 Dll injection 을이용해서대상프로세스에강제로침입을하는것이다. 일반적인 Dll loading 과비교해보았을때일반적인 Dll loading 은자기자신이사용할 Dll 파일을 loading 하는작업이지만 Dll injection 은자신이아닌특정프로세스에대해서 Dll loading 시키는 작업이라할수있다. 1
Dll injection 의기법은대표적으로세가지정도이며아래에소개한다. 1. Registry 값조작을이용한 Dll injection 2. Windows hook function 을이용한 Dll injection 3. Thread 생성을이용한 Dll injection 현재이문서에서는 RemoteThread 를생성해서 LoadLibrary() function 을 call 하는방법으로 Dll injection 을구현하는방법을이야기할것이다. 사실이렇게글로풀어놓아봤자이해하기힘들것이다. 그러니딱한마디로 Dll injection 을 줄이고그림으로설명하겠다. 다른프로세스에게 LoadLibrary() API 를호출하도록명령하여 내가원하는 Dll loading 하는것이다. ( reversecore blog 에서인용 ) figure1 은 (Matt Pietre s article 발췌 ) pe 라고불리는윈도우운영체제의실행파일 format 이다. Dll injection 을이해하려면아래의그림을이해하고머릿속에그릴수있어야한다. PE32(portable excutable32) 프로세스의내부가 이해가되지않는다면 An In-Depth Look into the Win32 Portable Executable File Format 을읽어보길 바란다. MSDN Magazine 에보면 Matt Pietrek 이쓴 An In- Depth Look into the Win32 Portable Executable File Format 이라는 Article 이있는데이문서에서는.Net 환경에서개발된프로그램을제외한모든 PE32 format 에대해서자세히언급하고있다. Figure 1 영문이라겁이난다면 Windows 시스템실행파일의 구조와원리 ( 한빛미디어, 이호동저 ) 라는책을참고하면된다. Matt Pietrek 이한이야기를포함해서 PE32 format 에대한내용을책으로풀어써놨기에방대한양이며, 굳이 Dll injection 을위해서책을다볼필요는없다고생각된다. 이왕이면 Matt Pietrek 이써놓은기사정도만읽어보면될듯하다. (Pietrek 의 Article 도무려 Part1, Part2 로나뉜다.) i i Matt Pietrek s Article : http://msdn.microsoft.com/en-us/magazine/cc301805.aspx 2
다음으로 figure2 는 Dll injection 을나타내는그림이다. 한번에이해가되는가? (reversecore blog 에서발췌 ) 이그림만이해한다면 Dll injection 에대한이해는끝난것이다. ^^ 참 ~ 쉽죠잉 (?!) 자여기서문제는우리가사용 할 RemoteThread function 을이용해서 Dll injection 을구현하면어떤그림이그려질것인가가문제겠군요? 뭐아랫부분에직접그릴예정입니다만이문서를보시는 분들각자가한번상상해보세요. 힌트는바로 CreateRemoteThread() 함수입니다. Figure 2 한마디로줄여보면 Target Process 의 Remote Thread ( 원격스레드 ) 를생성해서그 Thread 가 LoadLibrary() function 을실행하게하는것이다. i i Reversecore.com 3
Dll injection using CreateRemoteThread() API 이제위에서이야기한 Remote Thread 를이용해서 Dll injection 을수행하였을때어떤모양의그림이그려지는지이야기하겠다. 먼저 figure3 을보자. Thread A HANDLE CreateRemoteThread( HANDLE hprocess, PTHREAD_START_ROUTINE lpstartaddress, PVOID lpparameter); Target 에게가상메모리공간을할당받고 lpstartaddress 에해당하는 Thread 를할당하고실행한다. injection Process A Target Process Virtual memory allocation Process A 에대한 Thread A 의 가상메모리공간 (Dll Loading Code) LoadLibrary( in LPCTSTR lpfilename) lpfilename 는 lpparameter 에할당된다. 이는 LoadLibrary() API 가 1 개의매개변수만이용한다는점을착안한아주영리한발상이다. 결과적으로 lpparameter 에는 LoadLibrary() API 의 Address 이며 LoadLibrary() API 를 Call 하게만든다. 자세한사항은첨부된소스를참고하기바란다. (Dll injector project) 4
What is the next work? 자여기까지오느라고생했다. 이제내가원하는프로세스에침투하는것은완료했다. 예를들면 internet explorer ( 이하 ie) 프로세스에우리의 Dll 이침투했다고가정하자. 여러분은혹시 컴퓨터를사용하면서특정사이트가접속되지않거나인터넷이되지않는바이러스에감염되어본적이있는가? 우리가만들 Code injection Sample project 는바로 internet explorer 가제대로작동되지않게하는바이러스성프로그램을만들것이다. Remote Thread 를이용한 Dll injection 이아주손쉽게특정프로세스의메모리영역에침투하는기술이기에사실백신에서도쉽게감지되긴하지만우리는 injection 에대한개념을익히기위한목적으로만드는것이니 재미있게즐기기만하자!! 더궁금한사항이있다면구글링으로 ~ How can you control the ie? 여러분이만든 C 언어프로그램에서 printf 함수의주소를바꿀수있다면? 또는 printf 함수를 호출하기전에그함수로전달되는매개변수들을가로챌수있다고가정해보자. 그렇다면프로그램의사용자가기대하는출력값이아닌엉뚱한값이출력되도록만들수있겠다. 이러한발상을그대로 ie 로가져가자. ie 가사용하는 dll 파일중에 wininet.dll 이존재하는데해당 라이브러리가제공하는함수중 InternetConnect() 라는함수를눈여겨보아야한다. 이함수는 FTP or HTTP 서버에접속하는함수이다. 아래는이함수의 Syntax 다. HINTERNET InternetConnect( ); in HINTERNET hinternet, in LPCTSTR lpszservername, in INTERNET_PORT nserverport, in LPCTSTR lpszusername, in LPCTSTR lpszpassword, in DWORD dwservice, in DWORD dwflags, in DWORD_PTR dwcontext 이함수의자세한사항은 MSDN 을참고하기바라며이문서에서는 lpszservername 변수에만 집중하도록하겠다. 이변수는말그대로인터넷주소이다. 자이제다시한번상상해보자 ie 가 InternetConnect 함수를호출하는시점에그매개변수들을우리가가로챌수있다면, 5
ie 사용자가기대하는서버외에우리가원하는서버로접속하게만들수있을것이다. 만약 없는주소라면? 당연히인터넷이안되는것같은효과가발생할것이다. ^^;;; 아래그림은실제로임의의 API 에대한 Hooking 이어떻게이루어지는지설명한다. Internet Explorer Hooked Function()... Call InternetConnect( www.naver. com ); Hooked HINTERNET HookedFunc(a,b,c) { b = yahoo.co.kr 강제접속할주소 Call Origin InternetConnect(a,b,c); Injection 된 Dll 은원래의 InternetConnect() 의주소를 우리가만든임의의함수의주소로교체한다. Hooked func 은 InternetConnect() 함수의두번째변수의값을변조하고원래의 InternetConnect() 를 호출한다. } Call Origin InternetConnect() HINTERNET InternetConnect(a,b,c) { Function body } 마치며 시작하며언급했지만이문서는실제로구현부분의이야기는거의없다. 단순히 DLL INJECTION 의개념과 CODE INJECTION 을이용한 API Hooking 의원리에대해서정리한 문서이며첨부된코드에대한내용은생략한다. 솔직히다까먹었다. ( 지금은 2011.11 월 ) T_T 모쪼록 DLL INJECTION 을공부하는분들에게미약하나마도움이되길! 6