
OEP를 구하라고 하네요 :D
일단 Ollydbg로 올려봅시다!

올려보니 PUSHAD가 존재합니다! 패킹이 되어 있다는 소리인데..
이번에는 패킹을 디버깅으로 풀어보도록 하겠습니다 :D
먼저 PUSHAD는 무엇이냐!
8개의 레지스터를 스택에 쌓아줍니다!
(EAX -> ECX -> EDX -> EBX -> ESP -> EBP -> ESI -> EDI)
그리고 PUSHAD가 존재하면 마지막엔 반드시 POPAD가 존재한다는거 있지마세요 :D

자 위의 레지스터를 잘 주목해보세요!

지금 보이시나요?
레지스터가 들고 있던 값들이 전부 스택에 쌓아졌습니다!

1020C41 주소에서 ESI에 들어가는 주소인 101A000을 보면
Packing된 내용들이 들어가 있습니다!

1020C4C에 보면
EDI값을 스택에 쌓는데 보면 아무런 값이 없습니다 !
앞으로 이공간에 복호화된 값이 들어가게 될것입니다 ㅎㅎㅎ
자 그럼 트레이싱 기능을 이용해서 계속 분석해보도록 하다보면..

이렇게 복호화된 값들이 들어가게 됩니다!

그러다 LodaLibraryA를 통해서 Kernel32.dll을 로드합니다.
이것이 의미하는 바는 그 안에 존재하는 함수를 사용하겠다는 의미입니다.
그럼 한번 IAT를 살펴보도록 합시다!

IAT에 보니 API가 현저히 보족한거 보이실겁니다 !
즉, LodaLibraryA로 Kernel32.dll을 로드하는 이유는 GetProcAddress를 이용해서 복구하기 위해서였네요 :D

이렇게 복구하는 루틴입니다!
EDI가 가지는 값을 한번 살펴볼까요 :D

보니 API의 이름을 확인할 수 있네요!
API 이름 목록을 인자로 받아 GetProcAddress를 호출하고 해당 인자를 EAX에 저장합니다.
101F008부터 EAX의 값을 저장하면서 Kernel32.dll의 IAT를 복구하고 다른 IAT도 모두 복구시킵니다!

이렇게 복구가 되면 VirtualProtect 함수를 만나게 되고 실행권한을 부여합니다!

그리고 처음에 말했듯이 PUSHAD가 존재하면 POPAD도 존재한다고 했었죠 ㅎㅎㅎ?
이렇게 POPAD를 만나면 Unpacking이 마무리된 단계입니다 :D
그리고 ESP 값을 원래대로 되돌려 줍니다!

그리고 JMP를 통해서 OEP로 가게됩니다!

그래서 정답은 1012475입니다 :D
사실상 UPX로 언패킹하면 쉽게할 수 있지만 한번쯤은 이렇게 알아보는것도 공부가 될거라 생각합니다!
여기서 꿀팁!
POPAD를 바로찾아가는 방법도 있습니다만..
또 다른문제에서 패킹문제가 존재한다면 그 방법을 통해서 분석하도록 하겠습니다!
그럼 8번 문제 풀이를 마치겠습니다 :D
'CTF > CodeEngn.kr' 카테고리의 다른 글
Basic RCE L10 (0) | 2020.02.23 |
---|---|
Basic RCE L09 (0) | 2020.02.15 |
Basic RCE L07 (0) | 2020.02.13 |
Basic RCE L06 (0) | 2020.02.12 |
Basic RCE L05 (0) | 2020.02.10 |