如果觉得该文章有帮助的,麻烦师傅们可以搜索下微信公众号:良月安全。点个关注,感谢师傅们的支持。
免责声明
本博客所发布的所有内容,包括但不限于信息、工具、项目以及文章,均旨在提供学习与研究之用。所有工具安全性自测。如因此产生的一切不良后果与文章作者和本公众号无关。如有涉及公司与个人敏感信息,侵权烦请告知,我们会立即删除并致歉。
路由分析
首先看文件上传的url:/sys/cms/uploadLogo.do?b_upload=upload&isClose=2&type=1
查看配置文件,发现是 struts,但并未 struts.xml 路由配置。后在 web.xml 中发现 .do 请求的处理,发现是 struts1。
MainServlet 会将请求转发到相应的 action,查看 struts-config.xml 配置。
配置解析如下:path="/sys/cms/uploadLogo": 指定了请求路径,当用户访问 /sys/cms/uploadLogo.do 时,会由该 <action> 配置处理。
-
type="com.hrms.struts.action.FrameAction": 设置处理请求的 Action 类,这里是 com.hrms.struts.action.FrameAction,当请求路径匹配时,会实例化并调用该类。
-
name="channelForm": 设定表单名称(channelForm),这会和一个定义好的 ActionForm 关联,用于处理提交的数据。
-
scope="session": 设置表单数据的作用范围为 session,表示表单数据会存储在用户的会话中,在多个请求间共享。
-
validate="true": 启用表单验证,在请求到达 FrameAction 之前会先验证 channelForm 表单数据的合法性。
-
input="system.cms.select_upload_file": 当表单验证失败时,页面会重定向到 system.cms.select_upload_file,用于显示错误信息并让用户重新输入。
-
<set-property> 元素: 为 FrameAction 设置特定属性:
-
requireLogon: 表示该请求需要用户登录。
-
requireSession: 表示该请求需要会话。
-
canSwitch: 允许切换用户(可能适用于角色切换或多账户场景)。
-
<forward> 元素: 定义了不同的处理结果转发页面。
-
-
br_query 和 b_upload:都指向 system.cms.select_upload_file,即执行成功后转发的页面。可以根据不同情况在 FrameAction 中返回相应的 String 结果来指定转发路径。
FrameAction 类会通过 myexecuteIt 方法来处理这个请求。
上面循环中处理请求参数,然后执行相应操作。当 b_upload 被触发时,FrameAction 会实例化一个 FrameCmd 对象,并调用 execute() 方法。
FrameCmd 类的 execute() 方法会将 TransInfoView 对象传递给 MsgRouter 类。
在 MsgRouter 类的 execute 方法中会从 TransInfoView 中提取 requestId 或 workFlowId。
如果 workFlowId 不为空,MsgRouter 将其作为 funcid 使用。
否则,MsgRouter 会调用 B() 方法,从 MRMapping.xml 文件中根据 requestId 查找对应的 funcid。
再根据对应的 funcid 从 WFMapping.xml 配置文件中查找对应的映射。
上传分析
根据上面的 struts 配置,发现该路径需要登录才能访问。所以首先是通过访问 /module/system/qrcard/mobilewrite/qrcardmain.jsp 获取后台权限 cookie。
根据上面路由分析,最终在 com.hjsj.hrms.transaction.sys.cms.UploadLogoTrans 类中处理上传。
只要 logofile、twoFile、oneFile 中任意一个不为空就会进入 uploadFile 上传,问题就是这里需要传入 SafeCode.encode 后的 path。
这个 path 就可以从上面分析 struts-config.xml 配置中执行 b_upload 或者 br_query 成功后指向的 system.cms.select_upload_file 获取,其中就会输出加密后的真实路径。
所以只要先随便进行一次 b_upload 或者 br_query 操作,返回得到加密 path 后再拼接上传即可。
漏洞复现
关注微信公众号后台回复"20241115"获取。
获取Cookie:
获取加密路径:
文件上传: