-榮-

[CodeEngn] Basic RCE L16 본문

CodeEngn/Basic

[CodeEngn] Basic RCE L16

xii.xxv 2021. 3. 26. 17:14

 

● CodeEngn Basic RCE L16 문제

 

 

CodeEngn Basic RCE L16

 

 

◎ 파일 실행 화면

 

[그림 1] 파일 실행 화면 및 Wrong Password 화면

 

 

패킹 및 난독화 여부 확인

 

[그림 2] PEiD

 

 


 

● CodeEngn Basic RCE L16 분석 및 풀이

 

[그림 3] 디버거 - OllyDbg / 디버기 - 16.exe (Basic RCE L16 실행파일)

 

[Search for> All referenced text strings]에서 성공 문자열과 실패 문자열을 찾을 수 있습니다.

 

[그림 4] 성공 문자열과 실패 문자열 확인

 

성공 문자열 부분으로 이동하면, 분기 조건(0040159F)과 분기점(004015A2)으로 추정되는 부분을 볼 수 있습니다.

 

[그림5] 성공 문자열 부분

 

 

 

[그림 5]의 분기점에서 답을 찾았지만 프로그램을 분석해봅시다.

 

 

 

분기점으로 추정되는 곳에서 더 내려가면(주소 기준) Password를 받는 부분을 찾을 수 있습니다.

 

[그림 6] 문자열을 출력하고 Password 입력 받는 부분

 

 

Password를 입력 받는 부분보다 더 내려가면 Name을 입력받는 부분이 있습니다.

 

Name(CodeEngn)을 입력받고, "Enter your Password: " 문자열까지의 사이에 Serial을 만드는 코드가 존재합니다.

 

[그림 7] Create Serial

 

또한 분기 조건 위에 [0040158E ~ 0040159A] 코드로 Serial 값을 만드는 과정이 완료됩니다.

 

[그림 8] 분기 조건 전의 Serial 만드는 과정

 

# Create Serial 흐름

Create Serial 흐름
설명 및 예시

[0040153D ~ 0040155D]

1. eax = Name.length
2. edx = eax
3. eax = eax + eax
4. eax = eax + edx
5. shl eax, 2
6. [EBP-3C] = eax
7. eax = eax * [EBP-3C]
8. eax = eax * [EBP-3C]
9. eax = eax + 17
10. [EBP-3C] = eax

[0040158E ~ 0040159A]

11. eax = [EBP-3C]
12. edx = eax * 0ACE80h
13. eax = [EBP-3C]
14. eax = eax + edx

1. 입력받은 Name의 길이 (CodeEngn 길이 : 8h)

3.
eax : 8h + 8h : 10h

4. eax : 10h + 8h : 18h


5. eax를 2Bit Shift Left
    eax : 18h : 0001 1000b
    shl eax, 2 (eax : 0110 0000b : 60h)

7. eax : 60h * 60h : 2400h

8. eax : 60h * 2400h : D8000h

9. eax : D8000h + 17h : D8017h

12. edx : D8017h * ACE80h : E4B88D80h

14. eax : D8017h + E4B88D80h : E4C60D97h

 (13. LEA 명령어를 사용하여 eax에 [EBP-3C]의 주소값 입력)
 (14. [eax]와 edx를 더하여 [EBP-3C]에 더한 값이 저장)

 

분기 조건에서 각 비교 값들을 확인해 보면 [EBP-3C]에서 E4C60D97h를 확인할 수 있습니다.

 

[그림 9] 분기 조건 값 확인

 

 

이제 입력받은 Password의 암호화(?) 과정을 살펴봅시다.

 

 

[그림 8]을 보면 CALL 00428A40에서 Password를 입력 받은 뒤, Serial 생성의 마지막 과정을 거쳐 분기점으로 이어진 것을 확인 할 수 있습니다.

 

CALL 00428A40에서 입력받은 Password가 [그림 9]의 분기 조건에서 "4D2"로 변한 것으로 보면 CALL 00428A40에서 Password를 입력받고, 암호화(?)과정을 거쳐 반환 값으로 나온다는 것이 추측 가능합니다.

 

CALL 00428A40에서 Step Into[F7]을 하여 내부로 들어갑니다.

 

[그림 10] CALL 00428A40

 

CALL 00428A40에서 Step Over[F8]로 진행하다 보면 Password를 입력받는 함수를 만납니다.

그 함수를 지나 입력받은 Password를 암호화(?)하는 함수를 찾습니다.

 

[그림 11] CALL 00428A40 내부에서 입력된 Password를 가져오는 함수

 

00428B34의 입력받은 Password를 암호화(?)하는 함수가 CALL 00428A40에서 살펴봐야 되는 핵심입니다.

 

[그림 12] CALL 00428A40에서 입력된 Serial을 암호화(?)하는 함수

 

CALL EAX에서 Step Into[F7]로 들어가면 CALL 00415820에서 암호화(?)가 이루어진다는 것을 알 수 있습니다.

 

[그림 13] CALL EAX

 

CALL 00415820에서 Step Into[F7]을 하여 내부로 들어갑니다.

 

[그림 14] CALL 00415820

 

Step Over[F8]로 진행하다 보면 CALL EAX와 JMP 명령어를 만납니다. CALL EAX에서 31을 반환해주고, JMP로 이동한 곳을 보면 입력받은 값을 16진수로 변환하는 코드를 볼 수 있습니다.

 

[그림 15] CALL 명령어와 JMP 명령어

 

[00416034 ~ 00416037]

EDX에 입력받은 값을 한 Byte씩 읽어오고, 값을 EAX로 옮긴 뒤 EBX(A)를 곱하여 입력받은 10진수를 16진수로 변환합니다. 최종적으로 EAX에는 16진수로 변환된 입력받은 Serial(1234)이 존재합니다.

 

[그림 16] 입력 값을 16진수로 변환하는 코드

 


 

● CodeEngn Basic RCE L16 확인 및 답

 

[그림 16]에서 입력받은 Serial(1234)이 16진수로 "4D2"인 것을 확인합니다.

 

[그림 17] 1234의 16진수 4D2 확인

 

[그림 9]의 Name으로 만들어진 Serial(E4C60D97h)의 10진수가 CodeEngn의 Serial입니다.

 

[그림 18] CodeEngn의 Serial

 

[그림 19] Success

 

 

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

[CodeEngn] Basic RCE L18  (0) 2021.03.27
[CodeEngn] Basic RCE L17  (0) 2021.03.26
[CodeEngn] Basic RCE L15  (0) 2021.03.25
[CodeEngn] Basic RCE L14  (0) 2021.03.25
[CodeEngn] Basic RCE L13  (0) 2021.03.25