ybw4cry 发表于 2021-7-23 10:53

pwn_动手调试栈溢出

今天我们来结合实际案例,通过调试的方式讲讲栈溢出

题目链接 https://buuoj.cn/challenges#rip

这是一道入门的pwn题目
笔者正在入门pwn,在调试过程中对栈溢出有了清楚的认识,所以分享给大家

这是一个64bit的elf
用ida打开 反汇编

文件中还有一个fun函数 供我们拿shell

main函数中s长度为15,gets函数中能够造成溢出
我们来看一下main的栈帧

图中的英文告诉我们,r和s分别代表返回地址 和 保存的寄存器
Frame size 也就是 栈帧 大小为0x10

按照主流的说法,我们把这个栈的return addr覆盖掉就能够达到栈溢出的效果
让我们深入的理解一下这句话。

我们说 栈溢出 栈溢出,究竟什么是栈溢出呢
就是在一些不安全的函数中,我们通过构造payload修改了栈的数据,改变了程序本来的运行逻辑
我们一起调试看看
调试过程中我使用的是win+wsl2

如果有小伙伴不会这种调试我可以再写一篇来讲讲怎么操作
那根据上面栈帧的图片,
我们可以知道 字符串s的长度为15字节,s占了8个字节,r占了8个字节
我们使用23(23=15+8)个任意字符和一个64位地址来对返回地址进行覆盖
程序就能够跳到我们想要的地址去执行

如上图 我们输入了15+8+8个字符,这时我们已经把s和r都覆盖了
leave = mov esp ebp; pop ebp;
执行了leave之后,ebp='11111111',esp指向'22222222',显然此时的esp是无效的

这里我们改变r的值,让程序去fun函数(fun函数在0x401186)

retn = pop eip;
F8之后 我们来到了fun函数

但是这里存在问题
执行到call _system的时候会导致Segmentation violation

参考了大佬的文章说64位linux调用system()时需要对其栈附加一个ret来保持堆栈平衡
不是特别清楚为什么要这样,我们尝试去做一下
这回我们输入了15+8+8+8个字符

我们把'22222222'改成任意一个retn指令的地址
把'33333333'改成fun的地址

retn之后还是到了fun函数里面
这次就可以正常运行system函数了


Chianti 发表于 2021-7-23 17:13

作者大大太厉害了吧:eee,我的技术有救了

0xK4ws 发表于 2021-8-7 18:57

问题出在libc2.23和libc2.27里的system函数的movaps指令 他要求操作数必须16字节对齐 否则触发异常我的理解是 因此就只需要保证movaps指令的目标地址是0x10的倍数 最好的方法当然是在返回地址前传入任意ret的地址 从而达到堆栈平衡

Horizon8945 发表于 2021-7-23 13:52

赞同!有源码吗,作者大大

csp3949160 发表于 2021-7-23 14:28

弱弱的问一下,这个有什么用?

ybw4cry 发表于 2021-7-23 17:04

Horizon8945 发表于 2021-7-23 13:52
赞同!有源码吗,作者大大

调试的文件在网站里可以下载哦
< 题目链接 https://buuoj.cn/challenges#rip >

hywf 发表于 2021-7-23 17:35

学习一下,感谢分享!

Tamluo 发表于 2021-7-23 18:26

好东西,来支持一波!!赞

Juce 发表于 2021-7-24 13:24


学习一下,感谢分享!

aonima 发表于 2021-7-24 19:40

学习到了

Horizon8945 发表于 2021-7-25 12:45

ybw4cry 发表于 2021-7-23 17:04
调试的文件在网站里可以下载哦
< 题目链接 https://buuoj.cn/challenges#rip >

谢谢大大
页: [1] 2
查看完整版本: pwn_动手调试栈溢出