漏洞分析技术_栈溢出漏洞

news2024/10/25 18:23:39

1. 栈溢出漏洞概述

栈溢出漏洞是当程序在栈内存中写入数据超出预定容量时,导致数据溢出并覆盖关键的栈内容(如函数返回地址或控制信息),进而使攻击者能够执行任意代码或导致程序崩溃。该漏洞通常发生在没有适当边界检查的情况下,尤其是在使用不安全的函数处理用户输入时。栈溢出可能导致控制流劫持,允许攻击者接管系统。为了防止这种漏洞,常用的防护措施包括启用栈保护机制、使用安全函数和进行严格的输入验证。

2. 基础知识

2.1 Intel 64架构

Intel 在 2002 年引入了 64 位架构,这是因为 x86 架构的 32 位特性在设计上达到了极限。该架构包括四个通用寄存器(RAX、RBX、RCX、RDX),它们的低 32 位分别与原来的 32 位寄存器(EAX、EBX、ECX、EDX)重叠共用。此外,还引入了指针寄存器(RIP、RBP、RSP、RSI、RDI),以及额外的八个通用寄存器(R8 到 R15),从而增强了处理能力和内存寻址范围。

数据寄存器(也称为通用寄存器):主要用于存储操作数和运算结果。根据位宽不同,常用的数据寄存器包括 64 位的 RAX、RBX、RCX、RDX,32 位的 EAX、EBX、ECX、EDX,以及 16 位的 AX、BX、CX、DX。它们在不同位宽的操作中共享同一个物理寄存器,低位寄存器作为高位寄存器的一部分使用。

变址寄存器:主要用于存放存储单元在段内的偏移量。64 位架构下常用的变址寄存器包括 RSI 和 RDI,而 32 位和 16 位架构下分别使用 ESI、EDI 和 SI、DI。这些寄存器在地址计算、数组访问等场景中起到关键作用。

指针寄存器:主要用于存储堆栈内存储单元的偏移量,能够实现多种寄存器操作数的寻址方式。常见的指针寄存器包括 64 位的 RBP 和 RSP,32 位的 EBP 和 ESP,以及 16 位的 BP 和 SP。其中,BP(基指针)用于直接存取堆栈中的数据,而 SP(堆栈指针)仅用于访问栈顶。在不同的位宽架构下,这些寄存器对应的作用相同,但位宽不同决定了其使用的灵活性和存储能力。

段寄存器:根据内存分段管理模式而设置的,用于存储段的起始地址。通过段寄存器的值与一个偏移量组合,能够形成一个较大的物理地址,从而访问较大的内存空间。常见的段寄存器包括:CS(代码段寄存器)用于存储代码段的段值,DS(数据段寄存器)用于数据段,ES(附加段寄存器)用于附加数据段,SS(堆栈段寄存器)用于堆栈段,FS 和 GS 段寄存器则用于附加数据段。这些段寄存器通过结合段值与偏移量,实现对内存的高效访问。

指令指针寄存器:用于存放下一条即将执行的指令在代码段中的偏移量,它确保处理器能够正确顺序执行指令。常见的指令指针寄存器包括 RIP(64 位)、EIP(32 位)和 IP(16 位),分别对应不同位宽的处理器架构。

2.2 函数与函数栈

栈是一种先进先出的特殊数据结构,主要用于存储程序运行时的临时数据和地址,支持函数的执行和嵌套调用。栈的分配由编译时确定,无法由程序员直接控制,栈中保存着线程或进程的局部变量。不同的线程或进程有各自独立的栈空间,且栈的位置不同,程序在运行过程中不同线程和进程之间不能互相访问对方的栈地址。

栈帧结构:在 64 位程序中,当执行 call 指令时,程序会将下一条指令的地址压入栈中,以便函数执行完后可以返回调用点。call 指令完成压栈操作后,程序会跳转到被调用的函数开始执行。

push rbp   ; 保存父函数的栈底
mov rbp, rsp   ; 设置当前函数的栈底
sub rsp, 0x70  ; 为当前函数分配栈空间

在函数调用结束时,程序会执行 leaveret 指令。leave 指令等同于执行了两条指令:mov esp, ebppop ebp,将 ebpesp 两个指针恢复到函数被调用前的状态。ret 指令则将栈中的返回地址弹出到 rip 寄存器中,跳转回到父函数继续执行。这两个操作的组合确保了函数调用结束时栈帧和返回地址的正确恢复。

参数传递:函数通过传递参数来确定其具体的处理内容,而这些参数是通过栈来传递的。在下方的代码示例中,函数 foo 接受两个整数参数 xy,并通过栈传递给函数。在函数执行过程中,printf 打印出传递的参数值。在主函数 main 中,调用 foo(1, 2),这时 12 被传递到函数 foo 的参数 xy 中,完成输出。

#include <stdio.h>

int foo(int x, int y) {
    char a[10];
    printf("%d %d\n", x, y);
}

int main() {
    foo(1, 2);
}
  • 在 32 位操作系统中,函数的参数是通过直接压入栈的方式传递的,即参数被写入栈上。当执行 call 指令和函数内建立新栈时,ebp 保存的是父函数的栈底地址,依次向下是程序的返回地址和传递的参数。在函数调用时,push 指令会将数据压入栈,使得栈顶向低地址偏移。函数执行完毕后,通过 add esp, 0x10 指令恢复 esp,将栈顶指针恢复到调用函数前的状态,以保证程序能正确继续执行。这一过程确保了函数参数的正确传递和栈的完整性。
  • 在 64 位操作系统中,函数的参数不再直接通过栈传递,而是通过寄存器传递,常用的寄存器包括 `rdi`、`rsi`、`rdx`、`rcx`、`r8`、`r9` 等。只有当超出寄存器能存放的参数数量时,才会使用栈来存储额外的参数。在 64 位程序的反汇编结果中,函数参数直接赋值给 `edi` 和 `esi`,而不是压入栈中。由于没有栈的压入操作,函数执行完毕后也不需要对应的栈恢复操作,这简化了函数调用过程中的栈操作。

数据调用:栈中的数据在函数调用时主要分为两部分:传递的参数和局部变量。在函数调用中,传递的参数会被压入栈,局部变量则通过偏移量访问。例如,`printf` 函数的两个参数由父函数传递,第一个参数和第二个参数会依次压入栈中。而代码中的 `mov` 指令操作的是局部变量(如数组 `a` 的数据)。不论是参数还是局部变量,都是通过栈底指针(如 `ebp`)加上偏移量的方式进行读取和操作,这是一种统一的访问机制。

3. 漏洞原理

栈溢出的原理:栈溢出产生的原因通常是因为在编写代码时,程序员未对数组或字符串等变量的边界进行足够的检查。栈溢出漏洞的出现伴随两件事:程序向栈上写入一组数据,并且这些数据的长度没有经过有效的验证。当写入的数据过多时,会覆盖栈上其他变量甚至关键的地址(如返回地址),从而导致攻击者能够利用这一漏洞进行控制,篡改程序的执行流或获取未授权的访问。

栈溢出的危害:修改父函数的栈底地址、篡改函数的返回地址以及修改结构化异常处理(SEH)链表指针。这些操作会导致程序的执行流被攻击者控制,从而可能执行恶意代码或破坏程序的正常运行,带来严重的安全隐患。

4. 漏洞分析

#include<stdio.h>
#include<string.h>

int hackhere(){
    printf("Congratulations! You hacked me now.\n");
}

int foo(){
    printf("Wrong username!\n");
}

int main(){
    char tmp[10];
    char username[10];
    printf("Give me your username:");
    scanf("%s", username);
    if(strlen(username) == 4 && !strcmp(username, "admin")){
        hackhere();
    } else {
        foo();
    }
}

通过代码分析可以发现,在正常情况下,满足 if 语句条件(即用户名长度为 4 且等于 "admin")是非常困难的。通过观察程序流程可以看出,main 函数中在栈上声明了一个名为 username 的字符数组。但在读取输入时,未对输入的长度进行限制或检测,这导致可以通过 scanf 函数输入超过 username 数组长度的字符,进而引发栈溢出。

使用 IDA 工具对程序进行静态反汇编,找到 `hackhere` 函数的地址 `0x4006D6` 以及 `main` 函数执行结束前的地址 `0x4006F8`。通过反汇编工具,能够识别这些关键地址,以便进一步分析程序通过分析可以发现,s 的地址是用户输入的 username 字符串的起点。根据变量声明后的注释,s 的地址与当前栈 rsp 相同,且与 rbp 之间相隔 32 个字符。这意味着,写入 32 个字符后可以覆盖 rbp 所指向的父函数栈底地址。要进一步覆盖 rbp 所指向的父函数栈底地址相邻的函数返回地址,只需在 32 个字符后再填充 8 个字符,共 40 个字符即可完成覆盖和修改。的执行流程和调试过程。在ida中按F5反编译main函数,得到如下代码:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s[24]; // [rsp+0h] [rbp-20h] BYREF
  unsigned __int64 v5; // [rsp+18h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  printf("Give me your username:");
  __isoc99_scanf("%s", s);
  if ( strlen(s) == 4 && !strcmp(s, "admin") )
    hackhere();
  else
    foo();
  return 0;
}

通过分析可以发现,s 的地址是用户输入的 username 字符串的起点。根据变量声明后的注释,s 的地址与当前栈 rsp 相同,且与 rbp 之间相隔 32 个字符。这意味着,写入 32 个字符后可以覆盖 rbp 所指向的父函数栈底地址。要进一步覆盖 rbp 所指向的父函数栈底地址相邻的函数返回地址,只需在 32 个字符后再填充 8 个字符,共 40 个字符即可完成覆盖和修改。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2223461.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

win10怎么卸载软件干净?电脑彻底删除软件的方法介绍,一键清理卸载残留!

电脑上经常会下载各种各样的软件来协助我们办公&#xff0c;不同的软件能够满足不同的需求。 但是不少软件可能使用频率没有那么高&#xff0c;甚至完全不使用。这个时候就需要将这些不常用的电脑软件卸载掉了&#xff0c;卸载软件能够释放一定的存储空间&#xff0c;提高电脑…

封装echarts组件,即插即用(附源码)

前言&#xff1a;最近一个项目刚收工&#xff0c;分享一个常用的封装echarts的组件。 一、直接上组件代码 <template><el-card class"echart-card" shadow"hover"><template v-slot:header><div class"card-header">&…

[网络协议篇] UDP协议

文章目录 1. 简介2. 特点3. UDP数据报结构4. 基于UDP的应用层协议5. UDP安全性问题6. 使用udp传输数据的系统就一定不可靠吗&#xff1f;7. 基于UDP的主机探活 python实现 1. 简介 User Datagram Protocol&#xff0c;用户数据报协议&#xff0c;基于IP协议提供面向无连接的网…

郑州地铁携手百望云,以数电票平台升级打造坚实便民惠民服务能力

随着城市的快速发展&#xff0c;地铁成为很多大城市市民出行的主力工具。为民众出行提供安全、便捷、合规的出行服务&#xff0c;成为相关机构的重点工作。 近日&#xff0c;郑州地铁集团有限公司&#xff08;以下简称“郑州地铁”&#xff09;与百望云达成合作&#xff0c;开…

免杀对抗—特征码修改花指令资源修改加壳保护

前言 今天主要是讲这个特征码定位以及这个花指令&#xff0c;资源修改这个东西其实有点投机取巧啦&#xff0c;至于这个加壳之前也讲过了&#xff0c;直接工具搞就行。那么什么是特征码定位呢&#xff0c;众所周知&#xff0c;杀软是通过特征码来检测我们的exe是否是后门的&am…

老外说“奶茶”不叫“milk tea”?!那叫什么?柯桥英语口语学习生活日语培训

奶茶的英文怎么说&#xff1f; 其实&#xff0c;“奶茶”在英文中有多种表达方式&#xff0c;但最常见且准确的应该是“tea with milk”。这种表达方式直接描述了奶茶的本质——茶与牛奶的结合。当然&#xff0c;你也可以用“milky tea”来表达&#xff0c;但相对来说&#xf…

探索自然之美:SpringBoot驱动的安康旅游网站开发

第一章 绪论 1.1 研究现状 时代的发展&#xff0c;我们迎来了数字化信息时代&#xff0c;它正在渐渐的改变着人们的工作、学习以及娱乐方式。计算机网络&#xff0c;Internet扮演着越来越重要的角色&#xff0c;人们已经离不开网络了&#xff0c;大量的图片、文字、视频冲击着我…

基于SpringBoot的酒店管理系统的设计与实现

摘要 酒店管理系统的设计旨在提供快捷高效的住宿资源管理方案&#xff0c;帮助管理员实现对酒店内房间、客户信息、订单的全方位管理&#xff0c;同时为用户提供便捷的预订和查询功能。本系统基于Spring Boot框架&#xff0c;结合前端框架和数据库设计&#xff0c;构建一个用户…

基于双目立体视觉的图像匹配与测距

基于双目立体视觉的图像匹配与测距 Image-matching-and-ranging-based-on-binocular-stereo-vision 摘要 双目立体视觉是计算机视觉范畴的核心之一&#xff0c;它利用双目相机来获得目标物体的图像&#xff0c;经过物体图像处理之后得到目标物体所在场景环境的三维信息&…

邮件系统改造升级,让办公更智能、更高效!

在当今的商业环境中&#xff0c;电子邮件扮演着至关重要的角色&#xff0c;它是企业沟通的桥梁和信息传递的枢纽。然而&#xff0c;随着企业规模的扩大和业务需求的增长&#xff0c;传统的电子邮件系统可能会变得力不从心&#xff0c;无法满足日益增长的沟通需求。因此&#xf…

【C#】WPF 依赖属性,PasswordBox中的Password属性绑定

1. 关于依赖属性 <TextBox x:Name"sourceTBox" /> <TextBlock x:Name"tb" Text"{Binding Text,ElementNamesourceTBox}" />源对象&#xff1a; TextBox目标对象&#xff1a; TextBlock目标属性&#xff1a; TextBlock -> Text …

多个立方体盒子组成

效果&#xff1a; 知识了解&#xff1a; 在同一水平上&#xff0c;盒子经纬度计算&#xff1a;经度有误差&#xff0c;纬度没有误差 纬度计算&#xff1a;lat50/111320 约等于0.000449 经度计算&#xff1a;lon50/111320*cos(纬度) 约等于0.000519 一个立方体&#xff1a; // 添…

微信小程序性能优化 ==== 合理使用 setData 纯数据字段

目录 1. setData 的流程 2. 数据通信 3. 使用建议 3.1 data 应只包括渲染相关的数据 3.2 控制 setData 的频率 3.3 选择合适的 setData 范围 3.4 setData 应只传发生变化的数据 3.5 控制后台态页面的 setData 纯数据字段 组件数据中的纯数据字段 组件属性中的纯数据…

Hadoop-001-本地虚拟机环境搭建

一、安装VMware 官方下载VMware&#xff1a; https://vmware.mdsoft.top/?bd_vid5754305114651491003 二、下载镜像文件 阿里云镜像仓库&#xff1a; https://mirrors.aliyun.com/centos/ 本文档使用 CentOS-7-x86_64-DVD-1810-7.6.iso 搭建虚拟机 三、搭建虚拟机 1、编辑…

vue3 腾讯地图 InfoWindow 弹框

1、vue项目index.html引入地图js 2、页面使用 <script setup lang"ts"> import { useMapStore } from //store;defineOptions({ name: PageMap }); const emits defineEmits([update:area, update:address, update:latitude, update:longitude]); const prop…

【Java】SpringBoot实现MySQL数据库的增删查改

目录 1. 项目介绍 2. 相关代码 2.1 项目配置 2.2 SQL语句 2.3 数据访问层 2.4 业务逻辑层 2.5 Web表现层 3. 结果展示 4. 源码获取 1. 项目介绍 SpringBoot是一个轻量级框架&#xff0c;简化了Spring应用的开发和配置。相比较SSM框架&#xff0c;极大的简化了SSM中XM…

Android Navigation传递复杂参数(自定义)

打开要添加参数的navigation文件 使用Design视图 点击右侧Arguments的添加("")按钮 根据自定义类所继承的序列化接口选择这两项其中的一个 选择或者在搜索框检索你的类&#xff0c;然后点击OK&#xff0c;回到前一界面点击ADD即可 其他的操作就跟基本类型用法一样了

C++中指针类型、引用类型、值类型

定义&#xff1a; 1. 带 * 的声明&#xff1a;指针类型 声明方式&#xff1a;MyClass* obj; 是一个 指针类型&#xff0c;表示 obj 是一个指针&#xff0c;可以指向 MyClass 类型的对象。 指针特点&#xff1a; 指针存储的是对象的地址&#xff0c;可以为空&#xff08;null…

新的Midjourney就是一个增强版的Photoshop,你现在可以轻松的用它换衣服、换发型了

好久没有聊 Midjourney 了&#xff0c;昨晚他们发布了一项引人注目的新功能&#xff1a;AI 图像编辑&#xff0c;一个基于网页的加强版的 Photoshop 呼之欲出&#xff0c;让我大为震撼&#xff0c;也让用户们赞叹不已。 基于现有图像进行参考&#xff0c;进而生成新的图片&…

谈一谈 Netty 的内存管理 —— 且看 Netty 如何实现 Java 版的 Jemalloc

本文基于 Netty 4.1.112.Final 版本进行讨论 在之前的 Netty 系列中&#xff0c;笔者是以 4.1.56.Final 版本为基础和大家讨论的&#xff0c;那么从本文开始&#xff0c;笔者将用最新版本 4.1.112.Final 对 Netty 的相关设计展开解析&#xff0c;之所以这么做的原因是 Netty 的…