第4章 软件漏洞

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

2020/6/10
网络攻防技术
8
4.2.1 栈溢出
栈溢出攻击的相关概念最早要追述到1972年美国空军发表的一份 研究报告《Computer Security Technology Planning Study》。 在这份报告中,通过溢出缓冲区来注入代码这一想法首次被提了 出来。
直到1986年才出现了首次真实的攻击,Morris蠕虫病毒利用了 Unix操作系统中fingerd程序的gets()函数导致的栈溢出来实现远 程代码执行。
第四章 软件漏洞
本章主要内容
4.1 概述 4.2 典型漏洞类型 4.3 溢出漏洞利用原理 4.4 漏洞利用保护机制
2020/6/10
网络攻防技术
2
4.1 概述
漏洞的定义:指信息系统硬件、软件、操 作系统、网络协议、数据库等在设计上、 实现上出现的可以被攻击者利用的错误、 缺陷和疏漏。
通俗一点说,漏洞就是可以被攻击利用的 系统弱点。
2020/6/10
网络攻防技术
17
堆的数据结构
堆表
块首 数据
堆区
块首 数据
块首 数据
内存
堆表:堆表一般位于堆区的起 始位置,用于检索堆区中所有 堆块的总要信息。
堆块:堆区内存按不同大小组 织成块,以堆块为单位进行标 识。
一个堆块包括两个部分:块首和块 身。
块首用来标识块的自身的信息,例 如,大小、空闲或占用状态。
4
argv[1]);
6 printf( %s\n ,name);
7 return 0;
8
}
内存高端
栈溢出实例
name数组 (16字节) 前栈帧ebp
返回地址
main的参数
……
2020/6/10
网络攻防技术
main的栈帧 前栈帧
15
4.2.1 栈溢出
16
16
48
48
1016
1016
快表是Windows用来加速分配 16 而采用的一种堆表。
这类单向链表中不会发生堆块 合并(其中空闲堆块块首被置 为占用态防止堆块合并)。
快表也有128条,组织结构与空 表类似,只是堆块按单链表组 织,而且每条快表最多只有4个 节点。
2020/6/10
网络攻防技术
2020/6/10
网络攻防技术
21
堆的操作
(2)堆块释放
将堆块状态改为空闲,链入相应的堆表。所有的释放块都链入 堆表的末尾。
(3)堆块合并
堆块合并发生于空表。经过反复的申请与释放,堆区产生很多 内存碎片。
几个注意点:
快表空闲堆块被置为占用态,所以不会发生堆块合并操作。 快表只有精确分配时才会分配。 分配优先使用快表,失败时才使用空表。
堆是程序运行时动态分配的内存。所需分配的内存 大小在程序运行时由用户定义。
堆在使用时需要使用专用的函数进行申请,如C语言 中的malloc等函数、C++中的new函数等。
一般用一个堆指针来使用申请的内存,读、写、释 放都是通过这个指针来完成。
使用完毕后要通过堆释放函数进行回收这片内存, 否则会造成内存泄漏。如free、delete等。
20
堆的操作
(1)堆的分配:快表分配、普通空表分配和零号空表 (free[0])分配。
快表分配:寻找大小匹配的空闲堆块,把它从堆表中卸下,给 程序使用。
普通空表分配:先寻找最优的空闲块分配,若失败,则寻找次 优的空闲块分配。
零号空表分配:按照大小升序链着大小不同的空闲块,找最优 结果。
当空表中找不到最优的堆块时,会发生次优分配,即从大块按 照请求的大小精确割出一块进行分配,然后给剩下部分重新标 注块首,链入空表。
1
#include<stdio.h>
2
#include windows.h
内存低端
16个A
3
int main(int argc, char *argv[]){
4
char name[16];
5 strcpy(name,argv[1]);
6 printf( %s\n ,name);
AAAA (前栈帧ebp)
1996年,Elias Levy (a.k.a Aleph One)在大名鼎鼎的Phrack杂志 上发表了文章《Smashing the Stack for Fun and Profit》,从 此栈溢出漏洞的利用技术被广泛知晓。
2020/6/10
网络攻防技术
9
4.2.1 栈溢出
进程使用的操作系统内存一般可以划分为4部 分,按照内存地址由低到高,依次是:栈 (Stack)、堆、数据段、文本(代码)段。
偏移1
偏移2
偏移3
a
b
因为参数的不固定,可能导致栈中数据泄露
2020/6/10
网络攻防技术
26
4.2.4 整型溢出
一个整数是一个固定的长度 (32位或64位 ),它能存储的最大值是固定的,当尝试去存 储一个大于这个固定的最大值时,将会导 致一个整型溢出。
存储溢出 运算溢出 符号溢出
2020/6/10
用于进行空闲堆的管理。
1500
2000
2100
1600
空闲堆块的块首中包含一对
16
16
16
重要的指针,用于将空闲堆
块组织成双向链表。
48
48
由一个含有128个单元的数组 和相应的双向链表组成。其 中数组free[0]管理的是大于 1024字节以上的堆块。
数组free[i](0<i≤127)管理 的是i×8字节大小的堆块。
2020/6/10
网络攻防技术
3
4.1 概述
漏洞的分类:
针对安全操作系统研究而提出的漏洞分类。 将安全性漏洞和软件错误结合在一起的漏洞
分类。 多维度分类。 广义漏洞分类。 抽象分类。
2020/6/10
网络攻防技术
4
4.1 概述
漏洞攻击通常包含3个步骤,分别是:漏 洞发现(Vulnerability Discovery)、漏 洞分析(Vulnerability Analysis)、漏 洞利用(Vulnerability Exploit)。
4.2.3 格式化串
所谓格式化串,就是在*printf()系列函数 中按照一定的格式对数据进行输出,可以 输出到标准输出,即printf(),也可以输 出到文件句柄,字符串等。
对应的函数有fprintf,sprintf,snprintf ,vprintf,vfprintf,vsprintf, vsnprintf等。
从导致的后果来看,漏洞可能会造成:以 匿名身份直接获取系统最高权限;从普通 用户提升为管理员用户;实施远程拒绝服 务攻击等。
2020/6/10
网络攻防技术
5
4.1 概述
漏洞的标准化研究:
公共漏洞和暴露(Common Vulnerabilities & Exposures,CVE)
通用缺陷枚举(Common Weakness Enumeration, CWE)
2020/6/10
网络攻防技术
10
4.2.1 栈溢出
每个进程有一个栈,在这个进程中每个函 数被调用时分别从这个栈占用一段区域, 称为栈帧(Stack Frame)。
内存低端
B的局部变量 A栈帧ebp 返回地址 B的参数
A的局部变量
B的栈帧 A的栈帧
A() {
…… call B() ……
}
内存高端
2020/6/10
func函数入口 …… return
网络攻防技术
内存低端
内存高端
12
4.2.1 栈溢出
bu栈ff
Main函数栈底EBP
函数调用与栈
在一次函数调用中
004011D1 参数
main函数的数据
实际会保存在栈中 的数据包括:
main函数入口 ……
调用者参数、EIP的 值(返回地址)、 EBP的值
块身是最终分配给用户使用的数据 区。
2020/6/10
网络攻防技术
18
Windows系统的堆表——空表
free[0] free[1] free[12] free[3] free[4] free[5] free[6]
……
free[122] free[123] free[124] free[125] free[126] free[127]
main函数入口 ……
call func ……
func函数入口 …… return
2020/6/10
网络攻防技术
内存低端
内存高端
14
4.2.1 栈溢出
1
#include<stdio.h>
2
#include windows.h
内存低端
3
int main(int argc, char *argv[]){
2020/6/10
网络攻防技术
19
Windows系统的堆表——快表
lookaside[0] lookaside[1] lookaside[2] lookaside[3] lookaside[4] lookaside[5] lookaside[6]
……
lookaside[125] lookaside[126] lookaside[127]
栈:由编译器自动分配释放,是用户存放程序临时创建的局部 变量、函数参数等数据的地方。栈是一个寄存、交换临时数据 的内存缓冲区。
堆:一般由程序编写人员分配释放,若编写人员不释放,程序 结束时可能由操作系统回收,分配方式类似于链表。
数据段:用来存放程序中已初始化的全局变量的一块内存区 域。
代码段:用来存放程序执行代码的一块内存区域。这里存放着 由处理器直接执行的二进制代码。
call func ……
func函数入口 …… return
2020/6/10
网络攻防技术
内存低端
内存高端
13
4.2.1 栈溢出
bu栈ff
Main函数栈底EBP
函数调用与栈
如果在栈中发生缓 冲区溢出,极可能 使的栈所保存的
EIP指针值被改变。
也即程序原有流程 被改变。
004011D1 参数
main函数的数据
2020/6/10
网络攻防技术
22
堆溢出示例
1
#define BUFFSIZE 32
2
int main(int argc, char* argv[ ]){
3
char *buf1;
4
buf1 = (char *)malloc(BUFFSIZE);
//malloc a block of memory
5
2020/6/10
网络攻防技术
24
格式化串的栈结构
printf(“a=%d,b=%d\n ” ,a,b);
2020/6/10
网络攻防技术
25
格式化串溢出栈布局
低地址
栈 布 局
高地址
ebp 返回地址
格式控制符 %s
hello world
偏移1 偏移2
低地址 栈 布 局
高地址
ebp
返回地址
格式控制符 %p, %p, %p
前栈帧ebp
2020/6/10
网络攻防技术
11
4.2.1 栈溢出
bu栈ff
栈顶
Main函数栈底EBP
函数调用与栈
004011D1
参数
栈底
main函数的数据
内存方向:由低到高 栈方向:由高到低
main函数入口 ……
call func ……
00E00I044P400寄011112存1DDC1C10器1C4
网络攻防技术
27
存储溢出
长整型赋值给短整型
int len1 = 0x10000; short len2 = len1; //len2=0x0000
短整型赋值给长整型
int len1= -1; //len1=0xff ff ff ff short len2 =1; //len2=0x0001 len1=len2; //len1=0xffff0001= -13
2020/6/10
网络攻防技术
6
本章主要内容
4.1 概述 4.2 典型漏洞类型 4.3 溢出漏洞利用原理 4.4 漏洞利用保护机制
2020/6/10
网络攻防技术
7
4.2 典型漏洞类型
栈溢出(Stack Overflow,CWE-121) 堆溢出(Heap Overflow,CWE-122) 格式化串(Format String,CWE-134) 整型溢出(Integer Overflow,CWE-190) 释放再使用(Use after Free,CWE-416)
strcpy(buf1,argv[1]);
//copy parameter to buf1
6
printf("%s\n",buf1);
//print the buf1
7
free(buf1);
//free buf1
8
return 0;
9
}
拷贝字符串之前没有对字符串的长度进行检查 ,所以会产生溢出,覆盖缓冲区后面的内容, 也就是覆盖下一个堆块的块首,造成堆管理结 构混乱。
AAAA (返回地址)
main的参数
7 return 0;
8
}
内存高端
……
main的栈帧 前栈帧
在拷贝argv[1]指向的字符串之前,并没有检测该字符串的长度, 如果该字符串的长度大于16,则复制时就会覆盖name数组下方的 栈空间
2020/6/10
网络攻防技术
16
4.2.2 堆溢出
堆的特点:
相关文档
最新文档