ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Lenas Reversing for Newbies] 20
    Wargame/dreamhack.io 2021. 4. 4. 23:03

    이번 실습에서는 기본적인 packer, protector, compressing, unpacking 등의 개념을 배우고, OEP를 찾는 연습을 진행한다. 실습 예제 파일로는 다음과 같은 8가지 실행 파일이 있다.

     

    - UnPackMe_CrypKeySDK5.7.exe

    - UnPackMe_EZIP1.0.exe

    - UnPackMe_eXPressor1.3.0.1Pk.exe

    - UnPackMe_MEW1.1.exe

    - UnPackMe_NsPack3.5.exe

    - UnPackMe_NoNamePacker.d.out.exe

    - UnPackMe_Exe32Pack1.42.exe

    - UnPackMe_Fusion4.0.00.c.exe

     

    강의에서는 OEP를 찾은 후, 그 상태에서 OllyDbg 용 플러그인을 이용해 dump를 뜨고 PE 편집기로 section을 제거하는 작업을 진행한다. 포스팅에서는 OEP를 찾고 dump를 뜨는 과정까지만 진행해보겠다.

     

    1. UnPackMe_CrypKeySDK5.7.exe

    우선 PEiD로 파일을 열어보자.

     

    PEiD

    Nothing found [Overlay] *와 같은 문구가 나타난다. 구글링을 해보니 패커에 대한 정보가 db에 없기 때문이라고 한다. 다른 예제 파일들 모두 UnPackMe_(패커 이름)와 같은 형태로 이름이 지정되어 있어 CrypKeySDK5.7 이라는 패커를 이용했으리라 추측해 볼 수 있다.

     

    파일을 일반 환경에서 더블 클릭하여 실행해보자.

     

    실행 화면

    순전히 unpacking 연습을 위한 파일임을 알 수 있다. (다른 예제 파일들도 위와 유사한 형태의 메시지 박스를 출력한다.) 바로 OllyDbg로 파일을 열어보자.

     

    EP

    위와 같이 코드가 46B6DE 주소에서 시작하는 것을 확인할 수 있다. 무언가 시작 주소가 이상하다. 메모리 맵을 통해 어느 영역에 있는 것인지 확인해 보자.

     

    메모리 맵

    EP가 46B000 영역의 Have 섹션에 속해있는 것을 확인할 수 있다. 위의 EP에서 동그라미 표시한 RETN까지 Step Over(F8) 해보자.

     

    ??

    위 상태에서 Ctrl+A를 이용해 코드들을 Analyze 해보자.

     

    OEP

    위와 같이 OEP(Original Entry Point)가 나타나는 것을 확인할 수 있다. 같이 첨부된 OllyDump.dll 플러그인을 이용해 현재 상태에서 dump를 떠서 dump.exe 파일을 만들어 보자.

     

    크기 비교

    위와 같이 unpack 한 dump 파일의 크기가 기존의 파일보다 줄어든 것을 확인할 수 있다.

     

    2. UnPackMe_EZIP1.0.exe

    PEiD로 파일을 열어보자.

     

    PEiD

    EZIP 1.0이라는 패커를 이용해 실행 압축된 것을 확인할 수 있다. OllyDbg로 파일을 열어보자.

     

    실행 화면

    시작부터 역시 심상치 않다. 메모리 맵을 확인 해보자.

     

    메모리 맵

    위와 같이 특이하게 .text / .rdata / .data 영역이 2개씩 있는 것을 확인할 수 있다. 우선 실행 화면은 두 번째 .text 영역에 나타나는 것을 확인할 수 있다. F8을 눌러 첫 번째 명령어가 가리키는 영역으로 점프해보자.

     

    EP...?

    어떤 함수의 초기 부분으로 스택 프레임이 생성되는 영역으로 점프하였다. packer로 실행 압축된 파일은 실행 전에 적절한 decoding 루틴을 통해 코드를 복원하는 작업이 필요하며, 위 영역이 그 역할을 하는 것으로 추정해볼 수 있다. F7을 눌러 ESP가 변화가 일어난 직후, ESP에 하드웨어 BP를 설정하게 되면 디코딩 루틴이 종료되고 OEP로 점프하기 직전에 BP에 적중하는 것을 확인할 수 있다. 이와 같은 방법은 가장 전형적인 OEP를 찾는 방법이라고 한다. (물론 까다로운 패커는 이와 같은 방법을 적용해서 OEP를 찾도록 내버려두지 않는다.) ESP에 하드웨어 BP를 설정하고 난 후, F9를 누르면 아래와 같은 화면에서 BP에 적중할 것이다.

     

    BP 적중

    F7을 눌러 EAX 레지스터가 가리키는 영역으로 점프하게 되면 아래와 같이 OEP를 확인할 수 있다.

     

    OEP

    똑같이 dump를 떠서 패킹된 파일과 비교해보자.

     

    크기 비교

    1번째 예제와 달리 unpack한 파일의 크기가 증가한 것을 확인할 수 있다. 2번 패커는 파일의 크기를 줄이는 역할을 하는 듯 하다. 반대로 1번 예제는 오히려 실행 압축된 파일의 크기가 증가하는 것을 확인할 수 있는데 이는 리버싱을 어렵게 하기 위해 각종 기술들이 첨가되면서 파일의 크기가 늘어나는 것이라 한다. 이와 같은 패커를 프로텍터라 부르기도 한다.

     

    3. UnPackMe_eXPressor1.3.0.1Pk.exe

    PEiD로 파일을 열어보자.

     

    PEiD

    eXPressor 1.3.0 이라는 패커로 실행 압축된 파일이다. OllyDbg로 파일을 열어보자.

     

    EP

    2번 예제와 마찬가지로 PUSH EBP 명령어를 실행한 후, ESP에 하드웨어 BP를 설정하고 F9를 눌러 파일을 실행해보자.

     

    뜬금 메시지 박스

    위와 같이 실행 도중 eXPressor라는 패커로 패킹되었다는 메시지 박스가 나타난다. 디코딩 과정에서 나타나도록 설정된 듯하다. 확인 버튼을 마저 누르면 아래와 같은 부분에서 BP에 적중한다.

     

    OEP 점프 직전

    역시 EAX 레지스터가 가리키는 곳이 OEP이다. 마찬가지로 dump를 떠서 비교해보자.

     

    크기 비교

    크기가 상당히 늘어난 것을 확인할 수 있다. eXPressor 패커의 압축률이 앞의 두 패커에 비해서는 뛰어난 듯 하다.

     

    4. UnPackMe_MEW1.1.exe

    PEiD로 파일을 열어보자.

     

    PEiD

    MEW 11 1.2라는 패커가 이용되었다. OllyDbg로 파일을 열면 아래와 같다.

     

    EP

    F7을 눌러 UnPackMe.00400154로 점프해보자.

     

    디코딩 루틴...?

    무언가 복잡한 코드가 보인다. 스크롤을 조금 내려보면 아래와 같이 RETN 명령어가 있는 것을 확인할 수 있다.

     

    RETN

    해당 지점에 BP를 설정하고 실행시켜보자. 이후에 F7을 눌러 RETN 명령을 실행시키면 아래와 같은 영역으로 점프한다.

     

    OEP...?

    Ctrl+A를 이용해 Analyze 해보자.

     

    OEP

    그렇다 OEP다. 이제 이전 예제들과 마찬가지로 똑같이 dump를 떠보자.

     

    크기 비교

    MEW 11 1.1 패커도 높은 압축률을 자랑하는 것을 확인할 수 있다.

     

    5. UnPackMe_NsPack3.5.exe

    PEiD로 열어보자.

     

    PEiD

    NSPack 3.x 패커가 이용되었다. OllyDbg로 열어보자.

     

    EP

    이전과는 달라 보이는 명령어로 코드가 시작된다. PUSHFD, PUSHAD 명령어로 시작하므로 OEP에 들어서기 직전에 레지스터 및 플래그 값을 복원하기 위해 POPAD, POPFD 명령어가 나타나리라 예측하고 탐색을 해보았지만 명령어들이 인식되지 않았다. 아마도 디코딩 루틴 과정에서 모든 디코딩이 끝났을 때 해당 명령어들이 드러나는 방식인 듯하다. 어쩔 수 없이 F8을 이용해 트레이싱하다 루프를 만나게 되면 이후 명령어에 BP를 설정하는 방식으로 코드를 트레이싱 하다 보면 다음과 같은 곳에 도달할 수 있다.

     

    OEP...?

    특정 영역으로 점프한다는 점, 점프 명령어가 나오기 직전에 POPAD, POPFD를 통해 레지스터 값을 복원한다는 점에서 OEP로 점프할 것 같다. 점프해보자.

     

    OEP
    OEP + Anaylyze

    OEP를 찾았으니 마찬가지로 dump를 해보자.

     

    크기 비교

     

    6. NoNamePacker.d.out.exe

    PEiD로 파일을 열어보자.

     

    PEiD

    이름처럼 Nothing found * (무슨 패커인지 모르겠다는 말) 문구가 나타난다. OllyDbg로 열어보자.

     

    EP

    이 녀석은 앞선 예제들에 비해 OEP를 찾기가 약간 까다롭다. 일단 F9를 눌러 프로그램을 실행해보자. 일반 실행환경에서와 달리 다음과 같은 메시지 박스가 나타난다.

     

    ???

    exPressor 패커와 같이 친절하게 어떤 패커를 사용했는지 알려주려는 메시지 박스인가 싶지만 확인 버튼을 누르면 그대로 프로그램이 죽어버린다. 이 패커는 안티 디버깅 기법이 적용되어서 디버깅 탐지 루틴에 의해 디버거로 프로그램을 실행했을 때 흐름을 바꾸는 기능도 추가된다. 어쩔 수 없이 F8 + F9(BP) 조합으로 하나씩 트레이싱 해나가야 한다. 열심히 트레이싱하다 보면 다음과 같은 명령어를 확인할 수 있다.

     

    디버깅

    바로 IsDebuggerPresent API를 호출하는 것을 확인할 수 있다. 현재 디버거로 프로세스를 디버깅 중이므로 EAX 레지스터에는 1이 저장될 것이고, 이후의 JE 명령어에 의해 프로그램이 종료하는 방향으로 흐름이 바뀔 것이다. 일단은 API를 실행시키고 JE 명령어 위치에서 Zero flag를 반전시켜 점프가 일어나게 하자.

     

    zero flag 반전

    점프까지 일어나게 한 후, 메모리 맵을 살펴보자.

     

    메모리 맵

    .text 영역에 memory BP를 설정하고 F9를 눌러 실행시켜보자.

     

    BP 적중

    Ctrl+A를 통해 Anaylyze를 하게 되면 아래와 같이 OEP임을 확인할 수 있다.

     

    OEP

    dump를 떠보자.

     

    크기 비교

    직전의 몇몇 패커보다는 압축률이 살짝 떨어진다.

     

    7. Exe32Pack1.42.exe

    PEiD로 파일을 열어보자.

     

    PEiD

    EXE32Pack 1.3x 패커가 이용되었다. OllyDbg로 파일을 열어보자. 사실 해당 예제에도 디버거 탐지 루틴이 적용되어 있다. 일일이 트레이싱하여 찾아낼 수 있겠지만, 강의에서 첨부된 OllyDbg의 디버거 탐지 우회 플러그인을 적용하면 정상적인 디버깅이 가능하다. 7, 8번 예제에는 첨부된 플러그인들을 이용해 디버거 탐지 부분은 제외하고 OEP를 찾아보겠다.

     

    EP

    시작 코드가 심상치 않다. 하지만 두 번 Step in(F7) 해보면 다음과 같은 코드가 나타난다.

     

    EP

    PUSH EBP 명령어가 실행되면 ESP가 변화할 것이다. 이전에 했던 일반적인 방법(ESP에 하드웨어 BP 설정)을 적용한 후, F9로 실행해보자.

     

    BP 적중

    이전과는 다르게 이상한 명령어에서 BP에 적중한다. 당황하지 말고 step in 해보자.

     

    OEP...?

    OEP로 점프할 것 같은 냄새가 난다. 바로 점프해보자.

     

    OEP

    해당 부분에서 바로 dump를 떠주면 된다. 그런데 이번 예제에서 dump를 뜰 때 옵션에서 Rebuild Import 부분을 체크 해제해주어야 한다고 한다. (왜 그런지는 잘 모르겠으나 체크가 되어 있을 경우 dump 된 파일이 정상적으로 실행되지 않는다. 그 이유는 이후 실습에서 다룬다고 한다.) dump를 떠서 크기를 비교하면 다음과 같다.

     

    크기 비교

     

    8. UnPackMe_Fusion4.0.00.c.exe

    PEiD로 파일을 열어보자.

     

    PEiD

    Crunch 5.0.0 이라는 패커가 이용되었다. OllyDbg로 파일을 열어보자.

     

    EP

    Step in(F7) 해보자.

     

    디버깅

    위와 같이 바로 PUSH EBP 명령어가 나타난다. 처음에는 해당 명령어가 실행된 직후의 ESP에 하드웨어 BP를 설정해보았지만 OEP를 찾을 수 없었다. 동그라미 친 부분에 PUSH EBP 이후에 PUSHAD, PUSHFD 명령어가 나타나므로 본격적인 디코딩 루틴이 시작되는 부분이라는 것을 짐작할 수 있다. 0046B026 주소의 PUSH EBP가 수행된 직후 ESP에 하드웨어 BP를 설정하고 F9를 눌러 실행해보자.

     

    BP 적중

    위와 같이 RETN 명령문에서 BP에 적중한다. F7을 눌러 Step in 해보자.

     

    OEP

    위와 같이 OEP가 나타난다. 이번에도 dump를 뜨는데 Rebuild Import를 체크 해제한 후 해야 한다.

     

    크기 비교

     

    9. Comment

    다양한 형태의 패커로 실행 압축된 파일의 OEP를 찾아보는 연습을 했다. 리버싱 핵심원리에서 배웠던 PUSHAD / POPAD 명령어의 쌍을 찾는 형태로는 OEP를 찾을 수 없었다. 아마도 너무 쉬운 방법이기도 하고 디코딩 과정 중에 POPAD가 드러나는 형태로 패킹되었기 때문인 듯하다. 또한 이번 실습을 통해 안티 디버깅과 패커의 조합이 상당히 리버스 엔지니어링 하기 까다롭게 만든다는 점을 알 수 있었다.

     

     

     

     

     

    반응형

    'Wargame > dreamhack.io' 카테고리의 다른 글

    [Lenas Reversing for Newbies] 22  (0) 2021.04.13
    [Lenas Reversing for Newbies] 21  (0) 2021.04.11
    [Lenas Reversing for Newbies] 19  (0) 2021.04.01
    [Lenas Reversing for Newbies] 18  (0) 2021.03.29
    [Lenas Reversing for Newbies] 17  (0) 2021.03.14

    댓글

Designed by Tistory.