일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 블로그 이전했어요
- webcrawler
- leetcode 344
- 문자열 조작
- MapReduce 실습
- leetcode
- leetcode 937
- leetcode 121
- leetcode125
- 데이터레이크와 데이터웨어하우스
- Hortonworks Sandbox
- leetcode 819
- Python
- docker로 airflow 설치하기
- 스파크 완벽 가이드
- ctf-d
- Hadoop
- 배열
- 올바른 변수명 짓기
- wargame.kr
- leetcode 15
- airflow docker
- 빅데이터를 지탱하는 기술
- leetcode 238
- 컴퓨터구조
- 머신러닝
- leetcode 49
- leetcode 561
- leetcode 5
- leetcode 234
- Today
- Total
HyeM
[3]패킹&UPX패킹(디버거로 언패킹) 본문
00. 데이터 압축
-
비손실 압축 : 파일(데이터)크기를 줄여 보관, 이동에 용이하도록 함.
압축프로그램 이용하여 파일 압축.
대표 비손실 압축 알고리즘 : Run-Length, Lempel-Ziv, Huffman -
손실 압축 : 파일(데이터)에 의도적인 손상 줌. 압축률 높임. ex. jpj,mp3, mp4 대부분은 손실 압축 기법
-
실행 압축 : PE파일 내부에 압축 해제 코드를 포함하고 있어, 실행되는 순간 메모리에서 압축 해제 시켜 실행함.
실행 압축된 것도 PE파일. 내부엔 '원본 PE 파일 + decoding 루틴' 존재 -> EP코드에서 decoding 루틴이 실행되면서 압축해제시켜 실행함.
항목 | 일반 압축 | 실행 압축 |
대상 파일 | 모든 파일 | PE파일 (exe, dll, sys) |
압축 결과물 | 압축(zip,rar)파일 | PE파일 (exe, dll, sys) |
압축해제 방식 | 전용 압축해제 프로그램 사용 | 내부의 decoding 루틴 |
파일 실행 여부 | 자체 실행 불가능 | 자체 실행 가능 |
장점 | 모든 파일에 대해 높은 압축율 | 별도의 해제 프로그램 없이 바로 실행 ok |
단점 | 전용 압축 해제 프로그램이 없으면 해당 압축 파일 사용 못함 | 실행할 때 마다 decoding 루틴이 호출되기 때문에, 실행시간이 아주 미세하게 느려짐 |
01. 패커
: 일반 PE 파일을 실행 압축 파일로 만들어주는 유틸리티 (실행 파일 압축기, Run-Time 패커)
Anti-Reversing 기법에 특화된 패커를 '프로텍터'라고 함.
: 사용목적
- PE파일 크기 줄임
- PE 파일 내부코드와 리소스(문자열 , API, name String) 감춤
: 사용현황
최근엔 유틸리티, 패치 파일, 일반 프로그램 등 널리 사용됨.
: 패커종류
크게 두 종류
- 순수한 의도의 패커(VirusTotal에서 진단 안됨.) : 평범한 PE파일 만듦 _ UPX, ASPack 등
- 불순한 의도의 패커(VirusTotal에서 진단 됨.) : 원본 파일 크게 변형, PE헤더 심하게 훼손시킴 _ UPack, PESpin, NSAnti 등
02. 프로텍터
: PE파일을 'Reverse Code Engineering'으로 부터 보호하기 위한 유틸리티
- 패커처럼 실행 압축 + 리버싱 막기 위한 다양한 기법 적용(Anti-Debugging, Anti-Emulating, Code Obfuscating 등)
- 디버깅 하기 어려움
: 사용목적
- 크래킹 방지
- 코드 및 리소스 보호
: 사용 현황
- 크래킹에 민감한 보안 프로그램(ex. 게임 보안 프로그램)
- 일반적인 악성코드(Trojan, Worm)에서 사용. _ AV제품의 진단을 막거나 늦추기 위해 사용
: 프로텍터 종류
- 공개용 프로텍터 : UltraProtect, Morphine 등
- 상용 프로텍터 : ASProtect, Themida, SVKP 등
03. UPX 실행 압축 & 디버거로 OEP 찾기(언패킹) (실습)
사용할 패커 : UPX (x32버전)
압축 대상 : notepad.exe (win7 32bit)
실습환경 : win 7 32bit
upx 다운 받아서, 위의 명령어로 notepad.exe파일을 실행 압축한다.
이를 pe viewer로 보면 다음과 같다.
사진을 보면 VirtualSize는 28000인데, SizeOfRawData는 0인것을 볼 수 있다.
이유 : UPX로 실행 압축된 파일이 실행 되는 순간, 압축된 코드를 첫번째 섹션에 푼다.
+ 두번째 섹션에 압축해제코드와 있음.
지금 부터는 upx 압축한 notepad_upx.exe파일을 디버거로 열어 OEP를 찾아가는 과정에 대한 실습이다.
OEP : Original Entry Point _ 패킹된 파일의 실제 시작 부분이다.
참고로 notepad_upx.exe로 확인한 프로그램 시작 부분 코드는 다음과 같다.
notepad_upx.exe를 x32dbg로 열면 다음과 같다.
EP주소는 009E21B0 이고, 이 부분은 두 번째 섹션의 끝 부분이다.
코드를 보면 PUSHAD 명령으로 EAX~EDI 레지스터 값을 스택에 저장한다. 그리고
ESI에 두번째 섹션 시작 주소(00D8 9000)를,
EDI에는 첫 번째 섹션 시작 주소(00D6 1000)로 세팅한다.
뒤의 코드 흐름을 미리 예측해 보면 다음과 같다.
UPX파일에서 첫번째 섹션은 메모리에서만 존재하고, 압축 해제된 원본 파일의 코드가 저장될 것이다.
ESI 가 가리키는 버퍼에서 EDI가 가리키는 버퍼로 메모리 복사 발생할 것이다.
(ESI에서 데이터를 읽어 압축 해제 후, EDI에 저장시킴)
UPX파일 트레이싱
# 루프1
esi 의 값을 al로 옮김 esi++ al값을 edi로 옮김 edi++ ebx+=ebx 0이 아니라면 D121D1분기 뒤에 값이 더 크면 D121C0로 분기
|
루프의 내용은 ESI(009D 9000)에서 한 바이트를 읽어 EDI(009B 1000)에 쓰는 것이다. 즉, 두번째 섹션에서 첫번째 섹션에 바이트를 읽어 쓰는 것이다.
루프를 빠져나오기 위해, 009121D3에 BP를 걸고 F9로 탈출한다.
#루프2
두번째 루프는 크게 돌게 되는데, 이 루프에서는 첫번째 섹션 영역(00D6 1000)에 압축해제 된 코드를 쓰게 된다.
==> 본격적인 디코딩(decoding) 루프.(압축해제 루프)
두번째 섹션주소(UPX1)에서 차례대로 값을 읽어, 연산을 거친후, 압축해제하여 EDI가 가리키는 첫번재 섹션(UPX0)의 주소에 값을 써준다.
여기서 핵심 명령어는 다음과 같다.
mov byte ptr ds:[edi], al inc edi mov dword ptr ds:[edi], eax add edi, 0x4 |
이 루프를 탈출하기 위해, 00D9 227A에 BP를 두고 F9로 탈출한다.
그러고 나서 ESI와 EDI가 가리키고 있던 덤프 창을 확인해보면, 00으로 채워졌던 첫번째 영역 부분에 압축해제된 코드들로 쓰여진 것을 확인할 수 있다.
#루프3
이 부분은 원본 코드의 CALL/JMP 명령어의 destination 주소를 복원시켜주는 코드 이다.
이 루프도 역시 009D22AE에 BP를 걸고 F9로 탈출한다.
#루프 4
이 부분은 IAT를 세팅하는 루프이다.
00D9 22AE주소에서 EDI= 00D9 0000 로 세팅되고, 이곳은 두 번째 섹션(UPX1)영역이다.
이 주소(00D9 0000)에는 원본 notepad.exe에서 사용되는 API이름 문자열이 저장되어 있다.
이 문자열은 UPX가 notepad.exe를 실행 압축할때, 원본 파일의 IAT를 분석하여 사용하는 API이름 목록을 따로 뽑아 놓은 것이다.
API이름 문자열이 저장된 곳을 가리키는 EDI에서 연산을 통해 문자열을 하나씩 뽑아(=API이름 하나씩 뽑아),
00D9 22E8주소의 GetProcAddress()를 호출하여 API시작 주소를 얻어, EBX가 레지스터가 가리키는 원본 notepad.exe의 IAT 영역에 API주소를 입력한다.
이 과정을 API 이름 문자열이 끝날때까지 반복하면 , 원본 notepad.exe의 IAT 복원과정이 마무리 된다.
==>원본 notepad.exe의 압축 해제 모두 완료. 남은 단계는 OEP로 제어 돌려주는 것이다.
#마지막 OEP로 이동
루프4를 빠져나온 뒤, 코드 몇개를 지나고 나면 popad 명령어를 만날 수 있는데 ,
POPAD명령어는 위에서 봤던 UPX 코드 중 가장 첫 번째 명령어인 PUSHAD에 대응하는 명령어로, 레지스터를 원래대로 복원시키는 명령어이다.
최종적으로, 'jmp notepad_opx. 323689' 명령어로 OEP로 간다. JMP하는 323689주소는 원본 notepad.exe 의 EP주소로 확인가능하다.
원본 notepad를 열어, EP코드를 위에서 jump한 OEP코드와 비교하니 같은 것을 확인할 수 있다.
==> OEP 코드 찾기 완료 <==
04. 디버거로 OEP 찾기(언패킹)_빠르게 찾는 방법
1. UPX 패커의 특징인 , EP코드가 PUSHAD/POPAD명령어로 둘러쌓인 것을 이용하여, POPAD명령어 이후의 JMP명령어에 BP 설치
- POPAD 명령어 이후의 JMP명령어에 BP설치
UPX 패커의 특징으로 EP코드가 PUSHAD/POPAD명령어로 둘러 쌓인 것이니, POPAD명령어 이후 JMP명령어에 BP를 걸어 한번에 OEP코드로 이동한다. - 스택에 Hardware Break Point설치이 방법 역시 UPX 특징인 PUSHAD/POPAD 명령어 특성을 이용한 것이다.
Hardware BP란 CPU에서 지원하는 BP로, 일반적인 BP와 달리, BP설치된 명령어가 실행된 이후에 제어가 멈추게 된다.
PUSHAD 명령어를 실행하면 , 레지스터 값이 스택에 저장된 것을 확인할 수 있다.
덤프창에서 저 스택주소(0008 FAEC)로 이동하여, 마우스 커서를 이 주소에 정확히 위치시킨후, 우클릭하여 하드웨어 BP를 설치한다.
설치한 후, 이 상태로 실행하면 압축이 해제가 되면서 코드가 실행되고, POPAD를 호출한 순간에 하드웨어 BP가 설치된 0008 FAEC주소를 엑세스 하고 그때 제어가 멈춘다. 그러면 밑에 바로 OEP로 가는 JMP명령어를 만날 수 있다.
'Study > Reversing' 카테고리의 다른 글
DLL Injection(개념+실습) (0) | 2020.11.05 |
---|---|
[3]IAT, EAT 로딩 과정 (0) | 2020.10.25 |
[3]Dreamhack_Rev 4번 문제 (0) | 2020.10.12 |
[3]Dreamhack_Rev 5번 문제 (0) | 2020.10.12 |
[2]PE구조&wow64 fs redirection + a (0) | 2020.09.20 |