sharedBox

题目提示:kkfileview2.2.1 的漏洞利用

环境搭建

项目地址

https://github.com/kekingcn/kkFileView

git 下来后用 idea 打开,将分支重置到 tagv2.2.1

image根据文档进行部署

image运行启动脚本 startup.sh ​自动安装 openoffice

image

调试运行 FilePreviewApplication ​的 main 方法

image默认端口是 8012

漏洞分析

KKFileView 有三个路由

image

OnlinePreviewController#getCorsFile 存在任意文件读取漏洞

根据代码和网上的文章,可知 getCorsFile ​路由存在任意文件读取漏洞

对输入的 urlStr 没有过滤,可以直接通过 file 协议读取本地文件

image

image
但是在题目的环境中对这个路由进行了限制,直接访问的话会返回 403

所以这题接下来就是怎么绕过出题人对于这个路由的限制,再利用任意文件读取漏洞

OnlinePreviewController#onlinePreview 存在 SSRF 漏洞

逝逝 ssrf 打 getCorsFile 的文件读取

image

这处功能点从源码分析也是没有对输入字符串进行过滤的,存在 ssrf 漏洞

那么我们此时的目标就是
通过此处的 ssrf 来请求 getCorsFile 从而利用任意文件读取漏洞

那么我们现在先直接利用一下逝逝

image果不其然,回显不支持该格式

分析文件类型判断

那么先分析一下为啥不支持,打个断点

image

原来截取了后缀,得到了 getCorsFile,而系统配置里并没有预设这个后缀名,当然就返回了不支持了

我们翻一下源代码,在处我们可以看到系统预设了几种文件类型,而 picture、pdf 这些经过测试后显然是不行的,因为会在页面返回图片等,无法返回我们想要读取的 flag 文本

那么我们又留意到了有 simText ​这个文件类型,而包含的后缀有 txt、jsp 等等,可知这是类文本 的文件类型,按理说是可以返回文件内容的

image​那我们就测试一下

1
http://localhost:8012/onlinePreview?url=http://localhost:8012/getCorsFile.txt?urlPath=file%3A%2F%2F%2Fetc%2Fpasswd

发现页面返回空白,回源码看一下image

发现竟然多出了两个文件,而且还把 /etc/passwd 的内容写进了里面,这是不是就有利用成功的可能性了

image

为什么会保存文件

跟进代码,看一下为什么会写入文件

image可以看到 onlinePreview 最后调用了 filePreviewHandle​,继而调用了 downLoad

image而在 downLoad ​处调用 saveBytesToOutStream ​函数对文件内容进行了写入

imageimage原来是 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

image

而如下引述

在 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

image

如何读文件

那么我们怎么才能读到这个 getCorsFile.txt 呢

image
读 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 ​不就好了?

image

可惜请求 http://localhost:8012/onlinePreview?url=http%3A%2F%2Flocalhost%3A8012%2FgetCorsFile.txt ​就会被当成访问 getCorsFile ​这个路由捏!当然不可能读到文件啦

所以我们需要请求 http://localhost:8012/%09getCorsFile.txt​,用%09、%02等字符绕过一下令服务器将正确识别文件名为 getCorsFile.txt​,从而正确读取到文件内容(具体为啥这样可以我也不太懂

image或者直接访问也可以

image

题解

那么当 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 HTTP/1.1
Host: 101.201.35.76:22873

绕过后,读取的文件内容会保存在 getCorsFile.jsp 中,用 %09、%02 等字符绕过一下读取文件即可

1
2
3
GET /fileview/%09getCorsFile.jsp HTTP/1.1
Host: 101.201.35.76:22873

比赛的时候,/flag 提示我们要 RCE,但是这题可以通过非预期读取/proc/29/fd/6 获取到 flag

预期应该是读/root/flag.java 文件,然后再往下走……