#!/usr/bin/perl #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO # # ************************************************** !!! WARNING !!! *********************************************************** # ************************************************* DO NOT DISTRIBUTE ********************************************************** # * FOR SECURITY TESTiNG ONLY! * # ****************************************************************************************************************************** # * By using this code you agree that I makes no warranties or representations, express or implied, about the * # * accuracy, timeliness or completeness of this, including without limitations the implied warranties of * # * merchantability and fitness for a particular purpose. * # * I makes NO Warranty of non-infringement. This code may contain technical inaccuracies or typographical errors. * # * This code can never be copyrighted or owned by any commercial company, under no circumstances what so ever. * # * but can be use for as long the developer, are giving explicit approval of the usage, and the user understand * # * and approve of all the parts written in this notice. * # * This program may NOT be used by any Danish company, unless explicit written permission from the developer . * # * Neither myself nor any of my Affiliates shall be liable for any direct, incidental, consequential, indirect * # * or punitive damages arising out of access to, inability to access, or any use of the content of this code, * # * including without limitation any PC, other equipment or other property, even if I am Expressly advised of * # * the possibility of such damages. I DO NOT encourage criminal activities. If you use this code or commit * # * criminal acts with it, then you are solely responsible for your own actions and by use, downloading,transferring, * # * and/or reading anything from this code you are considered to have accepted the terms and conditions and have read * # * this disclaimer. Once again this code is for penetration testing purposes only. And once again, DO NOT DISTRIBUTE! * # ****************************************************************************************************************************** # #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO # # Author/Developer: Dennis Rand - CIRT.DK # Website: http://www.cirt.dk # Copyright: (c)2005 by Dennis Rand # Remember: This program may NOT be used, published or downloaded by any Danish company, unless explicit written permission. # This would be violation of the law on intellectual property rights, and legal actions will be taken. # Bugs/Features: Report bug and/or features to contact@cirt.dk # # Thanks to: Philippe Caturegli for all the nice feature ideas # # # What this tool does: # Have you ever been auditing a system where files are stored on a web server and accessed without authentication directly # by an application that knows each file URL. # # Have you tried a number of spider tools but they are based on links so they don't pull up anything. # # CIRT.DK WebRoot is a Webserver auditing tools, that tries each and every combination (incremental)or a list of words from # a file, against the Webserver. # # In short: # A Brute Forcing tool to discover hidden directories, files or parameters in the URL of a webserver. # #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO # # Usage: # Scan localhost port 80 search for 200 OK response at the url http://127.0.0.1:80/admin/ incremental lowercase 1 to 3 # characters. # WebRoot.pl -host 127.0.0.1 -port 80 -match "200 OK" -url "/admin/" -incremental lowercase -minimum 1 -maximum 3 # #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO # # Installation notes: # perl -MCPAN -e shell # cpan > install Bundle::LWP # cpan > install IO::Socket # cpan > install Getopt::Long # cpan > install Algorithm::GenerateSequence # cpan > install Net::SSLeay::Handle # cpan > install Time::HiRes # cpan > quit # # Clean a Wordfile before use to avoid doubles: # cat Common.txt | sort | uniq > Temp.txt # mv -f Temp.txt Common.txt # #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO # # TODO: # Make results go into an HTML Report - COMPLETED # Make support for SSL - COMPLETED # Make support for Cookies - COMPLETED # Make support for recursive scan. - COMPLETED # Make some sort of false positive check - COMPLETED # Make Verbose mode for more output to screen - COMPLETED # Make Debug mode for resolving problems - COMPLETED # Make support for resuming a scan, if stopped - COMPLETED # Make scanner use multi threats for speed. - MISSING # Make support for POST bruteforcing. - MISSING # # Ideas, Features, and code updates, or error corrections please send to contact@cirt.dk # #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO # # Version descriptions # Version 1.0 # I'm back from scratch, this time I'm going to make it a bit better, but have patience. # For now results are only written to screen. # # Version 1.1 # We now have support for saving the scanning into an HTML file # Decide how many lines of output from the server goes into the report. # # Version 1.2 # More information added into the report start # Now WebRoot also supports scanning of a HTTPS connection. # The response in the report now shows the HTML # # Version 1.3 # Fixed a bug in the -diff and -match options. # # Version 1.4 # Added possibility to use -txt if you want the report in pure text # Added recursive scanning, so if you use -recursive, it will bruteforce deeper to search for more. # Added more information to the update function on what the new version are including. # # Version 1.5 # Added possibility to add referer to the hostheader, use eg. -referer http://127.0.0.1/whatever/qwe.asp # Added raw logging, pure text and only the word that got the hit, use -rawlog # Changed name of the text log -txt replaced with -txtlog # Added a "GUI" to the scanning. # Added False Positive Check to the scan to ensure the right result, and be disabled with -override # Added -debuglines for deciding how many lines of output to have in debug mode # Added -debug for scanning in debug mode to also see what is being sent and recieved. # Added -debugdelay for making a delay between each debug request # Added -Verbose scanning to see findings on screen as they are spotted. # # Version 1.6 # Fixed the issue if you do not choose -diff or -match it will by default be -diff # Instead of only being able to delay for seconds, now possible to delay for microseconds # 1 second = 1000000 microseconds (Time::HiRes) # Fixed an error for recursive scan where we remote space and if there are errors in URL "/", "/ /", " /" or "/ " # Added the possibility to resume previous scans "-resume WebRoot-xxx-xxx.resume" # # Version 1.7 # Added funktionality so that the scan will not stop if server responds slow # Added timestamp to when a server does not respond or is dead, so it is possible to see when # Added the possibility to use "-noupdate" to avoid WebRoot checking for a new version at www.cirt.dk # # Version 1.8 # Changed the default progressbar to show how many tests made and how many sucessfully # Changed the HTML report so it supports more then just IE, also supporting FireFox and possible more. # #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO use IO::Socket; use Getopt::Long; use Algorithm::GenerateSequence; use Net::SSLeay::Handle qw/shutdown/; use Time::HiRes qw(usleep); $ver = "1.8"; $copyright = "(c)2005 by Dennis Rand - CIRT.DK"; $iconbase = "http://www.cirt.dk"; $host = "127.0.0.1"; $port = "80"; $user_agent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; WebRoot $ver)"; $command = "GET"; $url = "/"; $http_version = "HTTP/1.1"; $timeout = "10"; $l_number = 5; $delay = "0"; $debug_delay = 3; @lowerc = ('a'..'z'); @upperc = ('A'..'Z'); @integ = ('0'..'9'); @spec = ('.', '%', '-', '_', '&', '?', '#', '=', '@', '/', '\\', '\''); @all = (@lowerc, @upperc, @integ, @spec); $sucess = 0; $total = 0; $timestampe = localtime; $rap_updates = 0; $recursive_f = "WebRoot.Recursive.Scan"; $recursive = 0; $override_fp = 0; $failed = 1; $debug_lines = 15; $fp_check = "WebRoot.$ver.FALSEPOSITIVECHECK.html"; $c = "#"; $s = ""; $ml = 20; $noresponse = ": The server answers very slow or is dead ==> Retry number: "; $uri,$brute; GetOptions( "host=s" => \$host, "port=i" => \$port, "ssl" => \$ssl, "timeout=i" => \$timeout, "delay=i" => \$delay, "incremental=s" => \$incremental, "minimum=i" => \$inc_minimum, "maximum=i" => \$inc_maximum, "wordlist=s" => \$wordlist, "url=s" => \$url, "command=s" => \$command, "different=s" => \$diff, "match=s" => \$match, "useragent=s" => \$user_agent, "cookie=s" => \$cookie, "referer=s" => \$referer, "http_version=s" => \$http_version, "reportlines=i" => \$l_number, "saveas=s" => \$log, "recursive" => \$recursive, "txtlog" => \$txt_log, "rawlog" => \$raw_log, "override" => \$override_fp, "debuglines=i" => \$debug_lines, "verbose" => \$verbose, "debug" => \$debug, "debugdelay=i" => \$debug_delay, "noupdate" => \$noupdate, "resume=s" => \$resume, "help|?" => sub { print "\n" x 2; print "\t\too00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00\n"; print "\t\to Webserver Bruteforcing $ver o\n"; print "\t\t0 ************* !!! WARNING !!! ************ 0\n"; print "\t\t0 ******* FOR PENETRATION USE ONLY ********* 0\n"; print "\t\t0 ****************************************** 0\n"; print "\t\to $copyright o\n"; print "\t\too00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00\n\n"; print "\t\t Basic settings\r\n"; print "\t\t -host\t\t Set the host ip or hostname to scan\r\n"; print "\t\t -port\t\t Set the port where the webserver are located\r\n"; print "\t\t -timeout\t Set a maximum timeout for each try\r\n"; print "\t\t -delay\t Set a delay between each attempt (Microseconds)\r\n"; print "\r\n"; print "\t\t Scanning options\r\n"; print "\t\t -incremental\t Set if the scanning has to bruteforce\r\n"; print "\t\t use with \"lowercase\", \"uppercase\", \"integer\", \"special\ or \"all\"\r\n\r\n"; print "\t\t -minimum\t Set the min chars for the incremental scan\r\n"; print "\t\t -maximum\t Set the max chars for the incremental scan\r\n"; print "\t\t -wordlist\t Set if a wordlist is supplied\r\n"; print "\t\t -url\t\t Set the URL to bruteforce.\r\n"; print "\t\t Use where you want the bruteforcing\r\n"; print "\r\n"; print "\t\t Advanced scanning options\r\n"; print "\t\t -diff\t\t If the result has to be different, from the response(Default)\r\n"; print "\t\t use with \"404 File not found\" and it will find anything NOT matching in the response \r\n\r\n"; print "\t\t -match\t\t If the result has to match the response\r\n"; print "\t\t use with \"200 OK\" and it will find anything matching\r\n\r\n"; print "\t\t -command\t Set the HTTP command if not GET\r\n"; print "\t\t Remeber you can also use in this field\r\n\r\n"; print "\t\t -useragent\t Enter your own useragent\r\n"; print "\t\t -cookie\t Enter a cookie value\r\n"; print "\t\t -referer\t If you want a Referer in the header\r\n"; print "\t\t -http_version\t If you want to use anything other then HTTP/1.1\r\n"; print "\t\t -recursive\t Make WebRoot scan recursively when scanning for directories\r\n"; print "\t\t -override\t Override the False Positive Check - NOT A GOOD IDEA\r\n"; print "\t\t -resume\t Resume a previous scan\r\n"; print "\t\t -noupdate\t Do not check for updates of WebRoot\r\n"; print "\r\n"; print "\t\t Report options\r\n"; print "\t\t -saveas\t Save report as defines name\r\n"; print "\t\t -txtlog\t Save report in pure text format\r\n"; print "\t\t -rawlog\t Save report in pure text, and only includes the specific hit\r\n"; print "\t\t -reportlines\t Amount of lines output from webserver to put into report (ONLY HTML)\r\n"; print "\r\n"; print "\t\t Visual options\r\n"; print "\t\t -verbose\t Show findings on the screen\r\n"; print "\t\t -debug\t Shows some of the output to screen, so we can search for specific elements\r\n"; print "\t\t -debugline\t Decide how many lines to be in output from debugging - Default: $debug_lines\r\n"; print "\t\t -debugdelay\t Delay between each request made in debug mode - Default: $debug_delay\r\n"; exit; } ); print "\r\n\r\n"; print " oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00\n"; print " o Webserver Bruteforcing $ver o\n"; print " 0 ************* !!! WARNING !!! ************ 0\n"; print " 0 ******* FOR PENETRATION USE ONLY ********* 0\n"; print " 0 ****************************************** 0\n"; print " o $copyright o\n"; print " oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00\n\n"; # Cleanup Recursive list from earlier scans if(!$resume) { unlink("$recursive_f"); } #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO # Resume a previous scan if($resume) { print " [X] Resuming previous scan"; foreach (split(/,/, $resume)) { if (-f $_) { open(_RESUMEFILE, $_); while (<_RESUMEFILE>) { chomp; $host = $' if (/^host=/); $port = $' if (/^port=/); $ssl = $' if (/^ssl=/); $timeout = $' if (/^timeout=/); $delay = $' if (/^delay=/); $incremental = $' if (/^incremental=/); $inc_minimum = $' if (/^minimum=/); $inc_maximum = $' if (/^maximum=/); $wordlist = $' if (/^wordlist=/); $url = $' if (/^url=/); $command = $' if (/^command=/); $diff = $' if (/^diff=/); $match = $' if (/^match=/); $user_agent = $' if (/^useragent=/); $cookie = $' if (/^cookie=/); $referer = $' if (/^referer=/); $http_version = $' if (/^httpversion=/); $l_number = $' if (/^linenumbers=/); $log = $' if (/^saveas=/); $recursive = $' if (/^recursive=/); $txt_log = $' if (/^txtlog=/); $raw_log = $' if (/^rawlog=/); $override_fp = $' if (/^overridefp=/); $debug_lines = $' if (/^debuglines=/); $verbose = $' if (/^verbose=/); $debug = $' if (/^debug=/); $debug_delay = $' if (/^debugdelay=/); $total = $' if (/^total=/); $sucess = $' if (/^sucess=/); $recu = $' if (/^recustate=/); $resumestart = $' if (/^resumestart=/); $scantype = $' if (/^scan=/); } close(_RESUMEFILE); } else { print "\t\t FAILED '$resume' could not be found\n\r\n"; exit; } } print "\t\t - OK\r\n"; } sub wresume { $endtime = localtime; $resumefile = "WebRoot-".$total."-".$sucess.".resume"; print " [X] Writting Resume file\t\t - OK"; if ($incremental) { open(FILE, ">", $resumefile); print FILE "scan=$scantype\nincremental=$incremental\nminimum=$inc_minimum\nmaximum=$inc_maximum\n"; print FILE "host=$host\nport=$port\nssl=$ssl\ntimeout=$timeout\ndelay=$delay\nurl=$url\ncommand=$command\ndiff=$diff\nmatch=$match\nuseragent=$useragent\n"; print FILE "cookie=$cookie\nreferer=$referer\nhttpversion=$http_version\nlinenumbers=$l_number\nsaveas=$log\nrecursive=$recursive\ntxtlog=$txt_log\n"; print FILE "rawlog=$raw_log\noverridefp=$override_fp\ndebuglines=$debug_lines\nverbose=$verbose\ndebug=$debug\ndebugdelay=$debug_delay\n"; print FILE "total=$total\nsucess=$sucess\nresumestart=$found\n"; close FILE; } if ($wordlist) { open(FILE, ">", $resumefile); print FILE "scan=$scantype\nwordlist=$wordlist\n"; print FILE "host=$host\nport=$port\nssl=$ssl\ntimeout=$timeout\ndelay=$delay\nurl=$url\ncommand=$command\ndiff=$diff\nmatch=$match\nuseragent=$useragent\n"; print FILE "cookie=$cookie\nreferer=$referer\nhttpversion=$http_version\nlinenumbers=$l_number\nsaveas=$log\nrecursive=$recursive\ntxtlog=$txt_log\n"; print FILE "rawlog=$raw_log\noverridefp=$override_fp\ndebuglines=$debug_lines\nverbose=$verbose\ndebug=$debug\ndebugdelay=$debug_delay\n"; print FILE "total=$total\nsucess=$sucess\nresumestart=$found\n"; close FILE; } print "\n To restart use: WebRoot.pl -resume $resumefile\r\n\r\n "; print "oo00" x 12, "\r\n\r\n"; } if ($port >= 0 and $port <= 65535){} else { print "Error: Port number invalid, please use from 1-65535\r\n"; exit;} if (($inc_minimum) > ($inc_maximum)) {print "Error: The Maximum are larger then the Minimum\r\n"; exit;} if (!$inc_minimum){$inc_minimum = "1"}; if (!$inc_maximum){$inc_maximum = "3"}; $r_url = $url; #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO # Check for updates at www.cirt.dk sub ChkUpdates { $| = 1; $updates = IO::Socket::INET->new( Proto => "tcp", PeerAddr => "www.cirt.dk", PeerPort => "80", Reuse => 1, Timeout => 10,) || print "\t\t - NO ROUTE\r\n"; } print " [X] Checking for updates"; if (!$resume) { if(!$noupdate) { ChkUpdates(); $response = undef; print $updates "GET /tools/webroot/wr_update.txt HTTP/1.0\r\nHost: www.cirt.dk\r\nUser-Agent: Mozilla/4.0 (WebRoot Update Check)\r\n\r\n"; while(<$updates>) { if(!defined($response)){$response = $_;} $result .= $_; } if ($result =~ m/200 OK/mgsi) { if($result !~ m/$ver/mgsi) { ($result) = $result =~ m/Update_Info:\s+(.*)/; $result =~ s//\r\n\t/g; print "\t\t - FOUND\r\noo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00\r\nINFORMATION:\r\nCIRT.DK WebRoot scanner has been updated, get the latest version at www.cirt.dk\r\nUpdate includes following features: $result\r\nThe scan will continue in 5 seconds\r\noo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00\r\n"; close(updates); $rap_updates = 1; sleep(5); } else { print "\t\t - NO UPDATES\r\n"; } } } else { print "\t\t - NO CHECK\r\n"; } } else { print "\t\t - NO CHECK\r\n"; } #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO # Catch Interupt - CTRL + C sub catchInterrupt { $SIG{INT} = sub {exit;}; print "\n [X] Stopping scan\t\t\t - OK\n"; wresume(); exit; }; $SIG{INT} = \&catchInterrupt; # verify that interrupt handler was installed properly unless(defined($SIG{INT})){print "Unable to install signal handler, contact $copyright";} unless($SIG{INT} == \&catchInterrupt){print "There was an unexpected error installing the signal handler, contact $copyright";} #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO # Hexencoding for the HTML report sub hexencode { $unencoded = $_[0]; $encoded = ""; foreach my $char (split(//,$unencoded)) { $encoded .= sprintf("%02x",ord($char)); } return $encoded; } #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO # Lets create the host header $hostheader = "Accept: */*\r\n"; $hostheader .= "Accept-Language: en\r\n"; if($referer) { $hostheader .= "Referer: $referer\r\n"; } $hostheader .= "User-Agent: $user_agent\r\n"; $hostheader .= "Host: $host\r\n"; if($cookie) { $hostheader .= "Cookie: $cookie\r\n"; } $hostheader .= "Connection: Close\r\n"; #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO # False Positive Check to be made at the beginning of every scan if(!$override_fp) { if(!$resume) { print " [X] Checking for False Positive Scan"; $response_fpcode = undef; $fp_true = 0; connection(); $uri = $url; $uri =~ s//$fp_check/g; $uri =~ s/\/\//\//g; if($ssl) { $ssl=1; eval { tie(*SSL, "Net::SSLeay::Handle", $host,$port); }; print SSL "$command $uri $http_version\r\n$hostheader\r\n\r\n"; shutdown(\*SSL, 1); while() { if(!defined($response_fpcode)){$response_fpcode = $_;} $falsepositive .= $_; } } else { if(!$remote) { print STDERR "\r\n [X] There is no webserver at $host and port $port\r\n\r\n\r\n"; exit; } else { print $remote "$command $uri $http_version\r\n$hostheader\r\n\r\n"; while (<$remote>) { if(!defined($response_code)){$response_code = $_;} $falsepositive .= $_; } } } if($match) { if($falsepositive =~ m/$match/mgsi) {$fp_true = 1;} } else { if($falsepositive !~ m/$diff/mgsi) {$fp_true = 1;} } close($remote); if($fp_true) { print "\t - ERROR\r\n"; print " $command $uri $http_version\r\n\r\n"; my @lines = split(/\n/,$falsepositive); my $firstlines; for(0 .. $debug_lines) { $firstlines .= $lines[$_]; print " Line $_ $lines[$_]\n"; } print "\n ", "oo00" x 12, "\n [X] Scanning Cancled\t\t\t - OK\n ", "oo00" x 12, "\r\n\r\n"; exit; } print "\t - OK\r\n"; } } #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO # Write start of logfile sub start_log { if(!$resume) { if($raw_log) { if(!$log) { $log = "WebRoot_Scanner_".$host."_".$port.".raw"; } open(FH, ">", $log); close(FH); } elsif($txt_log) { if (!$log) { $log = "WebRoot_Scanner_".$host."_".$port.".txt"; } open(FH, ">", $log); print FH "\t\too00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00\n"; print FH "\t\to Webserver Bruteforcing $ver o\n"; print FH "\t\t0 ************* !!! WARNING !!! ************ 0\n"; print FH "\t\t0 ******* FOR PENETRATION USE ONLY ********* 0\n"; print FH "\t\t0 ****************************************** 0\n"; print FH "\t\to $copyright o\n"; print FH "\t\too00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00oo00\n"; print FH "\n\tooOOooOOooOOooOOooOOooOOooOOooOOOOooOOooOOooOOooOOooOOooOOooOOoo\n\n"; print FH "\tHost: $host\r\n"; print FH "\tPort: $port\r\n"; if($ssl) { print FH "\thttps://$host:$port$r_url\n"; } else { print FH "\thttp://$host:$port$r_url\n\r\n"; } if ($incremental) { print FH "\tIncremental: $incremental\r\n"; print FH "\tMinimum: $inc_minimum\r\n"; print FH "\tMaximum: $inc_maximum\r\n\r\n"; } if ($wordlist) { print FH "\tWordlist: $wordlist\r\n\r\n"; } if($match) { print FH "\tResult has to match: $match\r\n"; } else { print FH "\tResult has to be different from: $diff\r\n"; } if ($recursive) { print FH "\tUsing recursive scan\r\n"; } print FH "\r\n\tScan Started: $timestampe"; if($rap_updates) { print FH "\r\n\tThis scan was preformed with an outdated version of WebRoot,\r\n\t get the latest version from http://www.cirt.dk"; } print FH "\n\tooOOooOOooOOooOOooOOooOOooOOooOOOOooOOooOOooOOooOOooOOooOOooOOoo\n\n"; close(FH); } else { $r_url =~ s//>/g; if (!$log) { $log = "WebRoot_Scanner_".$host."_".$port.".html"; } open(FH, ">", $log); print FH "\r\n\r\n"; print FH "\n\nCIRT.DK WebRoot Security Scanner Version $ver\n\n"; print FH "\n\n"; print FH " \n\n"; print FH "\r\n\r\n"; print FH "\n"; print FH "\n"; print FH "\n\n\n
\n
\nCIRT.DK WebRoot Version $ver\n\n
\r\n"; print FH "\n\n\n
\n
\n$copyright\n\n
\r\n"; print FH "\n\n\n
\n
\nhttp://www.cirt.dk\n\n
\n
\r\n"; print FH "\n\n\n
\n
\nAudit Rapport for $host port $port\n\n\n
\n
\r\n"; if($rap_updates) { print FH "
This scan was run with an outdated version of WebRoot, get the latest version from http://www.cirt.dk\r\n

\r\n"; } print FH "\r\n"; print FH "\r\n"; print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH "\r\n"; if ($incremental) { print FH "\r\n"; print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH "\r\n"; print FH "\r\n"; print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH "\r\n"; print FH "\r\n"; print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH "\r\n"; } if ($wordlist) { print FH "\r\n"; print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH "\r\n"; } if($ssl) { print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; } print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; if($match) { print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; } else { print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; } if($recursive) { print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; } print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH "
\r\n"; print FH " Host:\r\n"; print FH " \r\n"; print FH " $host\r\n"; print FH "\r\n"; print FH "
\r\n"; print FH " Port number:\r\n"; print FH " \r\n"; print FH " $port\r\n"; print FH "
\r\n"; print FH "
Incremental:
\r\n"; print FH "
\r\n"; print FH "
$incremental
\r\n"; print FH "
\r\n"; print FH " Minimum:\r\n"; print FH " \r\n"; print FH " $inc_minimum\r\n"; print FH "
\r\n"; print FH " Maximum:\r\n"; print FH " \r\n"; print FH " $inc_maximum
\r\n"; print FH "
\r\n"; print FH "
Wordlist:
\r\n"; print FH "
\r\n"; print FH "
$wordlist
\r\n"; print FH "
\r\n"; print FH "
Using SSL:
\r\n"; print FH "
\r\n"; print FH "
TRUE
\r\n"; print FH "
\r\n"; print FH "
Bruteforce:
\r\n"; print FH "
\r\n"; if($ssl) { print FH "
https://$host:$port$r_url
\r\n"; } else { print FH "
http://$host:$port$r_url
\r\n"; } print FH "
\r\n"; print FH " Result has to match:\r\n"; print FH " \r\n"; print FH " $match\r\n"; print FH "
\r\n"; print FH " Result has to be different from:\r\n"; print FH " \r\n"; print FH " $diff\r\n"; print FH "
\r\n"; print FH "
Using Recursive scanning option
\r\n"; print FH "
\r\n"; print FH "
TRUE
\r\n"; print FH "
\r\n"; print FH " Scan Started:\r\n"; print FH " \r\n"; print FH " $timestampe\r\n"; print FH "
\r\n"; print FH "
Audit Results
\r\n"; print FH "\r\n"; print FH "
\r\n"; close(FH); } } } #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO # Write results to logfile sub write_log { $b64name = hexencode("$uri"); $timestamp = localtime; open(FH, ">>", $log); if($raw_log) { print FH "$brute\r\n"; } elsif($txt_log) { if($ssl) { print FH "\t$timestamp\t\=> https://$host:$port$uri\r\n"; } else { print FH "\t$timestamp\t\=> http://$host:$port$uri\r\n"; } } else { $html_hostheader = $hostheader; $html_hostheader =~ s/\r\n/
/g; print FH "\r\n"; print FH " \r\n"; print FH " \r\n"; } close (FH); recursive_learn(); } #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO # Write end to logfile sub end_log { $timestamp = localtime; open(FH, ">>", $log); if($raw_log){} elsif($txt_log) { print FH "\n\tooOOooOOooOOooOOooOOooOOooOOooOOOOooOOooOOooOOooOOooOOooOOooOOoo\r\n"; print FH "\tThe Scan completed: $timestamp\r\n"; print FH "\tPossible findings: $sucess\r\n"; print FH "\tTotal attempts: $total\r\n"; print FH "\tooOOooOOooOOooOOooOOooOOooOOooOOOOooOOooOOooOOooOOooOOooOOooOOoo\r\n"; } else { print FH "\r\n"; print FH "
\r\n"; if($ssl) { print FH " https://$host:$port$uri
\n"; } else { print FH " http://$host:$port$uri
\n"; } print FH "
\n"; print FH " \n"; print FH " Sent/Recieved Data
\n"; print FH " \n"; print FH "
  • Data sent to Server:
    \n"; print FH " $command $uri $http_version
    $html_hostheader

    "; print FH "
  • Response from Server:
    \n"; $result =~ s//>/g; my @lines = split(/\n/,$result); my $firstlines; for(0 .. $l_number) { $firstlines .= $lines[$_]; print FH "$lines[$_]
    \r\n"; } print FH "
    \n"; print FH "
    \r\n"; print FH "
  • \r\n"; print FH " \r\n\r\n"; print FH "
    Rapport Summary

    \r\n"; print FH "\r\n"; print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH "\r\n"; print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH "\r\n"; print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH " \r\n"; print FH "\r\n"; print FH "
    \r\n"; print FH " The Scan completed:\r\n"; print FH " \r\n"; print FH " $timestamp\r\n"; print FH "
    \r\n"; print FH " Possible findings:\r\n"; print FH " \r\n"; print FH " $sucess\r\n"; print FH "
    \r\n"; print FH " Total attempts\r\n"; print FH " \r\n"; print FH " $total\r\n"; print FH "
    \r\n"; print FH "\r\n"; print FH "
    $copyright


    \r\n"; print FH " \r\n"; print FH "\r\n\r\n"; print FH "\r\n"; } close (FH); unlink("$recursive_f"); } #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO # Save findings into for Recursive scanning sub recursive_learn { if($recursive) { open(RECU_LEARN, ">>", $recursive_f); print RECU_LEARN "$brute/\r\n"; close RECU_LEARN; } } #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO # Scan using Recursive if(!$resume) { if (-f $recursive_f) {} else { open(RECU, ">", $recursive_f); print RECU "\n"; close(RECU); } } sub recursive_scan { $recursive = 1; open(_RECU, $recursive_f); while (<_RECU>) { s/\r//; chomp; $recu = $_; if($incremental) { &incremen; } if($wordlist) { &wordlst; } } close(_RECU); } #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO #Incremental if ($incremental) { $scantype = 0; @choice = split(/,/, $incremental); print " [X] Using Incremental"; foreach $inc_input (@choice) { if ($inc_input eq "lowercase") {@do_choice = @lowerc;} elsif ($inc_input eq "uppercase") {@do_choice = @upperc} elsif ($inc_input eq "integer") {@do_choice = @integ} elsif ($inc_input eq "special") {@do_choice = @spec;} elsif ($inc_input eq "all") {@do_choice = @all;break;} else { print "\t\t\t - FAILED\n"; print " Error: You have to specify the -incremental with lowercase, uppercase, integer, special or all\r\n\r\n"; exit; } } print "\t\t\t - OK\n"; print " [X] Starting Scan\t\t\t - OK\n"; if(!$resume) { start_log(); } if(!$recursive || $recursive eq "0") { &incremen; } else { &recursive_scan ; } } sub incremen { $start_pos = ($inc_minimum - 1); do { my $len = $start_pos; my $gen = Algorithm::GenerateSequence->new( map {[@do_choice]} (0 .. $len) ); local $" = ""; while(my @c = $gen->next) { $brute = $recu; $brute .= join("",@c); $uri = $url; $uri =~ s//$brute/g; $uri =~ s/\/\//\//g; $uri =~ s/ \//\//g; $uri =~ s/\/ /\//g; $found = $brute; bruteforcing(); } $start_pos++; } until ($start_pos >= $inc_maximum); } #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO #Wordlist if ($wordlist) { $scantype = 1; print " [X] Using Wordlist"; print "\t\t\t - OK\n"; print " [X] Starting Scan\t\t\t - OK\n"; start_log(); if((!$recursive) || ($recursive = 0)) { &wordlst; } else { &recursive_scan; } } sub wordlst { foreach (split(/,/, $wordlist)) { if (-f $_) { open(_FILE, $_); while (<_FILE>) { s/\r//; chomp; $brute = $recu; $brute .= $_; $uri = $url; $uri =~ s//$brute/g; $uri =~ s/\/\//\//g; $uri =~ s/ \//\//g; $uri =~ s/\/ /\//g; $found = $brute; bruteforcing(); } close(_FILE); } else { print " The wordfile you are trying to use: '$_' could not be found\n"; print " WebRoot.pl -help or -?' for more information.\n\n"; exit; } } } #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO # The connection are setup here. sub connection { $| = 1; $remote = IO::Socket::INET->new( Proto => "tcp", PeerAddr => $host, PeerPort => $port, Reuse => 1, Timeout => $timeout,) } #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO #ooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOOooOO # Let the bruteforcing begin sub bruteforcing { if ($resume) { if ($brute eq $resumestart) { $resumereached=1; $firsttimeout = 0; } } if ($resumereached eq "1" || !$resume) { usleep($delay); $success_true = 0; $total++; $result = ""; $response_code = undef; connection(); while(!defined $remote) { connection(); if(!defined $remote) { if($ssl) { print STDERR "\r [X] $whattime$noresponse" . $failed++ ; sleep 5; $firsttimeout = 1; } else { $whattime = localtime; print STDERR "\r [X] $whattime$noresponse" . $failed++ ; sleep 5; $firsttimeout = 1; } } } if($firsttimeout) { print "\r\n"; $failed = 1; } $firsttimeout = 0; if($ssl) { $ssl=1; eval { tie(*SSL, "Net::SSLeay::Handle", $host,$port); }; print SSL "$command $uri $http_version\r\n$hostheader\r\n\r\n"; shutdown(\*SSL, 1); while() { if(!defined($response_code)){$response_code = $_;} $result .= $_; } } else { print $remote "$command $uri $http_version\r\n$hostheader\r\n\r\n"; while (<$remote>) { if(!defined($response_code)){$response_code = $_;} $result .= $_; } } if($match) { if($result =~ m/$match/mgsi) { $sucess++; write_log(); $success_true = 1; } } else { if($result !~ m/$diff/mgsi) { $sucess++; write_log(); $success_true = 1; } } close($remote); if($verbose) { $count_length0 = length("\t$command $uri $http_version"); if ($count_length0 > $count_length1) { $count_length2 = ($count_length0 - $count_length1); $verbose_space = " " x $count_length2; } printf STDERR "\r $command $uri $http_version"."$verbose_space"; $count_length1 = length("\t$command $uri $http_version"); if($success_true) { printf STDERR "\r $command $uri $http_version"."$verbose_space\r\n"; } } elsif($debug) { sleep($debug_delay); print " ","oo00" x 12,"\r\n REQUEST:"; print "\r\n$command $uri $http_version\r\n$hostheader\r\n\r\n RESPONSE:\r\n"; my @lines = split(/\n/,$result); my $firstlines; for(0 .. $debug_lines) { $firstlines .= $lines[$_]; print " Line $_ $lines[$_]\n"; } } else { #Progressbar print "\r [X] Relay Checking in progress:\t - ",$sucess,"/",$total; } } } end_log(); if($resume) { unlink("$resume"); # Clean up old resume files } print "\n\n [X] Scan complete\t\t\t - OK"; print "\n [X] Total attempts\t\t\t - $total"; print "\n [X] Sucessfull attempts\t\t - $sucess\n "; print "oo00" x 12, "\r\n\r\n";