Wargame.kr 포스트는 이해한 내용과 복습을 위한 목적으로 작성되었습니다.

이번 포스트에서는 keypad_crackme 문제에 대한 이해와 풀이를 진행해보도록 하겠습니다.


이번에는 이 문제는 exe 파일 하나를 제공하며, 리버싱을 통해 어떤 값이 AUTH 값인지 알아내는 문제입니다.

X64DBG와 IDA를 이용하여 문제를 풀었는데, 확실히 IDA가 훨~~~씬 좋은 것 같습니다.(푸는 속도 면에서)


이번에도 Reversing 문제를 IDA를 이용하여 풀이를 진행하도록 하겠습니다.




 

 문제 이해


문제는 다음과 같습니다.


간단한 리버싱 문제라고 합니다. 문제로 들어가면 exe 파일을 다운로드 받을 수 있는데 바로 문제풀이로 들어가보도록 하겠습니다.



 

 문제 풀이


문제를 풀기 위해서는 IDA 32bit를 이용하였습니다.



 

 IDA 32Bit로 문제 오픈


문제를 오픈하고, 바로 [Shift + F12]를 눌러 스트링 값을 검색하였습니다.


프로그램을 열어 아무 값이나 입력 후 AUTH를 누르게 되면 wrong password 라는 값을 뱉어냅니다.

문자열이 난독화되어 있지 않다면, 나오겠지요.



이제 aWrongPassword 값을 클릭하여 [x - Jump to xref] 버튼을 눌러 역참조로 들어갑니다.


그렇게 되면 다음과 같은 IDA View를 볼 수 있습니다.

여기서 분기문으로 나뉘게 되는데, 그림에서 보이는 세 가지 블록 중 아무 곳이나 클릭하여 [F5 - Pseudocode View]로 들어가줍니다.

(if 조건문으로 나뉘었을 뿐 Pseudocode 를 누르게 되면 동일한 코드 영역임을 볼 수 있음)



아래와 같은 코드가 나오게 될 것입니다.

이때 if 문 안에 있는 값은 INT 값으로 나오게 되지만, 임의로 HEX 값으로 바꿔서 캡처하였습니다.


아마 X64DBG나 Ollydbg와 같은 툴을 이용하여 쭉 읽다보면, 마지막에 cmp 부분에 0xBADBABE와 비교하는 곳을 발견하실 수 있을 것입니다.

그 위의 부분은 계산하는 부분이구요.


아래의 코드에서 변수 설명을 먼저 하도록 하겠습니다.

v6 = 프로그램을 실행한 localhost의 month 값(struct tm에서 tm.mon 은 0 ~ 11이기 대문에 값에 +1을 해준 것입니다.)

v5 = 사용자 입력값(v3에서 +116이 있는데, 헷갈리지 마세용 값의 변화를 주는 거 아닙니당)



고정된 값 0xFFFCECC9 * 몇 월인지 + 사용자 입력 값이 0xBADBABE이면 문제가 풀리는 것 같습니다.


문제 풀이를 직관적으로 보고자, 간단하게 코드를 작성하고 풀이를 진행해보았습니다.

import datetime

current_time = datetime.datetime.now()
current_mon  = current_time.month

compare_hex  = 0xFFFCECC9
result_hex   = 0xBADBABE

INT          = (compare_hex * current_mon)
HEX          = hex((compare_hex * current_mon))
HEX_8        = HEX[len(HEX)-8:]

diff_INT     = 0x100000000 - int(HEX_8, 16)
diff_HEX     = hex(diff_INT)

print('=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-')
print('[0xFFFCECC9 * current_month]')
print('=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-')
print('INT          : ', INT)
print('HEX          : ', HEX)
print('HEX_8        : ', HEX_8)
print('=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-')
print('[0x100000000 - HEX_8]')
print('=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-')
print('diff_INT     : ', diff_INT)
print('diff_HEX     : ', diff_HEX)
print('=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-')
print('INT+diff_INT : ', INT+diff_INT)
print('HEX+diff_HEX : ', hex(INT+diff_INT))
print('=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-')
print('[(0xFFFCECC9 * current_month) + \n(0x100000000 - int(HEX_8,16)) + \n0x0BADBABE]')
print('=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-')
print('result_INT   : ', ((INT + diff_INT) + result_hex))
print('result_HEX   : ', hex(((INT + diff_INT) + result_hex)))
print('=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-')
print('[+] Key      : ', diff_INT + result_hex)


위의 코드를 실행시키면 다음과 같이 나옵니다.


6월 달에 풀이한 값은 197144072입니다.

이걸 그대로 입력해보면 다음과 같이 결과가 나오게 됩니다.


끝!!


+ Recent posts