我正在x86_64 Macbook Pro上运行Debian wheezy。
我有以下不安全程序:
#include <stdlib.h>
#include <stdio.h>
CanNeverExecute()
{
printf("I can never execute\n");
exit(0);
}
GetInput()
{
char buffer[512];
gets(buffer);
puts(buffer);
}
main()
{
GetInput();
return 0;
}
我用
-z execstack
和-fno-stack-protector
进行了编译以进行测试。我已经能够通过gdb启动程序,获取
CanNeverExecute
函数的地址,而该函数从未调用,并溢出缓冲区以用该地址替换返回地址。我打印了“我永远也不会执行”,到目前为止,一切都很好。现在,我正在尝试通过在堆栈中引入shellcode来利用此缓冲区溢出。我目前正在直接尝试进入gdb:中断
GetInput
函数,通过gdb设置缓冲区值,并使用jump
命令跳转到缓冲区地址。获取功能后,我刚好有一个断点,我用512个a
字符作为输入运行了程序。在gdb中,我这样做了:(gdb) p buffer
= 'a' <repeats 512 times>
读取输入没有任何问题,我的缓冲区是512
a
然后尝试修改其值。如果执行此操作:
(gdb) set var buffer=""
并尝试打印缓冲区,其长度现在为511!为什么会出现?
(gdb) p buffer
= 'Too many array elements
0' <repeats 511 times>et:
当我尝试将其设置回512
a
时,我得到:q4312078q
我可以将其设置为511
a
,实际上是LAS字节不起作用...怎么来,有一个简单的解释吗?#1 楼
GDB保护您溢出char数组。(gdb) p &buffer
= (char (*)[512]) 0x7fffffffdfe0
要绕过此安全性,您可以直接写内存:作为更大的一个,然后设置您的东西:
(gdb) set 0x7fffffffe1e0=0x41414141
评论
谢谢,但是我不是想用513 A而是只用512写……还是最后一个字符必须是\ x00?
–NoéMalzieu
2013年6月9日在16:22
哦,抱歉,这是一个错字。是的,当然,最后一个字符必须是一个空字节,而且GDB尝试为您追加它。给定数组定义,这就是为什么编写511“ a”而不是512的原因。
– dna
2013年6月9日在16:28
好,多谢!最后一个问题:这是否意味着在C中,如果我创建char buffer [512] ;,那么我也只能填充511个char?
–NoéMalzieu
2013年6月9日在16:34
您可以随意用512个字符填充512个字符。但是在GDB中,当使用命令set buffer =“ A”时,您将用字符串填充它,从而使用最终的空字节终止符。
– dna
2013年6月9日在16:47
完全有道理
–NoéMalzieu
2013年6月9日17:05