缓冲区溢出漏洞浅析

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日

相关推荐

  • 大模型赋能自动化渗透测试技术

    本次报告围绕大模型赋能的自动化渗透测试技术展开,首先阐述了渗透测试的基本概念、研究背景和研究意义,然后介绍了大模型赋能的自动化渗透测试技术的研究现状和常见的agent框架。接着详细…

    2026年1月26日
    75
  • 不完全多视图聚类技术

    不完全多视图聚类技术旨在处理多视图数据中部分视图缺失的问题,确保在数据不完整的情况下仍能进行有效的聚类分析。通过整合各视图的信息,该技术能够弥合视图之间的差异,提升聚类性能。其应用…

    2024年9月10日
    587
  • DQN深度强化学习算法

    本次学术报告主要给大家详细的介绍DQN算法原理及其调参细节,并且进行举例说明和总结以加深大家的理解。

    2020年5月31日
    1.0K
  • 二进制代码补丁存在性测试

    二进制代码补丁存在性测试(Patch Presence Test, PPT) 旨在检测目标二进制文件是否已应用特定补丁,以确保安全性和合规性。希望在这次学术报告中,大家掌握二进制代…

    2025年3月3日
    589
  • 异常检测算法

        iForest (Isolation Forest)孤立森林 是一个基于Ensemble的快速异常检测方法,具有线性时间复杂度和高精…

    学术报告 2017年11月27日
    766
  • 基于协同过滤的推荐算法

          推荐系统在现在的生活中随处可见,淘宝天猫的商品推荐,音乐软件的每日歌曲推荐等,协同过滤就是一种很受欢迎的推荐…

    2018年8月27日
    752
  • 模型窃取

    机器学习,尤其是神经网络,已广泛部署在行业环境中,模型通常被部署为预测服务。但是,具有对模型的查询访问权的对手可以窃取该模型以获得与远程目标模型基本一致的替代模型,这就是模型窃取攻…

    2021年5月10日
    2.9K
  • 数据样本的质量评估方法

    本报告主要介绍数据样本的质量评估方法。随着数据规模的不断扩大,如何有效评估数据样本的贡献成为提升模型性能和效率的关键问题。报告分析了当前领域内的主要评估方法,讨论了不同评估标准对模…

    2025年2月24日
    720
  • GBDT梯度提升决策树

          梯度提升决策树(GBDT)是集成学习中梯度提升方法(Gradient Boost)与决策树(Decision…

    2018年5月7日
    757
  • 文本生成大模型后门攻击研究

    研究文本生成大模型的后门攻击,揭示了现有文本大模型的后门风险。本次学术报告详细介绍了现有文本生成模型的后门分类方法以及基准数据集,在文本大模型的多个下游任务实现了后门攻击,并总结了…

    2025年3月24日
    990