广东省强网杯团队赛pwn writeup
师兄:昨天强网杯怎么样?
我:预赛拿了第一
师兄:有没有什么收获?
我:有,收获了一整天的开心
pwn_c4
这个题的话,一眼看去不是很明白程序是干嘛的,我居然还试图去逆向,笑死,根本没有时间
后来搜了一手,发现了2020年的网鼎杯的boom1和这个比较类似
此处挂一挂轩哥的博客,网鼎杯boom1:https://xuanxuanblingbling.github.io/ctf/pwn/2020/05/10/boom/
大概就是一个小型的编译器,可以直接写程序,但是能用的语句比较有限,能用的比如if,int,malloc,free,printf这些
来个简单的测试,如下:
1 | from pwn import * |
运行,可以看到成功打印出了”Hello World”:
感觉这个printf能用的话就很舒服了,计算某些量的时候可以直接log大法输出出来看看对不对
那大概知道了怎么玩之后,解题思路就很清晰了:在有限的语句下getshell
可以模仿一波轩哥的办法:
第一步,泄露地址,可以通过环境变量索引的方式拿到栈上的某个libc
地址
第二步,计算出system
和malloc_hook
第三步,改malloc_hook
为system
,malloc("/bin/sh")
即可
exp:
1 | from pwn import * |
当然,本题的做法其实可以有很多,因为可操作性还是挺大的
总结起来就是,本题可以直接运行代码并具有内存读写的能力,关键就是要在受到限制的情况下通过内存读写来完成shell的获取
T_S
本题中,花指令把最关键的部分藏起来了,所以要先去除一波
关键在edit里面调用到的这个函数:
一眼看去,我觉得不需要搞清楚他在干嘛,因为看到用了strlen,我猜测可能会波及到chunk的size字段
但测试了一波是ok的,再看下面
可以看到最后这里有将1置为0的操作,且for循环未设置边界:
试验了一下果然可以造成溢出,为了成功让他破坏size
,填入的字符都为"\x01"
,即可循环到size那边,然后就是类似off-by-null
的效果
有一次show
的机会,泄露堆地址,即可伪造chunk
绕过新版unlink
,然后就是堆块重叠了,打到IO_2_1_stdout
泄露libc
地址,再free_hook--->system
即可getshell
exp:
1 | from pwn import * |
GirlFriend
漏洞点:非常明显,off-by-one
溢出一个字节
由于使用的是realloc
,add
函数中可同时完成free的功能,给realloc
的第二个参数传0即可
操作次数有限,只有16次,所以本题需要一个关键点:即为printf_chk
的格式化字符串漏洞
printf_chk
的特性使其难以在五个字节内完成泄露和任意写
例如想要使用printf_chk
完成对第七个参数的泄露,%7$p
已经不再管用,而是要%p%p%p%p%p%p%p
,即连写7个%p
才行
然而,题目中的格式化字符串长度最多只能是5,最多只能写两个%p
,同时寄存器的值也被清0,两个%p
并泄露不出什么有用的信息
但其实使用%a
就可以完成printf_chk
的泄露,拿到libc
地址
有了libc
之后,也就是说在16次add
和free
内完成一次任意写即可,开了沙箱,那就free_hook+setcontext
来打orw
利用手法就是溢出改size
完成fd
指针劫持,由于realloc
的特点,在chunk
的size
布置上要下点文章
除此之外,还可以利用此处的printf_chk
把栈上残留的栈地址给泄露出来,即buf
处原本的值
但是个人认为最关键的还是泄露libc
,在不知道libc
的情况下知道栈地址用处不大,而知道libc
的话又没必要知道栈地址
exp:
1 | from pwn import * |