LOB golem->darkknight
by St1tch문제를 보면 strncpy를 이용해서 딱 41바이트만 buf에 저장 시키는 것을 볼 수 있다.
그렇기 때문에 40바이트(buf) + 1바이트를 이용해서 공격을 해야한다.
버퍼의 크기는 40바이트이고 dummy가 없기 때문에 1바이트는 SFP의 최하위바이트를 수정한다.
SFP는 지금 함수가 종료되고 난 후의 ebp값을 가지고 있다. ( 함수 시작할 때, push ebp, mov ebp, esp 이 부분에서 sfp에 ebp가 저장된다.)
함수가 종료될 때 , leave명령어가 있는데, 이 부분에서 ebp에 sfp의 값을 받아온다. (leave명령어는 mov esp, ebp, pop ebp와 기능이 같다.)
따라서 problem_child 함수를 호출하고 복귀 할때, main의 ebp를 바꿀수 있다. 이를 이용해서 풀면 된다.
main함수의 모습. 특별한 것 없이 argc의 값만 검사를하고 problem_child함수를 호출한다.
스택에 40의 크기만큼 할당을 하고, argv[1]의 값을 41만큼 buf에 저장한다.
따라서 buf에 nop, shellcode, ret주소 등을 적절하게 넣고 그 sfp를 수정해 ebp를 buf쪽으로 돌리면 된다.
problem_child 함수 호출 전, main에서의 ebp
problem_child함수에서 strncpy함수 호출 전
sfp의 값이 main에서의 ebp값과 같다.
problem_child함수에서 strncpy함수 호출 후
A를 41개 넣어 줬더니, sfp의 최하위바이트가 '\x41'로 바꼇다.
problem_child 함수 호출 후, main에서의 ebp
ebp의 주소가 bffffc88이여야 하는데, 최하위바이트가 \x41로 바꼇다.
드래그한 부분은 buf의 시작주소로 저기를 기준으로 exploit을 작성했다.
exploit을 짤때 buf의 구조이다.
buf+40에서 sfp의 값을 buf+0주소로 설정을 해놓으면 ret주소(ebp+4)의 값은 내가 buf+4에 입력한 값이된다.
ret주소는 buf+8의 값으로 설정을 하면 main함수가 종료되며 nopslide를 지나 shellcode가 실행이된다.
일부러 segment fault를 만들게해서 core를 분석해 정확한 buf주소를 확인했다.
<exploit code>
./darkknight `python -c 'print "\x90"*4 + "\x6c\xfc\xff\xbf" + "\x90" * 7 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80" + "\x64"'`
블로그의 정보
튜기's blogg(st1tch)
St1tch