【发布时间】:2011-10-15 17:47:13
【问题描述】:
我正在为我的系统安全类编写返回 libc 攻击。一、易受攻击的代码:
//vuln.c
#include <stdio.h>
#include <stdlib.h>
int loadconfig(void){
char buf[1024];
sprintf(buf, "%s/.config", getenv("HOME"));
return 0;
}
int main(int argc, char **argv){
loadconfig();
return 0;
}
我想用一个返回libc的攻击。编译和调试程序:
$ gcc -g -fno-stack-protector -o vuln vuln.c
$ gdb vuln
(gdb) break loadconfig
(gdb) run
Reached breakpoint blah blah blah.
(gdb) p $ebp
$1 = (void *) 0xbfffefb0
(gdb) p system
$2 = {<text variable, no debug info>} 0x0016db20 <system>
(gdb) p exit
$3 = {<text variable, no debug info>} 0x001639e0 <exit>
(gdb) x/2000s $esp
...
0xbffff5af: "SHELL=/bin/bash"
为了执行攻击,我想将缓冲区溢出到loadconfig 的返回地址(又名$esp+4),将其替换为system 的返回地址,然后是exit 的返回地址(因为system 需要一个真实的返回地址),然后是命令名称(SHELL=/bin/bash 的地址加 6,以修剪 SHELL= 部分)。这应该可以通过制作一个包含 1024 个废话字符的 $HOME 环境变量,然后是 system、exit 和 /bin/bash 的小端地址来实现。
但是,对于我尝试过的每台计算机,system 都会加载到以 0x00 开头的地址,这将终止 sprintf 正在读取的字符串并停止攻击。有什么方法可以强制libc 加载到内存中的其他位置,还是我误解了攻击?
作为参考,我在 VirtualBox(Windows 主机)中运行 Ubuntu Server 11.10 虚拟机,gcc 版本 4.6.1 和 gdb 版本 7.3-2011.08。编辑:ASLR 被禁用,我用-fno-stack-protector 编译以删除金丝雀。由于我没有从堆栈中执行任何操作,因此我不需要 execstack 它。
【问题讨论】:
-
你可以把代码放到栈上吗?因为您可以稍后在包含执行您的漏洞利用代码的字符串中将返回值放入一个地址(当然要精心设计以避免 0 字节)。
-
对,这是标准的缓冲区溢出攻击。我特别想执行返回 libc 攻击,而不是编写任何 shell 代码。
-
您是否考虑过问题可能是您添加了调试信息?
标签: c buffer-overflow libc exploit