缓冲区溢出漏洞浅析

1.认识漏洞

 

1.1.漏洞的定义

百度:漏洞是在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,从而可以使攻击者能够在未授权的情况下访问或破坏系统。

Wikipedia:计算机系统安全方面的缺陷,使得系统或其应用数据的保密性、完整性、可用性、访问控制、监测机制等面临威胁。

王院士、罗老师:从整体上,一切影响信息系统及其服务群体正常工作,使得其基本安全属性(机密性、完整性、可用性、真实性、可控性)不能得到保障的缺陷。

 

1.2.漏洞的分类

1.从漏洞类型上

       输入验证错误、边界条件错误、缓冲区溢出、访问验证错误、异常条件错误、环境错误、配置错误、竞争条件、设计错误……

2.从漏洞利用方式上

本地攻击、远程攻击、目标访问攻击

 

1.3.相关概念

1. 0day 漏洞、1day漏洞

1day漏洞是指那些已经公布的但厂商或用户因为安全意识、时间等多种原因还未及时修补的漏洞。(因此应当及时为操作系统、应用程序打补丁,防止遭受攻击)

 

2.  Exploit(EXP)

Exploit的英文本意为“利用”。在计算机安全术语中,这个词通常表示利用漏洞渗透到脆弱系统的过程(例如,使自己编写的代码越过具有漏洞的程序的限制,从而获得敏感信息、运行权限等)。

同时它也表示一种自动检测漏洞并能在大多数情况下通过运行代码来尝试使用漏洞的程序。(比如,针对一个拒绝服务的漏洞,exploit将尝试使目标崩溃,使其无法对外提供服务;针对一个远程可利用的缓冲区溢出漏洞,exploit将尝试溢出目标并执行任意代码。)

 

3.POC

Proof of concept(概念验证)是对某些想法的一个较短而不完整的实现,以证明其可行性,示范其原理。对于漏洞来说,它通常代表并没有充分利用这个漏洞的exploit。

 

4.Shellcode

广义上:一段可执行的二进制代码(也可以是填充数据)。例如:

“\xB8\x0B\x00\x00\x00\x83\xC0\x16\xC3”,它代表如下汇编指令:

mov eax,11

add eax,22

ret

狭义上:一段利用特定漏洞的二进制代码,从而实现权限提升、任意代码执行等功能。

 

5.Payload

Shellcode 中的有效载荷,包含漏洞利用成功后恶意程序所做的有害的或恶意的动作。(运行指定的程序、开启一个后门等)

 

2.溢出漏洞原理

 

2.1.缓冲区溢出概念

首先看下面这个例子,当在命令行中输入多个1并按下回车后,程序会停止工作。通过程序崩溃时显示的信息,我们可以知道程序发生了堆栈溢出,堆栈中的函数返回地址被覆盖,使得程序无法继续执行。

缓冲区溢出漏洞浅析

图1 缓存区溢出

     因此,当向一个已分配了确定存储空间的缓冲区内复制多于该缓冲区处理能力的数据时,将发生缓冲区溢出。缓冲区溢出分为静态缓冲区溢出与动态缓冲区溢出,对应于堆栈溢出和堆溢出(堆腐烂)。

 

2.2.堆栈溢出(地毯式轰炸)

堆栈:线程相关的,每一个线程都会有一个独立的堆栈,是FILO结构,从内存高地址向内存低地址增长。

堆栈溢出:堆栈溢出是在静态缓冲区中发生的溢出,当堆栈空间的缓冲区过载时,就发生堆栈溢出。发生堆栈溢出时,返回地址可能将被覆盖,程序执行流程将被改变。利用缓冲区漏洞,通过精妙的控制,就可以获取控制权执行任意代码。

 

2.3.堆溢出(狙击)

堆:由操作系统中的堆管理系统进行管理,堆区的内存按不同大小组织成块,以堆块为单位进行标识。堆块包括块首和块身两个部分,块首用来标识堆块自身的信息(大小、状态、向前向后指针等)。块身就是最终分配给用户使用的数据区。Windows下,空闲态的堆块由堆区起始位置的堆表进行索引,占用态的堆块被使用它的进程索引。

堆溢出:堆溢出是在动态缓冲区中发生的溢出,其溢出原理与堆栈溢出类似,但是由于堆与堆栈结构的差异,导致其利用方式不同,甚至需要很多条件都满足时,才可以利用一个堆溢出漏洞。

堆溢出的利用有多种形式,常见的一种形式是利用堆结构本身的特点,在堆溢出时溢出覆盖“下一个堆块”的块首,改写其向前向后指针(堆区中的所有堆块在线性内存空间中是连续的,即便其中某些堆块已经被分配了出去),因此当分配、释放、合并等操作发生时就可能会获得一次向任意内存地址写入任意数据的机会。如同标红的NODE堆块已经被溢出,其FLINK与BLINK已经被改写,当它从空闲堆块链表中出链时,就会发生一次任意地址空间的读写:NODE -> BLINK -> FLINK = NODE -> FLINK

缓冲区溢出漏洞浅析

 

图2 空闲堆链

 

2.4.整数溢出(先头部队)

整数:在计算机中,所有整数类型都用一个固定的位数表示,所以其表示范围有限,当值超出最大或最小值范围时,就会发生“回绕”。

整数溢出:当一个整数值大于或者小于其范围时,就会产生整数溢出。整数溢出漏洞常常是攻击者致使缓冲区溢出的起点。因为许多情况下,缓冲区溢出都与数字有关,因为内存分配量、字符串操作长度都是用整数表示的。

当使用可能会发生回绕的变量来分配内存、限制字符串操作范围、或作为指向缓冲区的指针时,可能会发生缓冲区溢出。下图为一个存在整数溢出漏洞的函数示例,当Len为一个负数时,将绕过长度判断,从而实现缓存区拷贝(memcpy的参数3是一个无符号数)。

缓冲区溢出漏洞浅析

 

图3 整数溢出隐患

 

3.堆栈溢出漏洞Exploit

 

3.1.堆栈与函数调用

1.堆栈

<– ESP

局部变量
EBP
返回地址
参数1
参数2
参数3
参数4

图4 堆栈

2. 函数调用约定

调用约定规定了进行一次函数调用所采用的参数传递,返回值处理以及清理调用堆栈的方式。是在编译时,由编译器根据编译选项决定的。Windows下有多种调用约定,分别是__cdecl、__stdcall、__fastcall、__thiscall、__clrcall、__vectorcall。在x86架构下,所有调用约定都使用eax传递返回值,64位返回值则使用edx:eax传递返回值。

__cdecl:C语言默认的函数调用约定,它可以处理可变参数。函数参数从右至左依次入栈,由函数调用者(父函数)清理堆栈。

__stdcall:Win32 API中最常见的函数调用约定,所有不可变参数的API调用都使用这个约定。函数参数从右至左依次入栈,由被调用函数(子函数)自行清理堆栈。

__fastcall:快速函数调用约定,第一个和第二个DWORD参数(或者尺寸更小的)通过ecx和edx传递,其他参数通过从右向左的顺序压栈,由被调用函数(子函数)自行清理堆栈。

__thiscall:C++成员函数的默认调用约定,函数参数从右向左依次入栈,ecx保存this指针,由被调用函数(子函数)自行清理堆栈。注意thiscall不是关键词,因此不能被程序员指定。

表1 Calling Conventions

Keyword

Stack cleanup

Parameter passing

__cdecl

Caller

Pushes parameters on the stack, in reverse order (right to left)

__stdcall

Callee

Pushes parameters on the stack, in reverse order (right to left)

__fastcall

Callee

Stored in registers, then pushed on stack

__thiscall

Callee

Pushed on stack; this pointer stored in ECX

__clrcall

n/a

Load parameters onto CLR expression stack in order (left to right).

__vectorcall

Callee

Stored in registers, then pushed on stack in reverse order (right to left)

 

3.2.堆栈溢出漏洞远程利用示例

堆栈溢出:通过前面对堆栈及函数调用的介绍,我们已经可以理解堆栈溢出的原理,通过溢出堆栈低地址处的局部变量可以修改高地址处的返回地址,从而修改程序流程。

示例请参考《0day安全:软件漏洞分析技术》

 

4.安全编程

 

4.1.使用Windows安全机制

在编译链接程序时,你可以通过IDE中的编译、链接选项为程序设置如下保护,通过它们可以极大的增强程序的安全性(注意:没有绝对的安全,目前已经有多种技术可以绕过它们)。

  •  Stack cookies (/GS)                                      缓冲区安全检查
  •  SafeSEH (/EHsc)                                          异常处理器保护
  •  Data Execution Prevention (DEP)    (/NXCOMPAT)           数据执行保护
  •  Address Space Layout Randomization (ASLR)                随机基址

 

4.2.使用安全语言

安全语言:可以自动执行运行时检查,以预防程序超出所分配内存边界的编程语言。具备两种特性:内存安全&类型安全。

不安全的语言:C、C++ …

相对安全的语言:Java、C# …

(Note:这些相对安全的编程语言或多或少“消除”了缓冲区溢出的可能性,但是它们提供的缓冲区溢出保护措施也是以相当高的代价换来的。)

 

4.3.安全编程意识

  •  严格把关所有输入(字符串、整数等数据);
  •  重视编译器警告,且不要为了编译通过,而更改警告等级;
  •  注意动态内存的管理(分配与释放等);
  •   ……

原创文章,作者:admin,如若转载,请注明出处:https://www.isclab.org.cn/2014/10/21/%e7%bc%93%e5%86%b2%e5%8c%ba%e6%ba%a2%e5%87%ba%e6%bc%8f%e6%b4%9e%e6%b5%85%e6%9e%90/

(0)
adminadmin
上一篇 2014年10月19日
下一篇 2014年10月21日

相关推荐

  • 利用图挖掘的内部威胁检测方法

    随着图神经网络的广泛应用,以及越来越多的组织和企业关注内部威胁,利用图挖掘的方法检测内部威胁受到越来越多研究者的重视。本次报告介绍了利用图挖掘内部威胁检测方法的整体架构,以及如何从…

    2022年6月14日
    3.6K
  • 极端多标签文本分类

    极端多标签文本分类旨在为每个文本分配大量可能的标签,处理标签数量巨大和数据稀疏性问题。该技术通过高效的特征选择、标签嵌入和深度学习模型,提高分类准确性和速度。极端多标签文本分类广泛…

    2024年9月17日
    3.2K
  • 音频事件识别参数优化方法

    目前音频处理领域各种系统的参数优化研究,通常把系统的各个层次(一般包括特征提取、特征向量生成、模型训练等)割裂开来进行相互独立的参数寻优,再将独立寻优结果进行简单组合,构成系统的参…

    2015年1月28日
    3.6K
  • 联邦学习的后门攻击方法

    联邦学习在保证数据安全和隐私的情况下解决了数据孤岛和数据碎片化问题,主要分为横向联邦学习、纵向联邦学习和联邦迁移学习。本次学术报告首先介绍联邦学习的历史现状、分类及应用场景,然后通…

    2022年8月30日
    3.7K
  • 深度神经网络中的后门攻击

    深度神经网络在图像识别、语音处理以及机器翻译等领域具有良好的预测性能,但是由于深度神经网络对决策结果可解释性的缺乏以及解决训练开销而寻求的外包训练的安全难以有效保证,都导致深度神经…

    2020年12月7日
    4.0K
  • Dropout随机失活

    具有大量参数的深度神经网络是非常强大的机器学习系统。然而,在这样复杂的网络中,过拟合的问题难以解决。复杂的网络结构和缓慢的运行速度导致我们很难在测试时通过组合许多不同大型神经网络的…

    2022年1月21日
    3.1K
  • 成员推理攻击和防御

    机器学习已经演化为了一种服务模式,即机器学习即服务模式。互联网公司或提供模型训练接口,或提供模型预测接口给用户以提供相应的服务。但是,在提供服务的整个过程中,机器学习模型不可避免的…

    2021年6月24日
    4.9K
  • 多人协作开发Git使用介绍

    本报告介绍多人协作开发中Git的使用,通过讲述版本控制的概念和比对不同版本控制的区别,详细阐述Git底层工作原理及Git多人协作流程和核心用法,掌握Git相关基本知识及Git的核心…

    2023年2月6日
    3.2K
  • 基于图神经网络的中文短文本匹配方法

    本次报告介绍一种基于图神经网络的中文短文本匹配模型,采用图结构的多粒度输入解决中文文本分词错误、不一致、歧义等问题造成的匹配性能下降问题。同时,报告介绍了文本匹配的研究现状,帮助大…

    2020年6月27日
    4.2K
  • 基于图的课程推荐方法

    课程推荐在人机协同、个性化学习平台等智能教育系统中具有重要价值,显著提升了模型对用户兴趣动态变化的建模能力与推荐效果。本次报告将介绍课程推荐任务,分析其研究背景与应用意义,并重点讲…

    2025年4月22日
    3.1K