lab-01: 缓冲区溢出
俞仲炜 3220104929 241015
注:关于源代码文件名中最后一个字母,l
指攻击本地文件的,r
指远程攻击的
stack buffer overflow 实践
试验过程
反汇编 sbof2
,发现栈帧大小为 0x110
缓冲区大小为 0x100
,从 [rbp-0x100]
开始
我们需要将返回地址覆盖为缓冲区起始地址,以此为起点设计 payload
现在 payload 里放 shellcode 用于执行,再填充剩余的缓冲区,即 256 - len(shellcode)
再覆盖 8 byte
的 old rbp
,到达返回地址处,覆盖上 buffer_addr
,结束
本地结果
结果截图如下图,执行 ls
指令后,成功输出当前目录所有文件
远程结果
与本地攻击思路一致,不同的是需先通过 remote()
进行连接,并发送学号
rop
实践 1
试验过程
反汇编可知 func
栈帧大小为 0x50
,我们可以通过类似 sbof2
的攻击方式覆盖掉返回地址,但是 target_code
函数里面的执行的是 ls
,不是我们想要的
正好程序里的 gstr
存有我们要的字符串,于是 rop
链的思路就有了:
先使用 pop rdi
将 sh_addr
放入 rdi
寄存器,然后调用 system
函数,传入 rdi
中的参数,由此大功告成
发现使用 find_gadget(['pop rdi', 'ret'])
会失败,而将 ret
地址单独加入则没问题,从逻辑上似乎一致,只是多覆盖了 8
字节,查阅资料发现可能是 x86_64 对栈帧有 16 字节对齐的要求
栈的字节对齐,实际是指栈顶指针必须是16字节的整数倍。
https://www.cnblogs.com/tcctw/p/11333743.html
本地结果
结果截图如下图,执行 ls
指令后,成功输出当前目录所有文件
远程结果
与本地攻击思路一致,不同的是需先通过 remote()
进行连接
话说为什么还是 ssec2023 hhhh
rop
实践 2
试验过程
注意看,main
函数对 gbuffer
的 read
操作提供了一片可操作的缓冲区,由此联想到 sbof2
,我们可以尝试往 gbuffer
里填入 rop
链,然后让 func
返回地址覆盖为 gbuffer
地址
而 func
内的 read
函数正好溢出 0x10
,足够我们覆盖返回地址,使用栈迁移将栈指针指向 gbuffer
首先往 gbuffer
填充 rop
链,思路是先放入 "/bin/sh"
字符串,这样就能用 gbuff_addr
的地址调用这个字符串了,然后用 pop rdi
传入这个字符串,再连续两个 ret
以执行 system
进入 func
后,先填充缓冲区,覆盖 old rbp
为 gbuffer
地址,覆盖返回地址为 leave, ret
,首先 func
本身的 leave,ret
会将 rbp
指向 guffer
,并执行我们覆盖的 leave,ret
,
接下来 leave
会使 rsp
指向 gbuffer
,然后ret
指令开始执行 pop rdi
,注意这里 rsp
上移并不会清除栈上的数据
本地结果
结果截图如下图,执行
ls
指令后,成功输出当前目录所有文件
远程结果
以下为个人一点点感想,可以忽略不看
本人是 CS 大三的,见培养方案专业选修课有这门课,感觉很好玩就选了,但由于没有
x86
的汇编知识(实际上riscv
也不怎么会),感觉这门课和啃压缩饼干一样hhhh,课堂小测基本不会,靠课后一边看智云一边查资料现学才弄懂,真的如传闻中的一样硬核,不过弄懂后确实感觉挺好玩的hhh