#!/usr/bin/perl 
use LWP::UserAgent;
use URI::URL;
use strict;
my($count, $result_file, $outputchoice, $outputfile, $method, $methodchoice, $servercode, $codes, $answer, $sendfile, $varfile, %NAME, %SECOND, $second_, $sval_, $sent, $start_count, $hex_data, $cgi, %HEX, $string, @chars, $hdrs, $url, $req, $resp, $ua, $site, $data, $first, $fval, $second, $sval, $fval_1, $sval_1);
%HEX = (
	'!'	=>	'21',
	' '	=>	'20',  
	'"'	=>	'22',
	'#'	=>	'23',
	'$'	=>	'24',
	'%'	=>	'25',
	'&'	=>	'26',
	'\''	=>	'27',
	'('	=>	'28',
	')'	=>	'29',
	'*'	=>	'2a',
	'+'	=>	'2b',
	','	=>	'2c',
	'-'	=>	'2d',
	'.'	=>	'2e',
	'/'	=>	'2f',
	':'	=>	'3a',
	';'	=>	'3b',
	'<'	=>	'3c',
	'='	=>	'3d',
	'>'	=>	'3e',
	'?'	=>	'3f',
	'@'	=>	'40',
	nul	=>	'00',
	soh	=>	'01',
	stx	=>	'02',
	etx	=>	'03',
	eot	=>	'04',
	enq	=>	'05',
	ack	=>	'06',
	bel	=>	'07',
	bs	=>	'08',
	ht	=>	'09',
	nl	=>	'0a',
	vt	=>	'0b',
	np	=>	'0c',
	cr	=>	'0d',
	so	=>	'0e',
	si	=>	'0f',
	'['	=>	'5b',
	'\\'	=>	'5c',
	']'	=>	'5d',
	'^'	=>	'5e',
	'_'	=>	'5f',
	'`'	=>	'60',
	'{'	=>	'7b',
	'|'	=>	'7c',
	'}'	=>	'7d',
	'~'	=>	'7e',
	dle	=>	'10',
	dc1	=>	'11',
	dc2	=>	'12',
	dc3	=>	'13',
	dc4	=>	'14',
	nak	=>	'15',
	syn	=>	'16',
	etb	=>	'17',
	can	=>	'18',
	em	=>	'19',
	sub	=>	'1a',
	esc	=>	'1b',
	fs	=>	'1c',
	gs	=>	'1d',
	rs	=>	'1e',
	us	=>	'1f',
	sp	=>	'20',
	0	=>	'30',
	1	=>	'31',
	2	=>	'32',
	3	=>	'33',
	4	=>	'34',
	5	=>	'35',
	6	=>	'36',
	7	=>	'37',
	8	=>	'38',
	9	=>	'39',
	A	=>	'41',
	B	=>	'42',
	C	=>	'43',
	D	=>	'44',
	E	=>	'45',
	F	=>	'46',
	G	=>	'47',
	H	=>	'48',
	I	=>	'49',
	J	=>	'4a',
	K	=>	'4b',
	L	=>	'4c',
	M	=>	'4d',
	N	=>	'4e',
	O	=>	'4f',
	P	=>	'50',
	Q	=>	'51',
	R	=>	'52',
	S	=>	'53',
	T	=>	'54',
	U	=>	'55',
	V	=>	'56',
	W	=>	'57',
	X	=>	'58',
	Y	=>	'59',
	Z	=>	'5a',
	a	=>	'61',
	b	=>	'62',
	c	=>	'63',
	d	=>	'64',
	e	=>	'65',
	f	=>	'66',
	g	=>	'67',
	h	=>	'68',
	i	=>	'69',
	j	=>	'6a',
	k	=>	'6b',
	l	=>	'6c',
	m	=>	'6d',
	n	=>	'6e',
	o	=>	'6f',
	p	=>	'70',
	q	=>	'71',
	r	=>	'72',
	s	=>	'73',
	t	=>	'74',
	u	=>	'75',
	v	=>	'76',
	w	=>	'77',
	x	=>	'78',
	y	=>	'79',
	z	=>	'7a',
	del	=>	'7f',
		);
$ua = new LWP::UserAgent;

print "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nWelcome to bomber, the webserver tester!\n\n\n\n\n";

print "Enter the URL of the cgi, asp or whatever; http:// will be prepended:\n";
$cgi	= <STDIN>;
chomp ($cgi);
$url = new URI::URL$site;

# Find out how many pairs to send

print "How many variables are there to be sent?[0-9][default 1]\n";
$sent = <STDIN>;
chomp ($sent);
if ($sent eq "") {
		$sent = 1;
	}
die "Eh? enter a number, eh? $!\n" unless ($sent =~ /^[0-9]$/);
$start_count = $sent;
#We know how many variables will be sent, so ...
#How shall we proceed?
print "Enter the string on the command line or send files? [c|f]\n";
print "You will need files ready to send for the 'f' option to work...\n";
print "If you don't have files just enter c...\n";
sub answer {
print "Please enter either c or f:  ";
$answer = <STDIN>;
chomp ($answer);
	}
&answer;
sub answercheck {
print "Please enter either c or f:  ";
$answer = <STDIN>;
chomp ($answer);
	}
&answercheck until ($answer =~ "c" || $answer =~ "f"); 
if ($answer eq "f") 
{ 

# So you want to send files...
# Start a loop to set up the name/value pairs

while ($start_count >= 1) 
				{
	print "\nEnter the name of variable [$start_count]: "; # get the name
		$varfile = <STDIN>;
			chomp ($varfile);
				`echo "$varfile" > $varfile`;
	open(VARFILE, "$varfile") or die "$!\n";
		$NAME{$start_count} = <VARFILE>;  # put name into a hash
print "File to hex encode and send as value of variable [$start_count]: ";
	$sendfile = <STDIN>;     # take the filename to send
		chomp ($sendfile);
			open(SENDFILE, "$sendfile") or die "$!\n";
$sval = <SENDFILE>;                  # hex encode the file we are sending
	@chars = (split //, $sval);  # put each char into an array
open(HEXFILE, ">hexfile..$start_count");  # we need to write the hex to a file
		foreach $_ (@chars) {
		print HEXFILE "%$HEX{$_}" ; # do it
		}	
close HEXFILE;
open(HEXFILE, "hexfile.$start_count") or die "Eh, $!\n"; 
	$SECOND{$start_count} = <HEXFILE>;               
close HEXFILE;
						$start_count--;
	}
}
elsif ($answer eq "c") 

# we want to type in our own stuff on the command line

				{

# we still need to loop through the desired number of pairs

while ($start_count >= 1) 

{

# See which class of ascii we want to send each time ...

print "\n\nDo you want to send printable ascii or control codes for variable [$start_count]?\n";

sub codes {
print "Please enter [p]rintable or [c]ontrol: \n";
$codes=<STDIN>;
chomp ($codes);
	}
&codes;
sub codescheck {
print "Please enter [p]rintable or [c]ontrol: \n";
$codes=<STDIN>;
chomp ($codes);
	}
&codescheck until ($codes =~ "p" || $codes =~ "c"); 
# if it's ascii 40-176... we want to send

if ($codes eq "p") 

{ 

	print "Name of variable [$start_count]: "; #get the names
		$varfile = <STDIN>;
			chomp ($varfile);
				`echo "$varfile" > $varfile`;
	open(VARFILE, "$varfile") or die "$!\n";
		$NAME{$start_count} = <VARFILE>; #name into a hash
print "\nEnter text to hex encode and send as value of variable [$start_count]:\n ";
	$sendfile = <STDIN>; #take the input to send
		chomp ($sendfile);

# open filehandle for writing...

			open(SENDFILE, ">hex.tmp") or die "$!\n";

print SENDFILE "$sendfile" ;
close SENDFILE;
open(SENDFILE, "hex.tmp") or die "$!\n";
$sval = <SENDFILE>;                  
close SENDFILE;
# hex encode the file we are sending
@chars = (split //, $sval);  
# put each char into an array
open(HEXFILE, ">hexfile.$start_count");  
# we need to write the hex to a file
		foreach $_ (@chars) {
		print HEXFILE "%$HEX{$_}" ; # do it
					}	
close HEXFILE; 

# now we need to read the hexencoded file back into a variable so open it again

open(HEXFILE, "hexfile.$start_count") or die "Eh, $!\n"; 

# and read it into the %SECOND hash which we use to build the request

$SECOND{$start_count} = <HEXFILE>;               
						$start_count--;

}

elsif ($codes eq "c")

{ 

# I'm typing ascii range 1-40,177

	print "Name of variable [$start_count]: "; 

#get the names

		$varfile = <STDIN>;
			chomp ($varfile);
				`echo "$varfile" > $varfile`;
	open(VARFILE, "$varfile") or die "$!\n";
		$NAME{$start_count} = <VARFILE>; 

#into a hash

print "Enter codes (separated by spaces) to hex encode and send as value of variable [$start_count]: ";

	$sendfile = <STDIN>; #take the input to send from the command line
		chomp ($sendfile);
			open(SENDFILE, ">hex.tmp") or die "$!\n";
print SENDFILE "$sendfile" ;
close SENDFILE;
open(SENDFILE, "hex.tmp") or die "$!\n";
$sval = <SENDFILE>;                  
close SENDFILE;
# hex encode the file we are sending
@chars = (split / /, $sval);  

# put each code into an array

open(HEXFILE, ">hexfile.$start_count");  

# we need to write the hex to a file

		foreach $_ (@chars) {
		print HEXFILE "%$HEX{$_}" ; # do it
		}	
close HEXFILE;

# now read the hexencoded stuff back into the %SECOND hash

open(HEXFILE, "hexfile.$start_count") or die "Eh, $!\n"; 
	$SECOND{$start_count} = <HEXFILE>;              
						$start_count--;
		}
	}
}

# this section builds the request depending on how many pairs to send
# and on the selected method

print "\n\n$sent name=value pair[s] ready to send to:\n\n";
print "$cgi\n\n";
print "Select the request method:\n\n";
sub methodchoice {
print "GET [g], POST [p], PUT [u], TRACE [t]: \n\n";
$methodchoice=<STDIN>;
chomp ($methodchoice);
if ($methodchoice eq "g")
{
$method="GET";
}
if ($methodchoice eq "p")
{
$method="POST";
}
if ($methodchoice eq "u")
{
$method="PUT";
}
if ($methodchoice eq "t")
{
$method="TRACE";
}
}
&methodchoice;
sub methodchoicecheck {
print "Please enter one letter: GET [g], POST [p], PUT [u], TRACE [t]: \n\n";
$methodchoice=<STDIN>;
chomp ($methodchoice);
if ($methodchoice eq "g")
{
$method="GET";
}
if ($methodchoice eq "p")
{
$method="POST";
}
if ($methodchoice eq "u")
{
$method="PUT";
}
if ($methodchoice eq "t")
{
$method="TRACE";
}
}
&methodchoicecheck until ($methodchoice =~ "g" || $methodchoice =~ "p" || $methodchoice =~ "u" || $methodchoice =~ "t");
if ($sent == 1) {
print "\n\nRequest looks like this:\n\n";
print "$method http\:\/\/$cgi\?$NAME{'1'}\=$SECOND{'1'}\n\n";
$req = new HTTP::Request("$method", "http\:\/\/$cgi\?$NAME{'1'}\=$SECOND{'1'}", $hdrs);
	}
elsif ($sent == 2) {
print "\n\nRequest looks like this:\n\n";
print "$method http\:\/\/$cgi\?$NAME{'1'}\=$SECOND{'1'}&$NAME{'2'}\=$SECOND{'2'}\n\n";
$req = new HTTP::Request("$method", "http\:\/\/$cgi\?$NAME{'1'}\=$SECOND{'1'}&$NAME{'2'}\=$SECOND{'2'}", $hdrs);
	}
elsif ($sent == 3) {
print "\n\nRequest looks like this:\n\n";
print "$method http\:\/\/$cgi\?$NAME{'1'}\=$SECOND{'1'}&$NAME{'2'}\=$SECOND{'2'}&$NAME{'3'}\=$SECOND{'3'}\n\n";
$req = new HTTP::Request("$method", "http\:\/\/$cgi\?$NAME{'1'}\=$SECOND{'1'}&$NAME{'2'}\=$SECOND{'2'}&$NAME{'3'}\=$SECOND{'3'}", $hdrs);
	}
elsif ($sent == 4) {
print "\n\nRequest looks like this:\n\n";
print "$method http\:\/\/$cgi\?$NAME{'1'}\=$SECOND{'1'}&$NAME{'2'}\=$SECOND{'2'}&$NAME{'3'}\=$SECOND{'3'}&$NAME{'4'}\=$SECOND{'4'}\n\n";
$req = new HTTP::Request("$method", "http\:\/\/$cgi\?$NAME{'1'}\=$SECOND{'1'}&$NAME{'2'}\=$SECOND{'2'}&$NAME{'3'}\=$SECOND{'3'}&$NAME{'4'}\=$SECOND{'4'}", $hdrs);
	}
elsif ($sent == 5) {
print "\n\nRequest looks like this:\n\n";
print "$method http\:\/\/$cgi\?$NAME{'1'}\=$SECOND{'1'}&$NAME{'2'}\=$SECOND{'2'}&$NAME{'3'}\=$SECOND{'3'}&$NAME{'4'}\=$SECOND{'4'}&$NAME{'5'}\=$SECOND{'5'}\n\n";
$req = new HTTP::Request("$method", "http\:\/\/$cgi\?$NAME{'1'}\=$SECOND{'1'}&$NAME{'2'}\=$SECOND{'2'}&$NAME{'3'}\=$SECOND{'3'}&$NAME{'4'}\=$SECOND{'4'}&$NAME{'5'}\=$SECOND{'5'}", $hdrs);
	}
elsif ($sent == 6) {
print "\n\nRequest looks like this:\n\n";
print "$method http\:\/\/$cgi\?$NAME{'1'}\=$SECOND{'1'}&$NAME{'2'}\=$SECOND{'2'}&$NAME{'3'}\=$SECOND{'3'}&$NAME{'4'}\=$SECOND{'4'}&$NAME{'5'}\=$SECOND{'5'}&$NAME{'6'}\=$SECOND{'6'}\n\n";
$req = new HTTP::Request("$method", "http\:\/\/$cgi\?$NAME{'1'}\=$SECOND{'1'}&$NAME{'2'}\=$SECOND{'2'}&$NAME{'3'}\=$SECOND{'3'}&$NAME{'4'}\=$SECOND{'4'}&$NAME{'5'}\=$SECOND{'5'}&$NAME{'6'}\=$SECOND{'6'}", $hdrs);
	}
elsif ($sent == 7) {
print "\n\nRequest looks like this:\n\n";
print "$method http\:\/\/$cgi\?$NAME{'1'}\=$SECOND{'1'}&$NAME{'2'}\=$SECOND{'2'}&$NAME{'3'}\=$SECOND{'3'}&$NAME{'4'}\=$SECOND{'4'}&$NAME{'5'}\=$SECOND{'5'}&$NAME{'6'}\=$SECOND{'6'}&$NAME{'7'}\=$SECOND{'7'}\n\n";
$req = new HTTP::Request("$method", "http\:\/\/$cgi\?$NAME{'1'}\=$SECOND{'1'}&$NAME{'2'}\=$SECOND{'2'}&$NAME{'3'}\=$SECOND{'3'}&$NAME{'4'}\=$SECOND{'4'}&$NAME{'5'}\=$SECOND{'5'}&$NAME{'6'}\=$SECOND{'6'}&$NAME{'7'}\=$SECOND{'7'}", $hdrs);
	}
elsif ($sent == 8) {
print "\n\nRequest looks like this:\n\n";
print "$method http\:\/\/$cgi\?$NAME{'1'}\=$SECOND{'1'}&$NAME{'2'}\=$SECOND{'2'}&$NAME{'3'}\=$SECOND{'3'}&$NAME{'4'}\=$SECOND{'4'}&$NAME{'5'}\=$SECOND{'5'}&$NAME{'6'}\=$SECOND{'6'}&$NAME{'7'}\=$SECOND{'7'}&$NAME{'8'}\=$SECOND{'8'}\n\n";
$req = new HTTP::Request("$method", "http\:\/\/$cgi\?$NAME{'1'}\=$SECOND{'1'}&$NAME{'2'}\=$SECOND{'2'}&$NAME{'3'}\=$SECOND{'3'}&$NAME{'4'}\=$SECOND{'4'}&$NAME{'5'}\=$SECOND{'5'}&$NAME{'6'}\=$SECOND{'6'}&$NAME{'7'}\=$SECOND{'7'}&$NAME{'8'}\=$SECOND{'8'}", $hdrs);
	}
elsif ($sent == 9) {
print "\n\nRequest looks like this:\n\n";
print "$method http\:\/\/$cgi\?$NAME{'1'}\=$SECOND{'1'}&$NAME{'2'}\=$SECOND{'2'}&$NAME{'3'}\=$SECOND{'3'}&$NAME{'4'}\=$SECOND{'4'}&$NAME{'5'}\=$SECOND{'5'}&$NAME{'6'}\=$SECOND{'6'}&$NAME{'7'}\=$SECOND{'7'}&$NAME{'8'}\=$SECOND{'8'}&$NAME{'9'}\=$SECOND{'9'}\n\n";
$req = new HTTP::Request("$method", "http\:\/\/$cgi\?$NAME{'1'}\=$SECOND{'1'}&$NAME{'2'}\=$SECOND{'2'}&$NAME{'3'}\=$SECOND{'3'}&$NAME{'4'}\=$SECOND{'4'}&$NAME{'5'}\=$SECOND{'5'}&$NAME{'6'}\=$SECOND{'6'}&$NAME{'7'}\=$SECOND{'7'}&$NAME{'8'}\=$SECOND{'8'}&$NAME{'9'}\=$SECOND{'9'}", $hdrs);
	}

# Now that we have the input, we can build our HTTP request

$resp = $ua->request($req);







$resp = $ua->request($req);
print "Enter the number of times to send the request:\n";
$count = <STDIN>;
chomp $count; 
print "\nName of the file to which output will be written:  \n\n";
print "Output will be html appended to headers. Name the file target.html\n\n";
print "if you wish to view it in a browser.\n\n";

$outputfile=<STDIN>;
chomp($outputfile);
while ($count >= 1) {
do $ua->request($req);
	print "\n Request \#$count sent: output follows\n";
	open (OUTPUTFILE, ">$outputfile") or die "Could not open $!\n";
	print OUTPUTFILE "\nServer responded with code \n"; 
	print OUTPUTFILE  $resp->code;
	print OUTPUTFILE "\nServer responded to ... \n"; 
	print OUTPUTFILE  $resp->base();
	print OUTPUTFILE "\nServer sent this file ... \n"; 
	print OUTPUTFILE  $resp->as_string;
	print OUTPUTFILE "\n\n"; 
	close OUTPUTFILE;
	print "\n Server response code was:  \n";
	print $resp->code; 
	print "\n Server base URL was: \n";
	print $resp->base();
	print "\n Writing to $outputfile server response string: \n";
	print $resp->as_string;
$count--;
	print "\n Now sending request \#$count\n\n" unless ($count <= 0);
next;
}
#Clean up the temp files...
`rm hex.tmp`;
`rm hexfile.?`;
`rm $varfile 2>/dev/null`;
`rm $sval 2>/dev/null`;
`rm $sendfile 2>/dev/null`;
