# -*- coding: binary -*- module Msf ### # # This module provides methods for brute forcing authentication # ### module Auxiliary::Web module Analysis end require 'msf/core/auxiliary/web/http' require 'msf/core/auxiliary/web/fuzzable' require 'msf/core/auxiliary/web/form' require 'msf/core/auxiliary/web/path' require 'msf/core/auxiliary/web/target' include Auxiliary::Report attr_reader :target attr_reader :http attr_reader :parent attr_reader :page def initialize( info = {} ) super end # String id to push to the #checklist def checked( id ) parent.checklist << "#{shortname}#{id}".hash end # String id to check against the #checklist def checked?( id ) parent.checklist.include? "#{shortname}#{id}".hash end # # Called directly before 'run' # def setup( opts = {} ) @parent = opts[:parent] @target = opts[:target] @page = opts[:page] @http = opts[:http] end # Should be overridden to return the exploits to use for this # vulnerability type as an Array of Strings. def self.exploits end # Must return a configuration Hash for the given exploit and vulnerability. def self.configure_exploit( exploit, vuln ) end # Should be overridden to return the payloads used for this # vulnerability type as an Array of Strings. def payloads end def token "xssmsfpro" end # # Should be overridden to return a pattern to be matched against response # bodies in order to identify a vulnerability. # # You can go one deeper and override #find_proof for more complex processing. # def signature end # # Default #run, will audit all elements using taint analysis and log # results based on #find_proof return values. # def run auditable.each { |element| element.taint_analysis } end # Returns an Array of elements prepared to be audited. def auditable target.auditable.map do |element| element.fuzzer = self element end end # Checks whether a resource exists based on a path String. def resource_exist?( path ) res = http.get( path ) res.code.to_i == 200 && !http.custom_404?( path, res.body ) end alias :file_exist? :resource_exist? # Checks whether a directory exists based on a path String. def directory_exist?( path ) dir = path.dup dir << '/' if !dir.end_with?( '/' ) resource_exist?( dir ) end # Logs the existence of a resource in the path String. def log_resource_if_exists( path ) log_resource( :location => path ) if resource_exist?( path ) end alias :log_file_if_exists :log_resource_if_exists # Logs the existence of the directory in the path String. def log_directory_if_exists( path ) dir = path.dup dir << '/' if !dir.end_with?( '/' ) log_resource_if_exists( dir ) end # Matches fingerprint pattern against the current page's body and logs matches def match_and_log_fingerprint( fingerprint, options = {} ) return if (match = page.body.to_s.match( fingerprint ).to_s).empty? log_fingerprint( options.merge( :fingerprint => match ) ) end # # Serves as a default detection method for when performing taint analysis. # # Uses the Regexp in #signature against the response body in order to # identify vulnerabilities and return a String that proves it. # # Override it if you need more complex processing, but remember to return # the proof as a String. # # response - Auxiliary::Web::HTTP::Response # element - the submitted element # def find_proof( response, element ) return if !signature m = response.body.match( signature ).to_s return if !m || m.size < 1 m.gsub( /[\r\n]/, ' ' ) end def increment_request_counter parent.increment_request_counter end # Should be overridden and return an Integer (0-100) denoting the confidence # in the accuracy of the logged vuln. def calculate_confidence( vuln ) 100 end def log_fingerprint( opts = {} ) mode = name vhash = [target.to_url, opts[:fingerprint], mode, opts[:location]]. map { |x| x.to_s }.join( '|' ).hash parent.vulns[mode] ||= {} return if parent.vulns[mode].include?( vhash ) location = opts[:location] ? page.url.merge( URI( opts[:location].to_s )) : page.url info = { :web_site => target.site, :path => location.path, :query => location.query, :method => 'GET', :params => [], :pname => 'path', :proof => opts[:fingerprint], :risk => details[:risk], :name => details[:name], :blame => details[:blame], :category => details[:category], :description => details[:description], :owner => self } info[:confidence] = calculate_confidence( info ) parent.vulns[mode][vhash] = info report_web_vuln( info ) opts[:print_fingerprint] = true if !opts.include?( :print_fingerprint ) print_good " FOUND(#{mode.to_s}) URL(#{location})" print_good " PROOF(#{opts[:fingerprint]})" if opts[:print_fingerprint] end def log_resource( opts = {} ) mode = name vhash = [target.to_url, mode, opts[:location]]. map { |x| x.to_s }.join( '|' ).hash parent.vulns[mode] ||= {} return if parent.vulns[mode].include?( vhash ) location = URI( opts[:location].to_s ) info = { :web_site => target.site, :path => location.path, :query => location.query, :method => 'GET', :params => [], :pname => 'path', :proof => opts[:location], :risk => details[:risk], :name => details[:name], :blame => details[:blame], :category => details[:category], :description => details[:description], :owner => self } info[:confidence] = calculate_confidence( info ) parent.vulns[mode][vhash] = info report_web_vuln( info ) print_good " VULNERABLE(#{mode.to_s}) URL(#{target.to_url})" print_good " PROOF(#{opts[:location]})" end def process_vulnerability( element, proof, opts = {} ) mode = name vhash = [target.to_url, mode, element.altered]. map{ |x| x.to_s }.join( '|' ).hash parent.vulns[mode] ||= {} return parent.vulns[mode][vhash] if parent.vulns[mode][vhash] parent.vulns[mode][vhash] = { :target => target, :method => element.method.to_s.upcase, :params => element.params.to_a, :mode => mode, :pname => element.altered, :proof => proof.to_s, :form => element.model, :risk => details[:risk], :name => details[:name], :blame => details[:blame], :category => details[:category], :description => details[:description] } confidence = calculate_confidence( parent.vulns[mode][vhash] ) parent.vulns[mode][vhash].merge!( :confidence => confidence ) if !(payload = opts[:payload]) if payloads payload = payloads.select { |p| element.altered_value.include?( p ) }.sort_by { |p| p.size }.last end end uri = URI( element.action ) info = { :web_site => element.model.web_site, :path => uri.path, :query => uri.query, :method => element.method.to_s.upcase, :params => element.params.to_a, :pname => element.altered, :proof => proof.to_s, :risk => details[:risk], :name => details[:name], :blame => details[:blame], :category => details[:category], :description => details[:description], :confidence => confidence, :payload => payload, :owner => self } report_web_vuln( info ) print_good " VULNERABLE(#{mode.to_s}) URL(#{target.to_url})" + " PARAMETER(#{element.altered}) VALUES(#{element.params})" print_good " PROOF(#{proof})" end end end