尝试缓冲区溢出以覆盖堆栈上的返回地址以用于以下程序。我想在两个strcmp()
的情况下调用acceptvoid accept()
{
printf ("\nAccess Granted!\n");
return;
}
void deny()
{
printf ("\nAccess Denied!\n");
return;
}
int main()
{
char pwd[16]={0};
printf ("Enter Password: ");
gets (pwd);
if(strcmp(pwd, "pwd1"))
deny ();
else
accept ();
return 0;
}
在拆解main时,可以理解为0x080484fb <+14>: sub $0x14,%esp
中的变量分配20个字节
函数main的汇编代码转储:
0x080484ed <+0>: lea 0x4(%esp),%ecx
0x080484f1 <+4>: and $0xfffffff0,%esp
0x080484f4 <+7>: pushl -0x4(%ecx)
0x080484f7 <+10>: push %ebp
0x080484f8 <+11>: mov %esp,%ebp
0x080484fa <+13>: push %ecx
0x080484fb <+14>: sub $0x14,%esp
0x080484fe <+17>: movl $0x0,-0x18(%ebp)
0x08048505 <+24>: movl $0x0,-0x14(%ebp)
0x0804850c <+31>: movl $0x0,-0x10(%ebp)
0x08048513 <+38>: movl $0x0,-0xc(%ebp)
0x0804851a <+45>: sub $0xc,%esp
0x0804851d <+48>: push $0x8048611
0x08048522 <+53>: call 0x8048370 <printf@plt>
0x08048527 <+58>: add $0x10,%esp
0x0804852a <+61>: sub $0xc,%esp
0x0804852d <+64>: lea -0x18(%ebp),%eax
0x08048530 <+67>: push %eax
0x08048531 <+68>: call 0x8048380 <gets@plt>
0x08048536 <+73>: add $0x10,%esp
0x08048539 <+76>: sub $0x8,%esp
0x0804853c <+79>: push $0x8048622
0x08048541 <+84>: lea -0x18(%ebp),%eax
0x08048544 <+87>: push %eax
0x08048545 <+88>: call 0x8048360 <strcmp@plt>
0x0804854a <+93>: add $0x10,%esp
0x0804854d <+96>: test %eax,%eax
0x0804854f <+98>: je 0x8048558 <main+107>
0x08048551 <+100>: call 0x80484d4 <deny>
0x08048556 <+105>: jmp 0x804855d <main+112>
0x08048558 <+107>: call 0x80484bb <accept>
0x0804855d <+112>: mov $0x0,%eax
0x08048562 <+117>: mov -0x4(%ebp),%ecx
0x08048565 <+120>: leave
0x08048566 <+121>: lea -0x4(%ecx),%esp
0x08048569 <+124>: ret
当我尝试用输入字符串AAAAA模糊时...我发现缓冲区上的覆盖是部分
Backtrace stopped: Cannot access memory at address 0x41413d
(gdb) R
The program being debugged has been started already.
Start it from the beginning? (y or n) Y
Starting program: BufferOverflow.x
\Enter Password: AAAAAAAAAAAAAAAAAAAAAAAA
Access Denied!
Program received signal SIGSEGV, Segmentation fault.
0x08048569 in main ()
(gdb) BT
#0 0x08048569 in main ()
Backtrace stopped: Cannot access memory at address 0x4141413d
(gdb) R
The program being debugged has been started already.
Start it from the beginning? (y or n) Y
Starting program: BufferOverflow.x
Enter Password: AAAAAAAAAAAAAAAAAAAAAAAAA
Access Denied!
Program received signal SIGSEGV, Segmentation fault.
0x08048569 in main ()
(gdb) BT
#0 0x08048569 in main ()
Backtrace stopped: Cannot access memory at address 0x4141413d
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: BufferOverflow.x
Enter Password: AAAAAAAAAAAAAAAAAAAAAAAAAA
Access Denied!
Program received signal SIGSEGV, Segmentation fault.
0x08048569 in main ()
(gdb) bt
#0 0x08048569 in main ()
Backtrace stopped: Cannot access memory at address 0x4141413d
如果仔细观察,返回地址不会完全溢出,但部分为0x4141413d
,如果注意地址始终以3d
结尾,即使是100 A
s - 返回地址相同0x4141413d
我在开始之前禁用了
cat /proc/sys/kernel/randomize_va_space
0
编译为:
gcc BufferOverflow.c -o BufferOverflow.x -m32 -fno-stack-protector
使用gcc
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
任何帮助确定缓冲区未正确溢出的原因将不胜感激。
由于
答案 0 :(得分:0)
因为缓冲区溢出导致未定义的行为,所以很难说没有查看gets()函数的内部结构导致这种情况的原因。
很可能是一些指针内部的get()被操纵并导致这种损坏。另请注意“?”通常用于表示ASCII中不可打印的字符。这可能与您看到的行为有关,但我找不到任何描述此类行为的文档gets()
答案 1 :(得分:0)
只是有同样的问题,并最终找到答案here。简而言之,您需要将易受攻击的调用包装在另一个函数中,然后在main()中调用该函数。