在一个简单的pwn题目中探究执行系统调用前堆栈的对齐问题
题目介绍:在输入AAAAAAAAAAAAAAAAAAAAAAAAA后,程序会打开一个shell,这是为什么?字符串中的A能否更换为@?
1.程序接收输入AAAAAAAAAAAAAAAAAAAAAAAAA 获得shell的原理:
.text:0000000140001584 public vuln
.text:0000000140001584 vuln proc near ; CODE XREF: main+D↑p
.text:0000000140001584 ; DATA XREF: .pdata:000000014000F078↓o ...
.text:0000000140001584
.text:0000000140001584 DstBuf = byte ptr -10h
.text:0000000140001584
.text:0000000140001584 push rbp
.text:0000000140001585 mov rbp, rsp
.text:0000000140001588 sub rsp, 30h
.text:000000014000158C lea rax, [rbp+DstBuf]
.text:0000000140001590 mov r8d, 19h ; MaxCharCount
.text:0000000140001596 mov rdx, rax ; DstBuf
.text:0000000140001599 mov ecx, 0 ; FileHandle
.text:000000014000159E call read
.text:00000001400015A3 nop
.text:00000001400015A4 add rsp, 30h
.text:00000001400015A8 pop rbp
.text:00000001400015A9 retn
.text:00000001400015A9 vuln endp
可以看到写入的目标地址为rbp-10h处,read读入的字节数为19h,可以猜到read的输入覆盖了目标地址的16字节后,又覆盖了rbp的8字节,最后覆盖了地址的最低地址字节,由于此处地址是小端序,覆盖了地址的最低位,不难猜到,返回地址被修改到了原返回地址的附近的代码中,且根据输入AAAAAAAAAAAAAAAAAAAAAAAAA 和调用此函数的main函数代码对应的地址,可以推出地址被修改为0x0000000140001541附近的代码。
.text:0000000140001540 public backd00r
.text:0000000140001540 backd00r proc near ; DATA XREF: .pdata:000000014000F06C↓o
.text:0000000140001540 push rbp
.text:0000000140001541 mov rbp, rsp
.text:0000000140001544 sub rsp, 20h
.text:0000000140001548 lea rcx, Buffer ; "getshell"
.text:000000014000154F call puts
.text:0000000140001554 lea rcx, Command ; "C:\\Windows\\system32\\cmd.exe"
.text:000000014000155B call system
.text:0000000140001560 nop
.text:0000000140001561 add rsp, 20h
.text:0000000140001565 pop rbp
.text:0000000140001566 retn
.text:0000000140001566 backd00r endp
可以看到,该地址确实在一个名为backd00r的函数中,该函数执行系统调用获取了shell。
2.程序接收的输入中A能否更换为@
A对应ascii码为41,而@对应ascii码为40,更换后,ret指令将跳到0x0000000140001540处,多压栈了一次rbp,感觉上是可行的,因为即使堆栈不平衡应该也不会影响当前函数的调用,事实上前面的puts函数也确实能正常执行输出getshell字符串。但system却不能正常执行,使用xdbg动态调试,可以看到是在地址为0x7FFA3A437F64的语句:movaps xmmword ptr ss:[rsp+40],xmm6 处报访存异常。但不从push rbp开始时却没有这个问题。从这条语句开始分析,这条语句的意思是将xmm6浮点数寄存器保存的16字节内容存入栈中的地址,这时就不难想到是否是因为没有对齐的原因,查看此时栈中的地址,最低的16进制数不为0,确实没有对齐。

为了验证猜想,使用IDA将back00r函数修改如下,连续压入两个rbp,此时应该能对齐,此时用@代替A,确实能执行成功。
.text:0000000140001540
.text:0000000140001540 public backd00r
.text:0000000140001540 backd00r: ; DATA XREF: .pdata:000000014000F06C↓o
.text:0000000140001540 push rbp
.text:0000000140001541 push rbp
.text:0000000140001542 nop
.text:0000000140001543 nop
.text:0000000140001544 sub rsp, 20h
.text:0000000140001548 lea rcx, Buffer ; "getshell"
.text:000000014000154F call puts
.text:0000000140001554 lea rcx, Command ; "C:\\Windows\\system32\\cmd.exe"
.text:000000014000155B call system
.text:0000000140001560 nop
.text:0000000140001561 add rsp, 20h
.text:0000000140001565 pop rsi
.text:0000000140001566 retn
因此,使用@在此处不能代替A,虽然在执行系统调用时不会因为堆栈未平衡报错,但会在内核中一个mov语句拷贝16字节数据时因为地址未对齐而产生访存异常。
在一个简单的pwn题目中探究执行系统调用前堆栈的对齐问题的更多相关文章
- vue.js+webpack在一个简单实例中的使用过程demo
这里主要记录vue.js+webpack在一个简单实例中的使用过程 说明:本次搭建基于Win 7平台 Node.js 安装官网提供了支持多种平台的的LTS版本下载,我们根据需要来进行下载安装.对于Wi ...
- ASP.NET Core中的缓存[1]:如何在一个ASP.NET Core应用中使用缓存
.NET Core针对缓存提供了很好的支持 ,我们不仅可以选择将数据缓存在应用进程自身的内存中,还可以采用分布式的形式将缓存数据存储在一个“中心数据库”中.对于分布式缓存,.NET Core提供了针对 ...
- SCTF 2014 pwn题目分析
因为最近要去做ctf比赛的这一块所以就针对性的分析一下近些年的各大比赛的PWN题目.主防项目目前先搁置起来了,等比赛打完再去搞吧. 这次分析的是去年的SCTF的赛题,是我的学长们出的题,个人感觉还是很 ...
- c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程
c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...
- 谈一谈SQL Server中的执行计划缓存(下)
简介 在上篇文章中我们谈到了查询优化器和执行计划缓存的关系,以及其二者之间的冲突.本篇文章中,我们会主要阐述执行计划缓存常见的问题以及一些解决办法. 将执行缓存考虑在内时的流程 上篇文章中提到了查询优 ...
- 谈一谈SQL Server中的执行计划缓存(上)
简介 我们平时所写的SQL语句本质只是获取数据的逻辑,而不是获取数据的物理路径.当我们写的SQL语句传到SQL Server的时候,查询分析器会将语句依次进行解析(Parse).绑定(Bind).查询 ...
- OJ提交题目中的语言选项里G++与C++的区别(转)
G++? 首先更正一个概念,C++是一门计算机编程语言,G++不是语言,是一款编译器中编译C++程序的命令而已. 那么他们之间的区别是什么? 在提交题目中的语言选项里,G++和C++都代表编译的方式. ...
- [转]js中confirm实现执行操作前弹出确认框的方法
原文地址:http://www.jb51.net/article/56986.htm 本文实例讲述了js中confirm实现执行操作前弹出确认框的方法.分享给大家供大家参考.具体实现方法如下: 现在在 ...
- 进阶学习js中的执行上下文
在js中的执行上下文,菜鸟入门基础 这篇文章中我们简单的讲解了js中的上下文,今天我们就更进一步的讲解js中的执行上下文. 1.当遇到变量名和函数名相同的问题. var a = 10; functio ...
- SQL*PLUS中批量执行SQL语句
SQL*PLUS中批量执行SQL语句 今天由于工作的需要,要在CMD中批量执行大量的SQL语句,对于Oracle学习还处在入门阶段的我,只能硬着头皮到处去寻找资料(主要是网络资料,也包括自己的电子书) ...
随机推荐
- JavaScript -- 数据类型 --手稿
- 题解:AT_abc359_e [ABC359E] Water Tank
背景 中考结束了,但是暑假只有一天,这就是我现在能在机房里面写题解的原因-- 分析 这道题就是个单调栈. 题目上问你第一滴水流到每个位置的时间.我们考虑,答案其实就是比当前木板高且距离当前木板最近的那 ...
- ICPC游记
\[\Large\color{#FCAEBD}『2024ICPC河南站 游记』 \] Day 0 晚上打了场 \(ABC\),快成屎了,最后竟然还加分了. 晚上回家洗了个澡,收拾收拾东西,凌晨2点就睡 ...
- C#全局键盘监听(Hook)的使用
一.为什么需要全局键盘监听? 在某些情况下应用程序需要实现快捷键执行特定功能,例如大家熟知的QQ截图功能Ctrl+Alt+A快捷键,只要QQ程序在运行(无论是拥有焦点还是处于后台运行状态),都可以按下 ...
- Python pluggy框架基础用法总结
代码为例进行说明 实践环境 Python 3.6.5 pluggy 0.13.0 例1 注册类函数为插件函数 #!/usr/bin/env python # -*- coding:utf-8 -*- ...
- RIME:用交叉熵 loss 大小分辨 preference 是否正确 + 内在奖励预训练 reward model
文章题目:RIME: Robust Preference-based Reinforcement Learning with Noisy Preferences,ICML 2024 Spotlight ...
- php环境,性能优化
根据宝塔的推荐进行参数修改 我的是8G内存,修改成4G内存 下面是备份:修改前的 ; Start a new pool named 'www'.; the variable $pool can be ...
- 暑假java自学进度总结03
一.今日所学: 1.标识符命名规则: 必须: 1>由数字,字母,下划线,美元符组成: 2>不能以数字开头: 3>不能是关键字: 4>区分大小写: 建议: 1>命名方法,变 ...
- WorPress基础之谷歌GSC与GA统计代码安装
本篇文章讲介绍什么是GSC和GA以及如何安装. 什么是GSC GSC,全称为Google Search Console,由谷歌官方提供的网站管理工具,可帮助监控和维护网站在Google 搜索结果中的展 ...
- 如何在Arch Linux上构建Raspberry Pi虚拟环境
如何在Linux上构建Raspberry Pi虚拟环境 下面我们来讲讲如何使用QEMU来仿照树莓派环境.这里首先先分成两大类.第一类是跑比较老的,安全性较低的老树莓派,主要指代的是22年4月份发布 ...