2021MTCTFWriteup
baby_focal
glibc 2.31 ,没有 PIE ,没有输出功能,开沙盒的堆溢出:
没有输出功能思路基本都是攻击 stdout 泄露出 libc 地址,这条题目分配函数用的是 calloc ,相当于没有 tcache 存在的,攻击思路和 glibc 2.23 一样。然后就是利用 free_hook 栈迁移到堆上的 orw 。
思路
填满 tcache 之后,利用堆溢出形成堆重叠,形成两个指向同一个地址的指针。注意需要在第一个 unsortedbin 前面布置一个堆,用来修改 size 来绕过保护。
两个同一地址的指针,在 fastbin 写入 main_arena_xx 地址,爆破 1/16 到 stdout 上方,利用错位构造出符合 fastbin 的 size 位。
这篇文章末尾中有提及:http://blog.eonew.cn/archives/1190
修复 unsortedbin 恢复分配释放功能。利用堆溢出劫持 fastbin fd 指针将堆分配到堆指针数组(需要提前布置 size 绕过保护),实现任意地址写。
将 free_hook 劫持为 puts ,泄露出堆地址。
布置好两个堆,将 free_hook 劫持为 libc 控制 rbp 的 gadget 栈迁移到堆。
两个堆内容参考:https://www.mrskye.cn/archives/b88f4a53/#ParentSimulator ,第一个堆填充长度需要调整一下。
EXP
1 | #encoding:utf-8 |
相关资料
blind
关闭 canary 和 PIE ,存在格式化字符串漏洞、栈溢出:
一开始思路是想着让 read 返回值是 0 ,也就是输入 EOF 信号,然后到后门函数栈溢出完事。可是 scanf 输入的不能溢出修改 v3 的随机数 GG。最后参考师傅们思路:利用格式化字符串劫持 exit 函数内一条 call 指令调用后门函数,实现栈溢出。
一系列命令后最后调用
r12+rdx*8
。正常情况下 rdx 为 0 ,r12 指向函数地址R12 来源路径:从 rax+8 作为初值,然后加上 rbx 指向的值
- rax+8 是一个 bss 的地址,即 r12 初值是一个 bss 段地址
- rbx 指向的是一个栈上地址
控制 rbx 在栈上的值,将指令最后指向提前再 bss 段写入的后门地址完成调用。
思路
- 利用格式化字符串修改 exit 函数中 rdx 对应栈位置为预定值,并在同时写入后门地址
- 利用栈溢出构造一个 read 劫持某个函数 got 表为 onegadget ,需要爆破 1/16
EXP
1 | from pwn import * |
zlink
glibc 2.23 的远程环境,保护全开。
show 和 申请 0x100&0x500 两个功能共用一个全局标记,合计使用次数不能大于 2 。edit 功能只能使用一次,edit 里面还有在 __free_hook - 2 写入 0x7f ,用于将 fastbin 分配到 __free_hook ,也可以不利用这个后面写入的 0x7f ,从 __free_hook 向上找到 stdout 附近,通过偏移构造出 0x7f 。
当申请堆块 index 大于 9 时会有 off by null :
思路
- 使用 gift(申请 0x100 & 0x500 堆块)和 show 泄露出 libc 地址
- 利用 offbynull 修改 0x100 prev_inuse ,然后修改 0x100 前的 fastbin fk、bk 指针到 main_arena 特定地址绕过 unlink 检查,将 0x100 与前面 fastbin 合并,申请出两个指向同一地址的指针
- 劫持 __free_hook 为 setcontext+0x53 ,构造 read 向 libc bss 段写入
- Mprotect 给权限,然后 orw shellcode
EXP
1 | #encoding:utf-8 |