2023香山杯-sharedBox
sharedBox
题目提示:kkfileview2.2.1 的漏洞利用
环境搭建
项目地址
https://github.com/kekingcn/kkFileView
git 下来后用 idea 打开,将分支重置到 tagv2.2.1
根据文档进行部署
运行启动脚本 startup.sh
自动安装 openoffice
调试运行 FilePreviewApplication
的 main 方法
默认端口是 8012
漏洞分析
KKFileView 有三个路由
OnlinePreviewController#getCorsFile 存在任意文件读取漏洞
根据代码和网上的文章,可知 getCorsFile
路由存在任意文件读取漏洞
对输入的 urlStr 没有过滤,可以直接通过 file 协议读取本地文件
但是在题目的环境中对这个路由进行了限制,直接访问的话会返回 403
所以这题接下来就是怎么绕过出题人对于这个路由的限制,再利用任意文件读取漏洞
OnlinePreviewController#onlinePreview 存在 SSRF 漏洞
逝逝 ssrf 打 getCorsFile 的文件读取
这处功能点从源码分析也是没有对输入字符串进行过滤的,存在 ssrf 漏洞
那么我们此时的目标就是
通过此处的 ssrf 来请求 getCorsFile 从而利用任意文件读取漏洞
那么我们现在先直接利用一下逝逝
果不其然,回显不支持该格式
分析文件类型判断
那么先分析一下为啥不支持,打个断点
原来截取了后缀,得到了 getCorsFile,而系统配置里并没有预设这个后缀名,当然就返回了不支持了
我们翻一下源代码,在处我们可以看到系统预设了几种文件类型,而 picture、pdf 这些经过测试后显然是不行的,因为会在页面返回图片等,无法返回我们想要读取的 flag 文本
那么我们又留意到了有 simText
这个文件类型,而包含的后缀有 txt、jsp 等等,可知这是类文本 的文件类型,按理说是可以返回文件内容的
那我们就测试一下
1 | http://localhost:8012/onlinePreview?url=http://localhost:8012/getCorsFile.txt?urlPath=file%3A%2F%2F%2Fetc%2Fpasswd |
发现页面返回空白,回源码看一下
发现竟然多出了两个文件,而且还把 /etc/passwd 的内容写进了里面,这是不是就有利用成功的可能性了
为什么会保存文件
跟进代码,看一下为什么会写入文件
可以看到 onlinePreview 最后调用了 filePreviewHandle
,继而调用了 downLoad
而在 downLoad
处调用 saveBytesToOutStream
函数对文件内容进行了写入
原来是 spring-boot 1.x
一开始我看 wp 并不懂为啥 ssrf 请求 http://localhost:8012/getCorsFile.txt?urlPath=file%3A%2F%2F%2Fetc%2Fpasswd
可以读取到文件内容,getCorsFile.txt
和 getCorsFile
能一样吗,为啥能执行 getCorsFile
方法的功能
原来 kkFileView 默认使用的是 spring-boot 1.x
而如下引述
在 Spring Boot1.5 的版本中,假如我们定义了一个’/show’接口,默认情况下,我们可以按照/show 来访问页面,也可以按照/show.do 这样带有’.do’后缀的接口来访问资源。
但是到了 Spring Boot2.x 之后,我们发现再使用.do 的扩展名就无法访问资源了。
也就是说,现在的 Spring Boot 在默认情况下,禁用了后缀匹配模式!
刚刚好这又是 1.5.8,因此请求 /getCorsFile.txt
既能通过代码的后缀检测,又能执行 getCorsFile
函数
所以才会出现上面的 payload
1 | http://localhost:8012/onlinePreview?url=http://localhost:8012/getCorsFile.txt?urlPath=file%3A%2F%2F%2Fetc%2Fpasswd |
如何读文件
那么我们怎么才能读到这个 getCorsFile.txt 呢
读 demo 的图片是 http://localhost:8012/onlinePreview?url=http%3A%2F%2Flocalhost%3A8012%2Fdemo%2FAb1azE.png
那我读 getCorsFile.txt 请求
http://localhost:8012/onlinePreview?url=http%3A%2F%2Flocalhost%3A8012%2FgetCorsFile.txt
不就好了?
可惜请求 http://localhost:8012/onlinePreview?url=http%3A%2F%2Flocalhost%3A8012%2FgetCorsFile.txt
就会被当成访问 getCorsFile
这个路由捏!当然不可能读到文件啦
所以我们需要请求 http://localhost:8012/%09getCorsFile.txt
,用%09、%02等字符绕过一下令服务器将正确识别文件名为 getCorsFile.txt
,从而正确读取到文件内容(具体为啥这样可以我也不太懂
或者直接访问也可以
题解
那么当 getCorsFile 被限制后,通过 getCorsFile 的 ssrf 打 getCorsFile 的文件读取 这个利用的分析就到此结束了
比赛环境已经关了,赛题的后续利用无法复现了
下面贴上 Lxxx 师傅的 wp(https://www.yuque.com/dat0u/ctf/lbp2gfi6gttxsymb)
最终 Payload 如下,题目应该是在 nginx 或者/onlinePreview 路由处对 proc、fd 关键字做了匹配,由于是 SSRF,会发起两次 http 请求,因此可以通过双重 URL 编码绕过
1
2
3 GET /fileview/onlinePreview?url=http://localhost:8012/getCorsFile.jsp?urlPath=file:///%2570%2572%256f%2563/29/%2566%2564/6
Host: 101.201.35.76:22873绕过后,读取的文件内容会保存在 getCorsFile.jsp 中,用 %09、%02 等字符绕过一下读取文件即可
1
2
3 GET /fileview/%09getCorsFile.jsp
Host: 101.201.35.76:22873比赛的时候,/flag 提示我们要 RCE,但是这题可以通过非预期读取/proc/29/fd/6 获取到 flag
预期应该是读/root/flag.java 文件,然后再往下走……