在这篇文章中,我会谈谈如何绕过ASLR
和NX
缓解技术。如果你从来没有接触过这两个概念的话,可以参见维基百科上对ASLR 和NX的解释。
ASLR
: 地址空间布局随机化:一种通过使得内存空间地址随机化从而防止利用内存的缓解技术。当我们遇到基本的缓冲区溢出时,需要控制EIP
重定向到我们的shellcode
,但是使用这个措施后,很难预测到缓冲区的开始位置。并且,在堆、栈地址中都使用了ASLR
缓解措施。
NX
: 不可执行, 另一种缓解措施,以防止内存执行任何机器代码(shellcode)。正如我们在基本缓冲区溢出中看到的那样,将shellcode
放入堆栈中并将EIP
重定向到缓冲区开始执行,但是开启NX
后,就无效了。 但是,可以通过Ret2libc
技术绕过NX
。 通过文件内部或者 共享库,寻找gadgets,然后组合在一起,以此来绕过NX
,也称为 ROP-- 返回导向编程
,我会在另一篇文章中谈论这个话题。
在我们了解了 ASLR
和 NX
的基本信息后,来看下如何绕过。有许多方法绕过ASLR
,比如说Ret2PLT
使用了 过程链接表(Procedural Linkage Table ),表中包含全局函数的存根(stub)代码。.text
段中的call
指令并不直接调用函数,而是先调用位于PLT表中的存根函数(func@PLT),使用 Ret2PLT
的原因就在于 在执行前它的地址并没有被随机化。 另一种技术是覆盖GOT
表,当只有2个或者3个字节随机化的时候,暴力破解出来。
在这篇文章中,我将解释一下Ret2plt
和一些ROP gadgets
和Ret2libc
这些技术,首先来看Ret2PLT
:
有漏洞的代码:
用下面的选项编译:
检查一下系统是否开启了ASLR
:
正如上面图片中所显示的,libc 的地址被随机化,但是可以被爆破出来。
现在用gdb打开文件:
可以看到程序已经开启了NX
选项,通过pattern 字符串确定一下溢出的准确位置:
通过下面的命令,找到偏移地址:
1028个字节就可以覆盖到EBP,再加4个字节,控制EIP后就可以跳转到想要的位置。
现在可以看到我们已经控制了EIP,在这之后我们要想办法绕过ASLR
+ NX
,首先找到PLT表函数:
在这里,我们看到了strcpy
和system plt
两个函数,然后根据下面的方法来编写利用。
我们需要先找到文件中可写的节,然后像在传统的Ret2libc方法中那样调用system
。
首先在考虑下.bss段,编译器和链接器在数据段中用这部分来存放未初始化的静态分配变量。
之后,我们将使用strcpy
在.bss
段中写入字符串,但是地址是什么呢?
我们需要在plt
表中,找到strcpy
函数,复制字符串,然后通过调用system
函数执行命令。但是在这之前,先要找到/bin/sh
字符串。
现在我们得到了字符串的地址,把所有找到的部分组合起来。
1- 使用strcpy
函数,将字符串从源端复制到目的端,复制到可写的.bss
段。我们需要把strcpy
函数和system
函数连接起来,在这儿我们要找一些gadgets-- pop pop ret
。
我们选择了0x080484ba
这个地址,具体弹出哪个寄存器不是重点,关键在于两次的 pop操作。
2- 我们使用 system
函数,写入字符串,就和Ret2libc
所做的一样。在这里的话,/bin/sh
字符串的地址就是 .bss
段的 地址。
strcpy + ppr + .bss + s
strcpy + ppr + .bss + 1 + h
system + dump+ .bss
最终,我们获得了shell 权限! 在大多数情况下,你需要结合多种技术来绕过一系列的缓解技术。
原文链接
编译:看雪翻译小组 fyb波
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2019-2-1 13:20
被kanxue编辑
,原因: