Packing/Unpacking
1. packer
▶ packing하는 프로그램을 말한다.
▶ packing은 압축된 상태에서는 실행이 안되고 메모리에 압축을 풀어서 사용하는 것을 말한다.
1) Compressor
[1] 정의
▶ 실행파일의 용량을 줄이기 위해 압축한다.
[2] 사용이유
▶ 파일 용량을 줄이는데 목적이 있다.
▶ 그러나 프로그램 실행속도가 느려진다.
[3] 종류
▶ Petite, ASPack, MEW, FSG, UPX 등이 있다.
2) Protector
[1] 정의
▶ 실행파일을 암호화하여 분석을 어렵게 하고 실행할 때 복호화하여 메모리에 적재된다.
[2] 사용이유
▶ 내부로직을 보호하는데 목적이 있다.
▶ 파일이 커질 수 있고, 실행속도가 느려진다.
[3] 종류
▶ Themeda, Yoda,ASProtect, armadillo 등이 있다.
3) packer 제작
▶ packing하는 프로그램을 말하며 xor연산, rc4, des 등의 알고리즘을 이용해서 제작이 가능하다.
▶ 조금 더 지식을 쌓은 후에 프로젝트 형태로 제작해보려고 한다.
2. Unpacking
▶ packer는 패킹하지만 패킹을 푸는방법도 알아야 한다.
▶ packing을 푸는 것을 unpacking이라고 한다.
[1] 로더
▶ UPX Compressor를 사용할 경우는 위 사진과 비슷하다.
[2] UPX을 기준으로 과정설명
▶ 운영체제의 Loader가 실행파일을 메모리에 로딩한다.
▶ Packing된 파일은 Unpacking Code시작부분이 Entry Point이다.
▶ Entry Point(=진입점, EP)에서 프로그램이 실행된다.
▶ Packing된 파일은 Unpacking Code영역에 들어있다.
▶ Unpacking 코드는 패킹된 데이터를 하나씩 읽어 압축을 풀고 Empty Space(빈 공간)에 원래 데이터를 저장한다.
▶ 모든 코드가 Unpacking 되었다면 Original Entry Point(=원래 진입점, OEP)에서 프로그램이 다시 실행된다.
▶ Original Entry Point(=원래 진입점, OEP)은 Unpacking되기 이전 실행파일의 시작점을 말한다.
3. 시연
1) crackme1의 정보확인
▶ Detect It Easy 프로그램으로 정보를 확인한다.
▶ 기준주소는 0x400000이고 0x1000만큼 떨어진 곳에 시작주소가 있다.
2) UPX 패커로 패킹
▶ UPX 패커를 설치[https://upx.github.io] 한다.
▶ 이후 command창에서 [upx -o "패킹한 파일명(new)" "패킹할 파일명(기존)"] 명령어를 사용하여 crackme1을 패킹한다.
3) 패킹된 crackme1의 정보확인
▶ UPX packer를 사용한 것을 확인할 수 있다.
▶ Entry Point도 0x71b0로 변경된 것을 확인할 수 있다.
▶ 0x71b0은 Unpacking Code의 Entry Point로 보여진다.
4) 자동 Unpack 기능 해제
▶ [options - SFX] 에 들어가서 Unpack SFX modules automatically 체크를 해제한다.
▶ 만약 체크되어 있다면 디버거에 실행파일을 올리면 알아서 풀어준다.
5) 원래 주소의 내용확인
▶ 원래주소인 0x401000에 가서 보면 비어있는 것을 확인할 수 있다.
6) Unpacking 완료
▶ Unpacking이 완료되면 OEP(Original Entry Point)로 오게되고 이 곳에는 Packing이전의 코드가 복구되어 있다.
7) Unpacking 후 덤프뜨기
▶ [OllyDumpEx] plug-in을 다운로드 후 plug-in 폴더에 저장한다.
▶ [우클릭 - Dump process(OllyDumpEx)]를 누른다.
8) OEP지정 후 덤프뜨기[1]
▶ 원래는 0x71b0가 Entry Point이다.
9) OEP지정 후 덤프뜨기[2]
▶ Entry Point를 원래 주소로 변경한 후 저장한다.
10) 저장
▶ Unpacking한 내용을 저장한다.
11) 최종확인
▶ 내용 확인 후 Finish를 누른다.
12) Unpacking한 파일 저장 후 실행
▶ 저장한 실행파일을 실행시키자 .....?? DLL을 찾을 수 없다고 합니다.
13) 정보 확인
▶ 실제 내용을 보면 완전히 패킹이 해제된 것으로 보이지 않는다.
14) import 확인
▶ IAT(Import Address Table)가 깨져있는 것으로 보인다.
15) LordPE를 이용한 IAT복원
▶ LordPE에 위에서 저장한 파일을 드래그해서 넣는다.
▶ LordPE 프로그램은 깨진 IAT를 복원시켜준다.
16) 정보 재확인
▶ IAT가 복원되어 프로그램이 정상적으로 동작하며 내용을 다시 확인할 수 있다.
17) import 확인
▶ 이전에 깨져있던 것들이 정상적으로 잡혀있는 것을 확인할 수 있다.
▶ 여기까지 한 작업으로 UPX로 패킹한 프로그램을 직접 Unpacking하였다.
4. OEP(Original Entry Point)
▶ 지금은 OEP를 알고 있기 때문에 이런식으로 Unpacking이 가능하다.
▶ 다음장에서는 OEP를 찾는 방법을 구현해보려고 한다.
1) 시작위치
▶ pushad로 시작한다.
▶ pushad는 현재 레지스터의 상태를 전부 스택에 저장한다.
▶ 이 말은 함수가 시작되면 Unpacking 후 분명히 종료할 것이다.
▶ 종료를 한다면 이 후 어디론가 이동할 것이다.
▶ 이 어딘가가 OEP일 것이라는 느낌이 든다.
2) 종료위치
▶ 종료하는 부분을 찾은 이후 jmp문을 통해 0x401000으로 이동하는 것이 보인다.
▶ 이 곳이 0x401000이 OEP일 것 같다.
▶ 이와 같이 단순한 프로그램이 아니라면 종료하는 부분을 찾는 것이 쉽지는 않을 것이다.
※ 글이 길어질 것으로 예상되어 새로운 시연과 함께 OEP를 찾기위한 과정을 다음 글에서 작성할 예정이다.
'Try Attack > Reverse Engineering[basic]' 카테고리의 다른 글
[csaw CTF 2015] wyvern (0) | 2019.04.08 |
---|---|
BreakPoint (0) | 2018.12.28 |
Code Caving (0) | 2018.12.18 |
[crackme5] abex' 5th crackme 풀이 및 복원 (0) | 2018.11.16 |
[crackme3] abex' 3rd crackme 풀이 및 복원 (0) | 2018.11.08 |
댓글