CWE-170: Improper Null Termination(NULL终止符错误)

 ID: 170

类型:基础
结构:简单

状态:未完成

描述

软件不会终止或错误地终止具有空字符或等效终止符的字符串或数组。

扩展描述

空终止错误通常以两种不同的方式发生。一个“关闭一次”错误可能导致将空值写入边界之外,从而导致溢出。或者,程序可能不正确地使用strncpy()函数调用,这会阻止添加空终止符。其他情况也是可能的

关联视图

与“研究层面”视图(CWE-1000)相关

与“开发层面”视图(CWE-699)相关

与 "七种最有害的弱点" 视图(CWE-700)

引入模式

阶段

备注

实现

 

应用平台

 

语言

C (出现的可能性不确定)

C++ (出现的可能性不确定)

后果

 

范围

冲击

可能性

保密性
完整性
可利用性

技术冲击: 内存读取; 执行未获授权的代码或命令

省略空字符的情况是最危险的问题。这几乎肯定会导致信息泄漏,并可能导致缓冲区溢出条件,这些条件可能被用来执行任意代码。

 

保密性
完整性
可利用性

技术冲击: DoS: 崩溃、推出或者重启: 内存读取; DoS: 资源消耗(CPU): DoS: 资源消耗 (内存):

 如果从字符串中省略了一个空字符,那么大多数字符串复制函数都将读取数据,直到找到一个空字符,即使在字符串的预期边界之外。这可能:由于分段错误导致崩溃,导致敏感的相邻内存被复制并发送到外部,从而在将副本写入固定大小的缓冲区时触发缓冲区溢出。

 

完整性
可利用性

技术冲击: 修改内存; DoS: 崩溃、退出或重启

错误放置的空字符可能导致任何数量的安全问题。最大的问题是缓冲区溢出的一个子集,写下在何处条件下,在有效数据甚至指令上写一个空字符会导致数据损坏。随机放置的空字符可能会使系统处于未定义的状态,从而使系统容易崩溃。空字符放错位置可能会损坏内存中的其他数据。

 

完整性
保密性
可利用性
访问控制
Other

技术冲击: 改变执行逻辑; 执行未获授权的代码或命令

如果空字符损坏进程流,或影响控制访问的标志,则可能导致允许执行任意代码的逻辑错误。

 

被利用的可能性:

中等

示例

例1

下面的代码从cfgfile读取数据并使用strcpy()将其拷贝到inputbuf。这段代码错误的假设inputbuf中一直包含一个NULL结束符。

(问题代码)

Example Language:

#define MAXLEN 1024
...
char *pathbuf[MAXLEN];
...
read(cfgfile,inputbuf,MAXLEN); //does not null terminate
strcpy(pathbuf,inputbuf); //requires null terminated input
...

如果从cfgfile读取的数据按预期在磁盘上终止为空,则上述代码将正常工作。但是,如果攻击者能够修改此输入,使其不包含预期的空字符,则对strcpy()的调用将继续从内存复制,直到遇到任意的空字符为止。这很可能会溢出目标缓冲区,如果攻击者可以在inputbuf之后立即控制内存内容,则会使应用程序容易受到缓冲区溢出攻击。

例2

在下面的代码中,readlink()展开存储在path name中的符号链接的名称,并将绝对路径放入buf。然后使用strlen()计算结果值的长度。

(问题代码)

Example Language:

char buf[MAXPATH];
...
readlink(pathname, buf, MAXPATH);
int length = strlen(buf);
...

上面的代码的行为并不总是正确的,因为readlink()没有向buf附加空字节。一旦达到buf的最大大小,readlink()将停止复制字符,以避免缓冲区溢出,这将使值buf非空终止。在这种情况下,strlen()将继续遍历内存,直到在堆栈的下面遇到一个任意的空字符,从而产生一个比字符串大很多的长度值。readlink()返回复制的字节数,但如果此返回值与指定的buf大小(在本例中为maxpath)相同,则不可能知道路径名的长度是否正好等于多个字节,或者readlink()是否截断了名称以避免缓冲区溢出。在测试中,这样的漏洞可能不会被捕获,因为buf和紧随其后的内存中未使用的内容可能为空,从而导致strlen()看起来好像运行正常。

例3

虽然下面的示例不可利用,但它提供了一个很好的示例,说明了即使使用了“安全”函数,也可以忽略或放错空值:

(问题代码)

Example Language:

#include <stdio.h>
#include <string.h>

int main() {


char longString[] = "String signifying nothing";
char shortString[16];

strncpy(shortString, longString, 16);
printf("The last character in shortString is: %c (%1$x)\n", shortString[15]);
return (0);

}

上面的代码给出了以下输出:“短字符串中的最后一个字符是:n(6e)”。因此,即使使用了“安全”字符串函数strncpy(),短字符串数组也不会以空字符结尾。原因是,当源的长度等于或长于提供的大小时,strncpy()不会在字符串的末尾隐式添加空字符。

应对措施

阶段: 需求

使用不易受这些问题影响的语言。但是,请注意可能使用易受影响的语言编写的低级构造的空字节交互错误(CWE-626)。

阶段: 实现

确保所有使用的字符串函数都完全理解它们如何附加空字符。另外,在字符串结尾追加空值时,要小心一个错误。

阶段: 实现

如果性能约束允许,可以添加特殊代码来验证字符串缓冲区的空终止,这是一个相当幼稚且容易出错的解决方案。

阶段: 实现

切换到有界字符串操作函数。检查缺陷报告的缓冲区溢出跟踪中涉及的缓冲区长度。

阶段: 实现

.添加用空值填充缓冲区的代码(但是,仍然需要检查缓冲区的长度,以确保不在缓冲区的物理端写入以非空值结尾的字符串)。

种属

 

关系

类型

ID

名称

属于

730

OWASP Top Ten 2004 Category A9 - Denial of Service

属于

741

CERT C Secure Coding Standard (2008) Chapter 8 - Characters and Strings (STR)

属于

748

CERT C Secure Coding Standard (2008) Appendix - POSIX (POS)

属于

875

CERT C++ Secure Coding Section 07 - Characters and Strings (STR)

属于

884

CWE Cross-section

属于

973

SFP Secondary Cluster: Improper NULL Termination

属于

1161

SEI CERT C Coding Standard - Guidelines 07. Characters and Strings (STR)

属于

1171

SEI CERT C Coding Standard - Guidelines 50. POSIX (POS)

说明

应用平台

从概念上讲,这不仅适用于C语言;涉及终结符的任何语言或表示都可能存在此类问题。

维护

正如目前所描述的,这个条目更像是一个类别,而不是一个弱点。

关联

因素:这通常是由其他弱点(如关闭一个错误)导致的,但它可能是边界条件冲突(如缓冲区溢出)的主要原因。在缓冲区溢出中,它可以充当假定不变数据的扩展器。

关联

重叠缺少的输入终止符。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值