-
-
[原创]缓冲区溢出漏洞那些事:C -gets函数
-
发表于: 2022-3-25 16:33 15395
-
首发:https://sec-in.com/article/1606
缓冲区是在数据从一个位置传输到另一个位置时临时保存数据的内存存储区域。当数据量超过内存缓冲区的存储容量时,就会发生缓冲区溢出(或缓冲区溢出)。结果,试图将数据写入缓冲区的程序会覆盖相邻的内存位置。
缓冲区溢出原指当某个数据超过了处理程序回传堆栈地址限制的范围时,程序出现的异常操作。造成此现象的原因有:
攻击者通过覆盖应用程序的内存来利用缓冲区溢出问题。这会改变程序的执行路径,触发损坏文件或暴露私人信息的响应。例如,攻击者可能会引入额外的代码,向应用程序发送新指令以访问 IT 系统。
如果攻击者知道程序的内存布局,他们可以故意提供缓冲区无法存储的输入,并覆盖保存可执行代码的区域,用他们自己的代码替换它。例如,攻击者可以覆盖指针(指向内存中另一个区域的对象)并将其指向漏洞利用负载,从而获得对程序的控制权。
基于堆栈的缓冲区溢出更为常见,并利用仅在函数执行期间存在的堆栈内存。
基于堆的攻击更难执行,并且涉及将分配给程序的内存空间泛滥到超出用于当前运行时操作的内存。
C 和 C++ 是两种极易受到缓冲区溢出攻击的语言,因为它们没有内置的保护措施来防止覆盖或访问内存中的数据。Mac OSX、Windows 和 Linux 都使用用 C 和 C++ 编写的代码。
PERL、Java、JavaScript 和 C# 等语言使用内置的安全机制来最大限度地减少缓冲区溢出的可能性。
开发人员可以通过代码中的安全措施或使用提供内置保护的语言来防止缓冲区溢出漏洞。
此外,现代操作系统具有运行时保护。三种常见的保护措施是:
代码和操作系统保护中的安全措施是不够的。当组织发现缓冲区溢出漏洞时,它必须迅速做出反应以修补受影响的软件,并确保软件用户可以访问补丁。
根据STACK1_VS_2017.cpp代码进行修改
使用printf()函数输出提示信息,使用gets()函数获取用户输入信息
任意输入两个数值,不满足条件,程序运行完毕
诱因:char buf[2]; 代码部分解析---使用char 将变量buf声明成了一个拥有2个元素数组其中元素类型为字符.buf有了两个自己长度,
提示:u_int64 p =(u_int64)a-(u_int64)b; 代码部分对程序涉及变量了内存地址进行了一个减分计算并对赋值给变量 p,(为使其运算成立还对其进行了类型转义),结果可告知两个变量内存地址距离,方便溢出利用
隐患:使用gets()函数获取输入数据,因gets()函数无限读取数据并不检查缓冲区的大小限制,会将超出缓冲区的数据继续写入堆栈,导致存在溢出隐患。
为方便理解此处代码演示下:
在运行效果上可以看到超出堆栈空间的值继续写入堆栈导致覆盖了test在堆栈内对应的值,导致其数值进行了改变:test1-3456
反汇编分析其运行过程堆栈是如何变化的
有运行得知(外加源代码)程序初始关键词:test1初始值为test1
可通过此关键词,在反汇编程序快速定位到程序相关函数运行区域
在入口指令处下断点方便分析
并在实际运行发现运行到此处为显示相关特征字符信息,初步判断正确
将此区域字符串进行反编译与源码对照进一步验证
没汇编指令对照不太直观换个插件与工具,进行展示
未输入st值时test对应数据堆栈情况
000000000061FDE8 000000000061FE0A "test1"
输入后查看
000000000061FDE8 000000000061FE08 "123456"
000000000061FDF0 000000000061FE0A "3456" //之前为test1
根据此思路分析之前的示例程序
根据之前的思路定位关闭区域
定位特征代码:
根据特征代码搜索
在入口指令处下断点
运行看到一个变量的对应地址
继续运行看到另一个变量的地址
赞赏
- [原创]物联网安全:基础篇 4099
- 威胁情报小课堂:阻止活跃勒索软件的感染 2165
- [翻译]发现利用 Facebook 和 MS 管理控制台实施的 Kimsuky APT 攻击 7041
- 威胁情报小课堂:LockBit Black 2041
- 威胁情报小课堂:Nitrogen 2067