Kernal Exploitation 翻译 Chaper_2 by XY Meng.docxVIP

  • 7
  • 0
  • 约1万字
  • 约 19页
  • 2018-01-18 发布于河南
  • 举报
Kernal Exploitation 翻译 Chaper_2 by XY Meng

Chapter 2内核漏洞分类本章摘要:* 未初始化/未经验证的/损坏的指针解引用* 内存损坏漏洞* 整数型变量问题* 竞态条件* 逻辑Bug(也称作捕虫袋)简介软件总会有Bug。Bug是程序中的一个故障,会导致程序输出错误结果,非正常行为,或者直接异常崩溃。多数情况下,Bug是程序错误的结果,如下例子,这段代码来自Linux内核,版本2.6.9:这段代码里,proto这个参数和maximum的值,BLUEZ_MAS_PROTO,比对检测,当proto被用于数组内的下标时,用来避免越界读取超过bluez_proto数组的大小。问题是,proto是一个有符号整数,因此它可以有负值。所以,如果proto小于0,所有在bluez_proto数组之前的内存都可以被访问。由于这些内存用于函数指针,这个Bug可能会导致程序崩溃,一种情况是对一片未映射地址的引用,另一种情况是程序错误地访问某个其他内存地址,导致执行一段随机的字节码序列。修复该Bug的非常显而易见的方法是,在这段函数前面检测proto是否小于0,如果是则报错。(而这也是2005年Linux开发人员发现该问题后的举动)。当Bug的来源不是程序错误时,它常常来源于设计上的纰漏(尤其是大型的项目,比如操作系统的内核)。设计纰漏,顾名思义,是软件架构上的问题,但也常常是跟语言没什么关系的(即,不管用什么语言实现该软件,安全问题仍会出现)。一个经典的设计纰漏的例子是,依赖一个脆弱的加密机制,或是绝对地相信架构的某个组件,而入侵者可能假冒或操纵这个组件,而不需要某种权限。本章稍后在“由内核产生的用户级漏洞”一节里我们会举出一个设计纰漏的详细例子。当然,不是所有Bug都是安全Bug。事实上,Bug通常都跟安全问题无关。简而言之,只是有些人发现可以利用该Bug获取某些权限时,Bug变成安全问题。有时候利用一个Bug所使用的方法可以被生成并重用到其他类似Bug。在这些情况下,我们称为Bug类型和Bug利用技术。你做Bug定义和分类越精细,利用Bug技术就会越准确和可靠。这就是我们这章做分类的目标。第一节,未初始化的/未验证的/已损坏的指针解引用大概最有名的内核Bug类型就是Null指针解引用了。正如每本C语言手册提到的,指针是一个变量,存放内存中另一个变量的地址。每次指针被解引用的时候,指针存放的内存地址里所含有的值就要被取出。ISO C标准指出,一个静态的未初始化的指针有一个NULL(0x0)值,并且NULL又常常是表示内存分配功能失败的返回值。如果内核路径想要取一个NULL指针的值的时候,就等于是使用内存地址0x0,而这就会导致慌乱条件(Panic condition),因为那个地址一般不会放置任何东西。内核中发现的NULL指针解引用的Bug数量是惊人的多,随便用有所喜爱的搜索引擎一搜便知。 NULL指针解引用漏洞是更大一类漏洞“未初始化的/未验证的/已损坏的指针解引用”的一个子集,这个门类涵盖了所有使用指针的情况,所指内容被破坏,再也不能被适当设置,或是没有被确认。我们都知道,一个静态声明的指针被初始化为NULL,但一个被声明为函数的局部变量指针呢?一个指向刚刚被分配内存的结构体的指针指向的内容是什么?在这些指针被明确地赋值之前,它都是“未初始化的”,它的值是“不确定的”。让我们看一看细节。我们说一个指针是一个变量,和任何变量一样,它有大小,需要存在内存以便使用。指针的大小依赖于系统使用的数据模型(data model),体系结构往往直接决定了指针的大小,数据模型通常用int、long和pointer的大小标记来表示;例如,ILP32表示所有的ints,longs和指针都是32位宽的系统,而LP64表示所有的longs和指针都是64位宽的系统,但整数不是(事实上,整数是32位,但没有明确说明)。下面有一些体系结构的数据长度:表2.1 为每个模型提供了数据类型的大小的概述(大小用位数表示)。比如ILP32,指针占4位。在指针没被初始化的时候,那么指针的值是随机的。有利用此漏洞的头脑的人们会考虑,可不可以预测指针的内容并加以利用呢?答案是肯定的,或者说,在很多情况下是可以的。比如,一个指针被声明为本地变量,如下代码所示,那么该指针被存储在栈中,它的值其实是遗留在该栈的前一个函数:编译执行该程序,我们得到(注意,字母A的16进制值是0x41):能看到,指针被分配的地方恰恰就是前面的函数在栈里剩留的内容。事实上,这一部分用后的剩留内存被称为“死内存”或“死栈”。当然了,是我们杜撰了上述例子,你会认为这种情况发生几率很低,但请看如下真实存在的代码,来自FreeBSD8.0:注意[1]处,ucred在栈中声明。而后,注意[2]处,cr_groups[0]被赋值为dp-i_gid,不幸的是,ucre

文档评论(0)

1亿VIP精品文档

相关文档