Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/auxiliary/scanner/http/brute_dirs.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45require 'enumerable'67class MetasploitModule < Msf::Auxiliary8include Msf::Exploit::Remote::HttpClient9include Msf::Auxiliary::WmapScanDir10include Msf::Auxiliary::Scanner11include Msf::Auxiliary::Report1213def initialize(info = {})14super(update_info(info,15'Name' => 'HTTP Directory Brute Force Scanner',16'Description' => %q{17This module identifies the existence of interesting directories by brute forcing the name18in a given directory path.19},20'Author' => [ 'et' ],21'License' => BSD_LICENSE))2223register_options(24[25OptString.new('PATH', [ true, "The path to identify directories", '/']),26OptString.new('FORMAT', [ true, "The expected directory format (a alpha, d digit, A upperalpha)", 'a,aa,aaa']),27OptInt.new('TIMEOUT', [true, 'The socket connect/read timeout in seconds', 20]),28OptInt.new('DELAY', [true, "The delay between connections, per thread, in milliseconds", 0]),29OptInt.new('JITTER', [true, "The delay jitter factor (maximum value by which to +/- DELAY) in milliseconds.", 0]),30])3132register_advanced_options(33[34OptInt.new('ErrorCode', [ true, "The expected http code for non existent directories", 404]),35OptPath.new('HTTP404Sigs', [ false, "Path of 404 signatures to use",36File.join(Msf::Config.data_directory, "wmap", "wmap_404s.txt")37]),38OptBool.new('NoDetailMessages', [ false, "Do not display detailed test messages", true ]),39OptInt.new('TestThreads', [ true, "Number of test threads", 25])40])41end4243def wmap_enabled44true45end4647def run_host(ip)4849conn = false5051timeout = datastore['TIMEOUT']5253delay_value = datastore['DELAY'].to_i54if delay_value < 055raise Msf::OptionValidateError.new(['DELAY'])56end5758jitter_value = datastore['JITTER'].to_i59if jitter_value < 060raise Msf::OptionValidateError.new(['JITTER'])61end6263tpath = normalize_uri(datastore['PATH'])64if tpath[-1,1] != '/'65tpath += '/'66end6768vhost = datastore['VHOST'] || datastore['RHOST']6970dm = datastore['NoDetailMessages']7172# You may add more extensions in the extens array73extens = ["/"]7475# You may add multiple formats in the array76forma = []77forma = datastore['FORMAT'].split(',')7879ecode = datastore['ErrorCode'].to_i80extens.each do |exte|8182#83# Detect error code84#85ecode = datastore['ErrorCode'].to_i86begin87randdir = Rex::Text.rand_text_alpha(5).chomp88randdir << exte89res = send_request_cgi({90'uri' => tpath+randdir,91'method' => 'GET',92'ctype' => 'text/html'93}, timeout)9495return if not res9697tcode = res.code.to_i9899# Look for a string we can signature on as well100if(tcode >= 200 and tcode <= 299)101emesg = nil102File.open(datastore['HTTP404Sigs'], 'rb').each do |str|103if(res.body.index(str))104emesg = str105break106end107end108109if(not emesg)110print_status("Using first 256 bytes of the response as 404 string")111emesg = res.body[0,256]112else113print_status("Using custom 404 string of '#{emesg}'")114end115else116ecode = tcode117print_status("Using code '#{ecode}' as not found.")118end119120rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout121conn = false122rescue ::Timeout::Error, ::Errno::EPIPE123end124125forma.each do |f|126127numb = []128f.scan(/./) { |c|129case c130when 'a'131numb << ('a'..'z')132when 'd'133numb << ('0'..'9')134when 'A'135numb << ('A'..'Z')136# These dont actually work137# when 'N'138# numb << ('A'..'Z')+('0'..'9')139# when 'n'140# numb << ('a'..'z')+('0'..'9')141else142print_error("Format string error")143return144end145}146147#exte.scan(/./) { |c|148# numb << "#{c}"149#}150151Enumerable.cart(*numb).each {|testd|152153strdir = testd.join154155begin156teststr = tpath+strdir157teststr << exte158159# Add the delay based on JITTER and DELAY if needs be160add_delay_jitter(delay_value,jitter_value)161162vprint_status("Try... #{wmap_base_url}#{teststr} (#{vhost})")163164res = send_request_cgi({165'uri' => teststr,166'method' => 'GET',167'ctype' => 'text/plain'168}, timeout)169170if (not res or ((res.code.to_i == ecode) or (emesg and res.body.index(emesg))))171if dm == false172print_status("NOT Found #{wmap_base_url}#{teststr} #{res.code.to_i}")173#blah174end175else176if res.code.to_i == 400 and ecode != 400177print_error("Server returned an error code. #{wmap_base_url}#{teststr} #{res.code.to_i}")178else179print_good("Found #{wmap_base_url}#{teststr} #{res.code.to_i}")180181report_web_vuln({182:host => rhost,183:port => rport,184:vhost => vhost,185:ssl => ssl,186:path => "#{teststr}",187:method => 'GET',188:pname => "",189:proof => "Res code: #{res.code.to_s}",190:risk => 0,191:confidence => 100,192:category => 'directory',193:description => 'Directory found.',194:name => 'directory'195})196197end198end199200rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout201rescue ::Timeout::Error, ::Errno::EPIPE202end203}204end205end206end207end208209210