返回libc查找指针

12

我需要为一个软件安全课程制作一个简单的回归libc攻击。我成功地编写了一个perl脚本,只要给出正确的system()、exit()和/bin/sh字符串指针,就能完成攻击。我使用gdb "p system"等命令找到这些指针。现在,我想通过编写一个C程序,在运行时查找system()和exit()的地址,使攻击变得更加"动态"。我该如何做?我尝试了"&system",但它似乎并没有给我正确的地址。

编辑: 系统没有启用ASLR。

4个回答

6

您可以使用binutils - objdumpreadelf轻松查找地址,但仅限于二进制文件实际使用的符号地址。未使用的符号未与libc库链接。

假设你想黑掉ls命令:

objdump -d `which ls` | less

您会在这个部分找到:
0000000000402910 <exit@plt>:
  402910:       ff 25 da 89 21 00       jmpq   *0x2189da(%rip)        # 61b2f0 <_fini+0x208704>
  402916:       68 5e 00 00 00          pushq  $0x5e
  40291b:       e9 00 fa ff ff          jmpq   402320 <_init+0x10>

现在你有了地址:0x402910exit()函数的跳转地址(如果你尝试printf("%x\n", exit);,你将得到它打印出来的值)。

关于systemls没有使用这个符号,所以你不能通过这种方式访问它,因为它没有链接。


如果它不是库入口点,那么它必须在某个地方被定义。C标准要求将其定义为函数,因此它必须存在于某个地方。尝试找到它。 - randomusername
@randomusername 我更新了我的回答 - 现在我确切地知道如何找到函数的地址。但是,你想要调用的符号/函数必须已经被你想要攻击的二进制文件使用。否则,它不会被链接。 - Tomas
@randomusername 如果主函数返回,进程也会结束...没有特殊的函数可以做到这一点...程序已经运行完毕。如果一个符号没有被使用,那么它不需要出现在目标文件中。如果没有编译进去,你就必须在运行时动态链接...这种方法的效用有限,因为程序并没有使用它,而且在那个时候你已经执行了任意代码。 - Grady Player

2

如果我没理解错的话,你正在尝试用C语言编写一个程序,来执行和利用一个有漏洞的用户空间程序?在这种情况下,如果你的C语言程序使用了execve()函数,那么它将会启动一个带有自己进程空间的有漏洞的进程。这将包括重新加载的libc库。可以这样想:

pwner
 `-[libc]
 `-./vuln
    `-[libc]

在这种情况下,您的动态程序“pwner”将需要使用类似于ptrace()系统调用来跟踪易受攻击的程序并获取libc指针。当GDB调试二进制文件时,它实际上也是这样做的。您的程序应该使用ELF规范找到E_ENTRY的地址。从这里开始使用ptrace()。首先使用PTRACE_TRACEME,然后使用PTRACE_PEEKTEXT。

2

一些流行的Linux发行版默认启用了ASCII Armoring。它通常将重要库的地址映射到包含NULL字节的内存范围中。您可以在此处了解有关如何绕过ASCII Armoring的更多信息。


一篇有趣的文章。谢谢分享。+1 - Richard Chambers

0

我认为&system将在编译时解析。你尝试过dlopen()dlsym()吗?只是建议,我不知道它们是否有效。

编辑

如果存在某种地址空间布局随机化,则它们都无法在目标进程上下文之外工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接