1#!/usr/local/bin/perl 2# 3# Package to craft and send the HTTP requests 4# by chr1x & nitr0us 5# 6 7package DotDotPwn::HTTP; 8use Exporter 'import'; 9@EXPORT = qw(FuzzHTTP); 10 11use DotDotPwn::BisectionAlgorithm; 12 13use HTTP::Request; 14use LWP::UserAgent; 15use Time::HiRes qw(usleep); 16 17sub FuzzHTTP{ 18 my ($host, $port, $ssl, $method, $ping, $bisection_request) = @_; 19 our $n_travs = 0; 20 my $false_pos = 0; 21 my $foo = 0; # Used as an auxiliary variable in quiet mode (see below) 22 my $UserAgent; 23 24 open(AGENTS, "/usr/local/share/dotdotpwn/User-Agents.txt") or die "[-] Cannot open User-Agents.txt file: $!"; 25 my @UserAgents = <AGENTS>; 26 close(AGENTS); 27 28 if(!$bisection_request){ 29 open(REPORT , ">>$main::report"); 30 } 31 32 foreach my $traversal (@main::traversals){ 33 my $http = LWP::UserAgent->new(); 34 35 $UserAgent = @UserAgents[int(rand(@UserAgents))]; 36 my $request = new HTTP::Request $method, '' . ($ssl ? "https://" : "http://") . "$host" . ($port ? ":$port" : "") . "/" . $traversal; 37 $UserAgent =~ s/[\r\n]//g; 38 $request->header('User-Agent', $UserAgent); 39 40 # Return 1 (vulnerable) or 0 (not vulnerable) to BisectionAlgorithm() 41 if($bisection_request){ 42 my $reponse = $http->request($bisection_request); 43 44 if($response->code == 200){ 45 if($main::pattern){ 46 if($http->content() =~ /$main::pattern/s ){ 47 return 1; # Vulnerable 48 } else { 49 return 0; # Not Vulnerable 50 } 51 } else { 52 return 1; # Vulnerable 53 } 54 } else { 55 return 0; # Not Vulnerable 56 } 57 } 58 59 #my $request = new HTTP::Request $method, "http://$host" . ($port ? ":$port" : "") . "/" . $traversal; 60 #$request->header('User-Agent', $UserAgent); 61 my $response = $http->request($request); 62 if($response->message =~ /[Cc]onnect/){ # LWP reports 500 errors for Connection failed, timeout, etc :( 63 my $runtime = time - $main::start_time; 64 for my $fh (STDOUT, REPORT) { 65 print $fh "\n[+] False positives detected: $false_pos" if $false_pos > 0; 66 printf $fh "\n[+] Fuzz testing finished after %.2f minutes ($runtime seconds)\n", ($runtime / 60); 67 print $fh "[+] Total Traversals found (so far): $n_travs\n"; 68 } 69 if(!$ping){ 70 die "[-] Web server ($host) didn't respond !\n"; 71 } 72 } 73 74 if($response->code == 200){ 75 if($main::pattern){ 76 if($response->content =~ /$main::pattern/s ){ 77 for my $fh (STDOUT, REPORT) { print $fh "\n[*] Testing Path (response analysis): ".$request->uri." <- VULNERABLE!\n"; } 78 $n_travs++; 79 80 if($main::bisect){ 81 print "\n[========= BISECTION ALGORITHM =========]\n\n"; 82 DotDotPwn::BisectionAlgorithm::BisectionAlgorithm(1, $main::bisdeep, $request); 83 84 return 1; 85 } 86 87 return $n_travs if $main::break; 88 } else { 89 if($main::quiet){ 90 print ". " unless $foo++ % $main::dot_quiet_mode; 91 } else { 92 print "\n[*] Testing Path: ".$request->uri." <- FALSE POSITIVE!\n"; 93 } 94 95 $false_pos++; 96 } 97 } else { 98 for my $fh (STDOUT, REPORT) { print $fh "\n[*] Testing Path: ".$request->uri." <- VULNERABLE!\n"; } 99 $n_travs++; 100 101 if($main::bisect){ 102 print "\n[========= BISECTION ALGORITHM =========]\n\n"; 103 DotDotPwn::BisectionAlgorithm::BisectionAlgorithm(1, $main::bisdeep, $request); 104 105 return 1; 106 } 107 108 return $n_travs if $main::break; 109 } 110 111 usleep($main::time); 112 next; 113 } 114 115 if($main::quiet){ 116 print ". " unless $foo++ % $main::dot_quiet_mode; 117 } else{ 118 print "[*] HTTP Status: " . $response->code . " | Testing Path: ".$request->uri."\n"; 119 } 120 121 usleep($main::time); 122 } 123 124 for my $fh (STDOUT, REPORT) { print $fh "\n[+] False positives detected: $false_pos" if $false_pos > 0; } 125 126 return $n_travs; 127} 128