본문 바로가기

기술 문서/Reversing

[Reversing] Ollydbg를 이용한 UPX 패킹과 언패킹

반응형

※ 패킹이란?


PE 파일 전문 압축기. 파일 크기를 줄이고 내부 코드와 리소스를 감추기 위한 목적으로 사용 됩니다. 실행 압축 방식으로 파일 내부에 압축해제 코드를 포함하고 있기 때문에 실행되는 순간에 메모리에서 압축을 해제하여 바로 실행할 수 있습니다.



* 다음은 Win 7 64 bit, Ollydbg 2.00, 2.01 버전에서 진행 하였습니다.


UPX 패킹을 하는 방법은 간단합니다.



 - upx.sourceforge.net 에서 UPX 툴을 다운 받습니다.



- upx의 기본 사용법입니다. 패킹을 하려면 upx o [패킹 후 파일이름] [원본 파일이름]을 해주면 됩니다. 언패킹upx -d [언패킹 할 파일이름]을 해주면 됩니다.



- 예제 파일로 notepad를 패킹해보았습니다. 파일 사이즈가 줄어들고 성공적으로 패킹이 완료 된 것을 확인할 수 있습니다.

 



- 패킹된 파일을 통해서 원본 파일과 어떤 차이점이 있는지 알아봅시다.



- 원본 파일과 upx 패킹 파일의 PE 파일 구조입니다. 위 그림은 예시를 위해 가져온 자료이기 때문에 환경에 따라 주소에 차이가 날 수 있습니다(저는 Win 7 64bit 환경에서 했습니다). 차이점을 살펴보면 헤더 부분은 달라지는 점이 없고, 섹션의 이름이 .text 에서 .UPX0으로 .data.UPX1으로 변환 됩니다. 그리고 각 섹션의 헤더와 영역이 압축되어 줄어든 모습을 확인할 수 있습니다. 잘 살펴보면 .UPX0에는 아무런 영역이 할당되어 있지 않아 실제로는 존재하지 않는 것을 볼 수 있습니다. 이 섹션은 어떤 용도로 사용되는지 살펴봅시다. (이미지 출처 : http://blog.daum.net/tlos6733/45)

 


- PEID를 통해서 섹션의 사이즈를 보니 Raw Size0이지만 Virtual Size28000이 주어져 있는 것을 볼 수 있습니다. 앞서 실행 압축은 파일 내부 자체에서 실행되는 순간에 압축을 해제해주어 실행한다고 했는데, 이 압축을 풀어주는 영역이 .UPX0입니다. 이 압축된 코드와 압축을 해제시켜주는 코드는 .UPX1에 존재합니다.

 

그럼 Ollydbg를 통해 패킹된 파일에서 어떻게 원본 파일을 추출해내는지 알아보겠습니다.

저는 예제 프로그램으로 kisa 해킹방어 훈련장의 리버싱 문제 하나를 가져왔습니다.



UPX1로 패킹이 되어있다는 것을 PEID 툴로 확인하고, 섹션 정보도 확인해 보았습니다.



패킹되어 있는 파일을 olly로 열려고하면 다음과 같은 문구를 볼 수 있습니다. 아무거나 눌러도 똑같이 넘어갑니다.

 



여기서 EP주소는 00428BA0이고, 이 곳은 두 번째 섹션의 끝 부분입니다. PUSHAD 명령을 통해 EAX~EDI 레지스터 값을 스택에 저장해주고, ESI를 두 번째 섹션(.UPX1) 시작 주소(00423000)EDI를 첫 번째 섹션(.UPX0)의 시작 주소(00401000)으로 세팅해줍니다. 이제 이후의 코드는 ESI에서 데이터를 읽어 압축을 해제한 후 EDI에 저장 시킬 것을 알 수 있습니다.



- F8을 통해 트레이싱을 해보면, 다음과 같은 루프문을 자주 만날 수 있습니다. 이러한 루프를 통해 압축을 해제하고 해제한 데이터를 메모리에 저장을 하며 IAT를 세팅합니다.



- 압축을 해제하는 과정이 모두 끝나면 POPAD 명령어를 통해 레지스터들을 원래대로 복원시킵니다. 그리고 마지막에 JMP 하는 주소가 OEP(Original Entry Point)로 원본 파일의 시작 주소입니다. 위 그림에선 00401920입니다. JMP 부분에 BP를 걸고, F9로 실행하고 F8로 스텝 오버하면 원본 코드에 접근할 수 있습니다.



- 원본 코드에 접근한 모습입니다. 함수 프롤로그부터 진행 되는 모습을 볼 수 있습니다. 이렇게 언패킹 된 원본 소스를 저장하고 싶으면, OllyDump 같은 플러그인을 사용하여 덤프하면 됩니다. 2.01에서 OllyDumpEX 플러그인을 사용하니 자동으로 언패킹도 해줍니다.

 

그럼, 빠르게 OEP를 찾아내는 방법을 알아봅시다.

 

가장 쉬운 방법은 POPAD를 한 후 JMP를 해주는 부분을 찾는 것입니다. 이는 압축 해제가 완료된 뒤에 해주는 명령어이기 때문에 거의 맨 아래에 위치하므로 쉽게 찾을 수 있습니다. 또 다른 방법은 스택에 하드웨어 브레이크 포인터를 걸어 찾는 방법이 있습니다.



- PUSHAD를 실행하고 난 뒤 Dump 창에서 해당 Stack 주소의 위치로 이동합니다.



- 그 다음 해당 위치에서 오른쪽 클릭을 해서 하드웨어 브레이크 포인트를 선택합니다.



- Access, Byte를 선택하고 OK를 누르면 됩니다.



- 해당 위치에 브레이크 포인트를 걸고 F9를 통해 실행하면 POPAD를 한 이후의 위치에서 멈추는 것을 확인할 수 있습니다.



[출처] 리버싱 핵심원리(인사이트) 를 공부하며

 

반응형

'기술 문서 > Reversing' 카테고리의 다른 글

usb가 포트에 연결되었을 때  (0) 2016.03.25