强网杯和钓鱼城ctf部分题解
强网杯
最后35名,顺延进去了,还好努力没有白费
babymessage
栈溢出了,用栈迁移来解,赛后才知道我这办法有点傻逼。。
1 | __int64 __fastcall leave_message(unsigned int length) |
exp为:
1 | from pwn import * |
siri
格式化字符串,改__malloc_hook
exp为:
1 | from pwn import * |
easypwn
off_by_one
,没有了fastbin
,先修改global_max_fast
,在攻击stdout
泄露,最后触发malloc
报错来getshell,和去年byteCTF的一题挺像的,exp改改就好
1 | from pwn import * |
oldschool
这里看着就很诡异,最后是个越界写,感觉出题人写错了
1 | if(g_ptr + idx < g_ptr && (unsigned)(g_ptr + idx) < ADDR_HIGH){ |
exp:
1 | from pwn import * |
Just_a_Galgame
edit没有检查idx的合法性,所以一次edit用来泄露libc,一次用来修改__malloc_hook
1 | from pwn import * |
babynotes
regist
函数可以溢出下一块堆块的size
exp为:
1 | from pwn import * |
direct
edit的时候有越界写,我们可以修改到上面的堆块,所以修改__dirstream
结构的偏移,先泄露libc,在攻击tcache就行
1 | from pwn import * |
QWBlogin
这个自己写了个粗糙的emu,大概能看的出来逻辑,先是比较密码,接着就是一个read
,这里的read是由栈溢出的,我们可以修改程序的rip
,然后去test.bin
里找gadget,最后rop拿flag,这题挺有意思的
emu.cpp:
1 |
|
输出(能有个大概的逻辑):
1 | rip: 0x0 mov |
test.bin里藏了几个gadget,找到就行
最后exp:
1 | from pwn import * |
钓鱼城ctf
钓鱼失败
unknown
add的时候没有检查idx为负数的时候,所以可以先add一个0大小的,在用add时候的负数idx覆盖size,这样就可以堆溢出
exp:
1 | from pwn import * |
fsplayground
读取/proc/self/maps
泄露libc和栈地址,写/proc/self/mem
改返回地址rop
exp:
1 | from pwn import * |
block
比赛结束的时候刚好控制了__free_hook
,有点可惜
还有个后门函数。可以malloc,但是要猜密码
add选type的时候应该是有off_by_one,size | 1会多1byte
exp:
1 | from pwn import * |