#!/usr/bin/perl # # Tool name : OpenProxy.pl # Author : Ruben Unteregger # Homepage : http://www.megapanzer.com # Date : 2010.10.13 # use File::Basename; use HTTP::Proxy qw( :log ); use HTTP::Proxy::HeaderFilter::simple; my($lFHMessg); my($lFHError); my(@gProxyPorts) = (3128, 8000, 8080); my($gProxyPort) = 0; my($gPID) = 0; my($gProxy); #my($gProxyAddr) = '192.168.1.100'; my($gProxyAddr) = '0.0.0.0'; my($gMsgLogFile) = "./proxy.log"; my($gErrorLogFile) = "./proxy.err"; my($gWhoIsDir) = "WhoIs"; my($gMaxRequestTime) = 20; my($gAgent) = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.127 Safari/533.4"; if ($ARGV[0] eq "stop") { $gProcName = basename($0); system("killall -9 $gProcName"); print "All running $0 processes stopped\n"; exit(0); } ### # Initialisation ### my(%gPortsWhiteList) = (#80 => 1, # http 443 => 1, # https # 6667 => 1, # IRC 7000 => 1 # sub7 ); my($gDestBlackList) = '(10\\.0\\.0\\.|192\\.168\\.|\\.aol\\.com|\\.yahoo\\.com|\\.ubs\\.com)'; unless (open($lFHMessg, ">>$gMsgLogFile")) { print "Can't open logfile \"$gMsgLogFile\" : $!\n"; exit(0); } unless (open($lFHError, ">>$gErrorLogFile")) { print "Can't open logfile \"$gErrorLogFile\" : $!\n"; exit(0); } #system("iptables -F"); ### # Start proxy servers ### foreach $gProxyPort (@gProxyPorts) { if (($gPID = fork()) == 0) { $gProxy = HTTP::Proxy->new; $gProxy->logfh($lFHError); $gProxy->port($gProxyPort); $gProxy->host($gProxyAddr); $gProxy->logmask(NONE); $gProxy->timeout($gMaxRequestTime); $gProxy->via(""); $gProxy->x_forwarded_for(0); $gProxy->max_clients(64); $gProxy->push_filter( response => HTTP::Proxy::HeaderFilter::simple->new(\&ResponseFilter) , request => HTTP::Proxy::HeaderFilter::simple->new(\&RequestFilter) ); $gProxy->start(); exit(0); } } ########################################################################## sub RequestFilter ########################################################################## { my($self, $headers, $message ) = @_; my($lEmpty); my($lHost) = $message->uri->host?$message->uri->host:$message->header("Host"); my($lPort) = (split(/:/, $message->uri->host_port, 2))[1]; my($lURI) = $message->uri; my($lMethod) = $message->method; my($lLength) = $message->header("Content-Length"); my($lContentType) = $message->header("Content-Type"); my($lContent) = $message->content() if ($lMethod eq "POST"); my($lUserAgent) = $message->user_agent; my($lClientIP) = $self->proxy->client_socket->peerhost; my($lProxyPort) = $gProxy->port; #$self->proxy->client_socket->port; my($lName, $lAliases, $lAddrtype, $lLength, @lAddrs); my($lRemoteIP); my($a, $b, $c, $d); ### # initialisation ### $lContentType = $1 if ($lURI =~ /\.([\d\w]{1,4})$/); $lEmpty = HTTP::Response->new(200); $lEmpty->content_type('text/plain'); $lEmpty->content('.'); ### # complete blocked hosts list ### if (length($lHost) > 0 && $lPort != 80 && $lPort != 443) { ($lName, $lAliases, $lAddrtype, $lLength, @lAddrs) = gethostbyname($lHost); ($a, $b, $c, $d) = unpack('C4', $lAddrs[0]); $lRemoteIP = "$a.$b.$c.$d"; if (length($lRemoteIP) > 7) { # system("iptables -t filter -A INPUT -i eth1 -p tcp -s ${lRemoteIP} -m state --state NEW -m comment --comment \"Port was $lPort\" -j DROP"); } } ### # check HTTP authorization header ### if ($message->header("Authorization")) { logger("AUTH1,$lProxyPort,$lClientIP,$lHost,$lPort,$lMethod,$lContentType,$lUserAgent," . $message->header("Authorization"), 0); } ### # check POST HTML authorization header ### if ($lMethod eq "POST") { if ($lContent =~ /(username|user|uname|uid|login|id)=/i && $lContent =~ /(password|pass|pwd|passwd|key|passkey|secret|secretkey)=/i) { logger("AUTH3,$lProxyPort,$lClientIP,$lHost,$lPort,$lMethod,$lContentType,$lUserUgent,$lContent", 0); } } ### # block everything except GET, POST, HEAD and CONNECT requests ### if ($lMethod ne "GET" && $lMethod ne "HEAD" && $lMethod ne "POST" && $lMethod ne "CONNECT") { logger("BMETHOD,$lProxyPort,$lClientIP,$lHost,$lPort,$lMethod,$lContentType,$lUserAgent,$lURI", 0); $self->proxy->response($lEmpty); goto END; } ### # check for blocked ports. ### unless (defined($gPortsWhiteList{$lPort})) { logger("BPORT,$lProxyPort,$lClientIP,$lHost,$lPort,$lMethod,$lContentType,$lUserAgent,$lURI", 0); $self->proxy->response($lEmpty); goto END; } ### # check for blocked sites. ### if ($lHost =~ /$gDestBlackList/i) { logger("BADDR,$lProxyPort,$lClientIP,$lHost,$lPort,$lMethod,$lContentType,$lUserAgent,$lURI", 0); $self->proxy->response($lEmpty); goto END; } ### # modify header entries ### $message->remove_header("Proxy-Connection"); $message->remove_header("X-Forwarded-For"); $message->user_agent("$gAgent"); logger("REQUEST,$lProxyPort,$lClientIP,$lHost,$lPort,$lMethod,$lContentType,$lUserAgent,$lURI", 0); END: #in case you want to do some final stuff before returning. } ########################################################################## sub ResponseFilter ########################################################################## { my ( $self, $headers, $message ) = @_; # print "RESPONSE : " . join( " ", # $message->request->headers->header( 'Referer' ) || 'NULL', # $message->request->uri, # $message->code ) . "\n"; } ########################################################################## sub logger ########################################################################## { my($lLogMessage) = shift; my($lExitStatus) = shift; chomp($lLogMessage); flock($lFHMessg, LOCK_EX); print $lFHMessg time() . ",$lLogMessage\n"; flock($lFHMessg, LOCK_UN); exit($lExitStatus) if ($lExitStatus); }