C语言 写一个返回到libc攻击,但是libc在内存中是在0x00加载的



我正在为我的系统安全类编写一个return to 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;
}

我想使用回血攻击。编译和调试程序:

$ 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环境变量,然后是systemexit/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

将重要的libc函数映射到包含NULL字节的地址的行为称为ASCII装甲。这种保护是RedHat Exec-shield的一部分,目前在最近的ubuntu发行版中已启用link要禁用它,你必须以root用户运行:

sysctl -w kernel.exe -shield=0

顺便说一下,您可以在exploit-db

上找到关于如何绕过ASCII装甲的有趣材料。

我相当肯定这在11.10上是不可能的,至少在您提到的方面是不可能的。看一下:

https://wiki.ubuntu.com/Security/Features

详细说明,并挑选一些问题与您的想法:

(1)由于金丝雀值和其他原因,缓冲区溢出到esp+4将引发分割错误异常

(2)可能意味着提取环境变量的地址,传统上是在ESP (main) +一定数量的字节。然而,由于现在即使是逻辑内存地址在编译后也会被打乱/随机化,因此每次运行都会为$HOME变量获得不同的内存地址,可能在主堆栈的另一侧

(3)据我所知,现在还有其他方法可以阻止图书馆攻击的返回。我对这些不太熟悉。这应该就是为什么地址

看到x00的原因

现在在ubuntu系统上进行黑客攻击是很困难的。如果你只是需要为一个不坚持当前发行版的类做这个,那么在virtualbox中安装第一个ubuntu发行版。神奇的是,你所做的一切都会成功。没有更多的"标准溢出攻击",你也引用-即使你聪明地绕过金丝雀值等,设置nx位使这是不可能的。同样,虽然我不太确定libc攻击的返回是如何解决的,但不要依赖于相信这在当前的发行版上是可能的。好运!

最新更新