#!/usr/bin/perl use Net::RawIP qw(:pcap); system("clear"); $SIG{INT} = \&quit; my ($ip,$seq_nr,$count); $my_ip = "123.123.123.123"; # change value $count = 0; $|=1; $dev='eth0'; $ip_addr=${ifaddrlist()}{$dev}; $packet_tcp=new Net::RawIP({tcp=>{}}); $filt_tcp="ip proto \\tcp"; $pcap_tcp=$packet_tcp->pcapinit($dev,$filt_tcp,1500,60); $offset_tcp = linkoffset($pcap_tcp); if (fork){ loop $pcap_tcp,-1,\&check_tcp,\@packet_tcp;} sub check_tcp{ my $time = timem(); $packet_tcp->bset($_[2],$offset_tcp); $proto=$packet_tcp->proto; my ($saddr,$daddr,$sport,$dport,$seq,$ack_seq,$urg,$ack,$psh,$rst,$syn,$fin,$data)= $packet_tcp->get({ip=>['saddr','daddr'],tcp=>['source','dest','seq','ack_seq','urg','ack','psh','rst','syn','fin','data']}); if ($sport == "22" ) { # vorerst ssh ignorieren } elsif ( $dport == "22" ) { } else { $seq =~ s/-//g; if ($syn){ # & !$ack) { print "PACKET: $seq "; if ($urg) {print "URG "}; if ($ack) {print "ACK "}; if ($psh) {print "PSH "}; if ($rst) {print "RST "}; if ($syn) {print "SYN "}; if ($fin) {print "FIN "}; if ($saddr > $daddr) { print "\t",ip2name($saddr), ":$sport \t -> \t",ip2name($daddr),":$dport \n"; push(@ips, ip2name($daddr) . "#$seq"); } else { print "\t",ip2name($daddr), ":$dport \t <- \t",ip2name($saddr),":$sport \n"; # ATTACKER_IP - SEQ - ATTACK_PORT - MY_PORT push(@content, ip2name($saddr) . "#$seq#$sport#$dport"); if ($#content >= "120"){ foreach $entry(@content){ ($ip,$seq_nr,$attacker_port,$my_port) = split('#', $entry); if ($ip == ip2name($saddr) ){ $count++; } if ($count >= "100"){ print "INCOMING SYNFLOOD DETECTED!\n"; $attacker = $ip; foreach $bad (@content) { ($ipX,$seq_nrX,$attacker_portX,$my_portX) = split('#', $bad); if ($ipX == $attacker){ print "KILLING BAD CONNECTION ATTEMPT!\n"; # send FIN to abort connection my $new_packet= new Net::RawIP; $new_packet->set({ ip=>{ saddr=>$my_ip, daddr=>$attacker }, tcp=>{ source=>$my_port, dest=>$attacker_portX, fin=>"1", seq=>$seq_nrX } }); $new_packet->send; } } } } $count = 0; @content = (); } } } } } sub ip2name { my $addr = shift; (gethostbyaddr(pack("N",$addr),AF_INET))[0] || ip2dot($addr); } sub ip2dot { sprintf("%u.%u.%u.%u",unpack "C4", pack "N1", shift); } sub quit { exit(0); }