如何在以下代码中格式化输入以返回libc攻击:
void example_function(int x, const char *name)
{
void (*foo)(int, const char *) = http_serve_none;
char buf[1024];
sprintf(buf, name);
foo(x, buf);
}
鉴于堆栈不可执行。我想通过更改libc中系统的foo函数指针而不是通过更改example_function的返回地址来返回libc攻击。到目前为止我所做的是使用传统方法进行输入:
填充+系统地址(在foo函数的地址)+地址 exit + ptr to string(string =" / bin / sh")
但是这不起作用。我不知道如何在输入字符串中格式化我的参数以进行系统调用。我在互联网上搜索了很多但是我看到只使用返回地址调用system()。
额外假设:
没有' 0' 0在系统调用地址中。机器是32位且sprintf正常工作,即将名称存储到缓冲区buf [1024]。
答案 0 :(得分:1)
我终于解决了......我只是将指针传递给字符串" / bin / sh"在地址x,它对我有用
答案 1 :(得分:0)
首先,确保您的sprintf
实际上是sprintf
而不是__sprintf_chk
,这将试图阻止您的溢出。您可以告诉它强化版本,因为您将获得SIGABRT而不是其他东西(如SIGSEGV)。你可以在全球范围内关闭强化,但你也可以避免使用像:
(sprintf)(buf, name);
你的下一个问题是零。如果system
的地址中包含任何零字节,则sprintf
将在此时停止复制。这是"好吧,有很多64位地址,其中有零,"而且是有意的。它被称为ASCII装甲,在某些平台上,重要的libc功能肯定会在其中包含零以完全阻止这种攻击。 (有关此问题,请参阅Writing a return-to-libc attack, but libc is loaded at 0x00 in memory。)
您可能希望使用程序中的函数(即不是libc)来探索此攻击,并且您已确保其中没有零。如果你为32位构建,这样做会更容易一些。当然,你可能想要关闭强化和堆栈保护以及编译器正在做的所有其他事情来阻止这个:D(至少在你有一个基本版本工作之前;然后你可以在一个时间)。