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

我正在为我的系统安全类编写一个返回libc攻击。 首先,易受攻击的代码:

//vuln.c #include  #include  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 = {} 0x0016db20  (gdb) p exit $3 = {} 0x001639e0  (gdb) x/2000s $esp ... 0xbffff5af: "SHELL=/bin/bash" 

要执行攻击,我想将缓冲区溢出到loadconfig的返回地址(又名$esp+4 ),将其替换为system的返回地址,然后是exit的返回地址(因为system需要一个真实的返回地址),那么命令名称( SHELL=/bin/bash的地址SHELL=/bin/bash加6,修剪SHELL=部分)。 这应该可以通过制作1024个字符的crap的$HOME环境变量,然后是systemexit/bin/bash的little-endian地址来实现。

但是,对于我尝试过的每台计算机, system都会以一个以0x00开头的地址加载,该地址将终止sprintf正在读取的字符串并停止攻击。 有没有办法强制libc加载到内存中的其他位置,还是我误解了攻击?

作为参考,我在VirtualBox(Windows主机)中运行Ubuntu Server 11.10虚拟机, gcc版本为4.6.1, gdb版本为7.3-2011.08。 编辑:ASLR被禁用,我用-fno-stack-protector编译来删除金丝雀。 因为我没有从堆栈中执行任何操作,所以我不需要执行它。

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

sysctl -w kernel.exec-shield = 0

如此处所述

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

我相当肯定这在11.10是不可能的,至少在你提到的方式。 看一看:

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

详细而言,只是选择一些问题:

(1)由于金丝雀值和其他原因,缓冲区溢出到esp + 4会引发分段故障exception

(2)你可能意味着要提取环境变量的地址,传统上它应该是ESP(主)+一定数量的字节。 但是,由于现在甚至逻辑内存地址在编译后都被加扰/随机化,因此您将为每次运行获取$ HOME变量的不同内存地址,可能位于主堆栈另一侧的某处

(3)据我所知,现在还有其他方法可以阻止图书馆攻击的回归。 我对那些不熟悉。 这应该是你看到x00的地址的原因

这些天在ubunti系统上进行黑客攻击很难。 如果您只需要为不支持当前发行版的类执行此操作,请在virtualbox中安装第一个ubunti发行版。 奇怪的是,你所尝试的一切都会奏效。 没有更多的“标准溢出攻击”你也参考 – 即使你巧妙地绕过金丝雀等等,设置nx位也不可能。 同样地,虽然我不太确定如何解决从libc攻击中返回的问题,但不要依赖于相信这在当前的发行版中是可能的。 祝好运!