diff --git a/lib/msf/core/exploit/http.rb b/lib/msf/core/exploit/http.rb index 438a50b4cc..415d0d214d 100644 --- a/lib/msf/core/exploit/http.rb +++ b/lib/msf/core/exploit/http.rb @@ -12,6 +12,7 @@ module Msf # ### module Exploit::Remote::HttpClient + include Msf::Auxiliary::Report # # Initializes an exploit module that exploits a vulnerability in an HTTP @@ -334,6 +335,92 @@ module Exploit::Remote::HttpClient datastore['Proxies'] end + # + # Record various things about an HTTP server that we can glean from the + # response to a single request. If this method is passed a response, it + # will use it directly, otherwise it will make a request for /. + # + # Options: + # :response an Http::Packet as returned from any of the send_* methods + # + # Other options are passed directly to +connect+ if :response is not given + # + def http_fingerprint(opts={}) + + if (opts[:response]) + res = opts[:response] + else + connect(opts) + res = send_request_raw({ + 'uri' => '/', + 'method' => 'GET' + }, 25) + end + + # Bail if we don't have anything to fingerprint + return if not res + + extras = [] + + case res.code + when 301,302 + extras << "#{res.code}-#{res.headers['Location']}" + when 401 + extras << "#{res.code}-#{res.headers['WWW-Authenticate']}" + when 403 + extras << "#{res.code}-#{res.headers['WWW-Authenticate']||res.message}" + when 500 .. 599 + extras << "#{res.code}-#{res.message}" + end + + if (res.headers['X-Powered-By']) + extras << "Powered by " + res.headers['X-Powered-By'] + end + + if (res.headers['Via']) + extras << "Via-" + res.headers['Via'] + end + + if (res.headers['X-AspNet-Version']) + extras << "AspNet-Version-" + res.headers['X-AspNet-Version'] + end + + case res.body + when nil + # Nothing + when /openAboutWindow.*\>DD\-WRT ([^\<]+)\ 0 + + # Report here even if info is empty since the fact that we didn't + # return early means we at least got a connection and the service is up + report_service(:host => rhost, :port => rport, :name => (ssl ? 'https' : 'http'), :info => info) + + info + end + + protected attr_accessor :client diff --git a/modules/auxiliary/scanner/http/http_version.rb b/modules/auxiliary/scanner/http/http_version.rb index 09f2995296..5491c6fa83 100644 --- a/modules/auxiliary/scanner/http/http_version.rb +++ b/modules/auxiliary/scanner/http/http_version.rb @@ -20,7 +20,6 @@ class Metasploit3 < Msf::Auxiliary include Msf::Auxiliary::WMAPScanServer # Scanner mixin should be near last include Msf::Auxiliary::Scanner - include Msf::Auxiliary::Report def initialize super( @@ -35,88 +34,11 @@ class Metasploit3 < Msf::Auxiliary # Fingerprint a single host def run_host(ip) - begin - res = send_request_raw({ - 'uri' => '/', - 'method' => 'GET' - }, 25) - - if (res) - extra = http_fingerprint(res) - print_status("#{ip} #{res.headers['Server'] ? ("is running " + res.headers['Server']) : "has no server header"}#{extra}") - report_service(:host => ip, :port => rport, :name => (ssl ? 'https' : 'http'), :info => "#{res.headers['Server']}#{extra}") - end - + fp = http_fingerprint + print_status("#{ip} #{fp}") if fp rescue ::Timeout::Error, ::Errno::EPIPE end - - end - - # - # This is quick example of "extra" fingerprinting we can do - # - def http_fingerprint(res) - return if not res - - extras = [] - - case res.code - when 301,302 - extras << "#{res.code}-#{res.headers['Location']}" - when 401 - extras << "#{res.code}-#{res.headers['WWW-Authenticate']}" - when 403 - extras << "#{res.code}-#{res.headers['WWW-Authenticate']||res.message}" - when 500 .. 599 - extras << "#{res.code}-#{res.message}" - end - - if (res.headers['X-Powered-By']) - extras << "Powered by " + res.headers['X-Powered-By'] - end - - if (res.headers['Via']) - extras << "Via-" + res.headers['Via'] - end - - if (res.headers['X-AspNet-Version']) - extras << "AspNet-Version-" + res.headers['X-AspNet-Version'] - end - - case res.body - when nil - # Nothing - when /openAboutWindow.*\>DD\-WRT ([^\<]+)\