#!/usr/bin/perl -Tw # (c) 2001 SANS Institute. # jullrich@sans.org # distribution permitted. # # Modifications (c) 2006 Hugo van der Kooij # # Script to retrieve block list from DShield.org, validate it \ # and generate Cisco ACL lines # use strict; use LWP::UserAgent; # # A few parameters you may want to change. # my $debug=1; # Better: change this to /root or another directory that is # only read/writable by root my $tmpdir='.'; my $policyfile='ipv4-inet-in-dshield'; # # point to wherever you have gpg installed. Not tested with # pgp, but may work anyway if you change the parameters my $gpg='/usr/bin/gpg -q --verify '; my $rm= '/bin/rm'; # # for the current key. #OBSOLETE# my $signature='DShield.org \(Block List\) '; my $signature='DShield Blocklist \(Used to Sign DShield Blocklist\) '; # # Cisco ACL table style netmask my @netmask; $netmask[13] = '0.7.255.255'; $netmask[14] = '0.3.255.255'; $netmask[15] = '0.1.255.255'; $netmask[16] = '0.0.255.255'; $netmask[17] = '0.0.127.255'; $netmask[18] = '0.0.63.255'; $netmask[19] = '0.0.31.255'; $netmask[20] = '0.0.15.255'; $netmask[21] = '0.0.7.255'; $netmask[22] = '0.0.3.255'; $netmask[23] = '0.0.1.255'; $netmask[24] = '0.0.0.255'; # Use LWP routines to download the block list and gnupg signature print "Retrieve block list...\n" if $debug; my $ua = LWP::UserAgent->new; $ua->agent("BlockListRetriever V 1.5"); my $req=HTTP::Request->new(GET => 'http://feeds.dshield.org/block.txt'); my $res=$ua->request($req); die ("Request to retrieve block list failed.\n".$res->message."\n") unless ( $res->is_success) ; my $list=$res->content; print "Retrieve block list signature...\n" if $debug; $req->uri('http://feeds.dshield.org/block.txt.asc'); $res=$ua->request($req); my $sig=$res->content; # # Writing content to tmp file. # my $filenum; $ENV{PATH}=''; $ENV{BASH_ENV}=''; # Make unused temp file name $filenum=rand() until ( ( ! -e "$tmpdir/$filenum" ) && ( ! -e "$tmpdir/$filenum.asc" ) ); # First write the block list to a temporary file open(F,"> $tmpdir/$filenum"); die ("Temporary file problem ($tmpdir/$filenum).\n") if ( ! -z "$tmpdir/$filenum"); print F $list; close F; # Then write the signature to another temporary file open(F,"> $tmpdir/$filenum.asc"); die ("Temporary file problem ($tmpdir/$filenum).\n") if ( ! -z "$tmpdir/$filenum.asc"); print F $sig; close F; # Verify gnupg signature print "Check signature...\n" if $debug; open (F,"$gpg $tmpdir/$filenum.asc 2>&1 |"); my $valid='N'; while () { $valid='Y' if ( /Good signature from "$signature"/ ); } close F; # Abort if the signature doesn't check die ("Signature not valid. Please verify manually or check if you have the right key\n") if ($valid eq 'N'); # # Signature is valid.. Now we need to parse the block list. # # The block list that we downloaded from http://feeds.dshield.org/block.txt open (P,">$policyfile"); open (F,"$tmpdir/$filenum"); my ($start, $end, $block, $attacks, $name, $country, $email); while () { next if /^\s*(#|$|a)/; ($start, $end, $block, $attacks, $name, $country, $email)=split("\t"); # untaint $start=~/^([\d\.]+)$/; $start = $1; $block =~ /^(\d+)/; $block = $1; chomp($email); if ( defined($start) && defined($block) ) { print " remark -- $name -- $email --\n" if $debug; print P " remark -- $name -- $email --\n"; print " deny ip $start $netmask[$block] any log\n" if $debug; print P " deny ip $start $netmask[$block] any log\n"; } } close F; close P; system("$rm $tmpdir/$filenum"); system("$rm $tmpdir/$filenum.asc"); print "Apparently... done.\n" if $debug;