格式化字符串漏洞利用时计算的偏移到底是什么?

我们平时在自己做题或者是看大佬们的wp时都会看见这种说法

说法一:

说法二:


相信有不少半路出家的小白都和我一样都只是知其然不知其所以然,那这里所说的“偏移”到底是什么意思呢?

我们结合这道题来详细讲一讲这些个偏移量所具体代表的意思

先来看伪代码

//main函数
void __fastcall __noreturn main(int a1, char **a2, char **a3)
{int v3; // [rsp+24h] [rbp-Ch] BYREFunsigned __int64 v4; // [rsp+28h] [rbp-8h]v4 = __readfsqword(0x28u);sub_4009FF();puts("Welcome to the battle ! ");puts("[Great Fairy] level pwned ");puts("Select your weapon ");while ( 1 ){while ( 1 ){Menu();__isoc99_scanf("%d", &v3);if ( v3 != 2 )break;sub_4008EB();}if ( v3 == 3 ){puts("Bye ");exit(0);}if ( v3 == 1 )sub_400960();elseputs("Wrong!");}
}//显示开始菜单
int Menu()
{puts("1. Stack Bufferoverflow Bug ");puts("2. Format String Bug ");return puts("3. Exit the battle ");
}//分支2
unsigned __int64 sub_4008EB()
{char buf[136]; // [rsp+0h] [rbp-90h] BYREFunsigned __int64 v2; // [rsp+88h] [rbp-8h]v2 = __readfsqword(0x28u);memset(buf, 0, 0x80uLL);read(0, buf, 0x7FuLL);printf(buf);return __readfsqword(0x28u) ^ v2;
}

从伪代码中可知这道题需要先使用格式化字符串漏洞泄露出canary的地址,然后再使用栈溢出漏洞覆盖返回地址,因为重点是分析偏移的意义,这里我们着重分析前半部分。

我们看到分支2,这里有一个明显的格式化字符串漏洞,就是printf函数的输出是由输入者自定义的,并且没有给出格式化字符串,所以我们可以通过给输入buf加上自定义的格式化字符串以泄露出canary的值

观察汇编代码,我们注意到了main函数中存在着canary值的判断

.text:000000000040094A                 mov     rax, [rbp+var_8]
.text:000000000040094E                 xor     rax, fs:28h
.text:0000000000400957                 jz      short locret_40095E
.text:0000000000400959                 call    ___stack_chk_fail

先是把rbp+var_8移到了rax寄存器中,然后再对rax的值进行判断,从这里可以看出canary的值被存放在rbp+var_8的位置,下面查看var_8的值

栈结构

-0000000000000008 var_8           dq ?
+0000000000000000  s              db 8 dup(?)
+0000000000000008  r              db 8 dup(?)
+0000000000000010
+0000000000000010 ; end of stack variables

所以,canary被存放在rbp-0x8的位置

那么canary到我们的格式化字符串的输入存放位置有多远呢?

unsigned __int64 sub_4008EB()
{char buf[136]; // [rsp+0h] [rbp-90h] BYREFunsigned __int64 v2; // [rsp+88h] [rbp-8h]v2 = __readfsqword(0x28u);memset(buf, 0, 0x80uLL);read(0, buf, 0x7FuLL);printf(buf);return __readfsqword(0x28u) ^ v2;
}

我们可以看到输入buf的位置在rbp-0x90的位置,所以第一个偏移的位置就找出来了,就是buf距离canary的位置:0x90-0x8 = 0x88(十六进制别看错了

第二个偏移需要涉及到函数参数的获取方式

由于这个程序为64位程序,所以输入输出等函数的参数获取方式是栈与寄存器结合,而字符串类的参数自然是存放在栈中的(我觉得是因为因为这种参数大小不定,寄存器可能放不下)

其他类型函数获取参数具体方式可以看我的另一篇文章

函数参数获取方式

首先来看分支2中的read函数,read函数先在输入缓冲区中获取我们的输入,然后把输入保存在buf位置,然后read函数执行结束,执行printf函数,print函数首先查看格式化输出的字符串,然后严格地按照格式化字符串所指示的输出方式输出栈中的元素

但是,printf函数千算万算没想到啊,它所信任依赖的格式化字符串是用户(某个黑心的pwn手)输入的,很快啊,一下子就输出了canary的值,所以这个偏移实际上就是printf函数的栈顶到我们本应输出的字符串(buf)的位置。为了更清晰地说明这个问题,使用图表的方式解释这个问题。

栈帧结构:

高地址
| | 较早的栈帧
|堆|
| | 调用者rbp ——父函数(调用者)栈帧——
|栈| 参数n
| |
|生| 参数1
| | ——调用者返回地址——
|长| 调用者rbp ——子函数(被调用者)栈帧——
| | 保存的寄存器
|方| 局部变量
| |
\ 向 /
\/ 局部变量
低地址 栈顶指针rsp

在子函数调用时,执行的操作为:

  • 函数将调用参数从后向前压栈
  • 将返回地址压栈保存
  • 跳转到子函数起始地址执行
  • 子函数将父函数栈帧起始地址(rbp) 压栈
  • 将 %rbp 的值设置为当前 %rsp 的值,即将 %rbp 指向子函数栈帧的起始地址

所以,第二种情况所说的偏移量实际上就是printf函数(子函数)栈顶到main函数(父函数)其中某一个参数的偏移量,也就是到buf的偏移量。

这篇文章从汇编层面说明了printf函数执行时可能会出现的漏洞,同时顺带着粗略地介绍了函数调用时的栈帧结构。如果对于格式化字符串漏洞的利用方式感兴趣的话可以戳下面的链接看看我的另一篇文章。才疏学浅,文中如有错误欢迎各位大佬在评论区批评指正~~~

格式化字符串漏洞

格式化字符串漏洞利用时计算的偏移到底是什么?相关推荐

  1. (Buuctf) [第五空间2019 决赛]PWN5 简单格式化字符串漏洞利用

    这题是个基本格式化字符串漏洞利用; 满足if条件即可得到答案; 使 nptr 与 dword_804C044 相等即可; 可以使我们利用的是 第一次的输入输出; addr=0x804C044 payl ...

  2. 格式化字符串漏洞利用 五、爆破

    五.爆破 原文:Exploiting Format String Vulnerabilities 作者:scut@team-teso.net 译者:飞龙 日期:2001.9.1 版本:v1.2 当利用 ...

  3. 格式化字符串漏洞利用 三、格式化字符串漏洞

    三.格式化字符串漏洞 原文:Exploiting Format String Vulnerabilities 作者:scut@team-teso.net 译者:飞龙 日期:2001.9.1 版本:v1 ...

  4. Linux下的格式化字符串漏洞利用姿势

    [转]http://www.cnblogs.com/Ox9A82/p/5429099.html linux最早的漏洞防护机制nx-stack刚刚出现后就有人想出了突破方法.那就是只有栈是不可执行,而除 ...

  5. 格式化字符串漏洞利用 七、工具

    七.工具 原文:Exploiting Format String Vulnerabilities 作者:scut@team-teso.net 译者:飞龙 日期:2001.9.1 版本:v1.2 一旦利 ...

  6. 格式化字符串漏洞利用 六、特殊案例

    六.特殊案例 原文:Exploiting Format String Vulnerabilities 作者:scut@team-teso.net 译者:飞龙 日期:2001.9.1 版本:v1.2 有 ...

  7. 格式化字符串漏洞利用

    学习资料: https://ctf-wiki.github.io/ctf-wiki/pwn/linux/fmtstr/fmtstr_exploit/                        ht ...

  8. linux获取字符格式化,Linux 格式化字符串漏洞利用

    目的是接觸一些常見的漏洞,增加自己的視野.格式化字符串危害最大的就兩點,一點是leak memory,一點就是可以在內存中寫入數據,簡單來說就是格式化字符串可以進行內存地址的讀寫.下面結合着自己的學習 ...

  9. 格式化字符串漏洞利用 一、引言

    一.引言 原文:Exploiting Format String Vulnerabilities 作者:scut@team-teso.net 译者:飞龙 日期:2001.9.1 版本:v1.2 这篇文 ...

最新文章

  1. 损失函数之Cross-Entropy介绍及C++实现
  2. 浏览器获取浏览历史_浏览器历史的未来
  3. bzoj 4559 [JLoi2016]成绩比较 —— DP+拉格朗日插值
  4. HDU 5131 Song Jiang's rank list
  5. python的[:-1]和[::-1]用法及结果实例(取反、删除末尾字符串)
  6. 不需要安全实验证也可以开微信号_热门行业:电子专用设备工程师证考试报名时间及报名须知...
  7. 图(网)的存储结构(数组存储表示即邻接矩阵、邻接表)
  8. 将图的广度优先遍历在邻接矩阵和邻接表存储结构上分别实现_《青岛大学-王卓-数据结构》B站学习...
  9. vvv在线文档导出工具_墙裂推荐 | 在线文档编辑工具
  10. bootice添加黑苹果引导_Clover(四叶草)引导多系统(Linux亦可),黑苹果引导教程
  11. 二、通用、布局、导航组件
  12. 如何查看所有已安装的Windows驱动程序的列表
  13. 注册Apple ID -- 常识
  14. python推箱子代码详细讲解_python实现推箱子游戏
  15. python中整数类型取值范围有没有限制_python 数据库取值范围内
  16. matlab读取txt数据文件
  17. js 递归创建文件夹
  18. 如果生活中有什么结解不开,那就打个蝴蝶结吧
  19. 外汇交易与实务--外汇交易市场
  20. linux网络工具iproute2的使用简介 ip addr

热门文章

  1. 新浪随机图片壁纸API接口,刷新网页换背景接口
  2. 2013年最忧伤的句子
  3. 在线书架html代码大全,在线书架
  4. 我的世界java额外参数_我的世界超平坦自定义部分参数
  5. [Odoo] Odoo 上传附件 attachment
  6. NBIOT开发(一):NBIOT模组以及芯片厂家都有哪些?
  7. Ubuntu 22.10 (Kinetic Kudu) 发布
  8. 双重 for循环概述
  9. 【论文笔记】Rethinking Semantic Segmentation from a Sequence-to-Sequence Perspectivewith Transformers
  10. 减肥平台期突破宝典,你必须拥有!