물먹는산세베리아

패킹, UPX, notepad 언패킹 본문

Waregame & CTF/Reversing

패킹, UPX, notepad 언패킹

suntall 2021. 10. 6. 21:24

데이터 압축(Data Compression)


  • 비손실 압축 : 압축된 파일을 100% 원래대로 복원 가능

파일(데이터) 크기를 줄여서 보관, 이동에 용이

7-zip, 빵집과 같은 압축 프로그램이 이에 해당

알고리즘: Run-Length, Lempel-Ziv, Huffman 

 

  • 손실 압축 : 원래대로 복원할 수 없음

파일(데이터)에 의도적인 손상을 주어 댓가로 압축률을 높임

멀티미디어 파일(jpg, mp3, mp4)이 이에 해당

사람의 눈, 귀가 거의 알아차리지 못하는 수준에서 데이터에 손상을 입힘

 

  • 실행 압축

실행(PE)파일을 대상으로 파일 내부에 압축해제 코드 포함, 실행되는 순간에 메모리에서 압축을 해제 시킨 후 실행

실행 압축된 파일은 PE 파일, 내부에 원본 PE 파일과 decoding 루틴이 존재한다.

EP(Entry Point)코드에 decoding 루틴이 실행되면 메모리에서 압축 해제 후 실행됨

 

항목 일반 압축 실행 압축
대상파일  모든 파일 PE 파일(exe, dll, sys)
압축 결과물 압축(rip, rar) 파일 PE 파일(exe, dll, sys)
압축해제 방식 전용 압축해제 프로그램 사용 내부의 decoding 루틴
파일 실행 여부 자체 실행 불가 자체 실행 가능
장점 모든 파일에 대해 높은 압출율로 압축 가능 별도의 해제 프로그램 없이 바로 실행 가능
단점 전용 압축해제 프로그램 없으면 압축 파일 사용 못함 실행할 때마다 decoding 루틴이 호출되어서 실행시간이 미세하게 느려짐

 

 

패커


일반 PE 파일을 실행 압축 파일로 만들어주는 유틸리티 → PE 패커: 실행 파일 압축기(Run-Time 패커)

 

1. 사용 목적

  • PE 파일 크기 줄이기
  • PE 파일의 내부 코드와 리소스(문자열, API name string) 감추기 

* 압축된 데이터는 알아 보기 힘든 형태의 바이너리로 저장되어 내부 코드와 리소스를 감춰주는 효과가 있음

 

2. 사용 현황

과거에는 PC 속도가 빠르지 못해 파일을 실행할 때마다 압축 해제 과정이 큰 오버헤드로 작용했음.

하지만 지금은 PC 속도가 빨라져 실행 합축된 파일이나 원본 파일에서 시간 차이를 느끼기 어려운 정도임

현재 유틸리티, 패치 파일, 일반 프로그램에 널리 사용중이다.

 

3. 패커 종류

  • 평범한 PE 파일 생성하는 패커(VirusTotal에서 진단 X)

: UPX, ASPack 등

  • 원본 파일 변형, PE 헤더 심하게 훼손시키는 패커(VirusTotal에서 진단 O)

: UPack, PESpin, NSAnti 등 

 

 

 

프로텍터


Anti-Reversing 기법에 특화된 패커

PE 파일을 'Reverse Code Enginerring'으로부터 보호하기 위한 유틸리티

실행 압축 + 리버싱을 막기 위한 기법(Anti-Debugging, Anti-Emulating, Code Obfuscating,...)

 

1. 사용 목적

  • Cracking 방지
  • 코드 및 리소스 보호

: 프로텍터는 PE 파일 자체를 보호하고 파일 실행되었을 때 프로세스 메모리를 보호해 덤프를 뜨지 못하도록 한다.

 

2. 사용 현황

온라인 게임 설치 시 같이 설치 되는 보안 프로그램이 '게임 해킹 툴'의 실행을 방지함

크랙 성공 시 '게임핵'을 이용해 금전적 이익을 얻을 수 있음

보안 프로그램들은 크랙 방지를 위해 프로텍터를 사용하여 자신을 보호함

Troja, Worm 등 일반적인 악성 코드에서 많이 사용하고, AV제품의 진단을 막기 위해 사용함 (다형성 코드를 제공하여 다른 모양의 코드가 생성되어 AV 제품에서 진단하기 까다롭다)

 

3. 프로텍터 종류

  • 상용 프로텍터

: ASProtect, Themida, SVKP 등

  • 공개용 프로텍터

: UtlraProtect, Morphine 등

 

용어정리
PE파일: 윈도우 운영체제에서 사용되는 실행파일
OEP: Original Entry Point 원본 프로그램의 시작 위치
Trace: 코드를 하나하나 실행하면서 쫓아가는 것

 

 

UPX


 

upx 설치 위치에 notepad.exe 파일을 복사해서 패킹

 

66KB → 47KB로 크기가 줄어든 것을 확인할 수 있다. PE 파일이기 때문에 PE 헤더를 추가해야 하고, 압축 해제를 위한 코드도 넣어야 하기 때문에 압축률이 zip 같은 일반 압축보다 압축률이 떨어진다.

 

원본 vs UPX 패킹

원본
upx 패킹

  • PEiD에 넣어봤을 때 아래는 UPX로 패킹된 것을 확인할 수 있다.
  • Entrypoint가 달라짐(아래 디버깅 과정에서도 확인 가능)
  • EP의 위치가 원본에는 .text에 있었으나 UPX 패킹 후에는 두번째 섹션인 UPX1에 있음을 볼 수 있음
  • EP를 기준으로 값이 달라짐(원본: 6A, 70으로 시작, UPX: 60으로 시작)

 

  • PE header 크기는 동일하다
  • 섹션 이름이 변경됐다.
  • 리소스 섹션(.rsrc) 크기는 거의 변하지 않았음
  • 첫 번째 섹션 RawDataSize가 0으로 바뀜

 

UPX 패킹 파일의 첫번째 섹션(UPX0)의 RawDataSize가 0인 것을 볼 수 있는데 첫번째 섹션이 파일 내에 존재하지 않음을 의미한다. Virtual Size를 보면 10000으로 세팅되어 있는데 UPX 패킹된 파일이 실행되는 순간에 파일에 있던 압축된 코드를 첫번째 섹션에 풀어 버리기 때문이다. 

두번째 섹션에 압축해제 코드, 압축 원본 코드가 있고, 파일이 실행되면 압축 해제 코드가 실행되어 압축 원본 코드를 첫번째 섹션에 해제시킨다. 이 과정이 끝나면 원본 EP 코드를 실행한다.

 

 

UPX 패킹된 notepad 디버깅


UPX로 패킹된 notepad.exe 파일을 디버깅한다. 코드를 트레이싱하면서 원본 notepad.exe 코드를 찾는 것이 목표

notepad.exe 파일과, notepad_upx.exe파일을 x32dbg로 열었다.

 

원본

원본 notepad.exe EP

EP주소 0100739D

 

UPX 패킹

upx로 패킹한 notepad.exe EP

OllyDbg로 notepad_upx.exe파일을 열면 경고 메시지박스에서 해당 파일이 압축되었다고 경고가 뜬다는데 x32dbg로 열었을 때는 그냥 열렸다. 

 

EP주소01015320, 두 번째 섹션의 끝부분에 위치하고, 원본 notepad의 EP주소(0100739D)는 위쪽에 있다.

PUSHAD 명령어로 EAX~EDI 레지스터 값을 스택에 저장하고

ESI는 두 번째 섹션 시작 주소(01011000),

EDI는 첫 번째 섹션 시작 주소(01001000)로 세팅한다.

 

UPX에서 첫번째 섹션은 메모리에서만 존재, 압축해제된 
ESI, EDI가 동시에 세팅되면 ESI가 가리키는 버퍼에서 EDI가 가리키는 버퍼로 메모리 복사가 일어난다. 이때 소스(ESI)로부터 데이터를 읽어 압축을 해제한 후 Destination(EDI)에 저장시킨다.

 첫번째 섹션 시작 주소(01001000)
두번째 섹션 시작 주소(01011000)

 

UPX 파일 트레이싱


"Loop 만나면 역할 보고 탈출하기"

 

명령어 단축키 설명
Animate Into Ctrl+F7 Step Into 명령 반복 (화면 표시 됨)
Animate Over Ctrl+F8 Step Over 명령 반복(화면 표시 됨)
Trace Into Ctrl+Alt+F7 Step Into 명령 반복(화면 표시 안 됨)
Trace Over Ctrl+Alt+F8 Step Over 명령 반복(화면 표시 안 됨)

Animate명령어는 Ollydbg랑 똑같은데 Trace는 다른 듯?

 

 

루프 #1

처음 들어왔을 때 ECX는 36B이고, 코드를 보면 EDX(01001000)에서 한 바이트를 읽어 EDI(01001001)에 쓰도록 되어 있다.

EDX 값을 a1에 복사
EDX++
a1값을 EDI값에 옮기기
EDI++
ECX--(loop 돌리는 횟수)
0이면 10153CD로 점프

이때 EDI가 가리키는 01001000 주소는 첫번째 섹션인 UPX0의 시작 주소이고 UPX0의 첫번째 섹션은  메모리에서만 존재할 뿐 나중에 원본 파일의 코드가 저장될 장소이기 때문에 현재 내용은 전부 NULL 비어있다.

010153D6에 BP설치 후 빠져나온다(F9).

 

어셈블리어 명령어
INC: 피연산자에 +1, 레지스터와 메모리만 사용 가능
DEC: 피연산자에 -1, 레지스터와 메모리만 사용 가능
JNE: 다르면 점프(ZF가 0이면 점프)

 

 

루프 #2

좀 전에 BP 걸어둔 곳에서 시작하면 새로운 loop를 접할 수 있다. (길다)

여기가 압축 해제(decoding) 루프이다.

ESI가 가리키는 두 번째 섹션(UPX1)의 주소에서 차례대로 값을 가져와 연산을 거친 후 압축을 해제하여 EDI가 가리키는 첫 번째 섹션(UPX0)의 주소에 값을 써준다.

 

그려면 첫 번째 섹션 위치인 01001000에 값이 들어와야 하는데 안 들어왔다. 모르겠다. 

 

 

루프 #3

원본 코드의 CALL/JMP 명령어의 destination 주소를 복원시켜주는 코드이다.

01015426에 bp 걸어서 탈출

 

 

루프 #4

IAT를 세팅하는 루프이다.

01015426에서 EDI = 1014000으로 세팅되고, 여기가 두 번째 섹션(UPX1) 영역이다.

API 이름 문자열

두 번째 섹션 위치로 가보면 원본 notepad.exe에서 사용되는 API 이름 문자열이 저장되어 있다.

UPX가 원본 notepad.exe를 패킹할 때 원 본 파일의 IAT를 분석해서 프로그램에 사용되는 API 목록을 뽑아 놓은 것이다.

이제 이 문자열로  010142D에 있는 GetProceAddress()를 호출하여 API 시작 주소를 얻고, EBX가 가리키는 원본 notpead.exe의 IAT 영역에 API 주소를 입력한다.

API 이름 문자열이 끝날 떄까지 반복하면 IAT 복원 과정이 마무리 된다.

 

원본 notepad.exe 압축을 모두 해제하였으면 OEP로 제어를 돌려줘야 한다.

 

조금 더 내려가면 popad 명령어가 보이는데,  UPX코드 중 가장 첫 번째 명령인 PUSHAD에 대응되는 명령어로 레지스터를 원래대로 복원시킨다.

 

010154AB에서 jmp 명령어로 OEP로 가고 100739D는 원본 notepad.exe의 EP주소이다.

위에 캡쳐해둔 원본의 EP 주소와 일치한다.

 

 

UPX OEP 빨리 찾기


 

1. POPAD 명령어 이후의 JMP 코드 명령어에 BP 설치

EP 코드가 PUSHAD/POPAD 명령어로 둘러싸여 있다는 것이 UPX 패커의 특징이다. OEP 코드로 가는 JMP 명령어가 POPAD 명령어 바로 뒤에 나타나므로 여기에 BP를 걸면 된다.

 

2. 스택에 하드웨어 브레이크 포인트 설치

PUSHAD 명령 실행 후에 스택을 보면 EAX~EDI까지 스택에 저장되어 있는데 이때 DUMP 창에서 저 주소(000DFF54)로 가 하드웨어 BP를 설정한다.

 

하드웨어 BP는 일반 BP와 달리 저 지점에 있는 명령어가 실행된 이후에 제어가 멈추게 된다. 이 상태에서 실행하면 압축이 해제되면서 코드가 실행되고, POPAD가 호출되는 순간에 하드웨어BP가 설치된 0006FFA4주소를 엑세스 하게 되어 제어가 멈춘다. 이때 바로 밑에 있는 JMP는 OEP로 가는 명령어 이다. ( 2번은 솔직히 잘 모르겠다)

 

 

 

 

 

 

참고 리버싱핵심원리

'Waregame & CTF > Reversing' 카테고리의 다른 글

DLL Ejection  (0) 2021.11.13
DLL Injection  (0) 2021.11.13
[dreamhack.io] rev-basic-3  (0) 2021.10.06
[dreamhack.io] rev-basic-2  (0) 2021.10.06
[dreamhack.io] rev-basic-06  (0) 2021.10.02