SUCTF 2019 PWN writeup
前言
前几天SuCT的复盘
BabyStack
程序逻辑
main函数给出程序加载地址和栈地址,输入一个栈地址(emm自己试了很久)可以触发异常进入magic函数
1 | int __cdecl main(int argc, const char **argv, const char **envp) |
1 | int magic() |
magic函数中存在后门,由于有SafeSEH的保护,不能直接覆盖SEH到后门地址,每次系统重启,程序加载的地址才会变化,因此一次开机程序的加载地址就固定了,下面的exp都是基于这个写的。
这道题几乎是HITB的原题,在看雪找了篇帖子学习
看雪
magic函数存在溢出,我们按照帖子里的分析伪造一个假的scope table以及FilterFunc(和HandleFunc一样都会执行),泄露出GS、Security Cookie以及GS后面的2个值,SEH NEXT,payload结构如下:1
2
3
4
5
6
7
8
9payload = 'a'*4+p32(0xffffffe4)+p32(0)+p32(0xffffff0c)+p32(0)+p32(0xfffffffe)
payload += p32(system_addr)*2
payload = payload.ljust(0xa0,'b')
payload += GS
payload += canary_1
payload += canary2
payload += SEH_NEXT
payload += p32(SEH Handler)
payload += p32(SecurityCookie^(input_addr+4))
这里几个比较重要的地址:Security Cookie在0x47c004,GS在ebp-0x1c处,canary_1在ebp-0x18,canary_2在ebp-0x14,canary_3在ebp-0x10处
泄露的地址-0x20为ebp_addr
输入的地址为ebp_addr-0xac
上述地址的推断来自于OD调试,下断点,算偏移即可,例如:
泄露地址为0xb3f8f4,调试可以看到ebp_addr为leak_addr - 0x20 = 0xB3F8D4
exp.py
本地拿看雪师傅的辅助脚本跑失败了,Su那边服务器又关了,这里直接拿17师傅的脚本了,看了下payload结构应该没什么大的出入
1 | from pwn import * |
二手破电脑
漏洞利用
漏洞在写Name的时候的sprintf的off-by-one,构造堆块实在是太麻烦了,leak heap和leak libc花了我一天的时间。。最后是用Overlap chunk分配Large bin得到heap地址,自己做这种复杂一点的堆构造真的是太费劲了,思路不够清晰,做了很多无用功.
拿shell的方法是Overlap写一个pc的name_chunk为其本身,同时修改这个pc的size为fake size,从而Rename的时候地址任意写。
exp.py
1 | #coding=utf-8 |
playfmt
漏洞利用
简单的bss格式化字符串,flag在堆里,直接泄露即可
exp.py
1 | #coding=utf-8 |