SlideShare a Scribd company logo
REVERSING[7] Reverse Engineering
목차
• API hooking //리버싱 핵심원리 4부
• 개념 //29장
• 배경지식
• API 후킹이란?
• 구현
• debug 기법을 이용한 API 후킹 //30장
• 배경지식
• 실습
• DLL injection 기법을 이용한 API 후킹
• IAT 후킹 //32장
• 실습
• Code 패치
• 기본 //33장
• 글로벌 API 후킹 //33장
• 핫 패치 방식 //33장
• 고급 글로벌 API 후킹 //34장
• 과제
• 실습 따라 해보기
• CodeEngn
• 부록
• 참고 사이트
개념 • 배경지식
• API 후킹이란?
배경지식
• 후킹
• 정보를 가로채거나, 실행 흐름을 변경하거나, 원래와는 다른 기능을 제공하게 하는 기술
• 그 중에서도Win32 API를 후킹 하는 기술을 API 후킹이라고 한다
• API
• Windows는 여러 가지 이유(안정성, 보안, 효율, 기타)로 사용자 어플리케이션이 직접 시스템 자원에 접근하는 것을 막아 두었다
• 시스템 자원 : 메모리, 파일, 네트워크, 비디오, 사운드, 기타
• 사용자 어플리케이션이 시스템 자원을 이용하기 위해서는 OS에게 요청해야 한다
• MS에서 제공하는Win32 API를 이용
• 즉,API 함수 없이는 어떤 의미 있는 프로그램을 만들어 낼 수 없다.
• 모든 프로세스에는 기본적으로 kernel32.dll이 로딩되며, kernel32.dll은 ntdll.dll을 로딩 한다
• 특정 시스템 프로세스의 경우 kernel32.dll을 로딩하지 않지만, 매우 예외적인 경우이다.
• ntdll.dll의 역할이 바로 유저 모드 애플리케이션이 요구하는 시스템 자원에 대한 접근을 커널에게 요청하는 것
• GUI를 이용하는 프로그램은 user32.dll과 gdi32.dll을 필수로 로딩 한다
API 후킹이란?
• API 후킹 과정
• 디스어셈블러/디버거를 이용하여 프로그램의 구조와 동작 원리를 파악
• 원하는 동작을 하는 훅 코드 개발
• 실행 파일과 프로세스 메모리를 조작하여 훅 코드 설치
• API 후킹 예
• 메모장에서 저장 버튼을 누르면 CreateFile API가 호출된다
• 정상 상태에서는 kernel32.dll의CreateFile함수가 실행된다
• 이 예에서는 DLL injection을 이용하여 API를 후킹했다.
• 메모장 exe 코드에서 CreateFile함수를 호출하면 내 DLL의 함수가 불린다
• 내 DLL에서 임의의 코드를 실행한다
• 저장 기능이 정상적으로 진행되게 하고싶다면 원본API를 호출한다
<notepad.exe>
CreateFile API
호출
<kernel32.dll>
CreateFile API
실행
call
return
<정상 API 호출>
<notepad.exe>
CreateFile API
호출
<kernel32.dll>
CreateFile API
실행
call
return
<후킹 API 호출>
<Myhook.dll>
임의의 코드 실행
정상 API를 호출하여
정상적으로 보이게
할 수 도 있음
call
return
API 후킹이란?
• API 후킹을 이용하여 할 수 있는 일
• 소스코드가 없거나, 소스코드 수정이 여의치 않은 상황에서 프로그램을 고치거나 기능을 추가할 수 있음
• API 호출 전/후에 임의의 코드를 실행할 수 있음
• API에 넘어온 파라미터 혹은API 함수의 리턴 값을 엿보거나 조작할 수 있음
• API 호출 자체를 취소시키거나 사용자 코드로 실행 흐름을 변경시킬 수 있음
• 예)
• 메모장의CreateFile 함수를 후킹하여 저장 로그 찍기
• 계산기에 한글로 숫자 표시하기
• 브라우저의API를 후킹하여 유해 사이트로의 접근 차단하기
• ...
API 후킹이란?
• API 후킹 구현
• 여러가지 방법을 통해 가능
• 상황에 맞게 골라 쓴다
• 자주 쓰이는 방식은 빨간 글씨로 표시했음
Method Object
(무엇을 대상으로
조작을 가하는가)
Location
(어느 부분에
조작을 가하는
가)
Technique
(어떤 기술을 이용하여 조작하는가)
API
(기술을 적용하기 위해 이용하는 API)
static File
1) IAT
2) Code
3) EAT
X x
A) Debug
DebugActiveProcess
GetThreadContext
SetThreadContext
dynamic Process Memory
(가상 메모리)
B) Injection
B-1) Independent code CreateRemoteThread
B-2) DLL file
Registry (AppInit_DLLs)
BHO(IE only)
SetWindowsHookEx
CreateRemoteThread
API 후킹이란?
• Method, Object
• API 후킹 방식에 대한 대분류
• Static은 파일을 변경하는 방식
• Dynamic은 프로세스의 가상메모리를 변경하는 방식
• 일반적으로 말하는API 후킹은 이것을 의미
Method Object
(무엇을 대상으로
조작을 가하는가)
Location
(어느 부분에
조작을 가하는
가)
Technique
(어떤 기술을 이용하여 조작하는가)
API
(기술을 적용하기 위해 이용하는 API)
static File
1) IAT
2) Code
3) EAT
X x
A) Debug
DebugActiveProcess
GetThreadContext
SetThreadContext
dynamic Process Memory
(가상 메모리)
B) Injection
B-1) Independent code CreateRemoteThread
B-2) DLL file
Registry (AppInit_DLLs)
BHO(IE only)
SetWindowsHookEx
CreateRemoteThread
API 후킹이란?
• Location
• 어느 부분을 조작할 것인가
• IAT
• IAT에 있는 API 주소를 변경
• 장점 : 가장 쉽고 단순
• 단점 : IAT에 없는API는 후킹할 수 없다
• Code
• 프로세스 메모리에 매핑된 dll에서API 실제 주소를 찾아가 코드를 직접 수정
• 가장 널리 사용되는 방법
• 다양한 방법으로 구현할 수 있다
• 시작 코드를 JMP 명령어로 패치하는 방법
• 함수 일부를 덮어쓰는 방법
• 필요한 부분만 일부 변경하는 방법
• EAT
• DLL의 EAT에 기록된API 시작 주소를 변경
• 개념은 간단하지만 위의 방법이 더 쉬우므로 잘 사용되지 않음
Method Object
(무엇을 대상으
로
조작을 가하는가)
Location
(어느 부분
에
조작을 가하
는가)
Technique
(어떤 기술을 이용하여 조작하는
가)
API
(기술을 적용하기 위해 이용하는
API)
static File
1) IAT
2) Code
3) EAT
X x
A) Debug
DebugActiveProcess
GetThreadContext
SetThreadContext
dynamic Process Memory
(가상 메모리)
B)
Injection
B-1) Independent
code
CreateRemoteThread
B-2) DLL file
Registry (AppInit_DLLs)
BHO(IE only)
SetWindowsHookEx
CreateRemoteThread
API 후킹이란?
• Technique
• 대상 프로세스 메모리에 침투하여 후킹 함수를 설치하는 구체적 기법
• 크게 디버그와 인젝션 기법으로 나눌 수 있다
• 인젝션 기법은 다시 Code와 DLL 기법으로 나뉨
• 디버그 기법
• 대상 프로세스를 디버깅하면서 API를 후킹하는 방법
• 디버거는 디버깅 당하는 프로세스인 디버기에 대한 모든 권한(실행 제어, 메모리 액세스, 기타)을 가지기 때문에, 디버기의 프로세스 메모리에 후킹 함수를 자요롭게
설치할 수 있다
• 여기서 말하는 디버거는 일반적인 올리 디버거 등이 아니라, 후킹을 위하여 직접 제작한 프로그램이다
• OS가 제공하는 디버그 API를 이용하여 직접 디버거를 만들고, 제어한다.
• 올리 디버거 등을 이용할 수도 있다
• 자동화 스크립트에 대한 지식 필요
• 장점
• 강력함
• 단점
• 디버거에 대한 지식, 혹은 자동화 스크립트에 대한 지식이 필요
• 많은 테스트가 필요
Method Object
(무엇을 대상으
로
조작을 가하는가)
Location
(어느 부분
에
조작을 가하
는가)
Technique
(어떤 기술을 이용하여 조작하는
가)
API
(기술을 적용하기 위해 이용하는
API)
static File
1) IAT
2) Code
3) EAT
X x
A) Debug
DebugActiveProcess
GetThreadContext
SetThreadContext
dynamic Process Memory
(가상 메모리)
B)
Injection
B-1) Independent
code
CreateRemoteThread
B-2) DLL file
Registry (AppInit_DLLs)
BHO(IE only)
SetWindowsHookEx
CreateRemoteThread
API 후킹이란?
• Technique
• 인젝션 기법
• 대상 프로세스 메모리 영역에 침투하는 기술
• DLL 인젝션이 가장 널리 사용됨
• DLL 인젝션
• DLL에 후킹 코드를 만든다
• DLL main을 통해 API 후킹 작업을 수행한다
• Code 인젝션
• 악성코드가 많이 사용(탐지가 DLL 인젝션보다 어려움)
Method Object
(무엇을 대상으
로
조작을 가하는가)
Location
(어느 부분
에
조작을 가하
는가)
Technique
(어떤 기술을 이용하여 조작하는
가)
API
(기술을 적용하기 위해 이용하는
API)
static File
1) IAT
2) Code
3) EAT
X x
A) Debug
DebugActiveProcess
GetThreadContext
SetThreadContext
dynamic Process Memory
(가상 메모리)
B)
Injection
B-1) Independent
code
CreateRemoteThread
B-2) DLL file
Registry (AppInit_DLLs)
BHO(IE only)
SetWindowsHookEx
CreateRemoteThread
구현
• debug 기법을 이용
• DLL injection 기법을 이용
DEBUG 기법을 이용한 API
HOOKING
• 디버거를 구현하기 위해 제공되는 API를 이용하여 대상 프로세스의 API를 후킹
Method Object
(무엇을 대상으로
조작을 가하는가)
Location
(어느 부분에
조작을 가하는
가)
Technique
(어떤 기술을 이용하여 조작하는가)
API
(기술을 적용하기 위해 이용하는 API)
static File
1) IAT
2) Code
3) EAT
X x
A) Debug
DebugActiveProcess
GetThreadContext
SetThreadContext
dynamic Process Memory
(가상 메모리)
B) Injection
B-1) Independent code CreateRemoteThread
B-2) DLL file
Registry (AppInit_DLLs)
BHO(IE only)
SetWindowsHookEx
CreateRemoteThread
DEBUG 기법을 이용한 API HOOKING - 배경지
식
• 디버거
• 디버거 (debugger) – 디버깅 프로그램
• 올리 디버거, 비주얼 스튜디오의 디버거 등 프로그램을 디버깅하기 위해 이용하는 프로그램
• 디버기 (debuggee) – 디버깅 당하는 프로그램
• 디버거의 기능
• 디버기가 올바르게 실행되는지 확인하고, 프로그램의 오류를 발견하는 것
• 디버기의 명령어를 하나씩 실행할 수 있음
• 디버기의 레지스터와 메모리에 대한 모든 접근 권한을 가짐
• 디버기의 예외를 처리할 권한을 가짐
DEBUG 기법을 이용한 API HOOKING - 배경지
식
• 디버거 동작 원리
• 일단 디버거 프로세스로 등록이 되면, OS는 디버기에서 디버그 이벤트(debug event)가 발생할 때마다 디버기의 실행을 멈추고 해당 이벤트를 디버거에게
통보한다
• 디버거는 해당 이벤트에 대해 적절한 처리를 한 후 디버기의 실행을 재개할 수 있다
• 일반적인 예외(0으로 나누기 등)도 디버그 이벤트에 해당함
• 프로세스가 디버깅 중이 아니었다면 디버그 이벤트는 자체 예외 처리 혹은 OS의 예외 처리 루틴에서 처리
• 디버거는 디버그 이벤트 중에서 처리할 수 없거나 관심 없는 이벤트들은 OS가 처리하도록 만들어 준다
• 정리하자면, 예외가 발생하면 디버기의 진행을 멈추고 디버거에게 처리할 기회를 준다
• 디버거는 디버기의 자체 예외 처리를 이용할 수도 있고, 디버거가 예외를 직접 처리할 수도 있다
• 올리디버거에서 하는 일들을 생각해 보면 됨
OS
Debugee
(일반
프로그램)
예외
이벤트
이벤트
처리
<일반 프로세스의 예외 이벤트
처리>
OS
Debugee
예외
이벤트
이벤트
처리
<Debugger – Debuggee 관계의 예외 이벤트
처리>
Debuger
디버거가 처리하지
않을 예외 처리 요청
이벤트 처리
DEBUG 기법을 이용한 API HOOKING - 배경지
식
• 디버그 이벤트
• EXCEPTION_DEBUG_EVENT
• CREATE_THREAD_DEBUG_EVENT
• CREAT_PROCESS_DEBUG_EVENT
• EXIT_THREAD_DEBUG_EVENT
• EXIT_PROCESS_DEBUG_EVENT
• LOAD_DLL_DEBUG_EVENT
• UNLOAD_DLL_DEBUG_EVENT
• OUTPUT_DEBUG_STRING_EVENT
• RIP_EVENT
• 이 중 디버깅에 관련된 이벤트는 EXCEPTION_DEBUG_EVENT
DEBUG 기법을 이용한 API HOOKING - 배경지
식
• EXCEPTION_DEBUG_EVENT와 관련된 예외 목록
• EXCEPTION_ACCESS_VIOLATION
• EXCEPTION_ARRAY_BOUNDS_EXCEEDED
• EXCEPTION_BREAKPOINT
• EXCEPTION_DATATYPE_MISALIGNMENT
• Float 예외 처리
• EXCEPTION_FLT_DENORMAL_OPERAND
• EXCEPTION_FLT_DVIDE_BY_ZERO
• EXCEPTION_FLT_INEXACT_RESULT
• EXCEPTION_FLT_INVALUD_OPERATION
• EXCEPTION_FLT_OVERFLOW
• EXCEPTION_FLT_STACK_CHECK
• EXCEPTION_FLT_UNDERFLOW
• Int 예외 처리
• EXCEPTION_INT_DEVIDE_BY_ZERO
• EXCEPTION_INT_OVERFLOW
• EXCEPTION_ILLEGAL_INSTRUCTION
• EXCEPTION_IN_PAGE_ERROR
• EXCEPTION_INVALID_DISPOSITION
• EXCEPTION_NONCONTINUABKE_EXCEPTION
• EXCEPTION_PRIV_INSTRUCTION
• EXCEPTION_SINGLE_STEP
• EXCEPTION_STACK_OVERFLOW
DEBUG 기법을 이용한 API HOOKING - 배경지
식
• EXCEPTION_BREAKPOINT
• BP 처리
• BP는 어셈블리 명령어로 INT3, x86 기계어로 0xCC
• 코드 디버깅 중에 INT3 명령어를 만나면 실행이 중지되고, 디버거에게 EXCEPTION_BREAKPOINT예외 이벤트가 날아간다
• 실제로 BP를 걸면 해당 코드를 INT3 명령어로 바꾼다
• 올리 디버거에서 BP가 걸린 코드가 바뀌어 보이지 않는 것은 디버거가 원래 코드를 사용자에게 보여주는 것일 뿐이다
• 실제 메모리에는 INT3명령어로 적혀 있음
• BP에서 다시 디버깅을 진행할 때 원본 명령어로 복원하고 실행한다
• 디버그 기법을 이용한API 후킹은 이러한 BP의 특성을 이용한다
DEBUG 기법을 이용한 API HOOKING - 실습
• 기본 아이디어
• 디버거 – 디버기 관계를 가진 상태에서 디버기의API 시작 부분을 0xCC로 바꿔(BP를 걸어) 제어를 디버거로 가져온 상태에서 원하는 작업을
수행한 후, 디버기를 다시 실행 상태로 바꾼다.
• 작업 순서
• 1) 대상 프로세스에 디버거를 ‘attach’하여 대상 프로세스를 디버기로 만듦
• 2) 훅 – API 시작 주소의 첫 바이트를 0xCC로 변경 (=bp를 검)
• 3) 해당API가 호출되면 BP에 걸려 제어가 디버거에게 넘어옴
• 4) 원하는 작업을 수행
• 5) 언훅 – 0xCC를 원래대로 복원시킴 (API의 정상 실행을 위해)
• 6) 해당API 실행 (0xCC가 빠진 정상적인 상태)
• 7) 훅 – 다시 0xCC로 바꿈 (지속적인 후킹을 위해)
• 8) 디버기에게 제어를 되돌려 줌
• 위 방법은 기본적인 방법이다.
• 용도에 따라 원본API를 호출하지 않을 수도 있고, custom API를 호출할 수도 있고, 한 번만 후킹할 수도 있고, 여러번 후킹할 수도 있다
DEBUG 기법을 이용한 API HOOKING - 실습
• 실습할 것
• 편집 프로그램에서 저장을 하면 알파벳 소문자를 대문자로 바꾸어 저장한다
• 헤더, 함수 선언, 전역변수, main 함수 정
의
• 메인함수 입력 값으로 대상 프로세스의 PID를 받는
다.
• 디버거 기능을 총괄하는 함수
• 이벤트가 발생하면 각 상황에 맞는 작업을 한
다
• 프로세스가 attach 되었을 때 훅을 설치하고,
예외가 발생하면 처리해 준다. 디버기 프로그
램이 종료되면 디버거 프로그램도 종료되도
록 한다.
• 대상 프로세스가 attach 되었다는 이벤트
를 처리하는 함수
• 대상 프로세스의WriteFile API의 맨 처음 바이트에 bp
를 건다.
• Hook 설치
• 예외 이벤트를 처리하는 함수_1
• 설치한 BP를 만났을 때 원하는 작업을
할 수 있도록 한다.
• Thread context
• 쓰레드가 이용하던 레지스터 값을 저장
하는 구조체
• 각 쓰레드마다 하나씩 가지고 있다
• 방금 예외를 일으킨 쓰레드의 정보를 가
져오고, 레지스터 값을 이용할 것이다.
typedef struct _CONTEXT {
DWORD ContextFlags;
DWORD Dr0;
DWORD Dr1;
DWORD Dr2;
DWORD Dr3;
DWORD Dr6;
DWORD Dr7;
FLOATING_SAVE_AREA FloatSave;
DWORD SegGs;
DWORD SegFs;
DWORD SegEs;
DWORD SegDs;
DWORD Edi;
DWORD Esi;
DWORD Ebx;
DWORD Edx;
DWORD Ecx;
DWORD Eax;
DWORD Ebp;
DWORD Eip;
DWORD SegCs;
DWORD EFlags;
DWORD Esp;
DWORD SegSs;
BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];
} CONTEXT;
• 예외 이벤트를 처리하는 함수
_2
• 설치한 BP를 만났을 때 원하는 작업
을 할 수 있도록 한다.
• WriteFile이 받은 인자를 조작하고 있
다.
• API 복원 후 대상 프로그램의 EIP를
WriteFile의 시작 부분으로 변경해 주
어야 한다
• INT3을 실행하느라 한 바이트 뒤를
가리키고 있음
• 예외 이벤트를 처리하는 함수_3
• 설치한 BP를 만났을 때 원하는 작업을 할 수 있도록 한다.
• 다시 훅을 걸어 두어 후에 저장을 시도했을 때도 후킹되도록 한다.
• 주의!
• 책에서는 windows에 기본으로 있는 메모장을 대상으로 함. 그 메모장은 파일을 저장할 때만 WriteFile함수가 불림
• 다른 프로그램은 아닐 수 있음
• 프로그램을 종료하기 전 환경 설정등을 저장하는 경우도 있다(종료 이벤트가 발생하기 전)
• -> 후킹 프로그램을 끄는 게 나음
DEBUG 기법을 이용한 API HOOKING - 실습
• XP 이상부터는 DebugSetProcessKillOnExit()를 호출하여 디버거가 종료되는 순간에 디버기가 종료되지 않도록 할 수 있다
• 디버거를 종료하기 전에 언훅을 하지 않으면 디버기는 INT3에 걸려 BP 예외가 발생한다
• 따라서 언훅을 해 주어야 한다
DLL INJECTION 기법 -> IAT 후킹을 이용한 API HOOKING
• DLL injection기법으로 대상 프로세스의 IAT를 조작한다
• 장점 : 동작 원리와 구현이 비교적 간단
• 단점 : 후킹을 원하는API가 대상 프로세스의 IAT에 없다면 사용 불가
Method Object
(무엇을 대상으로
조작을 가하는가)
Location
(어느 부분에
조작을 가하는
가)
Technique
(어떤 기술을 이용하여 조작하는가)
API
(기술을 적용하기 위해 이용하는 API)
static File
1) IAT
2) Code
3) EAT
X x
A) Debug
DebugActiveProcess
GetThreadContext
SetThreadContext
dynamic Process Memory
(가상 메모리)
B) Injection
B-1) Independent code CreateRemoteThread
B-2) DLL file
Registry (AppInit_DLLs)
BHO(IE only)
SetWindowsHookEx
CreateRemoteThread
DLL INJECTION 기법 -> IAT 후킹을 이용한 API HOOKING - 실습
• 기본 아이디어
• IAT에 있는 함수 포인터를 내 DLL의 함수 주소로 변경한다
• 대상 프로세스가 훅을 걸어 둔 API를 호출하면 내 함수가 불린다
• 작업 순서
• 1) DLL main에서 훅을 설치하는 DLL을 만들고, injection 한다
• 2) 대상 프로세스가 훅을 걸어 둔 API를 호출하면 내 함수에서 원하는 일을 수행한다
• 3) 정상 함수를 호출해준다면 정상으로 보인다
내 함수
DLL INJECTION 기법 -> IAT 후킹을 이용한 API HOOKING - 실습
• 실습할 것
• 계산기가 숫자를 한글로 쓰도록 한다
• 헤더, 함수 선언, 전역변수, DllMain
• SetWindowTextW함수 대신 불리는 함수
• 버퍼를 조작한 뒤 원본 SetWindowTextW 함
수를 호출
• 훅을 설치하는 함수_1
• IAT를 조작한다
• 프로세스가 끝날 때는 반대로 언훅을 하기 위해 이용
된다
• 인자만 바꿔 넣으면 됨
• 훅을 설치하는 함수_2
DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_1
• DLL injection기법으로 API의 코드를 조작한다.
• 장점 : IAT 후킹 기법은 대상 프로그램의 IAT에 원하는 함수가 없으면 불가능했지만, 이 기법은 그런 제한은 없다.
• 동적으로 로딩한 DLL에 대해서도 후킹할 수 있다
• 단점 : API 코드 길이가 최소 5바이트보다 커야 한다 (모든 API가 이보다는 크기 때문에 사실상 제한 없음)
Method Object
(무엇을 대상으로
조작을 가하는가)
Location
(어느 부분에
조작을 가하는
가)
Technique
(어떤 기술을 이용하여 조작하는가)
API
(기술을 적용하기 위해 이용하는 API)
static File
1) IAT
2) Code
3) EAT
X x
A) Debug
DebugActiveProcess
GetThreadContext
SetThreadContext
dynamic Process Memory
(가상 메모리)
B) Injection
B-1) Independent code CreateRemoteThread
B-2) DLL file
Registry (AppInit_DLLs)
BHO(IE only)
SetWindowsHookEx
CreateRemoteThread
DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_1
• 기본 아이디어
• API의 맨 처음 명령어를 JMP 명령어로 패치해서,API가 호출되면 임의의 코드로 점프한다
• 작업 순서
• 1) DLL main에서 훅을 설치하는 DLL을 만들고, injection 한다
• 2) 대상 프로세스가 훅을 걸어 둔 API를 호출하면 내 코드로 jmp한다
• 3) 원하는 작업을 수행한다
DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_1
DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_1
• 실습할 것
• 은폐 프로세스(루트킷, Rootkit)의 일종
• 루트킷이란 : 프로세스, 파일, 레지스트리 등을 은폐하는 기술
• 메모장이 process explorer와 작업 관리자에서 보이지 않도록 한다
DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_1
• 들어가기 전에..
• 유저모드 프로그램이 프로세스 정보를 얻는 방법
• 관련API 이용
• 관련API로는 2가지가 있다
• CreateToolhelp32Snapshot API
• EnumProcess API
• 이 두API는 모두 내부적으로 ntdll의ZwQuerySystemInformation API를 호출한다
• ZwQuerySystemInformation를 직접 호출하여 얻을 수도 있다
• 이 함수를 통해서 실행중인 모든 프로세스의 정보(구조체)를 연결 리스트 형태로 얻을 수 있다
• -> ZwQuerySystemInformation를 후킹하여 리스트를 조작하면 perfect!
• (win 8부터는 변경되었다고 함)
• 후킹 대상은 숨겨지기를 원하는 프로세스가 아니라, 다른 모든 프로세스라는 것에 주의
• Process explorer와 작업관리자 뿐만 아니라 다른 프로그램들도 프로세스 정보를 이용한다
• 따라서 모든 프로세스에 후킹해야만 은폐되었다고 확신할 수 있다
• Ex) 스텔스 전투기는 레이더에 포착되지 않기 위해 각종 첨단 과학을 동원하여 전투기 자체를 새롭게 개발한 것.
• 프로세스는 반대로 모든 레이더를 망가뜨려서 일반 전투기가 스텔스 전투기가 된 것이다
• <DLL 코드>
• 헤더, 함수 선언, 전역변수
• 숨길 프로그램 이름은 공유 변수에 저장한다
• 무슨 프로그램을 숨길 지 간단하게 공유할 수 있음
• <DLL 코드>
• export하는 함수
• injector가 이 함수를 호출하여 DLL의 공유 변수에 숨길
프로그램의 이름을 저장한다
• <DLL 코드>
• DllMain 함수
• DLL이 올라가면 훅을 설치하고, 전부 내
려가면 언훅한다.
• injector 프로그램에는 훅을 설치하지 않
는다
• 이 프로그램 이름은 HideProc.exe로 할
것임
• <DLL 코드>
• Hook_By_Code 함수
• API의 주소를 찾고,
훅이 걸려있지 않다
면 맨 앞 코드를 jmp
코드로 변경하여 훅
을 건다.
• <DLL 코드>
• Unhook_By_Code 함수
• API의 주소를 찾고, 원래 코드를 복원한다.
• <DLL 코드>
• NewZwQuerySystemInformation 함수_1
• ZwQuerySystemInformation 함수를 호출했을 때, 훅을 통하여 실행될 함수이다.
• ZwQuerySystemInformation 함수의 결과를 받고, 그 결과를 조작한 뒤 return한다.
• 함수의 결과로 현재 실행중인 프로세스 정보 리스트를 받는다.
• 그 중 숨기고 싶은 프로세스와 관련된 정보를 삭제한다
• <DLL 코드>
• NewZwQuerySystemInformation 함수_2
• 리스트를 순회하며 숨기고 싶은 프로세스에 대한 정보가 있는지
살펴본다
• 있다면 그 정보를 삭제한다
• <DLL 코드>
• NewZwQuerySystemInformation 함수_3
• 언훅했던 함수에 다시 훅을 건다
• <injector 코드>
• typedef, enum, 함수 선언
• enum 사용법은 부록의 참고 사이트에 있음
• <injector 코드>
• 메인 함수
• 인자를 받는다
• 권한을 상승한다
• 앞서 만든 DLL의 export 함수를 이용하여 숨길 프로세스 이름을 설
정한다
• 모든 프로세스를 대상으로 인젝션 혹은 이젝션한다
• <injector 코드>
• SetPrivilege 함수_1
• 권한을 상승시키는 함수이다
• 메인 함수에서 호출한다
• 권한을 상승시켜야 일부 프로세
스들을 열고, 인젝션 혹은 이젝션
할 수 있다.
• <injector 코드>
• SetPrivilege 함수_2
• <injector 코드>
• Inject_Or_Eject_AllProcess 함수
• 메인 함수에서 호출한다
• 메인 함수의 인자에 따라 inject하거나 eject한다
• hide일 경우 inject
• show일 경우 eject
• 프로세스의 정보 리스트를 얻고, 순회하면서 모든 프로세스
에 DLL inject/eject 한다.
• <injector 코드>
• InjectDll 함수
• Inject_Or_Eject_AllProcess 함수에서
호출된다
• DLL injection에서 썼던 코드와 같은 코
드
• <injector 코드>
• EjectDll 함수_1
• Inject_Or_Eject_AllProcess 함
수에서 호출된다
• DLL ejection에서 썼던 코드와
같은 코드
• <injector 코드>
• EjectDll 함수_2
• Inject_Or_Eject_AllProcess 함수에서 호출된다
• DLL ejection에서 썼던 코드와 같은 코드
DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_2
• 은폐 기법의 문제점
• 1. 후킹 대상 프로세스 개수
• Process explorer와 작업관리자 뿐만 아니라 다른 프로그램들도 프로세스 정보를 이용한다
• 따라서 모든 프로세스에 후킹해야만 은폐되었다고 확신할 수 있다
• 2. 새로 생성되는 프로세스
• 여태까지의 인젝터는 실행된 프로세스에 인젝션 했다.
• 새로 실행한 프로세스에도 인젝션해야 완전히 은폐될 수 있다
• 해결 방법
• 글로벌 후킹을 이용
• 현재 실행중인 모든 프로세스의 API를 후킹함
• 나중에 실행되는 프로세스에도 똑같이 후킹함
• 시스템 전체에 걸쳐서 후킹을 한다고 해서 글로벌(Global)
DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_2
• 글로벌 후킹
• 구현에는 다양한 방법이 있음
• 그 중 또 다른 API를 후킹하여 구현하는 방법을 이용해보자
• 프로세스를 생성하는API를 후킹
• 프로세스 생성 관련 API
• CreateProcess함수
• 두 종류가 있음
• Kernel32.CreateProcessA (아스키 문자열을 이용하는 버전)
• Kernel32.CreateProcessW (유니코드 문자열을 이용하는 버전)
• 내부적으로 각각 CreateProcessInternalA,CreateProcessInternalWAPI를 이용
• 일반적으로 CreateProcess함수를 많이 이용하지만, 일부 MS 프로그램은 CreateProcessInternal 함수를 이용
• 좀 더 정확한 후킹을 위해서는 low level 함수를 후킹하는 것이 좋다
• 새로운 프로세스 생성 함수 : 프로세스 정상 생성 후 자식 프로세스에게 DLL injection 함
• 아주 짧은 시간동안 프로세스가 후킹되지 않은 채로 실행될 가능성이 있음
• ->ZwResumeThreadAPI 를 후킹하면 해결 가능(뒤에서 함)
DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_2
• 실습할 것
• process explorer를 새로 켰을 때도 notepad.exe에 대한 정보가 보이지 않도록 한다
• 앞에서 짠 코드를 수정/추가
이런 상황을
없앰
• <DLL 코드>
• 앞에서 쓴 코드에서 수정/추가된 부분만 썼음
• define, 공유변수 부분
• STR_MODULE_NAME은 이 DLL 파일 이름이다
• <DLL 코드>
• typedef부분
• 함수 포인터
• STR_MODULE_NAME은 이 DLL 파일 이름이다
• <DLL 코드>
• 앞에서 쓴 코드에서 수정/추가된 부분만 썼
음
• 전역변수 선언 부분/함수 선언 부분
• 기존 전역변수 이름도 바꾸었으므로 해당
전역변수를 이용하던 코드도 수정해야 한
다
• <DLL 코드>
• 전역변수 이름을 변경했으니 ZwQuerySystemInformation과 관련된
함수에서 이용한 전역변수도 바꿔준다
• DllMain과 NewZwQuerySystemInformation에 있음
• <DLL 코드>
• export 함수
• 공유변수에 인젝션할 DLL 경로를 넣는 함수이다
• <DLL 코드>
• DLL injection을 하기 위해 권한을
상승한다
• CreateProcess API에 대한 훅/언훅
함수를 호출한다
• <DLL 코드>
• SetPrivilege 함수
• 앞에서 만든 injector에서 그대로
떼어 오면 됨
• <DLL 코드>
• InjectDll2함수
• 앞에서 만든 InjectDll함수에서 조
금 변형했다.
• <DLL 코드>
• NewCreateProcessA함수
• <DLL 코드>
• NewCreateProcessA함수와 인자만 다름
• <Injector 코드>
• 앞에서 쓴 코드에서 수정/추가된 부분만 썼음
• typedef, main함수 일부 내용 추가
DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_3
• 핫 패치(Hot patch) 방식의 API 후킹
• 핫 패치란?
• 프로세스가 실행중인 상태에서 라이브러리를 프로세스 메모리에서 일시적으로 변경하는 기술
• 시스템 라이브러리를 업데이트 할 때, 실행중인 프로세스들이 업데이트 된 라이브러리를 이용할 수 있게 함
• 재부팅 하면 패치 대상 라이브러리 파일이 완전히 교체된다
• API 후킹 기법을 이용하여 이루어진다
• 핫 픽스(fix), 7바이트 코드 패치 방법이라고도 한다.
• 오른쪽은 CreateProcessW함수이다. (BP가 시작 부분)
• OS의 중요 시스템 라이브러리는 오른쪽 그림과 같이, 5개의 NOP과 MOV EDI, EDI가 함수 시작 부분에 있다
• 함수는 MOV EDI, EDI에서 시작한다
• 각 함수 사이에는 5개의 NOP으로 띄워져 있다
• ->7바이트의 쓰레기 코드가 있다
• 이는 핫 패치를 이용하기 위한 것
• 컴파일러 설정을 통해 오른쪽과 같이 핫 패치가 가능한 형태로 컴파일 할 수 있다
DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_3
• 기존 방법의 문제점
• 앞에서는 API의 처음 5바이트를 점프 코드로 수정했다
• 원본 함수를 이용하기 위해 반복적으로 훅, 언훅을 했다
• ->멀티 쓰레드 환경에서 문제를 일으킬 수 있음
• 어떤 쓰레드가 함수를 실행하려고 하고, 어떤 쓰레드가 쓰려고 하면 충돌이 일어난다
• 핫 패치의 원리
• 여유 자리로 남겨놓은 쓰레기코드 7바이트를 2개의 점프문으로 변경한다
• 원본 함수를 호출하고 싶다면 (함수 주소 +2) 를 이용한다.
DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_3
• short jmp와 far jmp
• short jmp는 2바이트 기계어를 이용한다
• 뒤 1바이트가 상대 주소
• -128~127 범위에서의 점프만 가능
• far jmp는 5바이트 기계어를 이용한다
• 뒤 4바이트가 상대 주소
• 프로세스 메모리 유저 영역 어느 곳으로도 점프 가능
• 핫 패치에서는 short jmp로 바로 위에 있는 far jmp코드로 가고, far jmp에서 원하는 함수로 이동
한다
• 핫 패치
• 장점 : 안정적이다, 원본 함수를 이용하기 위해 매번 훅/언훅하지 않아도 된다
• 단점 : 제약조건 (NOP 5개와 MOV EDI, EDI 즉, 7바이트의 쓰레기 코드)이 만족되지 않는API에는 적용할 수 없음
• 핫 패치 가능하도록 컴파일한 게 아닌 함수
• 모든API에 쓸 수는 없으므로, 먼저 후킹할 함수가 핫 패치 방식을 지원하는지 미리 확인해야 한다
• <DLL 코드>
• 메인 함수에서 CreateProcess함수
를 후킹하는 함수로 핫패치 함수를
호출한다.
• <DLL 코드>
• 핫패치를 이용하여 훅을 거는 함수
• <DLL 코드>
• 핫패치를 이용한 훅을 언훅하는 함수
• <DLL 코드>
• NewCreateProcessA 함수를 수정한다.
• <DLL 코드>
• NewCreateProcessW 함수를 수정한다.
DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_4
• Global 후킹을 하기 위해 프로세스를 생성하는 함수에 후킹했을 경우
• 프로세스 정상 생성 후 자식 프로세스에게 DLL injection 함
• 아주 짧은 시간동안 프로세스가 후킹 되지 않은 채로 실행될 가능성이 있음
• ->ZwResumeThread API 를 후킹하면 해결 가능
• ZwResumeThread API란?
• CreateProcess 계열 함수를 호출했을 시 API 호출 흐름
• kernel32.CreateProcessW
• kernel32.CreateProcessInternalW
• ntdll.ZwCreateUseProcess
• ntdll.ZwResumeThread
• ZwCreateUseProcess API가 호출되면 프로세스가 생성되지만, 메인 쓰레드는 suspend 상태이다
• ZwResumeThread를 호출해야 메인 쓰레드가 시작한다
• 즉, 생성된 프로세스의 메인 쓰레드를 시작하게 하는 API다
• Low level API vs High level API
• 대부분의 Low level API들은 문서화되어 있지 않으며, OS 버전에 따라 변경될 가능성이 있다
• High level API는 문서화 되어있으며, 변할 가능성이 없다
• 내부 구현을 변할 수 있지만 함수를 이용하는 방식 등은 변하지 않음 (API가 조금 수정되어도 그 API를 이용하는 프로그램들을 수정할 필요가 없음)
• Low level API를 후킹하면 더욱 강력함
• High level API를 후킹하면 안정적인 후킹 가능
• 상황에 따라 적절한 API를 선택할 필요가 있다
DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_4
• 실습할 것
• IE로 접속해서 특정 사이트에 접속했을 때, 다른 사이트로 우회 시킨다
DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_4
• 글로벌 API 후킹 개념 정리
• 일반적인API 후킹의 문제는 후킹을 원하는 프로세스가 생성될 때마다 매번API후킹을 해 줘야 한다는 것
• 글로벌API 후킹은 생성된 프로세스에 매번API 후킹을 하는 작업을 자동화한 것
• 대상 프로세스를 생성하는 프로세스에 후킹을 함
• 자동API 후킹의 기본 개념
• 이것을 시스템에서 실행중인 모든 프로세스를 대상으로 확장한 것이 글로벌API 후킹
• 하지만 필요에 따라 모든 프로세스에 후킹하지 않을 때도 있다
• 시스템 안정성과 불필요한 오버헤드를 막기 위해 특정 프로세스에만 후킹할 수도
DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_4
• 대상 프로그램
• 인터넷 익스플로러
• 탭 기능이 있음
• 새 탭을 열면 자식 프로세스가 생성된다
• 탭을 이용하는 많은 브라우저는 이와 같은 방법을 이용한다
• 탭들을 관리하는 부모 프로세스가 있고, 실제로 접속하는 자식 프로세스가 있다
• ->부모 프로세스에 후킹해 두면 OK
• IE 프로세스를 후킹해도 되고, 처음 인터넷 익스플로러를 실행해 주는 Explorer.exe에만 후킹해도 되고, 모든 프로세스를 후킹해도
된다
• <DLL 코드>
• 공유 영역 변수가 늘어났다
• typedef
• <DLL 코드>
• 구조체와 함수 포인터의 typedef
• 구조체가 저장된 헤더를 다운받아야 하므로 그냥 직접 typedef했다
• <DLL 코드>
• 함수 선언과 전역변수 선언
• 두 개의 함수를 후킹한다
• ZeResumeThread
• 자식 프로세스에도 후킹을 하기 위함
• InternetConnectW
• Redirect를 위해
• Hook_By_Code와 Unhook_By_Code, SetPrivilege 함수는 이전과 같다
• <DLL 코드>
• export하는 함수
• 공유 변수를 설정한다
• <DLL 코드>
• DllMain 함수
• <DLL 코드>
• NewZwResumeThread 함수_1
• <DLL 코드>
• NewZwResumeThread 함수_2
• <DLL 코드>
• NewZwResumeThread 함수_3
• <DLL 코드>
• NewInternetConnectW 함수_1
• <DLL 코드>
• NewInternetConnectW 함수_2
• <DLL 코드>
• InjectDll 함수_1
• <DLL 코드>
• InjectDll 함수_2
• <DLL 코드>
• MyCreateRemoteThread 함수_1
• vista 이상 버전에서는 CreateRemoteThread 함수의
내부 구조가 다르고, 또한 특별한 정책때문에 DLL
injection이 잘 되지 않았다
• vista 이상 버전에서도 잘 작동하도록 만든 함수
이다
• DLL injection 할 때 CreateRemoteThread 함수 대신 이
함수를 호출한다
• OS 버전에 따라 알맞은 처리를 함
• <DLL 코드>
• MyCreateRemoteThread 함수_2
• vista 이상 버전에서는 CreateRemoteThread 함수의
내부 구조가 다르고, 또한 특별한 정책때문에 DLL
injection이 잘 되지 않았다
• vista 이상 버전에서도 잘 작동하도록 만든 함수
이다
• DLL injection 할 때 CreateRemoteThread 함수 대신 이
함수를 호출한다
• OS 버전에 따라 알맞은 처리를 함
• <DLL 코드>
• IsVistaLater 함수
• MyCreateRemoteThread 함수에서 이용하는 함
수
• OS 버전이 vista 이상인지 알려줌
• <DLL 코드>
• DebugLog
• 프로그램 진행 상황을 보기 쉽도록 로그를 찍
음
• <Injector 코드>
• typedef, 함수 선언
• SetPrivilege와 InjectDll, EjectDll함수는 똑같음
• <Injector 코드>
• main함수 _1
• 인자에 주의
• <Injector 코드>
• main함수 _2
과제 • 실습 따라 해보기
• CodeEngn
실습 따라 해보기
• 실습 코드를 열심히 읽어서 이해해 보자
CODEENGN
• 18번
• 알고리즘 완전 분석 및 시리얼 생성 프로그램 작성
• 오래 걸리겠지만 할 만 함
• 잘 안 되면 질문
부록 • 참고 사이트
참고 사이트
• 루트킷이란?
• https://ko.wikipedia.org/wiki/%EB%A3%A8%ED%8A%B8%ED%82%B7
• ZwQuerySystemInformation API
• https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms725506(v=vs.85).aspx
• enum 사용법
• http://kimgagakk.tistory.com/341
• 프로세스 권한 상승
• http://clansim.tistory.com/96

More Related Content

PPTX
Linux reversing study_basic_3
 
PPTX
System+os study 1
 
PPTX
System+os study 7
 
PPTX
Linux reversing study_basic_4
 
PPTX
Windows reversing study_basic_9
 
PPTX
Windows reversing study_basic_7
 
PPTX
System+os study 4
 
PPTX
Pwnable study basic_3
 
Linux reversing study_basic_3
 
System+os study 1
 
System+os study 7
 
Linux reversing study_basic_4
 
Windows reversing study_basic_9
 
Windows reversing study_basic_7
 
System+os study 4
 
Pwnable study basic_3
 

What's hot (20)

PPTX
Assembly 스터디 1
 
PPTX
Pwnable study basic_1
 
PPTX
Windows reversing study_basic_6
 
PPTX
Windows reversing study_basic_1
 
PPTX
Windows reversing study_basic_5
 
PPTX
Web hacking introduction
 
PPTX
Assembly 스터디 2
 
PPTX
System+os study 3
 
PPTX
Windows reversing study_basic_2
 
PPTX
Windows reversing study_basic_3
 
PPTX
Python
 
PPTX
Pwnable study basic_2
 
PPTX
Windows reversing study_basic_4
 
PPTX
System+os study 5
 
PPTX
Linux reversing study_basic_2
 
PDF
[Kerference] 시작! 리버싱 - 김종범(KERT)
PPTX
System+os study 6
 
PDF
2016317 파이썬기초_파이썬_다중설치부터_Jupyter를이용한프로그래밍_이태영
PPTX
Linux reversing study_basic_1
 
PDF
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
Assembly 스터디 1
 
Pwnable study basic_1
 
Windows reversing study_basic_6
 
Windows reversing study_basic_1
 
Windows reversing study_basic_5
 
Web hacking introduction
 
Assembly 스터디 2
 
System+os study 3
 
Windows reversing study_basic_2
 
Windows reversing study_basic_3
 
Python
 
Pwnable study basic_2
 
Windows reversing study_basic_4
 
System+os study 5
 
Linux reversing study_basic_2
 
[Kerference] 시작! 리버싱 - 김종범(KERT)
System+os study 6
 
2016317 파이썬기초_파이썬_다중설치부터_Jupyter를이용한프로그래밍_이태영
Linux reversing study_basic_1
 
잘 알려지지 않은 숨은 진주, Winsock API - WSAPoll, Fast Loopback
Ad

Similar to Windows reversing study_basic_8 (20)

PDF
Exception&log
PPTX
포스트모템디버깅과 프로세스 덤프 실전
PDF
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
 
PDF
요람(CreateProcess)에서 무덤(ResumeThread)까지
PPTX
Windows kernel basic exploit
PDF
[2012 CodeEngn Conference 07] manGoo - Exploit Writing Technique의 발전과 최신 트랜드
PDF
윈도우 커널 익스플로잇
PPT
Windows Debugging Technique #2
PPTX
Quick & Dirty Tips for x64 hooks
PDF
6. code level reversing
PDF
Codegate 2013 Junior - Music Player Exploit
PPTX
프로세스 방어
PDF
19.debugger detected and anti anti-techniques hangul
PDF
Windows os 상에서 효율적인 덤프
PPTX
Net debugging 3_전한별
PDF
[2013 CodeEngn Conference 08] manGoo - Windows 8 Exploit
PDF
보안 위협 형태와 악성코드 분석 기법
PDF
04.basic+aesthetic patching hangul
PDF
[NDC07] 게임 개발에서의 클라이언트 보안 - 송창규
PDF
[2017 Incognito] 스택 구조 분석을 통한 ROP 기법의 모든 것
Exception&log
포스트모템디버깅과 프로세스 덤프 실전
해커가 되고 싶은 자는 나에게... 정보보안 입문과 길 찾기
 
요람(CreateProcess)에서 무덤(ResumeThread)까지
Windows kernel basic exploit
[2012 CodeEngn Conference 07] manGoo - Exploit Writing Technique의 발전과 최신 트랜드
윈도우 커널 익스플로잇
Windows Debugging Technique #2
Quick & Dirty Tips for x64 hooks
6. code level reversing
Codegate 2013 Junior - Music Player Exploit
프로세스 방어
19.debugger detected and anti anti-techniques hangul
Windows os 상에서 효율적인 덤프
Net debugging 3_전한별
[2013 CodeEngn Conference 08] manGoo - Windows 8 Exploit
보안 위협 형태와 악성코드 분석 기법
04.basic+aesthetic patching hangul
[NDC07] 게임 개발에서의 클라이언트 보안 - 송창규
[2017 Incognito] 스택 구조 분석을 통한 ROP 기법의 모든 것
Ad

Windows reversing study_basic_8

  • 2. 목차 • API hooking //리버싱 핵심원리 4부 • 개념 //29장 • 배경지식 • API 후킹이란? • 구현 • debug 기법을 이용한 API 후킹 //30장 • 배경지식 • 실습 • DLL injection 기법을 이용한 API 후킹 • IAT 후킹 //32장 • 실습 • Code 패치 • 기본 //33장 • 글로벌 API 후킹 //33장 • 핫 패치 방식 //33장 • 고급 글로벌 API 후킹 //34장 • 과제 • 실습 따라 해보기 • CodeEngn • 부록 • 참고 사이트
  • 3. 개념 • 배경지식 • API 후킹이란?
  • 4. 배경지식 • 후킹 • 정보를 가로채거나, 실행 흐름을 변경하거나, 원래와는 다른 기능을 제공하게 하는 기술 • 그 중에서도Win32 API를 후킹 하는 기술을 API 후킹이라고 한다 • API • Windows는 여러 가지 이유(안정성, 보안, 효율, 기타)로 사용자 어플리케이션이 직접 시스템 자원에 접근하는 것을 막아 두었다 • 시스템 자원 : 메모리, 파일, 네트워크, 비디오, 사운드, 기타 • 사용자 어플리케이션이 시스템 자원을 이용하기 위해서는 OS에게 요청해야 한다 • MS에서 제공하는Win32 API를 이용 • 즉,API 함수 없이는 어떤 의미 있는 프로그램을 만들어 낼 수 없다. • 모든 프로세스에는 기본적으로 kernel32.dll이 로딩되며, kernel32.dll은 ntdll.dll을 로딩 한다 • 특정 시스템 프로세스의 경우 kernel32.dll을 로딩하지 않지만, 매우 예외적인 경우이다. • ntdll.dll의 역할이 바로 유저 모드 애플리케이션이 요구하는 시스템 자원에 대한 접근을 커널에게 요청하는 것 • GUI를 이용하는 프로그램은 user32.dll과 gdi32.dll을 필수로 로딩 한다
  • 5. API 후킹이란? • API 후킹 과정 • 디스어셈블러/디버거를 이용하여 프로그램의 구조와 동작 원리를 파악 • 원하는 동작을 하는 훅 코드 개발 • 실행 파일과 프로세스 메모리를 조작하여 훅 코드 설치 • API 후킹 예 • 메모장에서 저장 버튼을 누르면 CreateFile API가 호출된다 • 정상 상태에서는 kernel32.dll의CreateFile함수가 실행된다 • 이 예에서는 DLL injection을 이용하여 API를 후킹했다. • 메모장 exe 코드에서 CreateFile함수를 호출하면 내 DLL의 함수가 불린다 • 내 DLL에서 임의의 코드를 실행한다 • 저장 기능이 정상적으로 진행되게 하고싶다면 원본API를 호출한다 <notepad.exe> CreateFile API 호출 <kernel32.dll> CreateFile API 실행 call return <정상 API 호출> <notepad.exe> CreateFile API 호출 <kernel32.dll> CreateFile API 실행 call return <후킹 API 호출> <Myhook.dll> 임의의 코드 실행 정상 API를 호출하여 정상적으로 보이게 할 수 도 있음 call return
  • 6. API 후킹이란? • API 후킹을 이용하여 할 수 있는 일 • 소스코드가 없거나, 소스코드 수정이 여의치 않은 상황에서 프로그램을 고치거나 기능을 추가할 수 있음 • API 호출 전/후에 임의의 코드를 실행할 수 있음 • API에 넘어온 파라미터 혹은API 함수의 리턴 값을 엿보거나 조작할 수 있음 • API 호출 자체를 취소시키거나 사용자 코드로 실행 흐름을 변경시킬 수 있음 • 예) • 메모장의CreateFile 함수를 후킹하여 저장 로그 찍기 • 계산기에 한글로 숫자 표시하기 • 브라우저의API를 후킹하여 유해 사이트로의 접근 차단하기 • ...
  • 7. API 후킹이란? • API 후킹 구현 • 여러가지 방법을 통해 가능 • 상황에 맞게 골라 쓴다 • 자주 쓰이는 방식은 빨간 글씨로 표시했음 Method Object (무엇을 대상으로 조작을 가하는가) Location (어느 부분에 조작을 가하는 가) Technique (어떤 기술을 이용하여 조작하는가) API (기술을 적용하기 위해 이용하는 API) static File 1) IAT 2) Code 3) EAT X x A) Debug DebugActiveProcess GetThreadContext SetThreadContext dynamic Process Memory (가상 메모리) B) Injection B-1) Independent code CreateRemoteThread B-2) DLL file Registry (AppInit_DLLs) BHO(IE only) SetWindowsHookEx CreateRemoteThread
  • 8. API 후킹이란? • Method, Object • API 후킹 방식에 대한 대분류 • Static은 파일을 변경하는 방식 • Dynamic은 프로세스의 가상메모리를 변경하는 방식 • 일반적으로 말하는API 후킹은 이것을 의미 Method Object (무엇을 대상으로 조작을 가하는가) Location (어느 부분에 조작을 가하는 가) Technique (어떤 기술을 이용하여 조작하는가) API (기술을 적용하기 위해 이용하는 API) static File 1) IAT 2) Code 3) EAT X x A) Debug DebugActiveProcess GetThreadContext SetThreadContext dynamic Process Memory (가상 메모리) B) Injection B-1) Independent code CreateRemoteThread B-2) DLL file Registry (AppInit_DLLs) BHO(IE only) SetWindowsHookEx CreateRemoteThread
  • 9. API 후킹이란? • Location • 어느 부분을 조작할 것인가 • IAT • IAT에 있는 API 주소를 변경 • 장점 : 가장 쉽고 단순 • 단점 : IAT에 없는API는 후킹할 수 없다 • Code • 프로세스 메모리에 매핑된 dll에서API 실제 주소를 찾아가 코드를 직접 수정 • 가장 널리 사용되는 방법 • 다양한 방법으로 구현할 수 있다 • 시작 코드를 JMP 명령어로 패치하는 방법 • 함수 일부를 덮어쓰는 방법 • 필요한 부분만 일부 변경하는 방법 • EAT • DLL의 EAT에 기록된API 시작 주소를 변경 • 개념은 간단하지만 위의 방법이 더 쉬우므로 잘 사용되지 않음 Method Object (무엇을 대상으 로 조작을 가하는가) Location (어느 부분 에 조작을 가하 는가) Technique (어떤 기술을 이용하여 조작하는 가) API (기술을 적용하기 위해 이용하는 API) static File 1) IAT 2) Code 3) EAT X x A) Debug DebugActiveProcess GetThreadContext SetThreadContext dynamic Process Memory (가상 메모리) B) Injection B-1) Independent code CreateRemoteThread B-2) DLL file Registry (AppInit_DLLs) BHO(IE only) SetWindowsHookEx CreateRemoteThread
  • 10. API 후킹이란? • Technique • 대상 프로세스 메모리에 침투하여 후킹 함수를 설치하는 구체적 기법 • 크게 디버그와 인젝션 기법으로 나눌 수 있다 • 인젝션 기법은 다시 Code와 DLL 기법으로 나뉨 • 디버그 기법 • 대상 프로세스를 디버깅하면서 API를 후킹하는 방법 • 디버거는 디버깅 당하는 프로세스인 디버기에 대한 모든 권한(실행 제어, 메모리 액세스, 기타)을 가지기 때문에, 디버기의 프로세스 메모리에 후킹 함수를 자요롭게 설치할 수 있다 • 여기서 말하는 디버거는 일반적인 올리 디버거 등이 아니라, 후킹을 위하여 직접 제작한 프로그램이다 • OS가 제공하는 디버그 API를 이용하여 직접 디버거를 만들고, 제어한다. • 올리 디버거 등을 이용할 수도 있다 • 자동화 스크립트에 대한 지식 필요 • 장점 • 강력함 • 단점 • 디버거에 대한 지식, 혹은 자동화 스크립트에 대한 지식이 필요 • 많은 테스트가 필요 Method Object (무엇을 대상으 로 조작을 가하는가) Location (어느 부분 에 조작을 가하 는가) Technique (어떤 기술을 이용하여 조작하는 가) API (기술을 적용하기 위해 이용하는 API) static File 1) IAT 2) Code 3) EAT X x A) Debug DebugActiveProcess GetThreadContext SetThreadContext dynamic Process Memory (가상 메모리) B) Injection B-1) Independent code CreateRemoteThread B-2) DLL file Registry (AppInit_DLLs) BHO(IE only) SetWindowsHookEx CreateRemoteThread
  • 11. API 후킹이란? • Technique • 인젝션 기법 • 대상 프로세스 메모리 영역에 침투하는 기술 • DLL 인젝션이 가장 널리 사용됨 • DLL 인젝션 • DLL에 후킹 코드를 만든다 • DLL main을 통해 API 후킹 작업을 수행한다 • Code 인젝션 • 악성코드가 많이 사용(탐지가 DLL 인젝션보다 어려움) Method Object (무엇을 대상으 로 조작을 가하는가) Location (어느 부분 에 조작을 가하 는가) Technique (어떤 기술을 이용하여 조작하는 가) API (기술을 적용하기 위해 이용하는 API) static File 1) IAT 2) Code 3) EAT X x A) Debug DebugActiveProcess GetThreadContext SetThreadContext dynamic Process Memory (가상 메모리) B) Injection B-1) Independent code CreateRemoteThread B-2) DLL file Registry (AppInit_DLLs) BHO(IE only) SetWindowsHookEx CreateRemoteThread
  • 12. 구현 • debug 기법을 이용 • DLL injection 기법을 이용
  • 13. DEBUG 기법을 이용한 API HOOKING • 디버거를 구현하기 위해 제공되는 API를 이용하여 대상 프로세스의 API를 후킹 Method Object (무엇을 대상으로 조작을 가하는가) Location (어느 부분에 조작을 가하는 가) Technique (어떤 기술을 이용하여 조작하는가) API (기술을 적용하기 위해 이용하는 API) static File 1) IAT 2) Code 3) EAT X x A) Debug DebugActiveProcess GetThreadContext SetThreadContext dynamic Process Memory (가상 메모리) B) Injection B-1) Independent code CreateRemoteThread B-2) DLL file Registry (AppInit_DLLs) BHO(IE only) SetWindowsHookEx CreateRemoteThread
  • 14. DEBUG 기법을 이용한 API HOOKING - 배경지 식 • 디버거 • 디버거 (debugger) – 디버깅 프로그램 • 올리 디버거, 비주얼 스튜디오의 디버거 등 프로그램을 디버깅하기 위해 이용하는 프로그램 • 디버기 (debuggee) – 디버깅 당하는 프로그램 • 디버거의 기능 • 디버기가 올바르게 실행되는지 확인하고, 프로그램의 오류를 발견하는 것 • 디버기의 명령어를 하나씩 실행할 수 있음 • 디버기의 레지스터와 메모리에 대한 모든 접근 권한을 가짐 • 디버기의 예외를 처리할 권한을 가짐
  • 15. DEBUG 기법을 이용한 API HOOKING - 배경지 식 • 디버거 동작 원리 • 일단 디버거 프로세스로 등록이 되면, OS는 디버기에서 디버그 이벤트(debug event)가 발생할 때마다 디버기의 실행을 멈추고 해당 이벤트를 디버거에게 통보한다 • 디버거는 해당 이벤트에 대해 적절한 처리를 한 후 디버기의 실행을 재개할 수 있다 • 일반적인 예외(0으로 나누기 등)도 디버그 이벤트에 해당함 • 프로세스가 디버깅 중이 아니었다면 디버그 이벤트는 자체 예외 처리 혹은 OS의 예외 처리 루틴에서 처리 • 디버거는 디버그 이벤트 중에서 처리할 수 없거나 관심 없는 이벤트들은 OS가 처리하도록 만들어 준다 • 정리하자면, 예외가 발생하면 디버기의 진행을 멈추고 디버거에게 처리할 기회를 준다 • 디버거는 디버기의 자체 예외 처리를 이용할 수도 있고, 디버거가 예외를 직접 처리할 수도 있다 • 올리디버거에서 하는 일들을 생각해 보면 됨 OS Debugee (일반 프로그램) 예외 이벤트 이벤트 처리 <일반 프로세스의 예외 이벤트 처리> OS Debugee 예외 이벤트 이벤트 처리 <Debugger – Debuggee 관계의 예외 이벤트 처리> Debuger 디버거가 처리하지 않을 예외 처리 요청 이벤트 처리
  • 16. DEBUG 기법을 이용한 API HOOKING - 배경지 식 • 디버그 이벤트 • EXCEPTION_DEBUG_EVENT • CREATE_THREAD_DEBUG_EVENT • CREAT_PROCESS_DEBUG_EVENT • EXIT_THREAD_DEBUG_EVENT • EXIT_PROCESS_DEBUG_EVENT • LOAD_DLL_DEBUG_EVENT • UNLOAD_DLL_DEBUG_EVENT • OUTPUT_DEBUG_STRING_EVENT • RIP_EVENT • 이 중 디버깅에 관련된 이벤트는 EXCEPTION_DEBUG_EVENT
  • 17. DEBUG 기법을 이용한 API HOOKING - 배경지 식 • EXCEPTION_DEBUG_EVENT와 관련된 예외 목록 • EXCEPTION_ACCESS_VIOLATION • EXCEPTION_ARRAY_BOUNDS_EXCEEDED • EXCEPTION_BREAKPOINT • EXCEPTION_DATATYPE_MISALIGNMENT • Float 예외 처리 • EXCEPTION_FLT_DENORMAL_OPERAND • EXCEPTION_FLT_DVIDE_BY_ZERO • EXCEPTION_FLT_INEXACT_RESULT • EXCEPTION_FLT_INVALUD_OPERATION • EXCEPTION_FLT_OVERFLOW • EXCEPTION_FLT_STACK_CHECK • EXCEPTION_FLT_UNDERFLOW • Int 예외 처리 • EXCEPTION_INT_DEVIDE_BY_ZERO • EXCEPTION_INT_OVERFLOW • EXCEPTION_ILLEGAL_INSTRUCTION • EXCEPTION_IN_PAGE_ERROR • EXCEPTION_INVALID_DISPOSITION • EXCEPTION_NONCONTINUABKE_EXCEPTION • EXCEPTION_PRIV_INSTRUCTION • EXCEPTION_SINGLE_STEP • EXCEPTION_STACK_OVERFLOW
  • 18. DEBUG 기법을 이용한 API HOOKING - 배경지 식 • EXCEPTION_BREAKPOINT • BP 처리 • BP는 어셈블리 명령어로 INT3, x86 기계어로 0xCC • 코드 디버깅 중에 INT3 명령어를 만나면 실행이 중지되고, 디버거에게 EXCEPTION_BREAKPOINT예외 이벤트가 날아간다 • 실제로 BP를 걸면 해당 코드를 INT3 명령어로 바꾼다 • 올리 디버거에서 BP가 걸린 코드가 바뀌어 보이지 않는 것은 디버거가 원래 코드를 사용자에게 보여주는 것일 뿐이다 • 실제 메모리에는 INT3명령어로 적혀 있음 • BP에서 다시 디버깅을 진행할 때 원본 명령어로 복원하고 실행한다 • 디버그 기법을 이용한API 후킹은 이러한 BP의 특성을 이용한다
  • 19. DEBUG 기법을 이용한 API HOOKING - 실습 • 기본 아이디어 • 디버거 – 디버기 관계를 가진 상태에서 디버기의API 시작 부분을 0xCC로 바꿔(BP를 걸어) 제어를 디버거로 가져온 상태에서 원하는 작업을 수행한 후, 디버기를 다시 실행 상태로 바꾼다. • 작업 순서 • 1) 대상 프로세스에 디버거를 ‘attach’하여 대상 프로세스를 디버기로 만듦 • 2) 훅 – API 시작 주소의 첫 바이트를 0xCC로 변경 (=bp를 검) • 3) 해당API가 호출되면 BP에 걸려 제어가 디버거에게 넘어옴 • 4) 원하는 작업을 수행 • 5) 언훅 – 0xCC를 원래대로 복원시킴 (API의 정상 실행을 위해) • 6) 해당API 실행 (0xCC가 빠진 정상적인 상태) • 7) 훅 – 다시 0xCC로 바꿈 (지속적인 후킹을 위해) • 8) 디버기에게 제어를 되돌려 줌 • 위 방법은 기본적인 방법이다. • 용도에 따라 원본API를 호출하지 않을 수도 있고, custom API를 호출할 수도 있고, 한 번만 후킹할 수도 있고, 여러번 후킹할 수도 있다
  • 20. DEBUG 기법을 이용한 API HOOKING - 실습 • 실습할 것 • 편집 프로그램에서 저장을 하면 알파벳 소문자를 대문자로 바꾸어 저장한다
  • 21. • 헤더, 함수 선언, 전역변수, main 함수 정 의 • 메인함수 입력 값으로 대상 프로세스의 PID를 받는 다.
  • 22. • 디버거 기능을 총괄하는 함수 • 이벤트가 발생하면 각 상황에 맞는 작업을 한 다 • 프로세스가 attach 되었을 때 훅을 설치하고, 예외가 발생하면 처리해 준다. 디버기 프로그 램이 종료되면 디버거 프로그램도 종료되도 록 한다.
  • 23. • 대상 프로세스가 attach 되었다는 이벤트 를 처리하는 함수 • 대상 프로세스의WriteFile API의 맨 처음 바이트에 bp 를 건다. • Hook 설치
  • 24. • 예외 이벤트를 처리하는 함수_1 • 설치한 BP를 만났을 때 원하는 작업을 할 수 있도록 한다. • Thread context • 쓰레드가 이용하던 레지스터 값을 저장 하는 구조체 • 각 쓰레드마다 하나씩 가지고 있다 • 방금 예외를 일으킨 쓰레드의 정보를 가 져오고, 레지스터 값을 이용할 것이다. typedef struct _CONTEXT { DWORD ContextFlags; DWORD Dr0; DWORD Dr1; DWORD Dr2; DWORD Dr3; DWORD Dr6; DWORD Dr7; FLOATING_SAVE_AREA FloatSave; DWORD SegGs; DWORD SegFs; DWORD SegEs; DWORD SegDs; DWORD Edi; DWORD Esi; DWORD Ebx; DWORD Edx; DWORD Ecx; DWORD Eax; DWORD Ebp; DWORD Eip; DWORD SegCs; DWORD EFlags; DWORD Esp; DWORD SegSs; BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION]; } CONTEXT;
  • 25. • 예외 이벤트를 처리하는 함수 _2 • 설치한 BP를 만났을 때 원하는 작업 을 할 수 있도록 한다. • WriteFile이 받은 인자를 조작하고 있 다. • API 복원 후 대상 프로그램의 EIP를 WriteFile의 시작 부분으로 변경해 주 어야 한다 • INT3을 실행하느라 한 바이트 뒤를 가리키고 있음
  • 26. • 예외 이벤트를 처리하는 함수_3 • 설치한 BP를 만났을 때 원하는 작업을 할 수 있도록 한다. • 다시 훅을 걸어 두어 후에 저장을 시도했을 때도 후킹되도록 한다. • 주의! • 책에서는 windows에 기본으로 있는 메모장을 대상으로 함. 그 메모장은 파일을 저장할 때만 WriteFile함수가 불림 • 다른 프로그램은 아닐 수 있음 • 프로그램을 종료하기 전 환경 설정등을 저장하는 경우도 있다(종료 이벤트가 발생하기 전) • -> 후킹 프로그램을 끄는 게 나음
  • 27. DEBUG 기법을 이용한 API HOOKING - 실습 • XP 이상부터는 DebugSetProcessKillOnExit()를 호출하여 디버거가 종료되는 순간에 디버기가 종료되지 않도록 할 수 있다 • 디버거를 종료하기 전에 언훅을 하지 않으면 디버기는 INT3에 걸려 BP 예외가 발생한다 • 따라서 언훅을 해 주어야 한다
  • 28. DLL INJECTION 기법 -> IAT 후킹을 이용한 API HOOKING • DLL injection기법으로 대상 프로세스의 IAT를 조작한다 • 장점 : 동작 원리와 구현이 비교적 간단 • 단점 : 후킹을 원하는API가 대상 프로세스의 IAT에 없다면 사용 불가 Method Object (무엇을 대상으로 조작을 가하는가) Location (어느 부분에 조작을 가하는 가) Technique (어떤 기술을 이용하여 조작하는가) API (기술을 적용하기 위해 이용하는 API) static File 1) IAT 2) Code 3) EAT X x A) Debug DebugActiveProcess GetThreadContext SetThreadContext dynamic Process Memory (가상 메모리) B) Injection B-1) Independent code CreateRemoteThread B-2) DLL file Registry (AppInit_DLLs) BHO(IE only) SetWindowsHookEx CreateRemoteThread
  • 29. DLL INJECTION 기법 -> IAT 후킹을 이용한 API HOOKING - 실습 • 기본 아이디어 • IAT에 있는 함수 포인터를 내 DLL의 함수 주소로 변경한다 • 대상 프로세스가 훅을 걸어 둔 API를 호출하면 내 함수가 불린다 • 작업 순서 • 1) DLL main에서 훅을 설치하는 DLL을 만들고, injection 한다 • 2) 대상 프로세스가 훅을 걸어 둔 API를 호출하면 내 함수에서 원하는 일을 수행한다 • 3) 정상 함수를 호출해준다면 정상으로 보인다 내 함수
  • 30. DLL INJECTION 기법 -> IAT 후킹을 이용한 API HOOKING - 실습 • 실습할 것 • 계산기가 숫자를 한글로 쓰도록 한다
  • 31. • 헤더, 함수 선언, 전역변수, DllMain
  • 32. • SetWindowTextW함수 대신 불리는 함수 • 버퍼를 조작한 뒤 원본 SetWindowTextW 함 수를 호출
  • 33. • 훅을 설치하는 함수_1 • IAT를 조작한다 • 프로세스가 끝날 때는 반대로 언훅을 하기 위해 이용 된다 • 인자만 바꿔 넣으면 됨
  • 35. DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_1 • DLL injection기법으로 API의 코드를 조작한다. • 장점 : IAT 후킹 기법은 대상 프로그램의 IAT에 원하는 함수가 없으면 불가능했지만, 이 기법은 그런 제한은 없다. • 동적으로 로딩한 DLL에 대해서도 후킹할 수 있다 • 단점 : API 코드 길이가 최소 5바이트보다 커야 한다 (모든 API가 이보다는 크기 때문에 사실상 제한 없음) Method Object (무엇을 대상으로 조작을 가하는가) Location (어느 부분에 조작을 가하는 가) Technique (어떤 기술을 이용하여 조작하는가) API (기술을 적용하기 위해 이용하는 API) static File 1) IAT 2) Code 3) EAT X x A) Debug DebugActiveProcess GetThreadContext SetThreadContext dynamic Process Memory (가상 메모리) B) Injection B-1) Independent code CreateRemoteThread B-2) DLL file Registry (AppInit_DLLs) BHO(IE only) SetWindowsHookEx CreateRemoteThread
  • 36. DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_1 • 기본 아이디어 • API의 맨 처음 명령어를 JMP 명령어로 패치해서,API가 호출되면 임의의 코드로 점프한다 • 작업 순서 • 1) DLL main에서 훅을 설치하는 DLL을 만들고, injection 한다 • 2) 대상 프로세스가 훅을 걸어 둔 API를 호출하면 내 코드로 jmp한다 • 3) 원하는 작업을 수행한다
  • 37. DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_1
  • 38. DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_1 • 실습할 것 • 은폐 프로세스(루트킷, Rootkit)의 일종 • 루트킷이란 : 프로세스, 파일, 레지스트리 등을 은폐하는 기술 • 메모장이 process explorer와 작업 관리자에서 보이지 않도록 한다
  • 39. DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_1 • 들어가기 전에.. • 유저모드 프로그램이 프로세스 정보를 얻는 방법 • 관련API 이용 • 관련API로는 2가지가 있다 • CreateToolhelp32Snapshot API • EnumProcess API • 이 두API는 모두 내부적으로 ntdll의ZwQuerySystemInformation API를 호출한다 • ZwQuerySystemInformation를 직접 호출하여 얻을 수도 있다 • 이 함수를 통해서 실행중인 모든 프로세스의 정보(구조체)를 연결 리스트 형태로 얻을 수 있다 • -> ZwQuerySystemInformation를 후킹하여 리스트를 조작하면 perfect! • (win 8부터는 변경되었다고 함) • 후킹 대상은 숨겨지기를 원하는 프로세스가 아니라, 다른 모든 프로세스라는 것에 주의 • Process explorer와 작업관리자 뿐만 아니라 다른 프로그램들도 프로세스 정보를 이용한다 • 따라서 모든 프로세스에 후킹해야만 은폐되었다고 확신할 수 있다 • Ex) 스텔스 전투기는 레이더에 포착되지 않기 위해 각종 첨단 과학을 동원하여 전투기 자체를 새롭게 개발한 것. • 프로세스는 반대로 모든 레이더를 망가뜨려서 일반 전투기가 스텔스 전투기가 된 것이다
  • 40. • <DLL 코드> • 헤더, 함수 선언, 전역변수 • 숨길 프로그램 이름은 공유 변수에 저장한다 • 무슨 프로그램을 숨길 지 간단하게 공유할 수 있음
  • 41. • <DLL 코드> • export하는 함수 • injector가 이 함수를 호출하여 DLL의 공유 변수에 숨길 프로그램의 이름을 저장한다
  • 42. • <DLL 코드> • DllMain 함수 • DLL이 올라가면 훅을 설치하고, 전부 내 려가면 언훅한다. • injector 프로그램에는 훅을 설치하지 않 는다 • 이 프로그램 이름은 HideProc.exe로 할 것임
  • 43. • <DLL 코드> • Hook_By_Code 함수 • API의 주소를 찾고, 훅이 걸려있지 않다 면 맨 앞 코드를 jmp 코드로 변경하여 훅 을 건다.
  • 44. • <DLL 코드> • Unhook_By_Code 함수 • API의 주소를 찾고, 원래 코드를 복원한다.
  • 45. • <DLL 코드> • NewZwQuerySystemInformation 함수_1 • ZwQuerySystemInformation 함수를 호출했을 때, 훅을 통하여 실행될 함수이다. • ZwQuerySystemInformation 함수의 결과를 받고, 그 결과를 조작한 뒤 return한다. • 함수의 결과로 현재 실행중인 프로세스 정보 리스트를 받는다. • 그 중 숨기고 싶은 프로세스와 관련된 정보를 삭제한다
  • 46. • <DLL 코드> • NewZwQuerySystemInformation 함수_2 • 리스트를 순회하며 숨기고 싶은 프로세스에 대한 정보가 있는지 살펴본다 • 있다면 그 정보를 삭제한다
  • 47. • <DLL 코드> • NewZwQuerySystemInformation 함수_3 • 언훅했던 함수에 다시 훅을 건다
  • 48. • <injector 코드> • typedef, enum, 함수 선언 • enum 사용법은 부록의 참고 사이트에 있음
  • 49. • <injector 코드> • 메인 함수 • 인자를 받는다 • 권한을 상승한다 • 앞서 만든 DLL의 export 함수를 이용하여 숨길 프로세스 이름을 설 정한다 • 모든 프로세스를 대상으로 인젝션 혹은 이젝션한다
  • 50. • <injector 코드> • SetPrivilege 함수_1 • 권한을 상승시키는 함수이다 • 메인 함수에서 호출한다 • 권한을 상승시켜야 일부 프로세 스들을 열고, 인젝션 혹은 이젝션 할 수 있다.
  • 51. • <injector 코드> • SetPrivilege 함수_2
  • 52. • <injector 코드> • Inject_Or_Eject_AllProcess 함수 • 메인 함수에서 호출한다 • 메인 함수의 인자에 따라 inject하거나 eject한다 • hide일 경우 inject • show일 경우 eject • 프로세스의 정보 리스트를 얻고, 순회하면서 모든 프로세스 에 DLL inject/eject 한다.
  • 53. • <injector 코드> • InjectDll 함수 • Inject_Or_Eject_AllProcess 함수에서 호출된다 • DLL injection에서 썼던 코드와 같은 코 드
  • 54. • <injector 코드> • EjectDll 함수_1 • Inject_Or_Eject_AllProcess 함 수에서 호출된다 • DLL ejection에서 썼던 코드와 같은 코드
  • 55. • <injector 코드> • EjectDll 함수_2 • Inject_Or_Eject_AllProcess 함수에서 호출된다 • DLL ejection에서 썼던 코드와 같은 코드
  • 56. DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_2 • 은폐 기법의 문제점 • 1. 후킹 대상 프로세스 개수 • Process explorer와 작업관리자 뿐만 아니라 다른 프로그램들도 프로세스 정보를 이용한다 • 따라서 모든 프로세스에 후킹해야만 은폐되었다고 확신할 수 있다 • 2. 새로 생성되는 프로세스 • 여태까지의 인젝터는 실행된 프로세스에 인젝션 했다. • 새로 실행한 프로세스에도 인젝션해야 완전히 은폐될 수 있다 • 해결 방법 • 글로벌 후킹을 이용 • 현재 실행중인 모든 프로세스의 API를 후킹함 • 나중에 실행되는 프로세스에도 똑같이 후킹함 • 시스템 전체에 걸쳐서 후킹을 한다고 해서 글로벌(Global)
  • 57. DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_2 • 글로벌 후킹 • 구현에는 다양한 방법이 있음 • 그 중 또 다른 API를 후킹하여 구현하는 방법을 이용해보자 • 프로세스를 생성하는API를 후킹 • 프로세스 생성 관련 API • CreateProcess함수 • 두 종류가 있음 • Kernel32.CreateProcessA (아스키 문자열을 이용하는 버전) • Kernel32.CreateProcessW (유니코드 문자열을 이용하는 버전) • 내부적으로 각각 CreateProcessInternalA,CreateProcessInternalWAPI를 이용 • 일반적으로 CreateProcess함수를 많이 이용하지만, 일부 MS 프로그램은 CreateProcessInternal 함수를 이용 • 좀 더 정확한 후킹을 위해서는 low level 함수를 후킹하는 것이 좋다 • 새로운 프로세스 생성 함수 : 프로세스 정상 생성 후 자식 프로세스에게 DLL injection 함 • 아주 짧은 시간동안 프로세스가 후킹되지 않은 채로 실행될 가능성이 있음 • ->ZwResumeThreadAPI 를 후킹하면 해결 가능(뒤에서 함)
  • 58. DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_2 • 실습할 것 • process explorer를 새로 켰을 때도 notepad.exe에 대한 정보가 보이지 않도록 한다 • 앞에서 짠 코드를 수정/추가 이런 상황을 없앰
  • 59. • <DLL 코드> • 앞에서 쓴 코드에서 수정/추가된 부분만 썼음 • define, 공유변수 부분 • STR_MODULE_NAME은 이 DLL 파일 이름이다
  • 60. • <DLL 코드> • typedef부분 • 함수 포인터 • STR_MODULE_NAME은 이 DLL 파일 이름이다
  • 61. • <DLL 코드> • 앞에서 쓴 코드에서 수정/추가된 부분만 썼 음 • 전역변수 선언 부분/함수 선언 부분 • 기존 전역변수 이름도 바꾸었으므로 해당 전역변수를 이용하던 코드도 수정해야 한 다
  • 62. • <DLL 코드> • 전역변수 이름을 변경했으니 ZwQuerySystemInformation과 관련된 함수에서 이용한 전역변수도 바꿔준다 • DllMain과 NewZwQuerySystemInformation에 있음
  • 63. • <DLL 코드> • export 함수 • 공유변수에 인젝션할 DLL 경로를 넣는 함수이다
  • 64. • <DLL 코드> • DLL injection을 하기 위해 권한을 상승한다 • CreateProcess API에 대한 훅/언훅 함수를 호출한다
  • 65. • <DLL 코드> • SetPrivilege 함수 • 앞에서 만든 injector에서 그대로 떼어 오면 됨
  • 66. • <DLL 코드> • InjectDll2함수 • 앞에서 만든 InjectDll함수에서 조 금 변형했다.
  • 67. • <DLL 코드> • NewCreateProcessA함수
  • 68. • <DLL 코드> • NewCreateProcessA함수와 인자만 다름
  • 69. • <Injector 코드> • 앞에서 쓴 코드에서 수정/추가된 부분만 썼음 • typedef, main함수 일부 내용 추가
  • 70. DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_3 • 핫 패치(Hot patch) 방식의 API 후킹 • 핫 패치란? • 프로세스가 실행중인 상태에서 라이브러리를 프로세스 메모리에서 일시적으로 변경하는 기술 • 시스템 라이브러리를 업데이트 할 때, 실행중인 프로세스들이 업데이트 된 라이브러리를 이용할 수 있게 함 • 재부팅 하면 패치 대상 라이브러리 파일이 완전히 교체된다 • API 후킹 기법을 이용하여 이루어진다 • 핫 픽스(fix), 7바이트 코드 패치 방법이라고도 한다. • 오른쪽은 CreateProcessW함수이다. (BP가 시작 부분) • OS의 중요 시스템 라이브러리는 오른쪽 그림과 같이, 5개의 NOP과 MOV EDI, EDI가 함수 시작 부분에 있다 • 함수는 MOV EDI, EDI에서 시작한다 • 각 함수 사이에는 5개의 NOP으로 띄워져 있다 • ->7바이트의 쓰레기 코드가 있다 • 이는 핫 패치를 이용하기 위한 것 • 컴파일러 설정을 통해 오른쪽과 같이 핫 패치가 가능한 형태로 컴파일 할 수 있다
  • 71. DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_3 • 기존 방법의 문제점 • 앞에서는 API의 처음 5바이트를 점프 코드로 수정했다 • 원본 함수를 이용하기 위해 반복적으로 훅, 언훅을 했다 • ->멀티 쓰레드 환경에서 문제를 일으킬 수 있음 • 어떤 쓰레드가 함수를 실행하려고 하고, 어떤 쓰레드가 쓰려고 하면 충돌이 일어난다 • 핫 패치의 원리 • 여유 자리로 남겨놓은 쓰레기코드 7바이트를 2개의 점프문으로 변경한다 • 원본 함수를 호출하고 싶다면 (함수 주소 +2) 를 이용한다.
  • 72. DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_3 • short jmp와 far jmp • short jmp는 2바이트 기계어를 이용한다 • 뒤 1바이트가 상대 주소 • -128~127 범위에서의 점프만 가능 • far jmp는 5바이트 기계어를 이용한다 • 뒤 4바이트가 상대 주소 • 프로세스 메모리 유저 영역 어느 곳으로도 점프 가능 • 핫 패치에서는 short jmp로 바로 위에 있는 far jmp코드로 가고, far jmp에서 원하는 함수로 이동 한다 • 핫 패치 • 장점 : 안정적이다, 원본 함수를 이용하기 위해 매번 훅/언훅하지 않아도 된다 • 단점 : 제약조건 (NOP 5개와 MOV EDI, EDI 즉, 7바이트의 쓰레기 코드)이 만족되지 않는API에는 적용할 수 없음 • 핫 패치 가능하도록 컴파일한 게 아닌 함수 • 모든API에 쓸 수는 없으므로, 먼저 후킹할 함수가 핫 패치 방식을 지원하는지 미리 확인해야 한다
  • 73. • <DLL 코드> • 메인 함수에서 CreateProcess함수 를 후킹하는 함수로 핫패치 함수를 호출한다.
  • 74. • <DLL 코드> • 핫패치를 이용하여 훅을 거는 함수
  • 75. • <DLL 코드> • 핫패치를 이용한 훅을 언훅하는 함수
  • 76. • <DLL 코드> • NewCreateProcessA 함수를 수정한다.
  • 77. • <DLL 코드> • NewCreateProcessW 함수를 수정한다.
  • 78. DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_4 • Global 후킹을 하기 위해 프로세스를 생성하는 함수에 후킹했을 경우 • 프로세스 정상 생성 후 자식 프로세스에게 DLL injection 함 • 아주 짧은 시간동안 프로세스가 후킹 되지 않은 채로 실행될 가능성이 있음 • ->ZwResumeThread API 를 후킹하면 해결 가능 • ZwResumeThread API란? • CreateProcess 계열 함수를 호출했을 시 API 호출 흐름 • kernel32.CreateProcessW • kernel32.CreateProcessInternalW • ntdll.ZwCreateUseProcess • ntdll.ZwResumeThread • ZwCreateUseProcess API가 호출되면 프로세스가 생성되지만, 메인 쓰레드는 suspend 상태이다 • ZwResumeThread를 호출해야 메인 쓰레드가 시작한다 • 즉, 생성된 프로세스의 메인 쓰레드를 시작하게 하는 API다 • Low level API vs High level API • 대부분의 Low level API들은 문서화되어 있지 않으며, OS 버전에 따라 변경될 가능성이 있다 • High level API는 문서화 되어있으며, 변할 가능성이 없다 • 내부 구현을 변할 수 있지만 함수를 이용하는 방식 등은 변하지 않음 (API가 조금 수정되어도 그 API를 이용하는 프로그램들을 수정할 필요가 없음) • Low level API를 후킹하면 더욱 강력함 • High level API를 후킹하면 안정적인 후킹 가능 • 상황에 따라 적절한 API를 선택할 필요가 있다
  • 79. DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_4 • 실습할 것 • IE로 접속해서 특정 사이트에 접속했을 때, 다른 사이트로 우회 시킨다
  • 80. DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_4 • 글로벌 API 후킹 개념 정리 • 일반적인API 후킹의 문제는 후킹을 원하는 프로세스가 생성될 때마다 매번API후킹을 해 줘야 한다는 것 • 글로벌API 후킹은 생성된 프로세스에 매번API 후킹을 하는 작업을 자동화한 것 • 대상 프로세스를 생성하는 프로세스에 후킹을 함 • 자동API 후킹의 기본 개념 • 이것을 시스템에서 실행중인 모든 프로세스를 대상으로 확장한 것이 글로벌API 후킹 • 하지만 필요에 따라 모든 프로세스에 후킹하지 않을 때도 있다 • 시스템 안정성과 불필요한 오버헤드를 막기 위해 특정 프로세스에만 후킹할 수도
  • 81. DLL INJECTION 기법 -> API 코드 패치를 이용한 API HOOKING_4 • 대상 프로그램 • 인터넷 익스플로러 • 탭 기능이 있음 • 새 탭을 열면 자식 프로세스가 생성된다 • 탭을 이용하는 많은 브라우저는 이와 같은 방법을 이용한다 • 탭들을 관리하는 부모 프로세스가 있고, 실제로 접속하는 자식 프로세스가 있다 • ->부모 프로세스에 후킹해 두면 OK • IE 프로세스를 후킹해도 되고, 처음 인터넷 익스플로러를 실행해 주는 Explorer.exe에만 후킹해도 되고, 모든 프로세스를 후킹해도 된다
  • 82. • <DLL 코드> • 공유 영역 변수가 늘어났다 • typedef
  • 83. • <DLL 코드> • 구조체와 함수 포인터의 typedef • 구조체가 저장된 헤더를 다운받아야 하므로 그냥 직접 typedef했다
  • 84. • <DLL 코드> • 함수 선언과 전역변수 선언 • 두 개의 함수를 후킹한다 • ZeResumeThread • 자식 프로세스에도 후킹을 하기 위함 • InternetConnectW • Redirect를 위해 • Hook_By_Code와 Unhook_By_Code, SetPrivilege 함수는 이전과 같다
  • 85. • <DLL 코드> • export하는 함수 • 공유 변수를 설정한다
  • 86. • <DLL 코드> • DllMain 함수
  • 87. • <DLL 코드> • NewZwResumeThread 함수_1
  • 88. • <DLL 코드> • NewZwResumeThread 함수_2
  • 89. • <DLL 코드> • NewZwResumeThread 함수_3
  • 90. • <DLL 코드> • NewInternetConnectW 함수_1
  • 91. • <DLL 코드> • NewInternetConnectW 함수_2
  • 92. • <DLL 코드> • InjectDll 함수_1
  • 93. • <DLL 코드> • InjectDll 함수_2
  • 94. • <DLL 코드> • MyCreateRemoteThread 함수_1 • vista 이상 버전에서는 CreateRemoteThread 함수의 내부 구조가 다르고, 또한 특별한 정책때문에 DLL injection이 잘 되지 않았다 • vista 이상 버전에서도 잘 작동하도록 만든 함수 이다 • DLL injection 할 때 CreateRemoteThread 함수 대신 이 함수를 호출한다 • OS 버전에 따라 알맞은 처리를 함
  • 95. • <DLL 코드> • MyCreateRemoteThread 함수_2 • vista 이상 버전에서는 CreateRemoteThread 함수의 내부 구조가 다르고, 또한 특별한 정책때문에 DLL injection이 잘 되지 않았다 • vista 이상 버전에서도 잘 작동하도록 만든 함수 이다 • DLL injection 할 때 CreateRemoteThread 함수 대신 이 함수를 호출한다 • OS 버전에 따라 알맞은 처리를 함
  • 96. • <DLL 코드> • IsVistaLater 함수 • MyCreateRemoteThread 함수에서 이용하는 함 수 • OS 버전이 vista 이상인지 알려줌
  • 97. • <DLL 코드> • DebugLog • 프로그램 진행 상황을 보기 쉽도록 로그를 찍 음
  • 98. • <Injector 코드> • typedef, 함수 선언 • SetPrivilege와 InjectDll, EjectDll함수는 똑같음
  • 99. • <Injector 코드> • main함수 _1 • 인자에 주의
  • 100. • <Injector 코드> • main함수 _2
  • 101. 과제 • 실습 따라 해보기 • CodeEngn
  • 102. 실습 따라 해보기 • 실습 코드를 열심히 읽어서 이해해 보자
  • 103. CODEENGN • 18번 • 알고리즘 완전 분석 및 시리얼 생성 프로그램 작성 • 오래 걸리겠지만 할 만 함 • 잘 안 되면 질문
  • 104. 부록 • 참고 사이트
  • 105. 참고 사이트 • 루트킷이란? • https://ko.wikipedia.org/wiki/%EB%A3%A8%ED%8A%B8%ED%82%B7 • ZwQuerySystemInformation API • https://msdn.microsoft.com/ko-kr/library/windows/desktop/ms725506(v=vs.85).aspx • enum 사용법 • http://kimgagakk.tistory.com/341 • 프로세스 권한 상승 • http://clansim.tistory.com/96