如何在 ASLR 打开时查找未导入的 libc 函数的地址?

How to find the address of a not imported libc function when ASLR is on?

我有一个 32 位的 elf 程序,我必须远程利用它(用于学术目的)。 最终目标是生成 shell。我有一个堆栈,可以用我想要的任何数据填充,我可以滥用其中一个 printf 格式字符串。唯一的问题是 system/execv/execvp 没有导入。 .got.plt 段充满了不是很有用的函数,我想用 system 替换 atoi 因为它们的签名非常相似并且代码流表明那是替换的正确功能。对于以下尝试,我使用了 IDA 远程调试,因此堆栈对齐错误和格式字符串不正确是不可能的。我想确保它是可行的,但显然对我来说还不行。

起初我试图用系统未随机化的地址替换atoi@.got.plt。收到 SIGSEGV。

好吧,可能是 ASLR 的问题,我们试试别的吧。我加载了 gdb 并查找了 system@0xb7deeda0atoi@0xb7de1250。然后我计算了差异,即 0xDB50。所以下次当我在 .got.plt 段中将 atoi 的地址更改为 system 时,我实际上只是将 diff 添加到该值以获得 system 的地址。再次获得 SIGSEGV。

我的逻辑:

0xb7deeda0 <__libc_system>
0xb7de1250 <atoi>
diff = 0xb7deeda0 - 0xb7de1250
system@.got.plt = atoi@.got.plt + diff
example: 0x08048726 + DB50 = 0x08056276

任何人都可以告诉我我做错了什么以及如何借助从 .got.plt 泄漏的函数地址跳转到 "valid system()"?

回答我自己的问题。测量你的函数之间的距离 l̲o̲c̲a̲l̲ libc 不保证 r̲e̲m̲o̲t̲e̲ libc 具有相同的对齐方式。 你必须以某种方式找到 libc 版本,然后你可以像这样获得地址差异:

readelf -s /lib32/libc-2.19.so | grep printf

如果您知道两个地址,查找 libc 版本的可能方法: