외로운 Nova의 작업실

리버싱 입문 - 8(패킹과 언패킹) 본문

Computer App Penetesting/Reversing

리버싱 입문 - 8(패킹과 언패킹)

Nova_ 2022. 12. 20. 16:05

- 패킹

패킹이란 프로그램의 코드 크기를 줄이려고 압축하거나 프로그램 분석을 어렵게 만들려고 암호화하는 것을 패킹이라고합니다. 특히 단순 압축하는 것을 컴프레싱, 암호화하는 것을 프로텍팅이락 구분합니다.

 

<패킹 원리>

패킹의 원리는 다음과 같습니다.

1. origin code를 알고리즘에 따라 패킹한 후 그 코드를 packed data로 프로그램에 unpackingc code와 함께 저장합니다.

2. origin code는 삭제합니다.

3. 엔트리 포인트를 unpacking code의 시작점으로 두면 패킹이 끝이납니다.

 

<언패킹 원리>

언패킹의 원리는 다음과 같습니다.

1. 엔트리 포인트에따라 unpacking code 알고리즘을 실행합니다.

2. unpacking code 알고리즘은 packed data를 기반으로 결과값을 origin code였던 부분에 재 작성합니다,

3. 작성이 완료되면 origin code의 OEP(origin entry point)로 가서 프로그램을 실행합니다.

 

<패킹 도구>

compressor 도구 : Petite, ASPack, MEW, UPX, FSG

protector 도구 : theneda, Yoda, ASProtcet, armadillo

 

- Packing(UPX)

UPX를 사용하여 실제로 패킹해보고 패킹한 파일을 원래의 코드로 되도려보는 실습을 해보도록 하겠습니다. 먼저 UPX를 다운받기위해 아래 사이트에 접속해서 다운을 받아줍니다.

https://github.com/upx/upx/releases/tag/v4.0.1

 

Release UPX 4.0.1 · upx/upx

Please see the file NEWS for a detailed list of changes. Note: all versions are functionally equivalent, i.e. each version can handle all executable formats, so you only need the file that runs on ...

github.com

이후 패킹할 파일 crackme1.exe파일을 upx.exe파일에 넣어줍니다.

cmd를 키고 upx 파일이 있는 곳으로 가서 upx -o [패킹후 파일] [패킹 전 파일] 명령어를 사용하여 아래 명령어를 사용합니다.

upx -o crackme1_pack.exe Crackme1.exe

그러면 81.25%로 줄었다고 나옵니다. 실제 패킹이 되었다면 EP(entry point)가 변경되었을 것이므로 실제 Detect It easy를 통해 먼저 origin 파일의 EP를 확인해보겠습니다. DIE - PE - IMAGE_OPTIONAL_HEADER - Address of entry point 값을 보겠습니다.

00001000 인것으로 확인됩니다. 그렇다면 crackme1_pack 도 한번 봐보겠습니다.

000071b0으로 확인됩니다. 실제로 EP가 변한것을 확인할 수 있습니다. 이는 ollydbg 실행에서도 확인할 수 있습니다. 다만, ollydbg의 시작부분은 EP(상대주소)와 imagebase(기준점)를 더한 실제 메모리 값으로 위에서 보게되면 imagebase 값은 004000000입니다. 즉 ollydbg의 시작주소는 004071b0 일것으로 예상할 수 있습니다. 실제 ollydbg로 열어보겠습니다. 단, ollydbg의 경우 UPX를 unpacking하는 기능이 포함되어있으므로 이를 꺼야합니다. 이는 option - SFX - unpack SFX modules automatically 부분을 꺼줘야합니다.

이후 실행시켜보면

실제로 주소가 맞는 것을 확인할 수 있습니다.

 

- unpacking(ollydbg)

이제 실제 언패킹해보겠습니다. 패킹된 프로그램을 실행해보게되면 먼저 unpacking code 부분이 시작되며 코드가 끝나면 original code로 점프한다고 했습니다. 따라서 origin code의 시작점이 00401000이니 JMP 00401000 명령문을 찾아보게습니다.

나왔습니다. 이에 bp를 걸고 코드를 보기전에 00401000부분에는 현재 무엇이 있는지 보겠습니다.

현재 origin code부분에는 0000의 아무것도 값이 없습니다. 그렇다면 JMP 00401000 명령까지 프로그램을 실행시키고 다시 봐보겠습니다.

이후에는 OEP부분에 origin code가 생성된 것을 확인할 수 있습니다. 이후 계속 실행시켜보면 crackme1.exe와 같은 알림문이 뜨게됩니다.

 

- unpacking memory capture(ollydbg)

unpacking된 실행파일을 만들려면 unpacking된 메모리 상태 그대로 dump를 하면됩니다. 이를 지원하는 ollydbg plugin이 있습니다. 이를 위해 ollyDumpEx를 아래 사이트에서 다운받은 후 ollydbg plugin 파일에 넣어줍니다.

https://low-priority.appspot.com/ollydumpex/

 

OllyDumpEx Plugin

 

low-priority.appspot.com

이후 아까 실행중인 프로그램을 끝까지 실행시켜주시고 왼쪽아래에 "process terminated, exit code 760800F9"가 확인된다면, plugin - ollydumpEx - Dump process 를 실행시켜줍니다.

여기서 모두 기본값으로 세팅하지만 왼쪽 중간에 있는 entrypoint를 변경해줘야합니다. 000071B0에서 원래 entry point엿던 00001000으로 변경하고 오른쪽위에 Dump 버튼을 눌러서 dump 파일을 생성해줍니다.

이후 실행시켜보면 에러파일이 뜰텐데, 이는 프로그램은 dll 파일들을 가져다 쓰는데 이 dll 파일들의 주소가 IAT 테이블안에 있습니다. 하지만 메모리 덤프과정에서 IAT 테이블이 쉽게 손상되기때문에 별도의 복구과정이 필요합니다. IAT 테이블은 DIE의 가져오기 버튼을 누르면 볼 수 있습니다. 아래는 원본의 IAT입니다.

아래는 dump된 파일의 IAT입니다.

이를 맞춰주시위해 LordPE.exe을 다운받아야합니다. 아래사이트에 접속하셔서 다운하시면 됩니다.

https://www.softpedia.com/get/Programming/File-Editors/LordPE.shtml

이제 exe파일을 실행시켜주시면

이렇게 나올텐데 Rebuild PE버튼을 눌러 crackme1_pack_dump파일을 선택해줍니다.

이후 ok버튼을 누르면 적용이 잘 된것이므로 이후 crackme1_pack_dump파일을 실행시켜보도록 하겠습니다.

잘되는 것을 확인하였습니다. unpacking에 중요한 부분은 OEP를 찾아야한다는 것입니다. memory dump를 하기전에 entry point를 변경해줘야하므로 OEP를 찾는 것은 중요합니다. 이를 찾는 방법을 다음시간에 배워보도록 하겠습니다.

Comments