./c0de/perl/proxyscan.txt

0.
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.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
#!/usr/bin/perl -w
 
######################################################################
# proxyScan v0.1
#
# by Ed Blanchfield http://www.e-things.org/
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the Perl Artistic License or the
# GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any
# later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# If you do not have a copy of the GNU General Public License write to
# the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
# MA 02139, USA.
# 
# 
#######################################################################
 
 
use Getopt::Long;
use LWP::UserAgent;
use strict;
 
my $DEBUG;
my $ports;
my $targets;
my $proxy;
my $method;
my $delay;
my $timeout;
my $userAgent = "proxyScan/0.1";
 
 
######################################################################
# main()
 
&getArgs;
 
# process each target host separated by comma's.
foreach my $targetHost (split(/,/, $targets)) {
	# check if it's an IP range
	if ($targetHost 
		=~ /^(\d+\.\d+\.\d+\.\d+)-(\d+\.\d+\.\d+\.\d+)$/) {
 
		# save start and end of range as decimal
		my $startIp 	= &ip2dec($1);
		my $endIp	= &ip2dec($2);
 
		# sanity check the range
		if ($startIp > $endIp) {
			print "$0: startIp is greater than endIp ";
			print "in $targetHost\n";
			die;
		}
 
		# iterate each IP address in the range
		for (my $dec=$startIp; $dec <= $endIp; $dec++) {
 
			# scan each IP by for each port
			foreach my $targetPort (split(/,/, $ports)) {
 
				# if the port is a range
				if ($targetPort =~ /^(\d+)-(\d+)$/) {
					my $startPort = $1;
					my $endPort   = $2;
 
					if ($startPort > $endPort) {
						print "$0: startPort is",
						 " greater than endPort",
						 " in $targetPort\n";
						die;
					}
 
					for (my $port=$startPort; 
					     $port <= $endPort; $port++) {
						my $ip=&dec2ip($dec);
						&scanPort($ip,$port);
					}
 
				# otherwise a single port
				} else {
					my $ip=&dec2ip($dec);
					&scanPort($ip,$targetPort);
				}
			}
		}
 
	# process single IP's, or hostnames
	} else {
 
		# scan this host for each port
		foreach my $targetPort (split(/,/, $ports)) {
 
			# if the port is a range
			if ($targetPort =~ /^(\d+)-(\d+)$/) {
				my $startPort = $1;
				my $endPort   = $2;
 
				if ($startPort > $endPort) {
					print "$0: startPort is",
					 " greater than endPort",
					 " in $targetPort\n";
					die;
				}
 
				for (my $port=$startPort; 
				     $port <= $endPort; $port++) {
					my $ip=$targetHost;
					&scanPort($ip,$port);
				}
 
			# otherwise a single port
			} else {
				my $ip=$targetHost;
				&scanPort($ip,$targetPort);
			}
		}
 
	}
}
 
# the end, only funtions from here on 
exit;
 
 
######################################################################
# Check and set options from command line args
#
sub getArgs() {
	Getopt::Long::Configure('bundling', 
        	'no_ignore_case');
 
	my $optVerbose;
	my $optHelp;
	my $optPorts;
	my $optTimeout;
	my $optDelay;
	my $optMethod;
	my $optTargets;
 
	GetOptions
		("v|verbose"    => \$optVerbose,
		"h|help"        => \$optHelp,
		"p|ports=s"     => \$optPorts,
		"o|timout=s"    => \$optTimeout,
		"d|delay=s"     => \$optDelay,
		"m|method=s"    => \$optMethod,
		"t|targets=s"   => \$optTargets);
 
	if ($optHelp) { # then help / usage option
		print "Usage: $0 [options below]\n";
		print "Options:\n";
		print "   --help",
		"\tthis message.\n";
		print "   --verbose",
		"\tbe verbose for debugging.\n";
		print "   --ports",
		"\tports to scan for.\n";
		print "\t\tExample: 80-90,8080-8090,443,23,22\n";
		print "   --targets",
		"\ttarget hosts to scan for through proxy. Default is localhost.\n";
		print "\t\tExample: localhost,10.1.1.1-10.1.1.100,myhost.somedomain.com\n";
		print "   --timeout",
		"\ttimeout in seconds to wait for a response. default is 2 seconds\n";
		print "   --delay",
		"\tdelay in seconds between requests. Default is 0.5.\n";
		print "   --method",
		"\trequest method (CONNECT/GET/OPTIONS/TRACE/etc). default is GET.\n";
		print "\n";
		print "Set proxy with environment variables *_proxy.  ";
		print "Example: export http_proxy=http://proxy.my.place:8080/\n\n";
		exit;
	}
 
 
	if ($optVerbose) {         # set debugging / verbose output
        	$DEBUG=1;
	} else {
		# default
        	my $DEBUG=0;
	}
 
	if ($optPorts) {         # ports to scan through
		if ($optPorts =~ /^[\d,-]+$/) {
			$ports = $optPorts;
		} else {
			die "$0: invalid ports.\n";
		}
	} else {
		# default port to 80
		$ports = "80";
	}
 
	if ($optTargets) {         # target hosts to scan through proxy
		if ($optTargets =~ /^[\d\w\.,-]+$/) {
			$targets = $optTargets;
		} else {
			die "$0: invalid targets.\n";
		}
	} else {
		# default targets to localhost only
		$targets = "localhost";
	}
 
	if ($optTimeout) {         # timout in secs for a response
		if ($optTimeout =~ /^\d+$/) {
			$timeout = $optTimeout;
		} else {
			die "$0: invalid timeout.\n";
		}
	} else {
		# default timeout
		$timeout = "2";
	}
 
	if ($optDelay) {         # delay in secs between request
		if ($optDelay =~ /^\d+$/) {
			$delay = $optDelay;
		} else {
			die "$0: invalid delay.\n";
		}
	} else {
		# default delay
		$delay = "0.5";
	}
 
	if ($optMethod) {         # HTTP method
		if ($optMethod =~ /^\w+$/) {
			$method = uc($optMethod);
		} else {
			die "$0: invalid method.\n";
		}
	} else {
		# default method
		$method = "GET";
	}
}
 
######################################################################
# Scan for a target and port 
#
sub scanPort() {
 
	my $target = shift 
		|| die "$0: no target passed to scanPort()\n";
 
	my $port = shift 
		|| die "$0: no port passed to scanPort()\n";
 
	if ($target && $port) {
 
		# Create a user agent object
		my $ua = LWP::UserAgent->new;
		$ua->agent("$userAgent ");
		$ua->timeout($timeout);
		$ua->env_proxy;
		my $url = "http://".$target.":".$port;
 
		if ($DEBUG) {
			if ($ENV{http_proxy}) {
				print "proxy = $ENV{http_proxy}\n";
			} else {
				print "proxy = [NOT SET]\n";
			}
			print "port = $port\n";
			print "target = $target\n";
			print "url = $url\n";
		}
 
		# Create a request
		my $req = HTTP::Request->new($method => $url);
 
		# Pass request to the user agent and get a response back
		my $res = $ua->request($req);
 
		# Check the outcome of the response
		my $passFail;;
		if ($res->is_success) {
			$passFail="pass";	
		} else {
			$passFail="fail";	
		}
 
		print "result=\"$passFail\",";
		print "URL=\"$url\",";
		print "method=\"$method\",";
 
		if ($ENV{http_proxy}) {
			print "proxy=\"$ENV{http_proxy}\",";
		} else {
			print "proxy=\"[NOT SET]\",";
		}
 
		print "result=\"".$res->status_line, "\"\n";
		# uncomment for the response content
		#print $res->content;
 
 
		# sleep a while based on the delay set
		# the delay is important.  without this LWP
		# will send out request as fast as it can and
		# we may miss the response.
		sleep($delay);
 
	} else {
		die "$0: you must specify at least on host and one port\n";
	}
}
 
######################################################################
# Convert IP addresses to decimal for use with ranges
#
sub ip2dec() {
	my $hex;
	my $ip = shift || return;
 
	# Sanity check arguments and example regex of an IP address, almost.
	if ($ip !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/ ) {
  		die "$0: Invalid IP address given to ip2dec - $ip\n";
	}
 
	# Convert to Hex
	foreach my $octet (split(/\./,$ip, 4)) {
  		die "Invalid IP address given\n" 
			if($octet < 0 || $octet > 255);
  		$hex .= sprintf("%02x",$octet);
	}
 
	# Convert to decimal and return
	return hex($hex);
}
 
######################################################################
# Convert Decimal to IP address
#
sub dec2ip {
	my $dec = shift || return;
 
	# Sanity check arguments 
	if ($dec !~ /^\d+$/ ) {
  		die "$0: Invalid decimal IP given to dec2ip - $dec\n";
	}
        my $hexagain = sprintf("%08x", $dec);
        my $octet1 = substr($hexagain,0,2);
        my $octet2 = substr($hexagain,2,2);
        my $octet3 = substr($hexagain,4,2);
        my $octet4 = substr($hexagain,6,2);
        my $dec1 = hex($octet1);
        my $dec2 = hex($octet2);
        my $dec3 = hex($octet3);
        my $dec4 = hex($octet4);
        return "$dec1.$dec2.$dec3.$dec4";
}
 
 

Back