-
Notifications
You must be signed in to change notification settings - Fork 1
/
perl-buster.pl
159 lines (123 loc) · 4.25 KB
/
perl-buster.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#! /usr/bin/perl
use strict;
use warnings;
use Getopt::Std;
use LWP 5.64;
print STDOUT <<HEAD;
#################################
# #
# perl-buster #
# #
#################################
HEAD
# FUNCTIONS
sub get_help {
print STDOUT <<HELP;
USAGE:
perl perl-buster.pl [args]
EXAMPLE:
perl perl-buster.pl -u [BASE_URL] -w [WORDLIST]
perl perl-buster.pl -u [BASE_URL] -w [WORDLIST] -t [TIME_BETWEEN_REQUESTS]
perl perl-buster.pl -u [BASE_URL] -w [WORDLIST] -o [OUTPUT_FILE_PATH]
perl perl-buster.pl -u [BASE_URL] -w [WORDLIST] -q
FLAGS:
-h, help me find what this program does
-u, base URL
-w, path to the wordlist file
-t, time between requests, make process quieter
-o, relative path to output file
-q, quiet mode, no responses printed to console
-p, specify the port number to make requests to, default is 80
-e, use HTTPS instead of the default HTTP protocol
-r, specify the reponse codes separated by commas,
e.g. 2,3,4 this will return all 200-499 response codes
e.g. 202,3,404 this will return 202, 300-399 and 404
-g, use GET request instead of HEAD request
-a, set the name of the user agent e.g. AppId/AppVersionId, by default this is libwww-perl/#.###
HELP
exit;
}
sub get_browser {
my ($user_defined_ua) = @_;
my $userAgent = LWP::UserAgent->new || die $!;
$userAgent->agent($user_defined_ua) if defined $user_defined_ua;
return $userAgent;
}
sub read_wordlist {
my ($filename) = @_;
open my $fh, "<", $filename;
return $fh;
}
sub get_response_code {
my ($url, $browser, $method) = @_;
my $response;
if ( $method eq "HEAD" ) {
$response = $browser->head($url);
}
elsif ( $method eq "GET" ) {
$response = $browser->get($url);
}
return $response->{_rc};
}
sub get_absolute_URL {
my ($url_arg) = @_;
if ( $url_arg !~ m/^http:\/\/|^https:\/\// ) {
$url_arg = "http://".$url_arg;
}
return $url_arg;
}
sub write_to_file {
my ($location, $info) = @_;
open my $fh, ">>", $location || die $!;
print $fh $info;
close($fh);
}
sub set_port {
my ($port, $url_string) = @_;
die "A port should be an integer. e.g. -p 80 is default -p 443 is https, -p 8080 may be a test size or API." if $port !~ m/^\d+$/ or $port > 65535;
return $url_string.":".$port;
}
sub set_https {
my ($url_string) = @_;
substr($url_string, 4, 0) = 's';
return $url_string;
}
sub set_response_codes {
my ($user_defined_codes) = @_;
$user_defined_codes =~ s/,$//;
$user_defined_codes =~ s/(\d),/$1|^/g;
substr($user_defined_codes, 0, 0) = "^";
return $user_defined_codes;
}
# OPTIONS
my %options = ();
getopts("hu:w:t:o:qp:er:ga:", \%options);
get_help() if defined $options{h};
my $url = get_absolute_URL($options{u}) if defined $options{u} || die "Please use the -u flag to pass in a URL. Use -h for help.\n";
my $wordlist = read_wordlist($options{w}) if defined $options{w} || die "Please use the -w flag and pass in a path to a wordlist. Use -h for help.\n";
my $sleeptime = defined $options{t} ? $options{t} : 1;
my $output_loc = $options{o} if defined $options{o};
my $quiet_mode = $options{q} if defined $options{q};
$url = set_port($options{p}, $url) if defined $options{p};
$url = set_https($url) if defined $options{e};
my $response_codes = defined $options{r} ? set_response_codes($options{r}) : "^2";
my $method = defined $options{g} ? "GET" : "HEAD";
my $agent = $options{a} if defined $options{a};
# MAIN
my $browser = get_browser($agent);
my $startTime = time;
while ( <$wordlist> ) {
my $full_url = $url."/".$_;
my $rc = get_response_code($full_url, $browser, $method);
if ( $rc =~ /$response_codes/ ) {
print STDOUT $rc, " -> ", $full_url if not defined $quiet_mode;
write_to_file($output_loc, "[".$rc."] ".$full_url) if defined $output_loc;
}
sleep($sleeptime);
}
my $totalTime = time-$startTime;
print STDOUT <<END;
#################################
Time to execute: $totalTime(s)
#################################
END