缓存区溢出的原理分析和防范

article/2025/9/17 6:11:28

1.前言

        缓冲区溢出(buffer-overflow)是一种非常普遍、同时非常危险的漏洞,在各种操作系统、应用软件中广泛存在。缓冲区溢出攻击是利用缓冲区溢出漏洞所进行的攻击,轻则可以导致程序失败、系统关机等,重则可以利用它执行非授权指令,甚至获取系统特权,从而进行其它的非法操作。所以,了解缓冲区溢出攻击的原理以及如何防范缓冲区溢出攻击就变得十分重要。

2.缓冲区溢出

        想了解缓冲区溢出攻击,首先就要了解什么是缓冲区和缓冲区溢出。缓冲区是一块连续的计算机内存区域,可保存相同数据类型的多个实例。缓冲区可以是堆栈(自动变量)、堆(动态内存)和静态数据区(全局或静态)。在C/C++语言中,通常使用字符数组和堆中动态分配的内存(也称为“malloc”或“new”区域)之类内存分配函数实现缓冲区。

        操作系统所使用的缓冲区又被称为堆栈,在各个操作进程之间,指令被临时存储在堆栈当中,堆栈也会出现缓冲区溢出。理想情况是,程序检查数据长度并且不允许输入超过缓冲区长度的字符串。但是绝大多数程序都会假设数据长度总是与所分配的存储空间相匹配,这就为缓冲区溢出埋下隐患。当一个超长的数据进入到缓冲区时,超出部分就会被写入其他缓冲区,其他缓冲区存放的可能是数据、下一条指令的指针,或者是其他程序的输出内容,这些内容都被覆盖或者破坏掉。可见一小部分数据或者一套指令的溢出就可能导致一个程序或者操作系统崩溃。

3.缓冲区溢出攻击

        在本节,会着重说明攻击者如何利用缓冲区溢出来实施攻击,并通过几个示例来加深对于缓存区溢出攻击的理解。

3.1缓冲区溢出攻击原理

        缓冲区溢出的一个致命的使用就是让程序执行它本来不愿意执行的函数。这是一种常见的通过计算机网络攻击系统安全的方法。通常,输入给程序一个字符串,这个字符串包含一些可执行代码的字节编码,成为攻击代码。另外,还有一些字节会用一个指向攻击代码的指针覆盖返回地址。那么,执行ret指令的效果就是跳转到攻击代码。

        攻击者可以故意将精心制作的输入馈入程序,程序将尝试将该输入存储在不够大的缓冲区中,因此输入会覆盖连接到缓冲区空间的部分内存。如果程序的内存布局定义明确,则攻击者可以故意覆盖已知包含可执行代码的区域。然后,攻击者可以用自己的可执行代码替换这些代码,这可以大大改变程序的工作方式。

        缓冲区溢出漏洞攻击都是在寻求改变程序的执行流程,使它跳转到攻击代码,最为基本的就是溢出一个没有检查或者其他漏洞的缓冲区,这样做就会扰乱程序的正常执行次序。通过溢出某缓冲区,可以改写相近程序的空间而直接跳转过系统对身份的验证。原则上来讲攻击时所针对的缓冲区溢出的程序空间可为任意空间。

3.2缓冲区溢出攻击示例

3.2.1 strcpy溢出的攻击

        在学习c/c++的时候,就讲到了一些C类型的字符串函数不是安全的,比如strcpy没有检查长度会溢出,推荐使用strncpy。而使用strcpy就容易造成缓冲溢出,从而收到缓冲溢出攻击,下面将演示由使用strcpy导致溢出得攻击。

#include <string.h>
#include <stdio.h>
#include <stdlib.h>int main(int argc, char *argv[])
{if (argc != 2){printf("Invalid params\n");exit(1);}bool check_result = false;char pass[10];memset(pass,0,10);strcpy(pass, argv[1]);if (0 == strcmp("password", pass)){check_result = true;}if (check_result){printf("Check password succ!\n");}else{printf("Check password failed!\n");}return 0;
}

        上面的代码在linux系统中打开终端使用g++编译 g++ -o guess 1.c 生成可执行文件,然后输入 ./guess 0123456789012345运行,运行结果如下图所示。

图3-1 strcpy溢出攻击运行结果

        很显然我们输入的密码是错误的,我们预期中它会输出“Check password failed!”,但是通过运行结果我们可以看到,程序运行输出的是“Check password succ!”。说明尽管我们不知道密码是多少,通过缓冲区溢出,我们绕过了密码的验证逻辑,直接登陆了进去。

         上述check_result和pass两个变量由于是局部变量,故申请的时候是在栈上分配。由于栈是从高地址往低地址,所以从地址由低到高,check_result分配在pass后面,当进行strcpy操作的时候,因为没有检测输入长度,所以pass溢出了,会覆盖后面的内存区域。由于check_result在pass后面,所以当溢出足够的时候,check_result被改写了。缓存溢出就意味着要面临数据被异常改写的风险。

4.缓冲区溢出攻击防范

4.1强制写正确的代码的方法

        编写正确的代码是一件非常有意义但耗时的工作,特别像编写C语言那种具有容易出错倾向的程序(如:字符串的零结尾),这种风格是由于追求性能而忽视正确性的传统引起的。尽管花了很长的时间使得人们知道了如何编写安全的程序,具有安全漏洞的程序依旧出现。因此人们开发了一些工具和技术来帮助经验不足的程序员编写安全正确的程序。虽然这些工具帮助程序员开发更安全的程序,但是由于C语言的特点,这些工具不可能找出所有的缓冲区溢出漏洞。所以,侦错技术只能用来减少缓冲区溢出的可能,并不能完全地消除它的存在。除非程序员能保证他的程序万无一失,否则还是要用到以下部分的内容来保证程序的可靠性能。

4.2栈随机化

        使得栈的位置在程序每次运行时都有变化(主要受linux系统版本限制,老版本不支持栈随机化)。为了在系统插入攻击代码,攻击者不但要插入代码,还需要插入指向这段代码的指针(指向攻击代码的首地址/栈地址),这个指针也是攻击字符串的一部分。产生这个指针需要知道这个字符串放置的栈地址。老的系统版本,如果在相同的系统运行相同的程序,栈的位置是相当固定的。所以黑客可以在一台机器上研究透系统上的栈是如何分配地址的,就可以入侵其它主机。

实现的方式:程序开始时,在栈上分配一段0~n字节之间的随机大小的空间。分配的范围n必须足够大,才能获得足够多样的栈地址变化,但是又要足够小,不至于浪费程序太多的空间。

4.3栈破坏检测

        检测到何时栈被破坏(主要受GCC版本的限制,老的GCC版本不支持栈破坏检测)。从strcpy等函数我们可以看到,破坏通常发生在当超越局部缓冲区的边界时。在C语言中,没有可靠的方法来防止对数组的越界写。但是,我们能够在发生了越界写的时候,并且,在其还没有造成任何有害结果之前,尝试检测到它,并且把程序终止。

实现的方式:加入一种栈保护机制。 在栈帧中,紧接着局部缓冲区的位置放置一个哨兵(金丝雀),哨兵值是随机产生的,攻击者没有简单的方法能够知道它是什么。在恢复寄存器状态和函数返回之 前,程序检查这个金丝雀的值是否发生改变,如果发生改变立即终止程序。

4.4限制可执行代码区域

        消除攻击者向系统插入可执行代码的能力,一种方法是:限制那些能够存放可执行代码的存储器区域。在典型的系统中,只有保存编译器产生的代码的那部分存储器才需要是可执行的,其它部分可以被限制为只允许读和写。

        一般的系统允许三种访问的形式:读(从存储器读数据)、写(存储数据到存储器)和执行(将存储器的内容看作是机器级代码)。以前,x86体系结构将读和执行访问控制合并为1位的标志,这样任何被标记为可读的页都是可执行的。栈又要求必须是既可以读又可以写的,所以x86体系结构栈上的字节都是可执行的。也有一些体制,能够限制一些页是可读但是不可执行,但是这些体制一般都会带来严重的性能损失。

        实现的方式:AMD为它的64位存储器的内容保护引入了“NX”(No-eXecute,不执行)位,将读和执行访问模式分开,intel也跟进了。从这开始,栈可以被标记为可读、可写,但是不可执行。检查页是否可执行由硬件来完成,效率上没有损失。


http://chatgpt.dhexx.cn/article/2EBJjIfZ.shtml

相关文章

缓存溢出

缓存溢出&#xff08;Buffer overflow&#xff09;&#xff0c;是指在存在缓存溢出安全漏洞的计算机中&#xff0c;攻击者可以用超出常规长度的字符数来填满一个域&#xff0c;通常是内存区地址。在某些情况下&#xff0c;这些过量的字符能够作为“可执行”代码来运行。从而使得…

逆向基础:软件手动脱壳技术入门

前言&#xff1a; 大家好&#xff0c;我是周杰伦 这里整合了一下之前自己学习软件手工脱壳的一些笔记和脱文&#xff0c;希望能给新学软件逆向和脱壳的童鞋们一点帮助。 1 一些概念 1.1 加壳 加壳的全称应该是可执行程序资源压缩&#xff0c;是保护文件的常用手段。加壳过…

iOS逆向之脱壳工具creakerXI+,最简单、最适合新手的脱壳工具

在学习iOS逆向中&#xff0c;脱壳是必备技能之一&#xff0c;在网上看教程有使用 Clutch 和 dumpdecrypted 但是&#xff0c;不知道 是我操作问题&#xff0c;还是手机版本&#xff0c;以及APP版本更新问题 尝试了几次&#xff0c;都无法成功脱壳 最后在网上看到有大神分享其…

【How2RE】 UPX壳及脱壳方式

0x00 什么是壳 壳是另外在PE文件中包含的代码&#xff0c;并且不影响PE文件正常的执行。而壳也分为很多种&#xff0c;这里从UPX壳开始介绍。 0x01 压缩壳 压缩的分类 压缩的目的就是将体积大的可执行文件缩小的过程。分为损失压缩和非损失压缩两种。损失压缩是指不能100%还…

脱壳(中) 脱壳的方法

那些年我们一起脱过的衣裳&#xff0d;脱壳(中) 珈蓝夜宇 2015/10/29 10:42 0x01 我能在万花从中脱去壳的衣裳!&#xff08;续&#xff09; 3.3ESP定律法 3.3.1ESP定律介绍 ESP定律法是脱壳的利器&#xff0c;是国外友人发现的。有了ESP定律&#xff0c;可以方便我们脱掉大多…

脱壳简单总结

title: 脱壳 date: 2021-07-05 14:37:06 tags: RE 脱壳 1.概述&#xff1a; 1.壳&#xff1a; 一&#xff1a;加壳的目的&#xff1a;为了隐藏程序真正的OEP&#xff08;入口点&#xff09;&#xff0c;防止被破解。 二&#xff1a;加壳软件是一种在编译好可执行文件之后&…

最新乐加固脱壳详细教程(有图有真相)

一、前言声明&#xff1a; 本次破解是基于Xposed Installer框架&#xff0c;具体使用方法请上网查询。假设你已经安装好框架&#xff0c;按照下面的步骤&#xff0c;实现乐加固加固脱壳修复DEX&#xff0c;并且重打包运行。本次选择脱壳的APP是小猿搜题&#xff0c;特此声明&a…

脱壳之简单加密壳

一、简单分析与解密 脱壳最重要的三步&#xff1a;找原始OEP&#xff0c;转存文件&#xff0c;修复文件   压缩壳按照这三步就可以完成脱壳&#xff0c;而加密壳因为对PE文件的信息进行了加密处理&#xff0c;找到OEP只是刚开始&#xff0c;还需要将加密之后的代码、数据进行…

iOS完美脱壳

iOS端IPA脱壳 背景&#xff1a;在软件安全领域中&#xff0c;我们与黑产做对抗时&#xff0c;不是被动防守&#xff0c;自己也可以做攻击方&#xff0c;来验证我方软件是否安全。 关于iOS端逆向分析如&#xff1a;虚拟定位、虚拟设备、修改内存等&#xff0c;始终离不开脱壳。…

脱壳工具:Youpk的使用详解

一. Youpk概述 Youpk基于ART的主动调用的脱壳机&#xff0c;主要针对dex整体加固和各式各样的dex抽取加固。 目前 Youpk 只支持 pixel 1代。所以必须需要 pixel 1代手机&#xff0c;而且需要刷入对应的系统。 Youpk可以处理大部分的加固&#xff0c;一些企业版的加固也能处理…

使用upx脱壳工具脱壳

使用upx脱壳工具脱壳&#xff08;攻防世界新手第七题为例simple-unpack&#xff09; 查壳工具链接&#xff1a;https://www.52pojie.cn/thread-437586-1-1.html 脱壳工具链接&#xff1a;https://github.com/upx/upx/releases 先查壳 一般做到逆向的部分题的时候&#xff0c…

脱壳工具:反射大师的使用详解

一. 反射大师概述 一个脱壳插件工具&#xff0c;需要在 Xposed 环境中使用&#xff0c;支持市面上大多数加密壳。 反射大师简单容易使用&#xff0c;能脱掉大多数壳&#xff0c;很值得使用 二. 下载Xposed和反射大师 Xposed &#xff0c;一款可以在不修改 Android APK 的情…

逆向工具之脱壳神器反射大师(附脱壳环境搭建、脱壳实战)

相信点击进入这篇博客的小伙伴都知道并且搞过App逆向&#xff0c;不过有时候会遇到各种加壳的App&#xff0c;不让你反编译。但是道高一尺&#xff0c;魔高一丈&#xff0c;有正向加密&#xff0c;就有逆向解密。此篇博客博主带大家搭建脱壳环境&#xff0c;并且手动脱一个加了…

手动脱壳教程

一、什么是壳&#xff1f; 壳是指在一个程序的外面再包裹上另一段代码&#xff0c;保护里面的代码不被非法修改或反编译的的程序。它们一般先于程序运行&#xff0c;拿到控制权&#xff0c;然后完成它们保护软件的任务。 二、壳的加载过程 1、保存程序入口参数 …

简单脱壳教程笔记

文章目录 1、手脱UPX壳简介&#xff1a;脱壳&#xff1a;笔记&#xff1a;方法1&#xff1a;单步跟踪&#xff08;需要有耐心&#xff09;一、使用ODE插件二、tools按钮选择LordPE进行脱壳&#xff08;提前在SETUP PATHS里添加好&#xff09; 方法2&#xff1a;ESP定律法方法3&…

常用编程语言开发工具

编程语言开发工具可分为文本开发工具 和 集成开发工具。 文本开发工具的特点是 体积小&#xff0c;功能也不弱。 集成开发工具的特点是 体积大&#xff0c;功能强大。 1.文本编辑器 widows 下的 notepad&#xff08;记事本&#xff09; Unix下的 vim &#xff0c;这两个工具系…

开发工具:2022个人开发工具清单

目录 ​编辑 1、谷歌浏览器 2、腾讯文档 3、Notepad 4、IntelliJ IDEA 5、VisualStudio 6、VSCode 7、微信开发者工具 8、Navicat 9、PDManer 10、Git/Tortoise Git 11、Axure 12、NxShell 13、ApiPost 14、Xmind 15、Everything 16、WizTree 17、猿如意 …

开发工具推荐

1.前言 俗话说&#xff1a;“工欲善其事&#xff0c;必先利其器”。 为了助力大家的学习和进阶&#xff0c;本小节介绍几个对 Java 学习非常有帮助的 IDEA 插件&#xff0c;代码反编译和反汇编工具&#xff0c;以及非常不错的网站等。 2. IDEA 插件 首先不必多说&#xff0c…

【高效开发工具系列】开发工具

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…

Linux--开发工具

前言&#xff1a; 是不是看见10月24日有种莫名的亲戚&#xff0c;在信息技术行业&#xff0c;由于2101024&#xff0c;所以1GB 1024MB&#xff0c;1MB 1024KB&#xff0c;1KB 1024B。于是1024是程序员们最为敏感的数字&#xff0c;那么今天祝所有铁子们节日快乐&#xff01;…