JavaPayload4Metasploit - Single payload loader class to be used in the Metasploit project

© 2010 Michael 'mihi' Schierl, <schierlm at users dot sourceforge dot net>

Introduction

The JavaPayloads contain useful payloads written in pure Java. But they assume that the attacker has a Java VM on his machine, as the the builders and stage handlers are written in Java. In addition, when creating a new payload class that should reside in a signed jar, the jar has to be re-signed as classes have changed.

In contrast, this package contains a single metasploit.Payload class which is configured by a property file in the classpath (i. e. in the same jar). As it is possible to add unsigned resources to a jar without requiring to re-sign it, and as it is easy to manipulate zip/jar files from Ruby, this makes it possible to leverage the powers of JavaPayload from Metasploit which is written in Ruby and not in Java.

System requirements

Same as JavaPayload. JRE 1.2 on the victim machine is enough :-)

On the attacker machine, no Java at all is required.

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 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 started using java -jar jarfile.jar. There are 3 example jars available that use this technique; they are described later.

Alternatively, the main class can of course be called from other classes, like metasploit.Payload.main(null);, as the arguments parameter is ignored. Note that in a sandboxed environment the caller needs to have all permissions, and also the Payload class has to be loaded with all permissions. In case there is untrusted code on the stack trace (but the direct caller has all permissions), the call has to be wrapped in a doPrivileged call (like it is done in the several well known public exploits for CVE-2008-5353).

Once loaded, the class will lookup a file called /metasploit.dat from the class path and load it as a Property file (basically a text file with Name=value lines, but note that some special characters need escaping). If the file cannot be found, default values are used.

Depending on the property values (see below), the class will then optionally write itself to disk and spawn a sub-process (once or several times) to disconnect the payload from the calling process. All temporary files will be deleted afterwards. (Even on Windows it is possible to 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, 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.

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

Supported properties (and their default values)

Spawn(=0)

The number of java processes that should be spawned. 0 will run the payload inside the original process, 1 will spawn once (to continue running when the original process terminates), and 2 will spawn twice (on certain popular operating systems it is impossible to obtain parent process informaion if the parent process has already died).

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.

LPORT(=4444)

Port to listen on or to connect to (if LHOST is also set). If explicitly set to 0, no connection will be made, but standard input/output streams will be used instead.

LHOST(=)

Host to connect to. If not set, the payload will listen instead.

Staging protocol

The staging protocol is quite simple. All classes are sent uncompressed (as they are inside the .jar file). Each class is prefixed by a 32-bit big-endian size. After the last class, a size of 0 is sent. The classes will be defined in the order they are sent (i. e. they can only refer to classes defined before), and the last sent class will be loaded as a stage.

In case of an embedded stage, no staging is used - the stream is directly passed to the stage.

Supported stages (in alphabetical order)

The stages are original JavaPayload 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
javapayload.stage.Stage, com.metasploit.meterpreter.MemoryBufferURLConnection, com.metasploit.meterpreter.MemoryBufferURLStreamHandler, javapayload.stage.Meterpreter
Parameters
Optional parameter NoRedirect for debugging.
Stage protocol
Meterpreter protocol

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
Parameters
Not supported
Stage protocol
Plain text

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.