#About


Author : Raz0r


Korean :

Unpack을 한 후 Serial을 찾으시오. 정답인증은 OEP + Serial

Ex) 00400000PASSWORD


English :

Unpack, and find the serial. The solution should be in this format : OEP + Serial

Ex) 00400000PASSWORD 




#Contents





#Solution


[그림 1] - 실행 화면



[그림 2] - 에러 메시지 출력


임의의 값을 준 뒤 Check Serial 버튼을 눌렀을 때, 에러 메시지가 출력 됨을 확인가능하며 값을 입력하지 않아도 같은 메시지가 출력 되었다


[그림 3] - UPX


디버거로 열기 전, 주어진 지문에서 패킹이 되어있음을 알 수 있었기 때문에 어떤 패커로 패킹되었는지 확인결과 UPX로 패킹되어 있었다


[그림 4] - 언패킹


언패킹과 원본파일의 유지를 위해 d와 k옵션을 사용하여 언패킹을 진행후 아래와 같이 디버거로 열었다


[그림 5] - Original Entry Point (OEP)


프로그램의 실제 시작 주소를 의미하는 OEP가 00401360임을 확인 후, 시리얼 키는

Static으로 저장되어 있을거라 생각 후 아스키 값만 뽑아주었더니 아래와 같이 시리얼로 추측되는 값을 확인할 수 있었다


[그림 6]


아스키 값을 확인하고 해당 값을 지니고 있는 주소로 이동해 보았다


[그림 7]


시리얼 값으로 추정되는 AD46DFS547이라는 값을 가지는 주소 주변에 가보았더니

분기문(JNZ)을 통해서 서로 다른 메시지를 출력하는 어셈블리코드를 확인할 수 있었다


JNZ SHORT 06.004010A3은 TEST EAX, EAX의 결과 값으로 0이 나오지 않았을때 004010A3으로 이동후

"Wrong serial!!!" 메시지를 출력시키는 MessageBoxA함수를 호출 했으며 해당 문제는 시리얼키를 얻어  "You got it ;)" 이라는

문구를 확인하는 것이 목적이므로 메시지 박스를 출력하기 전 분기문에 브레이크포인트를 걸고 실행해보았다


[그림 8]


실행 도중 시리얼키 입력창에 임의의 값을 넣어주었고 아래와 같이 00401069 부분에 값이 들어가 있음을 확인했다


[그림 9]


PUSH된 값은, 사용자 입력 값이며 다른 하나의 값은 AD46DFS547이며 JNZ구문에서 사용자 입력값과 AD46DFS547을 비교하여 분기함을 예상할 수 있다


[그림 10]


브레이크포인트에서 F8을 통해 다음 코드로 넘어가자 TEST 명령의 결과 값이 0이 아님을 뜻하는 JNZ가 실행되어

004010A3으로 분기했고, 다음 코드로는 Wrong serial!!!이라는 메시지박스를 출력함을 알 수 있었다


이는 입력 값과 시리얼이 틀림을 알 수 있기에 시리얼 값으로 예측되는 AD46DFS547을 넣어주면 You got it ;)이라는 메시지 가 출력될 것 같다


[그림 11]


입력 값에 AD46DFS547을 넣어주었고, 예상대로 JNZ에서 분기하지 않고 바로 다음 코드로 넘어간 뒤

00401094까지 내려가고 MessageBoxA 함수가 실행되고 You got it ;) 이라는 메시지 박스를 확인할 수 있었다

'Wargame' 카테고리의 다른 글

CodeEngn Basic 8  (0) 2017.09.25
CodeEngn Basic 7  (0) 2017.09.24
CodeEngn Basic 5  (0) 2017.09.08
CodeEngn Basic 4  (0) 2017.09.05
CodeEngn Basic 3  (0) 2017.09.05

#About


Author : Acid Bytes [CFF]


Korean :

이 프로그램의 등록키는 무엇인가


English :

The registration key of this program is?




#Contents


프로그램에 등록된 시리얼키를 찾는 것이 문제이며, 패킹의 개념을 이해하는 것을 목적으로 한다




#Solution


[그림 1] - 실행


[그림 2] - 에러


프로그램 실행시 나와있던 키 값으로 등록을 진행해보았지만 시리얼 값이 올바르지 않다는 문구를 볼 수 있음


[그림 3]


디버거로 해당 프로그램을 열었을 때, 코드 섹션의 압축과 암호화 또는 많은 양의 데이터가 끼워져 포함되어 있다는 문구를 확인할 수 있음


[그림 4]


처음보는 메시지였기에 잠깐 보류해두고 디버거로 해당 프로그램에 사용된 API를 확인해보기 위해 "Search for > All intermodular calls"

옵션을 사용했을 때 무언가 이상함을 느낄 수 있었고 에러메시지를 기반으로 검색해보았더니, 패킹이 되어 있음을 알 수 있었다


킹이란 실행압축이라는 의미를 가지며 그 의미인 즉슨 파일 내부에 압축해제코드를 포함하고 있어서

실행될 때 메모리단에서 압축해제 후 실행시키는 기술을 의미한다


 패킹을 진행하는 이유는 코드 분석을 통한 프로그램의 악용을 막는 용도로 많이 활용되며 구체적 설명으로는

정상적으로 프로그램이 실행되었을 때 자동으로 언패킹이 진행되며 원본코드가 동작하도록 하지만

코드 분석을 위해 접근했을 경우 패킹이 되어있기 때문에 원본코드의 분석의 어려움을 겪거나

원본코드의 OEP(Original Entry Point) 또는 디버깅에 필요한 정확한 위치를 찾지 못하게 하는 것에 초점이 맞춰져 있음


[그림 5] - 패킹 여부 확인


UPX(Ultimate Packer for eXecuteables)라는 방식으로 패킹되어 있었고 언패킹을 아래와 같이 진행했다


[그림 6] - 언패킹


언패킹을 위한 옵션 d와 원본 실행파일의 보존을 위해 k옵션을 주고 언패킹을 진행했고, 실행파일의 사이즈가 증가함을 확인할 수 있다


[그림 7] - API 목록


언패킹을 진행 후에는 [그림 4]와 달리 실행파일에 사용된 API 목록들을 확인할 수 있었으며 아래와 같이 아스키 텍스트도 확인할 수 있었다


[그림 8] - 아스키 텍스트 값 확인


[그림 9]


[그림 8]의 아스키 값과 [그림 9]의 어셈블리코드를 확인결과 인증로직이 있음을 알 수 있었고 로직은 다음과 같다


if ( name == empty ){

printf("Enter a Name!");


elif ( serial == empty ){

printf("Enter a Seiral!");


elif ( name == Registered User && serial == GFX-754-IER-954 ){

printf("Congrats! You cracked this CrackMe!");}}}



if ( name == FALSE ){

printf("Wrong Serial, try again!");


elif ( serial == FALSE ){

printf("Wrong Serial, try again!");}}


[코드 1] - 코알못 이해좀 (+어셈)


[그림 10] - 인증

'Wargame' 카테고리의 다른 글

CodeEngn Basic 7  (0) 2017.09.24
CodeEngn Basic 6  (0) 2017.09.13
CodeEngn Basic 4  (0) 2017.09.05
CodeEngn Basic 3  (0) 2017.09.05
CodeEngn Basic 2  (0) 2017.09.04

#About


Author : CodeEngn


Korean :

이 프로그램은 디버거 프로그램을 탐지하는 기능을 갖고 있다. 디버거를 탐지하는 함수의 이름은 무엇인가


English :

This program can detect debuggers. Find out the name of the debugger detecting function the program uses.




#Contents

해당 문제는 디버거를 탐지하는 함수명을 찾을 수 있는가에 대한 물음이지만 

더불어 디버거로 프로그램을 열더라도 정상이라는 문구를 출력시키는것을 목표로함




#Solution


[그림 1] - 파일을 실행했을 때 정상이라는 문구 출력


[그림 2] - 디버거로 열고 실행했을 때 디버깅 당함이라는 문구 출력


[그림 3] - All intermodular calls 옵션 사용


디버거를 탐지하는 기능을 구현한 함수를 찾기위해 Search for > All intermodular calls 옵션을 사용

[그림 4] - IsDebuggerPresent 함수 확인



검색 결과 IsDebuggerPresent() 함수는 kernel32.dll에 export되는 함수이며 디버깅을 체크하는 MS에서 공식적으로 지원하는 안티리버싱 API이다.

해당 프로세스가 디버깅을 당하고 있는지에 대한 여부를 PEB구조체의 디버깅 상태값을 확인하며 디버깅을 당하고 있다면 1을 아닐 경우 0을 리턴함 


또한 IsDebuggerPresent() 함수는 내부적으로 TEB(Thread Environment Block)와 PEB(Process Environment Block)을 이용하며

PEB내의 Begin Debugger라는 멤버의 값을 기준으로 유저모드 디버거에 의해 디버깅을 판단한다


# TEB(Thread Environment Block)

- 프로세스에서 실행되는 스레드에 대한 정보를 담고 있는 구조체

- TIB(Thread Information Block)라고도 한다

- TEB 구조체는 OS마다 달라진다 (Windows7의 경우 Windows XP SP3 보다 확장)

- 시작 주소 : FS:[0x00], FS:[0x18](유저모드)


# PEB(Process Environment Block)

- 프로세스의 정보를 저장하는 구조체

- PEB 구조체는 OS마다 달라진다 (Windows7의 경우 Windows XP SP3 보다 확장)

- 시작주소는 OS마다 다르다 (SP2미만 = 0x7FFDF000, SP2이상 = fs:[0x30], Windows7 유저모드 = fs:[0x30], fs:[0x18])


PEB와 TEB모두 커널모드에서는 존재하지 않고 모두 유저모드 프로세스 하나당, 유저모드 스레드 하나당 존재하게 됨


typedef struct _PEB {

BYTE                            Reserved1[2];

BYTE                            BeingDebugged;

BYTE                            Reserved2[1];

BYTE                            Reserved3[2];

PREB_LDR_DATA                   Ldr;

PRTL_USER_PROCESS_PARAMETERS    ProcessParameters;

BYTE                            Reserved4[104];

PVOID                           Reserved5[52];

PPS_POST_PROCESS_INIT_ROUTINE   PostProcessInitRoutine;

BYTE                            Reserved6[128];

PVOID                           Reserved7[1];

ULONG                           SessionId;

}   PEB, *PPEB;

PEB 구조체


[그림 5] - IsDebuggerPresent() 함수


[그림 6] - IsDebuggerPresent() 함수 내부 진입


해당 함수 내부로 진입하게 되면 4줄의 코드로 간단하게 구성되어 있다. TEB영역의 0x18번지를 EAX에 담고

다시 EAX기준으로 오프셋 0x30의 번지를 가져오며, 이렇게 두 줄을 실행하게 되면 PEB구조체의 처음을 가르키게 된다

다음으로 EAX+2는 PEB구조체의 오프셋 0x02에 위치하는 멤버 변수인 BeingDebugged의 값을 EAX에 담고 함수를 종료함


(출처 : c0mb.tistory.com/71)


해당 문제에서 요구하는 것은 디버거를 탐지하는 함수의 이름이지만 더 나아가 해당 함수를 우회하는

즉, 안티디버깅 우회를 해봄으로써 이해의 척도를 높여보려고 한다


[그림 7]


IsDebuggerPresent() 함수 호출 뒤에 브레이크포인트를 걸어줌으로써 함수 호출까지는 진행하며 EAX 값을 보고

 BeingDebugged에 담긴 값이 1임을 알 수 있었고 해당 값으로 인해 디버깅 당함이라는 문구가 출력됨을 확인할 수 있었다

따라서 반환 값을 1이아닌 0으로 바꿔준다면 디버깅 상태라도 정상이라는 문구가 출력됨을 생각해볼 수 있다


[그림 8] - 1 > 0으로 값 변경


[그림 9] - 안티리버싱 우회


ㅋㅋㅋ... 다시 써야할듯;

'Wargame' 카테고리의 다른 글

CodeEngn Basic 6  (0) 2017.09.13
CodeEngn Basic 5  (0) 2017.09.08
CodeEngn Basic 3  (0) 2017.09.05
CodeEngn Basic 2  (0) 2017.09.04
CodeEngn Basic 1  (0) 2017.09.04

+ Recent posts