Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何利用格式字符串漏洞?_C_Security_Format String - Fatal编程技术网

C 如何利用格式字符串漏洞?

C 如何利用格式字符串漏洞?,c,security,format-string,C,Security,Format String,我在阅读代码中的漏洞时遇到了这个格式字符串漏洞 说: 格式字符串错误通常出现在程序员希望 打印包含用户提供的数据的字符串。程序员可以 错误地写入printf(缓冲区)而不是printf(“%s”,缓冲区)。这个 第一个版本将缓冲区解释为格式字符串,并解析任何 它可能包含的格式化说明。第二个版本很简单 按照程序员的意图,将字符串打印到屏幕上 我发现printf(buffer)版本存在问题,但我仍然不知道攻击者如何利用此漏洞执行有害代码。有人能告诉我这个漏洞是如何被一个例子利用的吗?可能主要是因为它

我在阅读代码中的漏洞时遇到了这个格式字符串漏洞

说:

格式字符串错误通常出现在程序员希望 打印包含用户提供的数据的字符串。程序员可以 错误地写入printf(缓冲区)而不是printf(“%s”,缓冲区)。这个 第一个版本将缓冲区解释为格式字符串,并解析任何 它可能包含的格式化说明。第二个版本很简单 按照程序员的意图,将字符串打印到屏幕上


我发现printf(buffer)版本存在问题,但我仍然不知道攻击者如何利用此漏洞执行有害代码。有人能告诉我这个漏洞是如何被一个例子利用的吗?

可能主要是因为它会使你的程序崩溃,这被认为是拒绝服务攻击。您所需要的只是给出一个无效地址(实际上任何带有少量
%s
都可以保证工作),这就变成了一种简单的拒绝服务(DoS)攻击

现在,理论上,在异常/信号/中断处理程序的情况下,触发任何事件都是可能的,但我不知道如何做到这一点——您还需要知道如何将任意数据写入内存

但你可能会问,为什么有人关心程序是否崩溃?这难道不会给用户带来不便吗(不管怎么说,这是谁应得的)

问题是,一些程序被多个用户访问,因此使它们崩溃的代价是不可忽略的。有时它们对系统的运行至关重要(或者它们可能在做一些非常关键的事情),在这种情况下,这可能对你的数据造成损害。当然,如果你弄坏了记事本,那么没人会在意,但是如果你弄坏了CSRSS(我相信它实际上有一个类似的bug——特别是双自由bug),那么是的,整个系统都会跟着你一起崩溃


更新: 请参阅,以了解我所指的CSRSS错误


编辑: 请注意,读取任意数据与执行任意代码一样危险!如果您读取密码、cookie等,那么它与执行任意代码一样严重——如果您有足够的时间尝试足够的格式字符串,那么这是微不足道的。

啊,答案在文章中! 非受控格式字符串是1999年左右发现的一种软件漏洞,可用于安全漏洞攻击。以前认为无害的格式字符串攻击可用于程序崩溃或执行有害代码

典型的漏洞利用利用这些技术的组合,迫使程序用指向某些恶意外壳代码的指针覆盖库函数的地址或堆栈上的返回地址。格式说明符的填充参数用于控制输出的字节数,
%x
标记用于从堆栈中弹出字节,直到到达格式字符串本身的开头。格式字符串的开头被精心设计为包含地址,
%n
格式令牌随后可以用要执行的恶意代码的地址覆盖该地址

这是因为
%n
导致
printf
将数据写入堆栈上的变量。但这意味着它可以任意写入某些内容。你所需要的就是有人使用这个变量(如果它恰好是一个函数指针,你刚刚知道如何控制它的值,这就相对容易了),他们可以让你任意执行任何事情


看看文章中的链接;它们。

您可以通过多种方式直接或间接利用格式字符串漏洞。让我们以以下内容为例(假设没有相关的操作系统保护,这是非常罕见的):

此漏洞的基础是具有可变参数的函数的行为。实现可变数量参数处理的函数必须从堆栈中读取这些参数。如果我们指定一个格式字符串,使
printf()
在堆栈上预期两个整数,并且我们只提供一个参数,那么第二个参数必须是堆栈上的其他参数。通过扩展,如果我们可以控制格式字符串,我们可以拥有两个最基本的原语:


从任意内存地址读取 [编辑]重要提示:我正在对堆栈框架布局进行一些假设。如果您了解该漏洞背后的基本前提,并且它们在操作系统、平台、程序和配置中各不相同,则可以忽略它们

可以使用
%s
格式参数读取数据。您可以在
printf(text)
中读取原始格式字符串的数据,因此您可以使用它从堆栈中读取任何内容:

./vulnerable AAAA%08x.%08x.%08x.%08x
This is how you print correctly:
AAAA%08x.%08x.%08x.%08x
This is how not to print:
AAAA.XXXXXXXX.XXXXXXXX.XXXXXXXX.41414141
some_value @ 0x08049794 = -72 [0xffffffb8]

写入任意内存地址 您可以使用
%n
格式说明符写入任意地址(几乎)。同样,让我们假设上面的易受攻击程序,并尝试更改位于
0x08049794
some_值的值,如上所示:

./vulnerable $(printf "\x94\x97\x04\x08")%08x.%08x.%08x.%n
This is how you print correctly:
??%08x.%08x.%08x.%n
This is how not to print:
??XXXXXXXX.XXXXXXXX.XXXXXXXX.
some_value @ 0x08049794 = 31 [0x0000001f]
我们已使用在遇到
%n
说明符(
manprintf
)之前写入的字节数覆盖了
某些值。我们可以使用格式字符串本身或字段宽度来控制此值:

./vulnerable $(printf "\x94\x97\x04\x08")%x%x%x%n
This is how you print correctly:
??%x%x%x%n
This is how not to print:
??XXXXXXXXXXXXXXXXXXXXXXXX
some_value @ 0x08049794 = 21 [0x00000015]
有许多可能性和技巧可以尝试(直接参数访问、大字段宽度使环绕成为可能、构建您自己的原语),这只是冰山一角。我建议阅读更多关于fmt字符串漏洞的文章(Phrack有一些非常优秀的文章,尽管它们可能有点高级),或者阅读一本涉及该主题的书


免责声明:示例如下[尽管如此]
./vulnerable $(printf "\x94\x97\x04\x08")%x%x%x%n
This is how you print correctly:
??%x%x%x%n
This is how not to print:
??XXXXXXXXXXXXXXXXXXXXXXXX
some_value @ 0x08049794 = 21 [0x00000015]
"%200$p"