1. 문제
1) 문제확인
실행시키면 왼쪽 그림이 나오고 확인 누르면 왼쪽 그림처럼 파일을 찾을 수 없다고 뜸
- upx 언패킹 ㄱㄱ
근데 언패킹하고 다시 실행시켜보면 알 수 없는 문자가 나온다.
2. 접근방법
언패킹된 pe파일을 올리고 실행시키면 EP부터 nop sled마냥 nop이 연속적으로 나오고 MessageBoxA()를 호출하는데 MessageBoxA()의 인자 값에 아무 것도 안들어가서 알 수 없는 문자가 뜬 것 같다.
이후에 실행되는 로직을 살펴보면 딱히 별 거 없다. 문제의 요점은 Stolen Byte를 찾는 것이다. 언패킹되면서 MessageBoxA()의 인자로 들어가는 특정 코드가 다른 곳으로 옮겨진 듯하다. 따라서, 패킹된 pe파일을 확인하여 찾아보자
3. 문제풀이
일단 언패킹된 pe파일에는 패킹되었을 때 나온 문자열은 보이지만 참조되는 곳은 보이질 않는다.
그럼 이제 패킹된 pe파일을 디버깅해보자
0x40100c로 점프하기 직전에 스택에 0x402000, 0x402012를 push해주는데 해당 주소 값에는 메시지 박스에 출력되는 제목과 내용의 문자열이 담겨져 있다.
0x40100c로 점프하게 되면 MessageBoxA()의 인자로 들어가는 값들이 스택에 들어있으므로 깨지지 않고 잘 출력된다. 이 부분을 통해서 인자로 push하는 인스트럭션이 stolen byte임을 짐작할 수 있다.
따라서, 이제 해야할 일은 MessageBoxA()의 인자에 알맞게 들어가기 위해 OEP를 0x401000으로 변경하고 0x401000부터 6A 00 68 00 20 40 00 68 12 20 40 00
값을 채워주는 일이다. 사실 위에 12byte가 문제의 Stolen byte로 플래그 값이긴 하지만 다른 롸업을 보면서 x32dbg
환경에서 Scylla
플러그인을 이용하여 패치하는 방법이 있어 이 작업을 진행하도록 하겠다.
0x401000를 덤프로 따라간 다음에 nop으로 되어있는 부분만큼 블록하고 [Ctrl + e]
를 눌러 편집 창을 띄운다.
그리고 앞서 말했던 byte들로 편집한다.
[Ctrl + I]
를 누르거나 상단 탭에 플러그인에서 Scylla x86
을 찾아 창을 띄운다.
OEP
에 기존에 있었던 0x40100C
를 0x401000
으로 변경 후 IAT Autosearch
버튼을 누른다. 그러면 밑에 VA
와 Size
가 자동으로 잡힌다.
그리고 바로 옆에 Get Imports
버튼을 누르면 위에 Import된 dll들이 뜬다. 이후에 마지막으로 오른쪽에 Dump를 눌러 덤프 파일을 생성한다.
그리고 마지막으로 Fix Dump버튼을 누르면 위에 사진처럼 창이 뜨는데 방금 생성한 덤프 파일을 클릭한다.
그러면 09_dump_SCY.exe파일이 생성되는데 이거를 x32dbg에 올려보면
정상적으로 코드패치가 된 것을 알 수 있다. 그리고 정상적으로 MessageBoxA()가 호출된다.
Scylla를 이용하여 덤프 뜨면 자동으로 UPX unpacking도 해주는 것 같다.
4. 몰랐던 개념
- Stolen Byte
- 올바른 위치에 있던 코드를 훔쳐서 다른 곳으로 옮겨둔 Byte
- 프로그램 일부 byte(stolen byte)를 별도의 영역에서 실행되게 하여 OEP를 다른 위치에 저장
- stolen byte를 복구하지 못 한다면 덤프된 실행파일은 작동x
- tool을 이용해 자동으로 unpacking 하는 것을 방해하기 위한 것
- 덤프를 쉽게 하지 x
- Scylla
Uploaded by Notion2Tistory v1.1.0