首页 > 解决方案 > 使用外部控制格式字符串的漏洞

问题描述

首先,请看一下这个网站(https://cwe.mitre.org/data/definitions/134.html)。它们是一些代码存在漏洞。我真的不明白漏洞代码在哪里,他们在谈论。

它有 3 个存在漏洞的代码片段,例如 PrintWrapper、Snprintf 和 %1$d,出现在本网站上。

标签: c

解决方案


@CassieJade 您需要在线查看这些功能的文档。 printf, snpritf是很常见的功能。顺便说一句,这个平台不适用于学校作业。如果您尝试过某些事情并想从那里跟进,我们将非常欢迎您。

  1. http://www.cplusplus.com/reference/cstdio/printf/
  2. http://www.cplusplus.com/reference/cstdio/snprintf/

以下精美解释了您对$的关注。 (GCC) printf 格式字符串中的美元符号

表示法%2$d的含义与%d(输出有符号整数)相同,除了它使用给定的基于 1 的数字格式化参数(在您的情况下,它是第二个参数,b)。

int a = 3, b = 2;

printf("%2$d %1$d", a, b);

在这里,您希望打印 3 2,但它会打印 2 3,因为参数 a 变为 param#1,b 变为 param#2,并且首先打印 %2$d,因此首先打印 2,然后打印 %1 $d 是 3

您可能想查看 printf 的手册页,它对新手来说有点复杂,但它是最终的真相来源。

以下是您的打印包装。

char buf[5012];
memcpy(buf, argv[1], 5012);
printWrapper(argv[1]);
return (0);

您的网站说:当攻击者可以修改外部控制的格式字符串时,这可能会导致缓冲区溢出、拒绝服务或数据表示问题。

现在,如果这个 argv 1可以由不受信任的人提供,他可以提供任何垃圾参数,这些参数将发送给 printf。您的任务目标是不要使用任何外部控制的字符串来提供 print() 。例如 argv 1可以是非常大的字符串(最大允许值)。或者例如我是调用你的程序的人,我将 argv 1作为“%d Hello World”传递,你的 printWrapper 最终会打印一些像“-446798072 Hello World”这样的垃圾,因为在 printf(argv) 中没有整数作为参数传递1 )。

此外,memcpy 正在从源 argv 1读取固定数量的字节,这些字节可以具有更短长度的字符串,在这种情况下,它将是无效读取(读取越界)。

snprintf(buf,128,argv[1]);

这里的漏洞利用非常清楚,argv 1可以通过包含几个说明符来更改,例如 %n 可以将 n 个字节写入您的 buf 而不是预期写入。通过在 argc 1中使用 %X,黑客可以获得堆栈上变量的地址,可以进一步利用。所有这些都是易受攻击的,因为外部不受信任的来源正在创建您的 printf 或 snprintf、sprintf 函数使用的格式说明符字符串。例如假设黑客在 argv 1中给出了“%200d” 。sprintf(buf, 128, argv[1]); 将打印 200 个字节,然后是一个垃圾整数,这可能根本不是有意的,因为它的 snprintf 是一个有界函数,它只允许写入 128 个字节,这将是空的。

我希望现在很清楚。


推荐阅读