[코드엔진] Basic RCE L11 풀이

비얌·2022년 3월 17일
0

어셈블리 게임

목록 보기
9/15
post-thumbnail

코드엔진 Basic RCE L11 문제를 풀어보았다.

문제는 다음과 같다.


파일을 DIE에 올려보니 UPX로 패킹되어있다고 뜬다.


UPX로 언패킹해준다.


언패킹된 파일을 다시 DIE에 올려보았다. 패커가 감지되지 않는 걸로 보아 제대로 언패킹된 것을 알 수 있다. 여기에는 OEP가 0x400600라고 나오는데, 이게 맞는 값인지 검증해보자.


PE버튼을 눌러서 들어가보았다. 진입 지점은 ImageBase + AddressOfEntryPoint이라서 401000이 되어야 한다.

하지만, 진입 지점이 400600으로 나오는 것으로 보아 무언가 오류가 있어 잘못 나온 것으로 보인다. 그래서 OEP는 401000이라고 짐작할 수 있다.

(하이라이트를 잘못쳤는데, BaseOfCode가 아니라 AddressOfEntryPoint를 강조하려고 했다.)


1. StolenByte 찾기

이제 StolenByte를 찾아보자.

StolenByte란?

  • 안티디버깅 기법 중 하나이다.
  • OEP 주소의 코드를 따로 분리해서 OEP로 점프하기 직전에 push로 넘겨준다.
  • OEP의 옵코드 일부가 JMP 직전에 있어서 OEP로 코드 조각이 오지 못했고, 이 경우 StolenByte라는 옵코드를 찾아 실행코드 부분에 복원해준 다음 언팩을 해주어야 정상 실행이 가능하게 된다.

StolenByte를 찾기 위해 x64dbg에서 OEP로 점프하는 부분을 찾아서 그 직전에 push하는 부분을 살펴보기로 하자.


PUSHAD 명령어를 한 줄 실행시켜 레지스터들을 스택에 저장시킨다.


그리고 PUSHAD 후에 ESP값에 접근하는 지점에 BP를 설정한다.


F9로 실행시켜보면, 실행하다가 POPAD 아래에서 멈추는 것을 알 수 있다. 아래의 JMP 40100C가 OEP이고, 0x40736E부터 3줄이 StolenByte일 것이다.

💻 MessageBoxA 💻

파일이 언패킹 된 상태일 때, MessageBoxA에 인자가 하나만 들어간 걸 볼 수 있지만 원래 인자가 4개 들어가야 한다. 따라서 사라진 3개의 인자가 push되어야 하고, 결국 StolenByte는 3줄이다.


push된 문자열을 보면 실행파일의 깨진 문자 대신 들어올 정상적인 문자열인 것을 알 수 있다.


2. OEP 구하기

이제 StolenByte를 써서 정상적인 파일이 됐다고 가정했을 때의 OEP를 구해보자.

StolenByte는 MessageBoxA의 인자로 들어가므로 MessageBoxA가 call되는 0x40100C 윗부분의 nop부분에 들어간다.


nop 부분을 드래그해서 Ctrl + E를 눌러 코드 편집창을 연 후, StolenByte의 Hex값을 모두 써준다.


그러면 OEP가 0x401000인 파일이 완성된다!



따라서 OEP는 00401000이고, StolenByte는 기계어 6A00 6800204000 6812204000를 합쳐서 6A0068002040006812204000이 된다. OEP와 StolenByte를 합치면 004010006A0068002040006812204000이고, 정답이다!
profile
🐹강화하고 싶은 기억을 기록하고 공유하자🐹

0개의 댓글