-榮-

[CodeEngn] Advance RCE L08 본문

CodeEngn/Advance

[CodeEngn] Advance RCE L08

xii.xxv 2021. 4. 5. 00:28

● CodeEngn Advance RCE L08 문제

 

CodeEngn Advance RCE L08

 

◎ 파일 실행 화면

 

[그림 1] 파일 실행 화면

 

[그림 2] 패치의 필요 확인 및 틀린 Key는 반응 없음

 

◎ 패킹 및 난독화 여부 확인

[그림 3] exeinfo PE

 


 

● CodeEngn Advance RCE L08 풀이

 

[그림 4] 디버거 - OllyDbg / 디버기 - 08.exe (Advance RCE L08 실행파일)

 

우선, [그림 2]에서 찾은 패치 해야 되는 부분으로 이동합니다. [Search for > All referenced text string]에서 해당 문자열을 찾습니다.

[그림 5] Search for > All referenced text string

 

0045BB29의 Please Enter More Chars... 문자열은 CMP EAX, 3의 결과로 출력됩니다. 이 부분을 패치하여 Name이 두 문자일 때, 해당 구문이 안나오도록 만듭니다.

[그림 6] 패치 부분

 

Name은 문제의 힌트에서 두 문자라 하였으니 3이 아닌 2와 비교하도록 패치하였습니다.

[그림 7] 패치

 

[※참고]

패치파일 만드는 법은 CodeEngn Basic RCE L01의 "+α 패치파일 만드는 법"

[그림 8] 디버거 - OllyDbg / 디버기 - 08_patched.exe

 

[Search for > All referenced text string]에서 성공 문자열을 찾아 주소로 이동합니다.

[그림 9] Search for > All referenced text string

 

성공 문자열의 주소로 이동하면 분기점이 보입니다. 분기 조건은 0045BBA4의 CALL 00404C3C로 보이며, 실패 시 이동한 0045BBC5에 Timeout(Sleep 함수 파라미터)이 있는 것으로 [그림 2]에서 실패 시 반응이 없었던 것이 생각납니다.

[그림 10] 분기점 및 성공 문자열

 

주소를 내리다 보면 CALL 0043A074가 반복되는 것을 볼 수 있습니다.

CALL 0043A074이후에 CMP가 있고, Please Enter More Chars... 와 Please Enter Not More Then 30 Chars... 문자열로 보아 CALL 0043A074는 입력된 문자열을 가져오는 함수이고, CALL 0043A0A4는 문자열을 출력하는 함수로 예상됩니다.

[그림 11] Name 및 Key 가져오는 함수

 

[그림 12] 코드에서 입력된 Name과 Key를 가져와서 길이를 검사한 뒤, 문자열을 가져오는 함수를 두 번 더 호출하는 것을 보면 Name과 Key를 다시 가져오는 것으로 추측됩니다.

Name과 Key를 가져온 뒤 CALL 0045B850에서 입력된 Name으로 Key를 생성하고, CALL 00404C3C에서 생성된 Key와 입력된 Key를 비교하는 것으로 생각됩니다.

[그림 12]에서 CALL 0045B850에서 Name으로 Key를 만든다는 것을 확인할 수 있습니다.

[그림 12] 입력 문자열 길이 검사 후 코드

 

[그림 13]에서 CALL 00404C3C의 파라미터를 보면 Name으로 만들어진 Key와 입력받은 Key를 확인할 수 있습니다.

[그림 13] CALL 00404C3C의 파라미터

 

입력받은 Name으로 Key를 생성하는 CALL 0045B850의 내부를 확인해 봅시다.

[그림 14] CALL 0045B850 내부

 

CALL 0045B850 내부에는 반복문이 크게 4개가 있습니다.

[그림 15] CALL 0045B850 내부의 반복문

위 반복문들의 결과는 표와 같습니다.

EDX : AAC1 6C20 EBP - 10 : 0597 A3EC
EDI : 7364 640A EBX : 2769 FC81

 

[그림 12]에서 Name(AB)으로 만들어진 Key("AAC1-597A-6F192DD3-7364-2769")을 봤을 때, 반복문들의 결과의 (0을 제외한) 4자리가 Key 앞과 뒤의 두 단락이 같다는 것을 알 수 있습니다.

CALL 0045B850 내부에서 두 번째 반복문 이후의 CALL 0045B54C에서 Key의 중간 문자열이 만들어지는 것을 추측할 수 있습니다.

[그림 16] 중간 Key 생성 함수 호출

 

Key가 "AAC1-597A-6F192DD3-7364-2769"인 Name을 찾기 위해

첫 번째 반복문을 분석하여 반복문의 결과 값이 "5D88"가 나오는 두 자리를 찾아봅시다.

 

[그림 17] 첫 번째 반복문

◎ 첫 번째 반복문 흐름

첫 번째 반복문 흐름
설명 및 예시

1. eax = Name.length
2. ecx = 1

2. [반복문]
   1) ebx = [EBP-4]
   2) esi = [ebx+ecx-1]
   3) esi = esi + edx
   4) esi = esi * 772h
   5) edx = esi
   6) edx = edx * esi
   7) esi = esi + edx
   8) esi = esi * 474h
   9) esi = esi + esi
   10) edx = esi

1. 입력받은 Name의 문자열을 가져오기 위한 ecx
   ex. Name : AB

1) 
[EBP-4] : 입력받은 Name의 주소
   ex. 첫 번째 반복 : 입력받은 A의 주소 값
    / 두 번째 반복 : 입력받은 B의 주소 값

2) esi : 입력받은 Name을 Byte 단위로 입력
   ex. ① esi : 0x41 ('A') / ② esi : 0x42 ('B')

3) 첫 번째 Name의 결과 값을 더해서 계산
   ex. ① esi : 41 ; edx : 0 / ② esi : 41 ; edx : FFE3 74F0

4) ex. ① esi : 41 * 772 : 1E3F2

6) 
ex. ① edx : 1E3F2 * 1E3F2 : 92DB 10C4

7) ex. ① esi : 1E3F2 + 92DB 10C4 : 92DC F4B6

8) ex. ① esi : 92DC F4B6 * 474 : FFF1 BA78

9) ex. ① esi : FFF1 BA78 + FFF1 BA78 : FFE3 74F0

 

반복문의 결과 값이 "5D88"이 나오는 두 자리를 찾는 코드

def First_Loop(name, edx): ## 첫 번째 반복문
    
    esi = name + edx
    esi = esi * 0x772
    edx = esi
    edx = edx * esi
    esi = esi + edx
    esi = esi * 0x474
    esi = esi + esi
    edx = esi

    return edx

if __name__ == '__main__':

    for name1 in range(0x30, 0x7A): ## 숫자 0 부터 z 까지
        First_edx = First_Loop(name1, 0)  
        for name2 in range(0x30, 0x7A):
            serial = First_Loop(name2, First_edx)

            lenght = len(hex(serial))

            if '5d88' == hex(serial)[lenght-8:lenght-4]: ## '5D88'와 일치하는 name 출력
                print(chr(name1) + chr(name2))
                break

 

 


 

● CodeEngn Advance RCE L08 확인

 

[그림 18] Python 코드 결과

 

[그림 19] Well done!

 

CodeEngn Advance RCE L08의 답(Name의 MD5) : 7E8B9F5CAB4A8FE24FAD9FE4B7452702입니다.

 


CodeEngn Advance RCE L08 파일의 코드는 CodeEngn Basic RCE L17 문제와 매우 흡사합니다. (Name의 문자 수 차이)

[※참고]

CodeEngn Basic RCE L017

 

 

'CodeEngn > Advance' 카테고리의 다른 글

[CodeEngn] Advance RCE L10  (0) 2021.04.07
[CodeEngn] Advance RCE L09  (0) 2021.04.05
[CodeEngn] Advance RCE L07  (0) 2021.04.04
[CodeEngn] Advance RCE L06  (0) 2021.04.02
[CodeEngn] Advance RCE L05  (0) 2021.04.02