java反序列化漏洞专项
阅读原文时间:2022年07月06日阅读:2

  背景条件: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;  
    }  
}  

}

  输出:

http://9ofptp.dnslog.cn/ http://9ofptp.dnslog.cn/

Process finished with exit code 0

  反序列化的时候触发:

 

  黑盒测试poc:

http://9ofptp.dnslog.cn/ http://9ofptp.dnslog.cn/

此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

  半自动化寻找反序列化利用链:

(1)https://www.mandiant.com/resources/hunting-deserialization-exploits

   (2)https://github.com/wh1t3p1g/tabby

  (3)https://github.com/JackOfMostTrades/gadgetinspector 下午使用了下,还可以,标记下

  反序列化漏洞防护建议:

(1)  https://medium.com/codex/deserialization-vulnerability-from-a-developers-perspective-94c3d795b9e0

   (2) java安全管理器 secuirty manager

   (3) 白名单策略等

  先到这里吧,四天的调研暂告一段落。