Moin, ok hier ist das skript das sowas realisiert. Ich kenne mich mit perl aber nicht so gut aus dass ich jetzt wüsste was genau das skript alles tut:
#!/usr/bin/perl
###################################################### # Pennywize Online Client # Version 2.0, December 17, 2001 ######################################################
# Pennywize Online # Copyright (C) 1997-2001 Zarvon Pty Ltd # All Rights Reserved
# See http://www.pennywize.com for more info
This code may not be redistributed in part or in whole
without the written consent of the author.
This code may not be altered or changed without the
# written consent of the author.
###################################################### use Socket;
Pennywize Configuration Section
$PENNYWIZE_USERNAME = "meinusername"; $PENNYWIZE_PASSWORD = "meinpasswort";
End of Configuration Section
$PENNYWIZE_SERVER = "online.pennywize.com"; $PENNYWIZE_PORT = "80"; $PENNYWIZE_VERSION="2.0-20011217"; $BAPS = 2; $BAPS_TIME = 60;
# Signal Handler $SIG{'HUP'} = sub { exit(0) };
if (defined($ENV{'SCRIPT_FILENAME'})) { # Unblock Output $|=1;
# Extract the QUERY STRING variables %params = (); @query_string = split(/[&;]/, $ENV{'QUERY_STRING'}); foreach $i (0 .. $#query_string) { # Split $params[$i] =~ s/+/ /g; ($key, $val) = split(/=/,$query_string[$i],2); $key =~ s/%(..)/pack("c",hex($1))/ge; $val =~ s/%(..)/pack("c",hex($1))/ge; $params{$key} .= "\0" if (defined($query_string{$key})); $params{$key} .= $val; }
# Determine the CGIBIN_PATH ($CGIBIN_PATH, $ignore) = &SplitPath ($ENV{'SCRIPT_FILENAME'}); $CGIBIN_PATH =~ s//$//;
# If cgiwrap is involved, fix it if (($CGIBIN_PATH =~ /cgiwrap/) && (-r $ENV{'PATH_TRANSLATED'})) { ($CGIBIN_PATH, $ignore) = &SplitPath ($ENV{'PATH_TRANSLATED'}); $CGIBIN_PATH =~ s//$//; }
# Taint Checking $failed = 0; $failed = 1 if ($params{'ACTION'} !~ /^\w*$/); $failed = 1 if ($params{'SITE'} !~ /^\w*$/); $failed = 1 if ($params{'PASSWORD'} !~ /^\w*$/); $failed = 1 if ($params{'DATA'} =~ /\/~|/); $failed = 1 if ($params{'TIME'} !~ /^\d*$/);
if ($failed == 1) { # Print out the header print "Content-type: text/html\n\n";
&WelcomeScreen; print "ERROR: One or more of your variables failed taint checking\n"; exit; }
# Validate the password if ($params{'PASSWORD'} eq $PENNYWIZE_PASSWORD) { # Check the action if (!(defined($params{'ACTION'}))) { # Print out the header print "Content-type: text/html\n\n";
&WelcomeScreen; &TestSetup($params{'SITE'}); }
if ($params{'ACTION'} eq "DISABLE") { # Print out the header print "Content-type: text/html\n\n";
$result = &AddRule ($params{'DATA'}, $params{'SITE'}, $params{'TIME'}); print $result; } } else { # Print out the header print "Content-type: text/html\n\n";
&WelcomeScreen; print "You are not authorised to access this script [$ENV{'REMOTE_ADDR'}]\n"; } exit; }
# Determine the CGIBIN_BASE ($CGIBIN_PATH, $ignore) = &SplitPath ($0); $CGIBIN_PATH =~ s//$//; if (($CGIBIN_PATH !~ /^//) || (!(-d "$CGIBIN_PATH/pennywize"))) { print ("Pennywize has been incorrectly called. Please email support@pennywize.com\n"); exit (1); }
# Children Process Handling $SIG{CHLD} = sub { wait };
%hits = (); %bytes = (); %blocked = (); %second_attempts = (); ($last_minute, $last_second) = &GetTime(); while ($line = <STDIN>) { chop ($line); if ($line =~ /^.+|.+|\d+|.+$/) { ($ip, $username, $status, $site, $bytes) = split (/|/, $line); if (($username ne "-") && (($status eq "200") || ($status eq "401")) && ($ip =~ /^\d+.\d+.\d+.\d+$/)) { # Form the subnet only @ipz = split (/./, $ip); $subnet = "$ipz[0].$ipz[1].$ipz[2]";
# Regular hit if ($status eq "401") { $username = "$-PPP-$"; $subnet = $ip; $status = "200"; }
# Get the time ($this_minute, $this_second) = &GetTime();
if ($status eq "200") { # Add the hit if (defined($hits{"$site|$username|$subnet"})) { $hits{"$site|$username|$subnet"}++; $bytes{"$site|$username|$subnet"} += $bytes; $second_attempts{"$site|$username|$subnet|$this_second"}++; } else { $hits{"$site|$username|$subnet"} = 1; $bytes{"$site|$username|$subnet"} = $bytes; $second_attempts{"$site|$username|$subnet|$this_second"} = 1; }
# Check to see if this 401 exceeds the limit per second if ($username eq "$-PPP-$") { if ($second_attempts{"$site|$username|$subnet|$this_second"} >= $BAPS) { if ($blocked{"$site|$subnet"} ne "1") { &AddRule ($subnet, $site, $BAPS_TIME); $blocked{"$site|$subnet"} = "1"; } } } }
# Check the current minute if ($this_minute != $last_minute) { if (fork() == 0) { # Flush all the hits &ProcessHits (%hits, %bytes);
# Expire IP address bans &ExpireFiles();
# Exit child process exit; }
%hits = (); %bytes = (); %blocked = (); %second_attempts = (); $last_minute = $this_minute; } } } } exit;
sub ProcessHits { local ($hits, $bytes) = @_; local ($combo, $numhits); local ($query, $rin, $win, $ein, $timeout, $nfound, $timeleft) = "";
if (&EstablishConnection) { print PPP "POST /cgi-bin/ppp_server_isp.pl HTTP/1.0\n"; print PPP "Connection: Keep-Alive\n"; print PPP "User-Agent: Pennywize Password Protection/2.0\n"; print PPP "Host: online.pennywize.com\n"; print PPP "Content-type: application/x-www-form-urlencoded\n";
# Construct the content string $query = "DATA="; while (($combo, $numhits) = each (%$hits)) { ($site, $username, $ip) = split (/|/, $combo); $bytez = $$bytes{$combo} || 0; $query .= &Escape("$PENNYWIZE_USERNAME|$PENNYWIZE_PASSWORD|$site|$username|$ip|$numhits|$bytez|$PENNYWIZE_VERSION\n"); }
# Calculate the length of the content print PPP "Content-length: ".length($query)."\n";
# Print the content print PPP "\n$query\n";
# Wait for any response or max 30 seconds $rin = $win = $ein = ''; vec($rin,fileno(PPP),1) = 1; $ein = $rin | $win; $timeout = 30; ($nfound,$timeleft) = select($rout=$rin, $wout=$win, $eout=$ein, $timeout);
# Close the connection &CloseConnection; }
}
sub EstablishConnection { local ($pppaddr, $oldfh);
# Get the server address $pppaddr = ($PENNYWIZE_SERVER =~ /^(\d{1,3}).(\d{1,3}).(\d{1,3}).(\d{1,3})$/) ? pack('C4',$1,$2,$3,$4) : (gethostbyname($PENNYWIZE_SERVER))[4];
# Get the socket $proto = (getprotobyname('tcp'))[2]; if (!socket(PPP, AF_INET, SOCK_STREAM, $proto)) { return (0); }
if (!(connect(PPP, sockaddr_in($PENNYWIZE_PORT, $pppaddr)))) { return (0); }
# Unbuffer the output $oldfh = select(PPP); $| = 1; select($oldfh);
# Return Success return (1); }
sub CloseConnection { shutdown (PPP, 2); }
sub GetTime { local ($sec, $min, $ignore, $ignore, $ignore, $ignore) = localtime(time); return ($min, $sec); }
sub Escape { local ($text) = @_; local ($escapes);
return undef unless defined $text;
# Build the escape hash for (0..255) { $escapes{chr($)} = sprintf("%%%02X", $); }
# Default unsafe characters. (RFC 2396 ^uric) $text =~ s/([^;/?:@&=+$,A-Za-z0-9-_.!~*'()])/$escapes{$1}/g;
return ($text); }
sub AddRule { local ($data, $site, $time) = @_; my ($now); my ($directory) = "$CGIBIN_PATH/pennywize/$site"; my ($filename) = "$directory/$data";
# Create the sub-directory if it doesnt exist mkdir ($directory, 0777) or return ("Unable to create directory $directory") if (!(-d $directory)); chmod 0777, $directory;
# Write out the data if (!(-e $filename)) { open (OUTPUT, "> $filename") or return ("Unable to open file $filename"); close (OUTPUT); chmod 0777, $filename;
# Change the file modification time $now = time() + $time; utime $now, $now, $filename; }
# Return return ("Disable rule successfully written:\n$CGIBIN_PATH/pennywize/$site/$data\n"); }
sub ExpireFiles { local ($dir, $file, $age); local (@files) = ();
# Get all the files opendir (DIR, "$CGIBIN_PATH/pennywize"); while ($dir = readdir(DIR)) { # Test to see if it's a directory if ((-d ("$CGIBIN_PATH/pennywize/$dir")) && ($dir !~ /^./)) { # Get all files within the directory opendir (FILES, "$CGIBIN_PATH/pennywize/$dir"); while ($file = readdir(FILES)) { if (-f "$CGIBIN_PATH/pennywize/$dir/$file") { push (@files, "$CGIBIN_PATH/pennywize/$dir/$file"); } } closedir (FILES); } } closedir (DIR);
for (@files) { local ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, $atime,$mtime,$ctime,$blksize,$blocks) = stat($_);
# Remove the block if the file has 'expired' if ((time() > $mtime) && ($size == 0)) { unlink ($_); } } }
sub SplitPath { my ($path) = @_; my ($directory,$file) = ('','','');