Try Attack/Reverse Engineering[basic]

Packing/Unpacking

D4tai1 2018. 12. 19.

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

댓글