编写一个返回libc攻击,但libc在内存中加载到0x00

sto*_*umb 4 c exploit libc buffer-overflow

我正在为我的系统安全类编写一个返回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;
}
Run Code Online (Sandbox Code Playgroud)

我想使用返回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"
Run Code Online (Sandbox Code Playgroud)

为了执行攻击,我想将缓冲区溢出到loadconfig's返回地址(又名$esp+4),将其替换为返回地址system,然后返回地址exit(因为system需要一个真实的返回地址),然后是命令名(地址)SHELL=/bin/bash加6,修剪SHELL=部分).这应该是可以通过精心制作$HOME的废话1024个字符,环境变量那么的小端地址system,exit/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它.

Fab*_*zzi 5

将重要的libc函数映射到包含NULL字节的地址的行为称为ASCII装甲.这个保护是RedHat Exec-shield的一部分,目前在最近的ubuntu发行版链接上启用了 要禁用它,你必须以root身份运行:

sysctl -w kernel.exec-shield = 0

为解释在这里

顺便说一下,你可以在exploit-db上找到有关如何绕过ASCII装甲的有趣资料