c - 使用外部控制格式字符串的漏洞
问题描述
首先,请看一下这个网站(https://cwe.mitre.org/data/definitions/134.html)。它们是一些代码存在漏洞。我真的不明白漏洞代码在哪里,他们在谈论。
它有 3 个存在漏洞的代码片段,例如 PrintWrapper、Snprintf 和 %1$d,出现在本网站上。
解决方案
@CassieJade 您需要在线查看这些功能的文档。
printf, snpritf
是很常见的功能。顺便说一句,这个平台不适用于学校作业。如果您尝试过某些事情并想从那里跟进,我们将非常欢迎您。
- http://www.cplusplus.com/reference/cstdio/printf/
- 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 个字节,这将是空的。
我希望现在很清楚。
推荐阅读
- javascript - 按升序对天数数组进行排序
- javascript - 是否有正确的方法来加载脚本一次,并在整个文档的 iFrames 中使用它?
- java - 哪种方法更好?
- c# - 一旦玩家点击任何位置,我如何绘制曲线+直线以显示可能的路径?
- html - 如何使用 ngModel 在 div 的 innerhtml 属性上实现 2 路数据绑定?
- oracle - 当我更改文本字体时,Oracle 报告 10g 崩溃
- c++ - 具有特征成员变量排序和赋值错误的c ++类
- html - 使用 mat-paginator 时出现“this.container is undefined”错误
- android - 对齐小部件内部在颤动中展开成行
- xaml - WebView GestureRecognition 在 Xamarin 表单中不起作用