From 0f17bbdfdd91cf21bdf2d93652e5fb0b0fa4e5b7 Mon Sep 17 00:00:00 2001 From: Willis Vandevanter Date: Tue, 6 Mar 2012 00:30:30 -0500 Subject: [PATCH] squid pivot scanning module --- .../scanner/http/squid_pivot_scanning.rb | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 modules/auxiliary/scanner/http/squid_pivot_scanning.rb diff --git a/modules/auxiliary/scanner/http/squid_pivot_scanning.rb b/modules/auxiliary/scanner/http/squid_pivot_scanning.rb new file mode 100644 index 0000000000..b6471c55af --- /dev/null +++ b/modules/auxiliary/scanner/http/squid_pivot_scanning.rb @@ -0,0 +1,130 @@ +## +# $Id$ +## + +## +# 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' +require 'rex/socket/range_walker' + +class Metasploit3 < Msf::Auxiliary + + # Exploit mixins should be called first + include Msf::Exploit::Remote::HttpClient + # Scanner mixin should be near last + include Msf::Auxiliary::Scanner + include Msf::Auxiliary::Report + + def initialize + super( + 'Name' => 'Squid Proxy Port Scanner', + 'Description' => %q{ + A misconfigured Squid proxy can allow an attacker to make requests on their behalf. + This may give the attacker information about devices that they cannot reach but the + squid proxy can. For example, an attacker can make requests for internal IP addresses + against a misconfigurated open squid proxy exposed to the Internet therefore performing + an internal port scan. The error messages returned by the proxy are used to determine + if the port is open or not. Many squid proxies use custom error codes so your mileage + may vary. + }, + 'Author' => ['willis'], + 'Version' => '$Revision$', + 'References' => + [ + 'URL','http://wiki.squid-cache.org/SquidFaq/SecurityPitfalls' + ], + + 'License' => MSF_LICENSE + ) + + register_options( + [ + OptString.new('RANGE', [true, "IPs to scan through squid proxy", '']), + OptString.new('PORTS', [true, "Ports to scan; must be TCP", "21,80,139,443,445,1433,1521,1723,3389,8080,9100"]), + OptBool.new('MANUAL_CHECK',[true,"Stop the scan if server seems to answer positively to every request",true]) + ], self.class) + + end + + def run_host(target_host) + + begin + iplist = Rex::Socket::RangeWalker.new(datastore['RANGE']) + dead = false + vprint_status("#{iplist.length} total IPs") + portlist = Rex::Socket.portspec_crack(datastore['PORTS']) + + iplist.each do |target| + portlist.each do |port| + next if dead + + vprint_status("[#{rhost}] Running test check") + #request a non-existent page first to make sure the server doesn't respond with a 200 to everything. + res = send_request_cgi({ + 'uri' => "http://127.0.11.1:80", + 'method' => 'GET', + 'data' => '', + 'version' => '1.0', + 'vhost' => '' + }, 10) + + if res and res.body and (res.code == 200) + print_error("#{rhost} likely answers positively to every request, check it manually.") + print_error("\t\t Proceeding with the scan may increase false positives.") + manual = true + end + + next if manual and datastore['MANUAL_CHECK'] + + vprint_status("[#{rhost}] Checking #{target}:#{port}") + if port==443 + res = send_request_cgi({ + 'uri' => "https://#{target}:#{port}", + 'method' => 'GET', + 'data' => '', + 'version' => '1.0', + 'vhost' => '' + }, 10) + else + res = send_request_cgi({ + 'uri' => "http://#{target}:#{port}", + 'method' => 'GET', + 'data' => '', + 'version' => '1.0', + 'vhost' => '' + }, 10) + end + + if res and res.body + + if res.code == 200 or res.body =~ /Zero/ or res.code == 404 or res.code == 401 + print_good("[#{rhost}] #{target}:#{port} seems OPEN") + report_service(:host => target, :port => port, :name => "unknown", :info => res.body ) + end + if res.body =~ /No route to host/ + dead = true + print_bad("[#{rhost}] #{target} is DEAD") + end + + print_status("[#{rhost}] #{target}:#{port} blocked by ACL") if res.body =~ /Access control/ + + if res.body =~ /Connection refused/ or res.body =~ /service not listening/ + report_host(:host => target) + print_good("[#{rhost}] #{target} is alive but #{port} is CLOSED") + end + end + end + dead = false + end + + rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout + rescue ::Timeout::Error, ::Errno::EPIPE + + end + end +end