2016. 2. 1. 02:21

Crackit2.exe 의 flag 를 찾는 것이 목표이다.

기본적으로 프로그램을 실행시켜서 아무 값이나 입력하면 다음과 같다.

Ollydbg를 이용하여 이 프로그램을 열고 "All referenced text string" 창을 열면 다음과 같이 "ACCESS DENIED" 와 "ACCESS GRANTED" 를 찾을 수 있다.

"ACCESS GRANTED" 와 ACCESS DENIED" 분기문으로 갈리는 지점을 찾아가면 다음과 같다.

004027A7 에서 EAX 값을 테스트하여 바로 JNZ 를 통해 분기하는 것을 알 수 있다.

004027A7을 실행하기 직전의 레지스터 값을 보면 다음과 같다.

EAX에 FFFFFFFF가 들어있는데, 위의 분기문에서 "ACCESS DENIED"가 있는 부분으로 점프하지 않고 "ACCESS GRANTED"가 있는 부분으로 넘어가기 위해서는 EAX의 값이 0이 되어야 함을 알 수 있다.


이제 다시 프로그램을 처음부터 실행시켜 보자.

빈칸에 아무 값이나 입력하고 코드 부분을 보면 다음과 같은 내용이 나온다.

004022E4에서 PUSH EAX 을 실행하는데, EAX에는 내가 입력한 값이 들어있었다. 따라서 EAX 값을 스택에 저장한 뒤 MSVBVM60.__vbaLenBstr 함수를 호출하여 입력한 값의 길이를 구하게 된다. 그 값은 다시 EAX에 저장되게 된다. 그 후 004022ED에서 CMP EAX,7 을 실행하는데, 이는 그 길이가 7인지 확인하는 부분이다.

그 밑으로 몇줄 내려오면 다음과 같다.

0040230C 에서 JE 명령어가 나오는데, 이는 CMP EAX,7에서 EAX가 7이 아닐 경우 zero flag가 1이 되기 때문에 점프를 실행하게 된다. EAX가 7이면 바로 다음 줄의 명령을 실행하게 된다.

일단 7이 아닌 크기의 문자열을 입력하여 점프를 실행하면 이 글의 첫 부분에서 말했던 분기점 부분으로 바로 넘어가게 된다.

0040279D에서 "yes"라는 값을 스택에 넣고 vbaStrCmp 함수를 호출한다. 그런데, vbaStrCmp는 스택에 있는 두 개의 값을 불러들여 비교하게 되는데, "yes"가 하나 들어있기 때문에 비교하면 EAX에 FFFFFFFF라는 값이 결과값으로 들어가게 된다. 따라서 바로 "ACCESS DENIED" 부분으로 넘어가게 된다. 즉, 이제 나는 7글자의 문자열을 입력한 뒤 그 문자열을 분석하는 코드를 지나면서 스택에 "yes"가 들어갈 수 있게 하면 된다.

이제 문자열 7개를 분석하는 부분에 초점을 맞춘다. 그 중 어떠한 값을 스택에 넣고 vbaStrCmp를 호출한 뒤 점프를 실행하는 부분을 발견할 수 있다.

그 중 최초로 값을 비교하는 부분에서 스택을 확인하면 내가 입력했던 값이 한 글자씩 차례대로 스택에 저장되어 있음을 확인할 수 있다.

즉, 내가 입력했던 글자 하나하나를 비교하여 틀리면 바로 점프를 통해 넘어가는 코드 내용임을 알 수 있다. 따라서 코드에 나와있는 유니코드에 해당하는 글자 7개가 flag임을 알 수 있다. 그런데 flag에서 4번째와 6번째 문자는 char 형으로 저장되고, 나머지는 유니코드로 저장된다. 따라서 비교할 때도 그렇게 비교하게 되는데, 위에 코드에서 유니코드 부분과 char 부분을 구분할 필요가 있다. 따라서 유니코드를 char로 변환하면 flag가 최종적으로 "Ech3l0n" 임을 알 수 있다.


'WriteUp' 카테고리의 다른 글

Crackit2.exe Writeup  (0) 2016.01.15
Crackit2.exe Writeup  (0) 2016.01.14
[예시] Easy Keygen (100pt)  (0) 2016.01.11
Posted by 알 수 없는 사용자
2016. 1. 30. 21:27

TLS 콜백은 프로세스에서 스레드가 생성되기 전, 스레드가 종료된 후 자동으로 실행되는 함수 들이다 . 메인 함수가 실행되는 스레드도 예외가 아니기 때문에 메인함수 시작 전에도 TLS 콜백이 실행된다. 메인의 엔트리 포인트 이전에 실행되기 때문에 안티 디버깅을 위한 용도로 쓰이기도 한다.


TLS TLS 콜백을 등록하기 위해서는 아래와 같은 형태의 함수를 사용해야한다.이 형태는 DLL에서 쓰이는 것과 같다.


예제 코드


#pragma comment(linker, "/INCLUDE:__tls_used")

#pragma data_seg(".CRT$XLX")

PIMAGE_TLS_CALLBACK TLS_CALLBACk[] = { tlsCallback, 0 };

#pragma data_seg()


위의 코드가 TLS를 사용하기 위해 필요하다. .CRT$XLX 영역에 PIMAGE_TLS_CALLBACK 변수 또는 배열을 이용하여 TLS 콜백 함수들을 등록한다.

위의 코드를 실행하면 아래와 같은 결과를 볼 수 있다.

메인 함수가 실행되기 전 TLS 콜백이 실행되어 문자열 TLS가 출력된다.

스레드 실행 전 후로 TLS 콜백이 실행되는 것을 확인할 수 있다.

디버깅을 해보면 메인 함수 종료 후에도 TLS 콜백이 실행되나 printf 함수가 제대로 동작하지 않아 실제로 출력은 되지 않는다.


PE 내부 TLS의 위치와 구조

TLS를 사용하면 IMAGE_NT_HEADER.IMAGE_OPTIONAL_HEADER.IMAGE_DATA_DIRECTORY[9]에 TLS 테이블의 크기와 RVA가 기록된다.


PEview로 확인하면 TLS table에 대한 정보가 있는 것을 확인할 수 있다.

RVA 0x176EC에 해당하는 RAW인 0x68EC에는 IMAGE_TLS_DIRECTORY가 있다.


IMAGE_TLS_DIRECTORY 구조체 중 Address of Callbacks에 TLS 콜백 함수들의 주소(VA)가 저장되어있다.

00416720에 해당하는 곳은 아래 그림에서 볼 수 있다.


Address of Callbacks에 해당하는 곳인 0x00416720의 모습이다. 콜백 함수들의 주소가 저장되고 마지막은 NULL로 끝난다. 우리가 정의한 함수의 주소인 0x004110EB는 아래의 그림에 있다.


0x004110EB의 값을 보면 E9로 시작한다. E9 XXXXXXXX는 점프문에 해당하기 때문에 점프 주소를 쉽게 확인하기 위해 올리 디버거로 확인해보았다.


올리 디버거로 확인해보면 VA 0x004110EB에는 JMP 007316E0 명령어가 있고, 이 점프문을 따라가면 우리가 정의했던 TLS 콜백 함수가 나타난다.


문자열 TLS를 스택에 넣고 출력하는 것으로 보아 우리가 정의했던 TLS 콜백 함수임을 알 수 있다.

'리버싱핵심원리' 카테고리의 다른 글

Reverse Engineering Chap 50-51  (0) 2016.02.03
Reverse Engineering Chap 21-22  (0) 2016.02.03
Reverse Engineering Chap 34  (0) 2016.01.27
Reverse Engineering Chap 3-6  (0) 2016.01.27
Reverse Engineering Chap 33  (0) 2016.01.27
Posted by 지환태
2016. 1. 27. 23:54

Chap 34. 고급 글로벌 API 후킹 - IE 접속 제어


이번 장의 실습 목표는 IE 프로세스의 API를 후킹하여 특정 사이트로 향하는 접속을 다른 사이트로 우회시키는 것이다.


34.1. IE 프로세스 구조


- IE 7부터는 탭 개념을 도입하면서 프로세스 구조가 부모-자식 관계임


34.2. 글로벌 API 후킹 개념 정리


- 일반적인 API 후킹은 Test.exe 프로세스에 인젝션하여 후킹하는 방법 --> 후킹 대상 프로세스가 새로 생성될 때마다 수동으로 API 후킹을 해야 함

- 글로벌 API 후킹은 Windows OS의 기본 Shell인 Explorer.exe 프로세스에 인젝션하여 자식 프로세스 생성에 관련된 API를 후킹하여 자식 프로세스를 생성할 때마다 인젝션 하도록 하는 것임


34.3. ntdll!ZwResumeThread() API

- 글로벌 API 후킹을 하기 위해서는 자식 프로세스를 생성하는 API에 대해 알아야 함

- 프로세스를 생성하는 대표적인 API는 Kernel32!CreateProcess() 임

- CreateProcessW() API의 호출 흐름은 다음과 같음

- 위의 4개의 API 중 어떤 것을 후킹해도 글로벌 API 후킹이 가능하지만 이번 실습에서는 ntdll!ZwResumeThread() API 를 후킹함


34.4. redirect.cpp

- DllMain() 함수에서는 ntdll!ZwResumeThread() 와 wininet!InternetConnectW() API 를 훅/언훅 하는 기능을 함

- NewInternetConnectW() 함수에서는 IE 의 접속 주소를 모니터링 하면서 특정 사이트에 접속할 때 원하는 사이트로 접속을 돌리는 역할을 함

- NewZwResumeThread() 함수에서는 자식 프로세스에 redirect.dll을 인젝션해주는 역할을 함

redirect.cpp


34.5. 실습 예제 - IE 접속 제어


InjDll32.exe

InjDll64.exe

redirect.dll

- InjDll.exe 프로그램은 책 저자가 만든 프로그램(target 프로세스가 32bit인지 64bit인지에 따라 선택해서 사용하면 됨) --> 타깃 프로세스에 원하는 DLL을 인젝션/이젝션하는 기능을 함









'리버싱핵심원리' 카테고리의 다른 글

Reverse Engineering Chap 21-22  (0) 2016.02.03
Reverse Engineering Chap 45  (0) 2016.01.30
Reverse Engineering Chap 3-6  (0) 2016.01.27
Reverse Engineering Chap 33  (0) 2016.01.27
Reverse Engineering Chap 32  (0) 2016.01.24
Posted by 알 수 없는 사용자