如何利用格式化字符串漏洞将特定字符串写入内存?

逆向工程 二元分析 C C++ 漏洞分析 字符串
2021-07-06 02:43:48

我想我了解格式字符串漏洞的工作原理,但到目前为止我所看到的只能用于增加整数的值。

格式化字符串漏洞也可以用来写其他东西吗?

顺便说一句,除了 C 和 C++ 之外,是否还有其他语言存在造成此类漏洞的风险?如果我只有二进制文件,如何发现格式字符串漏洞?

1个回答

问题有点多,这里有几个答案:

我们如何在内存中写入带有格式字符串漏洞的内容?

为此,您需要了解printf格式字符串规范中使用的两个特定功能首先,%n是具有以下效果的格式说明符(根据手册页):

%n到目前为止写入的字符数存储到由int *(或变体)指针参数指示的整数中不转换任何参数。

现在,第二个格式字符串功能将允许我们从格式字符串中选择一个特定的参数。主要的选择运算符是$,下面的代码意味着我们选择第二个参数(这里的结果是显示2):

printf("%2$x", 1, 2, 3)

但是,在一般情况下,我们可以printf("%<some number>$x")选择当前printf函数的任意参数(格式字符串参数不计算在内)。

如果我们可以将字符串传递AAAA%10$n给程序并使其显示为格式字符串,那么我们可以将值写入4地址0x41414141

因此,格式字符串错误可能会提供对内存的完全访问权限,您可以决定要写入的内容以及在内存中的位置。

我真的建议您阅读Scut (2001) 中的利用格式字符串漏洞”,以全面掌握此类操作。

它们是不是 C/C++ 之外的其他语言容易受到这些错误的影响?

好吧,格式字符串错误与printf函数系列以及格式字符串可能传递给函数的方式有关。这本身就是一整类安全问题。因此,您可能会找到利用其他语言中类似问题的方法。但是,您可能找不到完全相同的功能,因为其他语言中的格式字符串功能可能会有很大差异。

我确实考虑过 Perl、Python 等语言,它们都提供对格式字符串功能的类似访问。

如果我只有二进制文件,如何发现格式字符串漏洞?

首先,您必须找到对printf家庭过程的调用然后,我会说模糊测试(fuzzing)应该是发现漏洞的好方法。特别是如果您可以使用种子伪造一些条目,例如AAAA%10$n.

如果您想要一种更准确、更详尽的方法来找到它,您可能需要对每个对printf家族过程的调用进行一些二元分析和污点分析