我正在尝试使用以下C程序来理解缓冲区溢出攻击
#include"stdio.h"
#include"string.h"
void iwontprint()
{
printf("i wont be printed!");
}
void callme()
{
char buffer[8];
gets(buffer);
puts(buffer);
}
int main(int argc,int** argv)
{
callme();
return 0;
}
在调用
gets(buffer)
之前在GDB中加载该程序将获得以下ESP值:0xbffff4d4: 0xb7ff0590 0x080484db 0xb7fc1ff4 0xbffff4e8
0xbffff4e4: 0x080484b6 0xbffff568 0xb7e79e46 0x00000001
在输入输入
123456789abc\x7c\x84\x04\x08
后,我在ESP中得到的值完全不同:0xbffff4d4: 0xbffff4d8 0x34333231 0x38373635 0x63626139
0xbffff4e4: 0x6337785c 0x3438785c 0x3430785c 0x3830785c
我已经设置了
randomize_va_space = 0
$cat /proc/sys/kernel/randomize_va_space
0
任何人都可以提供关于我在这里缺少什么的任何指针吗?
#1 楼
您的堆栈完全没问题。仔细看一下这些值:0x34333231 0x38373635 0x63626139 0x6337785c 0x3438785c 0x3430785c 0x3830785c
解释为ascii字符串的值变成了这个。从字面上看:
123456789abc\x7c\x84\x04\x08
如您所见,这正是您输入的内容。我的意思是,例如
\x7c
是字符串"\x7c"
而不是"|"
。使用此技术可以正确发送值:echo -e "123456789abc\x7c\x84\x04\x08" | ./yourbinary
评论
感谢您的答复。但是我不明白为什么那里是0x63626139而不是0x0804847c(我在little endian中作为输入输入)。
–新手用户
13年4月9日在10:07
AFAIK,0xbffff4d8和0x34333231用于char缓冲区[8],而0x38373635应该用于EBP值(旧)。那么下一个值应该是我输入的值(超过12个字节)?
–新手用户
13年4月9日在10:09
不。您没有输入0x0804847c。您输入了0x3830785c,即:0x5c == \,0x78 == x,0x30 == 0,0x38 == 8,即\ x08作为字符串。不是字节值0x08。
– Samuirai
2013年4月9日10:17
实际上,除非您指定-e开关,否则echo也不会解释\ x转义。
–0xea
13年4月9日在10:26
仅在Linux上。 BSD版本不知道此选项(unix.com/man-page/FreeBSD/1/echo)
– Samuirai
13年4月9日在10:28
#2 楼
武士的答案是正确的,但更明确地说,您的错误是您输入了文字字符串123456789abc\x7c\x84\x04\x08
其中您可能想要的是:
perl -e 'print "123456789abc\x7c\x84\x04\x08"' | ./yourbinary
在第一种情况下,
\x7c\x84\x04\x08
只是一个16个字符长的字符串,在第二种情况下,\x
的转义序列被实际解释,而\x7c\x84\x04\x08
仅被打印为4个字节。
评论
尽管非常有趣,但我还是不喜欢它,但投票关闭