[Reversing.kr] Twist1

semon·2022년 11월 15일
0

Reversing

목록 보기
10/10

Reversing.kr의 Twist1 문제입니다.

다음과 같이 packing은 되어있지않고 32비트의 c/c++로 작성되었습니다.

그리고 문제와 같이 있던 readme.txt에는 Twist1.exe는 x86 windows 환경에서 실행된다고 되어있습니다.

Windbg를 사용하여 디버깅을 해보았습니다.


entry point

코드를 한줄씩 실행하다보니 다음과 같이 ecx에 0x407000이라는 주소를 옮기고 해당 주소의 값을 xor 연산을 통해 바꾸는 것을 확인할 수 있었습니다. 이 부분을 통해 정적분석으로는 알 수 없는 새로운 코드가 나타났습니다.

해당 코드를 분석해보니 fs 영역의 offset이 0x30인 위치의 값을 가져오는 것을 알 수 있습니다. fs 영역의 0x30에 위치한 것은 PEB라는 구조체로 아래와 같습니다.

PEB, TEB
각각 유저 레벨에서 프로세스에 대한 정보를 저장하고 있는 구조체(커널은 각각 EPROCESS, ETHREAD)

TEB 주소 = fs:[0x0]

PEB 주소 = TEB:[0x30] = fs:[0x30]

fs:[0x30] + 0x28^0x30
= fs:[0x30] + 0x18
= process heap의 위치

Process Heap
PEB 구조체를 이용한 안티 디버깅 기법 중 하나로 Heap을 가리키는 PEB.processHeap 포인터를 이용한다. 
디버깅 중에는 특정 값으로 설정되는 Flags(+0xc)멤버와 ForceFlags(+0x10)을 사용한다.
Flags는 정상 실행 중에는 0x02의 값을 갖고 ForceFlags는 0x00의 값을 가진다.(xp환경)

Dword ptr [edx] = PEB.ProcessHeap
ecx = PEB.ProcessHeap + 0xc
= Flags 멤버 => 0x2

다음 내용으로 안티 디버깅을 우회해주면 됩니다.


cl의 값이 ZF가 1이되어야하므로

a4인 cl을

00으로 바꾸어 주어 우회합니다.

다음으로 PEBLdr이라는 값을 ebx에 옮기고 +0x10에 위치한 값을 비교하는 부분을 확인할 수 있습니다.

PEB.Ldr
Ldr 구조체는 디버깅을 표시하기 위헤 heap영역에 사용하지 않는 부분을 0xFEEEFEEE 또는 0xABABABAB로 채운다.
Ldr + 0xC부터 heap의 영역으로 자주 쓰이는 부분인 0x10부분 부터 검사를 통해 디버깅 중인지 확인

0x1F4 크기만큼 비교를 해주므로


메모리 영역을 확인하여 0x1F4에 해당하는 영역에 존재하는 0xEEFEEEFE와 0xABABABAB를 0x00000000로 바꾸어주어 2번째 안티디버깅도 우회했습니다.


이후 rol과 ror을 통해 메모리를 복구하는 코드를 확인할 수 있었습니다.


복구된 내용을 가지고 문자열을 검색하여 해결하려 하였으나

다음과 같이 앞에서 나온 ReadMe.txt의 내용처럼 64비트 운영체제를 확인하는 부분이 있었습니다.

그래서 이후는 vmware에 32비트 윈도우 7 환경에서 진행하였습니다.

앞에서의 안티디버깅을 전부 우회하니 아래와 같은 부분이 나왔습니다.


Correct라는 문자열을 찾아 한줄씩 디버깅을 하면 문제를 해결 할 수 있을것 같습니다.

하지만 안티디버깅이 아직 남아있었습니다. 위에 보이는 ZwQueryInformationProcess가 바로 그 부분입니다.

ZwQueryInformationProcess를 활용한 안티 디버깅
1번째 인자(ProcessHandle) : 프로세스의 핸들
2번째 인자(ProcessInformaionClass) : 0x7(ProcessDebugPort)
3번째 인자(ProcessInformation) : Debugger 연결중이면 -1 아니면 0반환

==> 이 문제에서는 return 값을 다양하게 줌

총 3가지의 비교문을 우회하면 해결 할 수 있습니다.


안티 디버깅을 전부 우회하고 나면 다음과 같은 루틴이 나오고


해당 루틴을 모두 우회하면 답을 얻을 수 있습니다.

profile
보안을 공부합니다

0개의 댓글