zj3t

email: euntaejang@gmail.com

Latest Posts
안녕하세요.
오랫만의 포스팅입니다~
저번에 포스팅은 Global API Hooking에서 Injdll.exe로 API를 후킹하여
야후, 네이트, 다음, 네이버를 접속하면  www.reversecore.com(리버스 코어)로 우회되도록 우회 될 URL이 고정 되어있었습니다.

이번에는 파일을 변경하여 원하는 곳으로 우회할 수 있도록 고정하는 방법을 포스팅해보겠습니다.
아주 약간의 PE 구조에 대한 지식만 필요로하며 DLL 폴더에있는 PE구조를 변경시켜 직접 Injection을 하는 방법보다는 훨씬 쉽습니다.

그럼 시작하겠습니다.
우선 IDA로 redirect.dll 을 엽니다.
redirect.dll 은 Injll.exe에서 사용되는 dll 파일입니다. 즉 우회 될 사이트와 우회를 시킬 사이트의 정보가 담겨있습니다.



여기 네이버, 다음, 네이트, 야후가 보입니다. 우회시킬 사이트들이 나열 되어있습니다. 그리고 그 밑으로 조금 더 내려보면 www.reversecore.com, 우회 URL이 쓰여있습니다.
PUSH로 URL을 넣고 함수를 CALL합니다. 그럼 www.reversecore.com은 어디 있나 찾아보았습니다.


여기 URL 들이 나열 되어있습니다. 위에서 본 URL들은 모두 이쪽에서 가져온 것을 확인할 수 있습니다.

ollydbg로도 확인해보니 AC98에서 가져 오는 것을 확인할 수 있었습니다.
그렇다면 우회 URL을 바꾸는 방법은 크게 두 가지를 나눠 볼 수 있습니다.

1. AC98에 있는 URL을 단순히 원하는 URL로 바꾸는 방법
2. NULL 지역을 찾아 그곳에 원하는 URL을 입력한다음 PUSH 주소(1AB3)를 URL이 입력된 주소로 바꾸는 방법

1번을 해보려했는데 보시는 것처럼 공간이 없습니다. 짧은 URL은 괜찮지만 긴 URL은 뒤의 data를 침범하기 때문에 프로그램이 제대로 실행되지 않을 수도 있습니다.

따라서 2번방법으로 실습해 보겠습니다.

이제 PEview와 HxD로 확인해 보겠습니다.


이렇게 바꾸어 주었습니다. 우회될 URL은 제 블로그 주소입니다.


이 부분이 | PUSH 우회 URL |  주소 입니다. URL 을 가리키는 주소는 AC98(리틀 엔디안)으로 쓰여있는 것을 확인 할 수 있었습니다. 이 주소를 우리는 NULL 지역에 쓴 새로운 URL이 있는 주소로 바꾸어 주어야 합니다.


File Offset도 확인이 됬습니다. 이제 헥스에디터로 찾아가 URL이 참조되는 주소를 바꿔주면 될 것 같습니다.


바꾸어 주었습니다. redirect.dll -> JMPOEP.dll 이름 변경을 한 뒤 실행을 해보겠습니다.


PID를 확인했습니다. 왜 부모 프로세스는 Hooking이 안되는지 아직도 모르겠습니다. 어떤 보호기법인거 같은데 자세히는 모르겠습니다. 따라서 자식 프로세스의 PID를 확인했습니다.




부모 프로세스의 인젝션은 실패,
자식 프로세스의 인젝션은 성공

자식 프로세스가 이제 원하는 URL로 우회가 되는지 확인해 보겠습니다.




시작페이지 daum에서 naver로 이동을 하니 제 블로그로 우회되었습니다. 이를 응용한다면 네이버, 다음, 네이트, 야후가 아닌 유해사이트들 다른 사이트로 돌리도록 할 수도 있습니다.

저번 dll을 자체적으로 인젝션하는 건 조금 어려웠지만 이렇게 PE Header를 건드리지 않고 body 부분에서만 데이터를 바꿔주는 것은 매우 쉽습니다. 앞으로 PE를 가지고 노는 것을 많이 포스팅 해보겠습니다.




혹시 redirect.dll 파일에 대한 저작권을 침해했다면 글 지우겠습니다.











리버싱 핵심원리에 간단한 실습이 있길래 같이 실습해보려고 합니다.

실습 내용은 IE프로세스의 특정 API를 후킹하여 국내 4대 포털 사이트(NAVER, DAUM, NATE, YAHOO)에 접속 시도할 때 다른 주소(www.reversecore.com)로 연결해버리는 것 입니다.
또한 IE의 탭이 새로 생성되면서 동시에 프로세스가 추가되는 경우를 대비해서 Global API Hooking 기법을 사용해 보겠습니다.

API 후킹은 redirect.dll을 인젝션해서 구현합니다. 나중에 코드를 보시겠지만 redirect.dll은 아래 2개의 API를 후킹합니다.

wininet.InternetConnetW() -IE 프로세스의 접속 주소를 제어하기 위해 후킹
ntdll.ZwResumeThread()    -글로벌 API후킹을 구현하기 위해 사용

실습을 위해 먼저 IE를 실행합니다.


Process Explorer를 이용하여 현재 실행 중인 IE 프로세스의 구조를 살펴보겠습니다. 
일단 부모-자식관계로 실행되는 것을 알 수 있습니다. 따라서 부모 프로세스만 ntdll.ZwResumeThread() API를 후킹해도 이후부터 생성되는 모든 자식 IE 프로세스들은 자동으로 후킹됩니다.


다음 redirect.dll 파일을 IE 프로세스(iexplorer.exe)에 인젝션합니다.


왜....책처럼 따라했는데 부모프로세스는 인젝션이 안되고 자식프로세스만 인젝션이 되는 걸까요?? 아시는 분들 답좀 달아주세요....
저도 빨리 알아내겠습니다.

일단 자식 프로세스만 인젝션한채로 해보겠습니다. (그럼 Global이 되지 않을텐데요...)




일단 되기는 하지만 다른 탭 추가시켜서 실행해보니 우회되지 않았습니다. 

Global API Hooking...다음 포스팅에 제대로 찾아서 쓰겠습니다. 또 아까 www.reversecore.com이 아닌 제 블로그 주소로 우회하려고 IDA로 redirect.dll 파일을 뜯어봤는데 PE공간이 넉넉하지 않아 NULL 패딩지역을 찾아 PE Header를 수정해서 그곳에서 우회해야 하겠더라고요. 그것까지 함께 포스팅 해보겠습니다.








프로세스를 생성하는 API에 대해서 생각해봅시다.
프로세스를 생성하는 API는 kernel32!CreateProcess() API가 가장 유명합니다.
CreateProcess() API의 디버깅을 위하여 다음과 같이 간단한 프로그램을 만들어보겠습니다.



이 코드를 빌드해서 cptest.exe를 생성합니다. 이 파일을 디버깅해보면 프로세스 생성과 관련된 API들의 호출 흐름을 할 수 있습니다.

-코드
  1. #include "Windows.h"
  2. #include "tchar.h"
  3. void main()
  4. {
  5. STARTUPINFO si={0,};
  6. PROCESS_INFORMATION pi={0,};
  7. TCHAR szCmd[MAX_PATH]={0,};

  8. si.cb=sizeof(STARTUPINFO);
  9. _tcscpy(szCmd, L"notepad.exe"); //notepad.exe의 실행정보를 szCmd에 저장

  10. if(!CreateProcess(NULL, 
  11.  szCmd,NULL,           //lpCommandLine
  12.  NULL,FALSE,
  13.  NORMAL_PRIORITY_CLASS,
  14.  NULL,NULL,&si,&pi)
  15.  )

  16. return;

  17. if(pi.hProcess !=NULL)
  18. CloseHandle(pi.hProcess);
  19. }

CreateProcess() API를 보실 수가있습니다.



kernel32.CreateProcessW() 내부로 따라 들어가면(F7) 위와 같이 kernel32.CreateProcessInternalW() 호출 코드를 볼 수 있습니다. 그리고 notepad.exe가 그대로 넘어와서 세번 째 인자가 된다는 것을 볼 수강 있습니다.

CreateProcessInternalW() 내부를 살펴보도록 하겠습니다.


이렇게 긴 코드가 나옵니다. CreateProcessInternalW() 함수는 상당히 큰 함수라는 것을 알 수 있습니다. 아래로 쭉 스크롤 해보면 


ntdll.ZwCreateUserProcess()를 호출하는 코드가 나옵니다.


이번 그림에서 아래쪽의 스택을 보면 위 그림처럼 인자를 알려주는 스택형태와 많이 다른 형태인 것을 알 수 있습니다. 2번째 파라미터(Arg2)는 어떤 구조체인데 왼쪽의 Hex dump창을 보면 구조체 멤버 중에 19F9EC주소에  0019FD30가 쓰여있는 것이 확인됩니다.

이 주소로 이동해보겠습니다.


밑에 보이시죠?? notepad.exe 문자열을 확인할 수가 있었습니다. 그럼 ntdll.ZwCreateUserProcess를 한번 실행시켜보겠습니다.


notepad.exe화면은 보이지 않지만 프로세스는 생성되었습니다. 즉 아직 EP(Entry Point)코드가 실행되지 않은 상태라고 볼 수 있습니다.



위의 ntdll.ZwCreateUserProcess을 실행시킨 후 계속 아래로 진행하면...............
ntdll.ZwResumeThread() API 호출 코드를 볼 수 있습니다. ntdll.ZwResumeThread()는 함수 이름 그대로 스레드를 Resume해줍니다. 이 스레드가 바로 자식 프로세스(notepad.exe)의 메인 스레드입니다. 따라서 이 API가 호출되면 비로소 자식 프로세스의 EP코드가 실행되는 것 입니다.

보시는 것처럼 notepad.exe가 EP코드가 실행되어 프로그램 창이 띄어진 것을 확인 할 수 있습니다.

지금까지의 CreateProcessW() API 호출 흐름을 정리해보도록 하겠습니다.

kernel32.CreateProcessW
     kernel32.CreateProcessInternalW
           ntdll.ZwCreateUserProcess    //프로세스 생성됨(메인 스레드는 Suspend 상태
           ntdll.ZwResumeThread        //메인 스레드 Resume 시킴(프로세스가 실행됨)

자식 프로세스 생성에 있어서 가장 마지막에 호출되는 API가 바로 ntdll.ZwResumeThread() 입니다. 따라서 우리는 이 API를 후킹하여 자식 프로세스의 EP코드가 실행되기 바로직전에 제어를 가로챈 후 원하는 API를 후킹시킬 수 있습니다.

이 4개의 API (CreateProcessW, CreateProcessInternalW, ZwCreateUserprocess, ZwResumeThread) 중에서 어떤 걸 후킹해도 우리 목적에 맞는 글로벌 후킹이 가능합니다.

"리버싱 핵심원리" 에서는 ntdll.ZwResumeThread() API 후킹을 실습했기 때문에 그걸 토대로 저도 실습을 하겠습니다.


출처, 참고: 리버싱핵심원리-이승원 지음






API Hooking에서 가장 핵심적인 사항은 바로 후킹 대상 API를 선정하는 것입니다.
이번 포스팅에는 Explorer.exe를 다룰건데, 작업전 간단히 '예상'을 해보면 소켓 라이브러리(ws2_32.dll) 혹은 MS에서 제공하는 인터넷 관련 라이브러리(wininet.dll, winhttp.dll)들을 후킹하면 될 것 같습니다.
저는 후자로 진행하겠습니다.(이 책에서도 후자로 진행하였기 때문..)


IE를 하나 띄었는데 부모 프로세스 밑에 자식 프로세스가 실행 된 것을 볼 수가 있었고, Wininet.dll를 로딩하고 있었습니다. Wininet.dll에서 제공하는 API중에 InternetConnet()라는 API(출처:MSDN)가 있습니다. 함수 이름 그대로 어떤 웹 사이트에 접속하려고 할 때 사용하는 API입니다.

HINTERNET InternetConnect(
 __in HINTERNET hInternet,
 __in LPCTSTR lpszServerName, //접속 URL
 __in INTERNET_PORT nServerPort,
 __in LPCTSTR lpszUsername,
 __in LPCTSTR lpszPassword,
 __in DWORD dwService,
 __in DWORD dwFlags,
 __in DWORD_PTR dwContext
);

Wininet.InternetConnect() API가 후킹 대상 API로 적절한지 검증해보겠습니다.

시연을 성공으로 하고 포스팅 글을 쓰려고 스샷을 찍으려 다시 실습하려했는데

attach가 되질 않습니다...


원인을 빨리 찾아서 일반적인 API 후킹 실습을 보여드리겠습니다. 되다가 갑자기 안되니까 당황 스럽네요....





출처and참초: 리버싱 핵심원리 




-General API Hooking


일반적인 API후킹의 문제는 후킹을 원하는 프로세스가 생성될 때마다 매번 API후킹을 해주어야 한다는 것입니다. 밑의 그림은 DLL Injection 기법을 이용한 일반적인 API 후킹을 표현한 것입니다.
<그림1>

이 그림에서 후킹 대상 프로세스는 Test.exe(1)입니다. InjDll.exe 프로그램을 이용하여 Hook.dll을 인젝션해서 원하는 API를 후킹하였습니다.
그런데 이후에 또 다른 Test.exe(2) 프로세스가 생성되었다면 이 프로세스에도 역시 Hook.dll을 인젝션해줘야 정상적인 API후킹이 이루어질 것입니다. 
즉 후킹 대상 프로세스가 새로 생성될 때마다 계속해서 수동으로 API 후킹을 해야 합니다.

-Global API Hooking


<그림2>

InjDll.exe는 Windows OS의 기본 셸(Shell)인 Explorer.exe 프로세스에 gHook.dll을 인젝션 합니다. 후킹하고자 하는 Test.exe가 아닌, Test.exe를 실행시켜주는 프로세스인 Explorer.exe를 후킹한다는 것이 핵심입니다. gHook.dll은 <그림1>의 Hook.dll의 기능에다가 자식 프로세스 생성에 관련된 API를 후킹하여 자식 프로세스를 생성할 때마다 자신(gHook.dll)을 인젝션하는 기능을 가지고 있습니다.--<그림2>참고 
따라서 Windows 셸인 Explorer.exe 프로세스에 gHook.dll을 한 번 인젝션해놓으면, 이후 Explorer.exe.에서 생성되는 모든 자식 프로세스들에게 자동으로 gHook.dll이 인젝션 됩니다. 이것이 자동 API 후킹의 기본 개념이며, 이를 시스템에 실행 중인 모든 프로세스를 대상으로 확장한 것이 바로 글로벌 API 후킹입니다.










-출처: 리버싱 핵심원리


리버싱 핵심정리 도서로 API 후킹을 공부하다가 아주 간단한 실습이 있어 해보았습니다~~