我正在为我的系统安全课程编写返回 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
(since system
期望一个真实的返回地址),然后是命令名称(SHELL=/bin/bash
加 6,修剪SHELL=
部分)。这应该可以通过制作一个$HOME
1024 个字符的环境变量,然后是小端地址system
, exit
, and /bin/bash
.
然而,对于我尝试过的每台计算机,system
被加载到以 0x00 开头的地址,这将以 null 终止字符串sprintf
正在阅读并停止攻击。有什么办法可以强制libc
加载到内存中的其他位置,还是我误解了攻击?
作为参考,我在 VirtualBox(Windows 主机)中运行 Ubuntu Server 11.10 虚拟机,其中gcc
版本 4.6.1 和gdb
版本7.3-2011.08。编辑:ASLR被禁用,我编译了-fno-stack-protector
删除金丝雀。由于我没有从堆栈中执行任何内容,所以我不需要execstack
it.