Wargame/Hacker School FTZ2012. 11. 12. 12:47
Level20
pwd : we are just regular guys
소스코드가 짧습니다.
setreuid가 보이고
fgets를 사용해서 bleh에 입력받습니다.
BOF가 안먹힙니다.
읭??????????????????
printf를 보면 format string을 사용하지 않고 바로 bleh를 입력했습니다.
Format string bug가 먹힙니다.
Format string bug에 대한 개념을 모르시면 다음 글을 읽고 오세요.
-> http://slimv.tistory.com/entry/Format-String-Bug
gdb로 attackme를 열어봅니다.
Disassemble이 안됩니다.
Symbol을 지워버린듯 합니다.
아왜
.dtors라는 부분을 통해 간단히 해결하는 방법도 있지만
저는 .dtors를 모릅니다.
머리가 나쁘면 몸이 고생이라고
몸 좀 고생해 보도록 하겠습니다.
objdump를 이용해 attackme를 dump 뜹니다.
실행되는 code들은 일반적으로 .text section에 있습니다.
main 함수 처음에 변수 bleh를 위해 stack을 할당받을 것을 예측할 수 있습니다.
Assembly를 대충 예상하자면
push %ebp
mov %esp, %ebp
sub $80, %esp
이쯤 될 듯 합니다.
sub에서 $80은 여유공간까지 생각하면 대충 80 근방의 수가 될 듯 합니다.
Stack을 비슷한 크기인 88(0x58)만큼 확보하는 곳을 찾았습니다.
main이 맞는지 확인하기 위해 gdb를 통해 해당 주소를 disassemble 해봅니다.
setreuid도 보이고 fgets도 보이고 printf도 보입니다.
main을 찾았습니다.
bleh에 접근하는 printf의 주소를 찾은 후 ret의 주소를 찾도록 하겠습니다.
printf주변을 찾아봅니다.
0xbffffad0부터 bleh가 시작됩니다.
ret의 주소는 bleh 시작 지점에서 88(sizeof(bleh)) + 4(sfp) 만큼 떨어진 위치에 있습니다.
ret의 주소는 0xbffffb2c입니다.
bleh에 shell code를 집어넣고 format string bug를 이용해
ret를 nop slide로 떨어뜨려줍니다.
Shell code와 nop slide를 합한 크기는 70-byte로 만들겠습니다.
Nop slide 중간쯤에 떨어지도록 0xfad0은 0xfae0로 바꾸겠습니다.
0xfae0은 64224입니다.
앞서 출력할 부분을 빼면 64154이 됩니다.
0xbfff는 49151입니다.
앞서 출력할 부분을 빼면 overflow가 나므로
0x1bfff로 계산합니다.
0x1bfff는 114687입니다.
다시 계산을 하면 50463이 됩니다.
아무것도 안됩니다.
심지어 세그멘테이션 폴트조차도 나지않습니다.
아왜
Stack 내부의 실행주소 저장 공간 때문이라 추측해봅니다.
상대주소보다 절대주소가 당연히 길테니 모든 주소를 16-byte씩 당겨보겠습니다.
ret 주소는 0xbffffb3c로
Shell code의 주소는 0xbffffaf0으로 바꿉니다.
0xfaf0은 64240 입니다.
앞의 출력 부분을 빼면 64170이 됩니다.
0x1bfff는 114687입니다.
앞의 출력 부분을 빼면 50447이 됩니다.
공격해봅니다.
Hacker School FTZ의 마지막 레벨을 통과했습니다.