天天看点

CWE-843: Access of Resource Using Incompatible Type (使用不兼容类型访问资源)

 ID: 843

类型:基础

结构:简单

状态:未完成

描述

程序使用一种类型分配或初始化资源,例如指针、对象或变量,但稍后它使用与原始类型不兼容的类型访问该资源。

扩展描述

当程序使用不兼容的类型访问资源时,这可能会触发逻辑错误,因为资源没有预期的属性。在没有内存安全的情况下,如C和C++,类型混淆可能导致越界内存访问。             

虽然在C中解析具有许多不同嵌入对象类型的数据时,这种弱点经常与联合有关,但它可以出现在任何能够以多种方式解释相同变量或内存位置的应用程序中。

这种弱点并不是C和C++独有的。例如,当需要scalar时,可以通过提供数组参数来触发PHP应用程序中的错误,反之亦然。诸如Perl这样的语言,当访问某个类型的变量时,它会像访问另一个类型一样执行自动转换,也可能包含这些问题。

相关视图

 "研究概念" 视图(CWE-1000)

Nature Type ID Name
ChildOf 704 Incorrect Type Conversion or Cast
CanPrecede 119 Improper Restriction of Operations within the Bounds of a Memory Buffer

 "开发概念"视图 (CWE-699)

Nature Type ID Name
ChildOf

引入模式

阶段 说明
实现

应用平台

语言

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

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

示例

例1

以下代码使用联合来支持不同类型消息的表示。它根据消息的类型对消息进行不同的格式设置。

(问题代码)

Example Language: C 

#define NAME_TYPE 1

#define ID_TYPE 2

struct MessageBuffer

{

int msgType;

union {

char *name;

int nameID;

};

};

int main (int argc, char **argv) {

struct MessageBuffer buf;

char *defaultMessage = "Hello World";

buf.msgType = NAME_TYPE;

buf.name = defaultMessage;

printf("Pointer of buf.name is %p\n", buf.name);

buf.nameID = (int)(defaultMessage + 1);

printf("Pointer of buf.name is now %p\n", buf.name);

if (buf.msgType == NAME_TYPE) {

printf("Message: %s\n", buf.name);

}

else {

printf("Message: Use ID %d\n", buf.nameID);

}

}

代码打算将消息作为名称类型处理,并将默认消息设置为“hello world”。但是,由于buf.name和buf.nameid都是同一联合的一部分,因此它们可以作为同一内存位置的别名,具体取决于编译后的内存布局。             

因此,修改buf.nameid(int)可以有效地修改存储在buf.name(字符串)中的指针。

程序的执行可能会生成如下输出:             

名称指针为10830             

指针现在是10831             

信息:Ello World

注意buf.name的指针是如何更改的,即使buf.name没有被显式修改。              在这种情况下,省略消息的第一个“h”字符。但是,如果攻击者能够完全控制buf.nameid的值,那么buf.name可能包含任意指针,导致读取或写入超出界限。例2

下面的PHP代码接受一个值,加5,然后打印和.

(问题代码)

Example Language: PHP 

$value = $_GET['value'];

$sum = $value + 5;

echo "value parameter is '$value'<p>";

echo "SUM is $sum";

调用时输入下面的查询字符串时:

value=123

程序计算sum并且打印:

SUM is 128

然而,攻击者可能提供下面的查询串 :

value[]=123

用"[]" 标记的 $value 被作为数组对待,当计算sum时会产生致命错误:

Fatal error: Unsupported operand types in program.php on line 2

例3

下面的Perl代码旨在通过访问$userprivilegarray引用来查找用户ID在0和3之间的特权。预期只有userid 3是管理员(因为它列在数组的第三个元素中).

(问题代码)

Example Language: Perl 

my $UserPrivilegeArray = ["user", "user", "admin", "user"];

my $userID = get_current_user_ID();

if ($UserPrivilegeArray eq "user") {

print "Regular user!\n";

}

else {

print "Admin!\n";

}

print "\$UserPrivilegeArray = $UserPrivilegeArray\n";

在这种情况下,程序员打算使用“$userprivilegarray->$userid”访问数组中的正确位置。但由于省略了下标,“user”字符串与$userprivilegarray引用的标量表示形式进行了比较,后者的形式可能是“array(0x229e8)”或类似的形式。             

由于逻辑也“打开失败”(CWE-636),因此该错误的结果是所有用户都被分配了管理员权限。

虽然这是一个强制示例,但它演示了类型混淆如何产生安全后果,即使是在内存安全语言中。

种属

关系 类型 ID 名称
属于 1157 SEI CERT C Coding Standard - Guidelines 03. Expressions (EXP)

说明

应用平台

这种弱点在任何类型的不安全编程语言中都是可能的。

研究空白

类型混淆的弱点受到了应用研究人员和主要软件供应商对C和C++代码的关注。一些公开报告的漏洞可能具有类型混淆作为根本原因的弱点,但这些漏洞可能被描述为“内存损坏”。这一弱点在未来几年可能会变得突出。             

就其他语言而言,很少有关于类型混淆弱点的公开报告。这些可能是研究不足的。由于许多程序直接或间接地依赖于松散类型,潜在的“类型混淆”行为可能是有意的,可能需要更多的手动分析。

继续阅读