본문 바로가기

Reversing/CodeEngn

[CodeEngn] Basic RCE L20풀이

https://ch.codeengn.com/

 

CodeEngn.com [코드엔진]

코드엔진은 국내 리버스엔지니어링 정보공유를 위해 2007년 부터 리버스엔지니어링 컨퍼런스 및 세미나, 워크숍을 현업 실무자들과 함께 운영하고 있는 비영리 커뮤니티입니다.

ch.codeengn.com


그림 1

 

그림 2

문제를 보면 ‘Cracked by: CodeEngn!’ 문구가 출력되도록 하는 crackme3.key 파일 안의 데이터를 구하라고 한다.

실행시켜보면 아무런 화면도 출력되지 않고, exeinfo로 확인해보아도 별 다른 점이 보이지 않는다.

 

X32 디버거로 열어주었다.

 

파일을 열어주면 문자열 찾기를 할 것도 없이 분석해야 할 부분들이 쭉 나와있고,

조금 더 내려보면 문제에서 찾으라고 했던 부분을 볼 수 있다.

 

그림 3
그림 4

위의 그림을 보다 보니 createfileA와 READFILE이라는 함수가 있길래 찾아보았다.

 

ReadFile 함수는 파일 데이터를 읽는 함수로, 이 함수를 쓰기 전에 먼저 CreateFile 함수를 사용해서 파일의 핸들을 받아와야 한다고 한다.

 

두 함수가 세트인가보다. 파일을 열어서 파일 데이터를 읽는 함수 세트라고 한다.

 

확인해보니 CRACKME3.KEY 파일을 열고 있는데 문제에서 다운로드할 때 KEY 파일은 함께 다운이 되지 않았다.

그렇기 때문에 파일을 실행했을 때 아무 화면도 뜨지 않았나 보다.

 

임의로 123456789012345678 이라는 값을 넣어 CRACKME3.KEY 파일을 생성해주었다.

(처음에는 이렇게 넣지 않았지만 분석 중에 KEY 파일에 18글자가 있어야 한다는 것을 알고 바꾸어 주었다!)

 

그림 5
그림 6

즉, CRACKEME3.KEY 파일이 있으면 이 파일 데이터를 읽어오는데, 읽어온 파일을 0X12(18)이랑 비교한다. 다시 말해서 KEY 파일에 18바이트가 들어있어야 한다는 뜻이다.

그래서 위에서 KEY 파일을 18글자로 미리 만들어주었다.

 

그리고 READFILE 함수를 지나면 EBX와 402008에 KEY 파일의 값들이 담기게 된다. 

 

그림 7

이어서 한 줄씩 실행하다 보니 401311 함수를 호출하는 부분을 지나자 402008에 담긴 값들이 이상한 글자로 바뀌는 것을 볼 수 있었다.

 

그림 8

해당 함수 내부로 들어가 보았다.

반복문이 있는 것 같아서 그래프 모드로 확인해보았다.

 

그림 9

 

하나씩 확인해보겠다.

1.    xor ecx, ecx                      | ecx = 0

2.    xor eax, eax                      | eax = 0

3.    mov esi, dword ptr ss:[esp+4]     | esi에 key 파일 값 담기

4.    mov bl, 41                          | bl에 0x41(A) 담기

 

------------------------------ 여기부터 반복문 ------------------------------

<40131B>

5.    mov al, byte ptr ds:[esi]           | al = [esi] = key 파일 값 한 글자

6.    xor al, bl                         | al = al ^ bl = [esi] ^ 41

7.    mov byte ptr ds:[esi], al           | [esi] = al = al ^ bl

8.    inc esi                            | esi = esi +1

9.    inc bl                             | bl = bl + 1 = 42

10. add dword ptr ds:[4020F9], eax   | [4020F9] = [4020F9] + eax

                                                     ([4020f9]뒤에 덧붙임 / eax = al ^ bl)

11. cmp al,0                          | al이 0이면 함수 끝 (파일이 끝나면)

12. je 20. 401335

 

<40132E>

13. inc cl                             | cl = cl + 1

14. cmp bl, 4F                        | bl = 0x4F이면 401335로 go!

15. jne 20. 40131B

 

<401335>

16. mov dword ptr ds:[402149], eax

17. ret

 

즉, 정리하면 [4020F9]에 [ CRACKEME3.KEY ^ (41부터 4F까지) ]가 들어간다.

이제 다시 흐름을 타고 메인 함수로 나가보겠다.

 

그림 10

401311에서 결정된 [4020F9]와 12345678을 XOR하여 다시 [4020F9]에 담고 있다.

 

이제 조금 더 내려가서 다시 KEY 파일을 인자로 삼고 있는 함수를 찾아보니 40133C 함수가 있어서 해당 부분을 이동해주었다.

 

그림 11

4줄짜리 함수였다!

 

한 줄씩 실행해보니 [esp+4]에 key로 만들어진 값이 들어가고, 결과적으로 esi에 마지막 4글자인 5678이 들어가고 있다.

그리고 해당 함수를 빠져나온 후, 마지막 4글자와 [4020F9]의 값을 비교하고 있다.

현자 [4020F9]에 있는 값은 {KEY ^ (41~4F)} ^ 0X12345678이다.

 

일단 다시 메인 함수로 돌아와서 우리가 봐야 할 아래 부분까지 쭉 실행하다 보면 중간에 점프 문을 종종 바꿔주어야 한다.

 

그림 12

아래의 “cracked by:” 로 가기 위해서 위의 그림의 점프문을 je로 수정해주었다.

그리고 한 줄씩 실행하다 보니 아래의 그림과 같이 창이 뜨는 것을 확인할 수 있다.

 

그림 13

결론적으로 우리가 아까 본 이상한 문자들이 cracked by : 뒤에 들어가고, 느낌표는 자동으로 붙는 것 같으니, 우리는 401311의 결과로 나온 값이 CodeEngn이면 문제를 해결할 수 있을 것 같다.

 

일단 CodeEngn의 Hex 값을 확인해본 결과

0x43  0x6F  0x64  0X65  0X45  0X6E  0X67  0X6E 가 되었다.

 

코드를 작성할 수도 있지만 코딩은 싫기 때문에 41부터 직접 XOR 해주었다.

결과는 아래와 같이 나온다.

0X02  0X2D  0X27  0X21  0X00  0X28  0X20  0X26  0X49

(마지막 문자가 0이어야 반복문이 끝나니까 0X00 ^ 0X49 = 0X49)

 

KEY 파일을 HxD로 열어서 수정을 해보자!

 

그림 14

그림 14와 같이 앞부분을 수정해주고, 이제 eax와 [4020F9]를 비교할 때

{KEY^(41~4F)} ^ 0X12345678의 결과가 [4020F9]에 들어간다.

디버거로 덤프해서 따라가 보니

7B  55  34  12

가 들어있고, 해당 부분은 마지막 4글자에 해당하므로 HxD에서 뒤의 글자들도 수정을 해주었다.

 

그림 15
그림 16

수정을 해서 저장을 한 후 파일을 실행시키면 아래와 같이 창이 뜨면서 문제가 해결되었음을 알 수 있다.

 

그림 17

문제에서 CRACKME3.KEY 파일 안의 데이터는 무엇이 되어야 하냐고 했으므로,

16진수를 다 모으면 아래와 같이 답이 나오는 것을 알 수 있다.

 

(답 인증이 안되길래 찾아보니, 중간의 0X30~0X34 까지를 0으로 채워주어야 한다고 한다. 문제에서 CONTACT로 연락 하면 확인해주겠다고 했지만, 귀찮으니 0으로 바꾸어서 다시 인증을 해보면 문제가 해결되는 것을 알 수 있다.)

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

[CodeEngn] Advance RCE L02풀이  (0) 2021.10.05
[CodeEngn] Advance RCE L01풀이  (0) 2021.10.05
[CodeEngn] Basic RCE L19풀이  (0) 2021.09.13
[CodeEngn] Basic RCE L18풀이  (0) 2021.09.13
[CodeEngn] Basic RCE L17풀이  (0) 2021.09.13