-榮-

[CodeEngn] Basic RCE L05 (+α UPX 패킹 상태에서 OEP 찾는 법) 본문

CodeEngn/Basic

[CodeEngn] Basic RCE L05 (+α UPX 패킹 상태에서 OEP 찾는 법)

xii.xxv 2021. 3. 21. 21:22

 

● CodeEngn Basic RCE L05 문제

 

CodeEngn Basic RCE L05

 

 

◎ 파일 실행 화면

 

[그림 1] 파일 실행 화면 및 Register now! 클릭 후

"Wrong Serial,try again!" 문자열을 찾고 분기점을 찾으면 될 것 같습니다. 분기를 판별하는 코드가 등록키와 입력된 키를 비교하는 것으로 추정됩니다.

 

◎ 패킹 및 난독화 여부 확인

 

[그림 2] PEiD - UPX 패킹 확인

 

※ PE Packer란 실행 파일 압축기입니다.

   정확한 명칭은 Run-Time 패커로, PE 파일 전문 압축기입니다. (출처:리버싱 핵심원리)

 

※ 사용 목적

  1. PE 파일의 크기를 줄이고자 하는 목적
  2. PE 파일의 내부 코드와 리소스를 감추기 위한 목적

 

● CodeEngn Basic RCE L05 분석 및 풀이

 

 

[그림 3] UPX Unpacked

※ -d : decompress / -k, --backup : keep backup files

 

언패킹을 한 뒤 디버거에 올리면 OEP(Original Entry Point)가 띄워지는 것을 확인할 수 있습니다.

 

[그림 4] UPX packed 파일 코드 / unpacked 파일 코드

 

[Search for > All referenced text strings]에서 문자열을 찾습니다.

 

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

실패 문자열 두 개와 성공 문자열 그리고 그 위에 User이름과 등록키로 추측되는 문자열을 확인할 수 있습니다.

 

해당 문자열 중 성공 위치를 확인합니다.

 

[그림 6] Success 문자열

 

[그림 6]을 보고 흐름을 예상해 봅시다.

  1. [EBP-4]에 위치한 입력받은 USER 문자열과 "Registered User"을 [CALL 00403B2C]에서 비교
  2. [CALL 420E20]에서 입력받은 등록키를 [EBP-4]에 적재
  3. [EBP-4]에 위치한 입력받은 등록키와 "GFX-754-IER-954"을 [CALL 00403B2C]에서 비교
  4. 성공 창 띄우기 [CALL 0043D068]

 


 

● CodeEngn Basic RCE L05 확인

 

예상한 대로 입력하여 확인해봅시다.

 

[그림 7] EAX : 입력받은 문자열 / EDX : [00441014]

 

[그림 8] EAX : 입력받은 문자열 / EDX : [0044102C]

 

[그림 9] Success

 

 


+α UPX 패킹 상태에서 OEP 찾는 법

 

UPX 패킹을 언패킹 하거나 트레이싱하는 방법 외에 빠르게 OEP를 찾는 2가지 방법

  1. POPAD 찾기
  2. Hardware BP

1. POPAD 찾기

 

UPX 패커는 PUSHAD 명령어와 POPAD명령어로 EP코드가 둘러싸여 있다는 특징을 가지고 있습니다. 그리고 OEP로 가는 JMP 명령어가 POPAD 명령어 바로 이후에 나타납니다.

 

[그림 10] POPAD 명령어 검색

 

PUSHAD 명령어 다음의 POPAD 명령어 위치에서 바로 다음에 나오는 JMP 명령어가 OEP 위치로 갈 수 있는 명령어입니다.

 

 

2. Hardware BP

 

이 방법도 PUSHAD 명령어와 POPAD명령어로 둘러싸여 있다는 특징을 이용한 방법입니다.

PUSHAD 명령어를 실행하면 스택에 레지스터 값들이 저장됩니다. 이때, dump 창에서 가장 최근에 저장된 스택 주소로 이동하여 Hardware BP를 겁니다.

 

[그림 11] Hardware BP

 

Hardware BP를 걸고 실행(F9)하면 POPAD가 호출되는 순간, Hardware BP를 설치한 지점이 access 되면서 멈춥니다.

바로 밑에 OEP로 가는 JMP 명령어가 있습니다.