ldd显示共享库在运行时链接的内存地址
$ cat one.c
#include<stdio.h>
int main() {
printf ("%d", 45);
}
$ gcc one.c -o one -O3
$ ldd one
linux-gate.so.1 => (0x00331000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00bc2000)
/lib/ld-linux.so.2 (0x006dc000)
$
从this answer到另一个问题,
......地址基本上是随机数。在设计安全实现之前,ldd将始终指示加载程序段的内存地址。从大约五年前开始,许多版本的Linux现在故意随意加载地址以挫败潜在的病毒编写者等。
我不完全理解这些内存地址如何用于开发。
问题是“如果地址是固定的,那么可以在该地址放置一些不需要的代码,这些代码就像是一个库一样被链接”或者它不仅仅是这个?
答案 0 :(得分:3)
“如果地址是固定的,可以在该地址放置一些不需要的代码,这些代码将被链接,就好像它是一个库”
是
另外。缓冲区溢出漏洞需要一致的内存模型,以便溢出缓冲区的字节对代码的已知部分做了已知的事情。
http://www.corewars.org/这个原则的一个很好的例子。
答案 1 :(得分:3)
某些漏洞允许覆盖某些地址(堆栈溢出允许覆盖返回地址,利用堆溢出通常会覆盖Win32上的SEH指针和Linux上动态调用函数的地址(GOT条目),...)。因此攻击者需要将覆盖的地址指向有趣的东西。为了使这一点变得更加困难,已采取了几项措施:
因此,您必须将加载地址随机化视为许多(几个防御层以及所有这些)中的另一个对策。
另请注意,漏洞利用不限于任意代码执行。获取程序来打印一些敏感信息而不是(或者除了,想到字符串截断错误)一些非敏感信息也被视为漏洞利用;用这种漏洞编写一些概念验证程序并不困难,因为知道绝对地址会使可靠的漏洞成为可能。
你一定要看一下return-into-libc和面向返回的编程。这些技术大量使用可执行文件和库中的地址知识。
最后,我会注意到有两种方法可以随机化库加载地址:
答案 2 :(得分:2)
一个简单的例子:
如果在流行的操作系统上,标准C库总是在地址0x00100000处加载,并且标准C库的最新版本在偏移量0x00000100处具有system
函数,那么如果有人能够利用其中的缺陷在具有此操作系统的计算机上运行的程序(例如Web服务器)导致它将一些数据写入堆栈(通过缓冲区溢出),他们会知道如果他们将0x00100100写入堆栈中的位置很可能当前函数期望其返回地址为,那么它们可以使得当从当前函数返回时将调用system
函数。虽然他们仍然没有完成使system
执行他们想要的东西所需的一切,但他们很接近,并且有一些技巧会将更多东西写入堆栈,而上述地址的可能性很高导致有效字符串指针和强制调用system
运行的命令(或一系列命令)。
通过随机化加载库的地址,攻击者更有可能使Web服务器崩溃,而不是获得对系统的控制权。
答案 3 :(得分:1)
典型的方法是通过缓冲区溢出,将特定地址放在堆栈上,然后返回到它。您通常会在内核中选择一个地址,它假设已经在堆栈上传递的参数已被检查,因此它只是使用它们而无需进一步检查,从而允许您执行通常不允许的操作。 / p>