├── .gitignore ├── README.rst ├── files ├── attacker_ips.txt ├── attacker_ips_whois.txt ├── dns_queries.txt ├── full_http_requests.txt └── http_requests.txt ├── json_summary.py ├── libs ├── __init__.py └── c2utils.py ├── output_summary.py ├── pcap_summary.py └── pcaps ├── dump.pcap └── sample.pcap /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | Dependencies 2 | ============ 3 | - http://code.google.com/p/dpkt/ 4 | - http://pypi.python.org/pypi/cymruwhois 5 | - http://pypi.python.org/pypi/simplejson/ 6 | 7 | Files 8 | ===== 9 | output_summary - take in one file and summarize the output to the screen 10 | 11 | pcap_summary - take in one file or a directory of PCAP files and summarize them in files 12 | 13 | json_summary - take in a single file and print out a JSON object of all the summary data - meant to show output 14 | -------------------------------------------------------------------------------- /files/attacker_ips.txt: -------------------------------------------------------------------------------- 1 | 255.255.255.255 2 | 10.0.2.15 3 | 239.255.255.250 4 | 10.0.2.255 5 | 192.168.249.2 6 | 224.0.0.22 7 | 65.55.21.19 8 | 178.162.174.162 9 | 209.139.208.130 10 | 69.64.38.6 11 | 46.4.30.143 12 | 66.197.204.134 13 | 216.92.12.78 14 | 72.14.204.147 15 | 72.14.204.105 16 | 66.70.127.101 17 | -------------------------------------------------------------------------------- /files/attacker_ips_whois.txt: -------------------------------------------------------------------------------- 1 | 255.255.255.255 - - - 2 | 10.0.2.15 - - - 3 | 239.255.255.250 - - - 4 | 10.0.2.255 - - - 5 | 192.168.249.2 - - - 6 | 224.0.0.22 - - - 7 | 65.55.21.19 - MICROSOFT-CORP---MSN-AS-BLOCK - Microsoft Corp - 8075 - 65.55.0.0/19 8 | 178.162.174.162 - LEASEWEB-DE Leaseweb Germany GmbH (previously netdirekt e. K.) - 28753 - 178.162.128.0/17 9 | 209.139.208.130 - GT-BELL - Bell Canada - 6539 - 209.139.192.0/19 10 | 69.64.38.6 - SERVER4YOU - Hosting Solutions International, Inc. - 30083 - 69.64.32.0/19 11 | 46.4.30.143 - HETZNER-AS Hetzner Online AG RZ - 24940 - 46.4.0.0/16 12 | 66.197.204.134 - NOC - Network Operations Center Inc. - 21788 - 66.197.128.0/17 13 | 216.92.12.78 - PAIR-NETWORKS - pair Networks - 7859 - 216.92.0.0/16 14 | 72.14.204.147 - GOOGLE - Google Inc. - 15169 - 72.14.204.0/23 15 | 72.14.204.105 - GOOGLE - Google Inc. - 15169 - 72.14.204.0/23 16 | 66.70.127.101 - DATAPIPE-SEA - DataPipe, Inc. - 22205 - 66.70.120.0/21 17 | -------------------------------------------------------------------------------- /files/dns_queries.txt: -------------------------------------------------------------------------------- 1 | A - TRANSERSDATAFORME.COM - 66.197.204.133 2 | A - TRANSERSDATAFORME.COM - 66.197.204.134 3 | A - TRANSERSDATAFORME.COM - 66.197.204.135 4 | A - TRANSERSDATAFORME.COM - 66.197.204.136 5 | A - classicbattletech.com - 209.139.208.130 6 | A - givishoolstome.com - 178.162.174.162 7 | A - istockanalyst.com - 66.70.127.101 8 | A - jointhenewworldorder.com - 216.92.12.78 9 | A - limfoklubs.com - 69.64.38.6 10 | A - regfeedbackaccess.com - 178.162.174.162 11 | A - time.microsoft.akadns.net - 65.55.21.19 12 | A - www.l.google.com - 72.14.204.103 13 | A - www.l.google.com - 72.14.204.104 14 | A - www.l.google.com - 72.14.204.105 15 | A - www.l.google.com - 72.14.204.147 16 | A - www.l.google.com - 72.14.204.99 17 | A - xprstats.com - 46.4.30.143 18 | CNAME - time.windows.com - time.microsoft.akadns.net 19 | CNAME - www.google.com - www.l.google.com 20 | -------------------------------------------------------------------------------- /files/full_http_requests.txt: -------------------------------------------------------------------------------- 1 | destination_ip - 178.162.174.162 2 | uri - /logo.png?tq=gKZEtzoYwLzEvUb5dQzRsrCpBfEtTca3l74EgC5OjrPGpgfib1XFp5zpRPksUt%2BA%2FgSoSEU%3D&pr=41 3 | source_ip - 10.0.2.15 4 | host - regfeedbackaccess.com 5 | accept - */* 6 | user-agent - chrome/9.0 7 | connection - close 8 | version - 1.0 9 | method - GET 10 | 11 | destination_ip - 178.162.174.162 12 | uri - /logo.png?tq=gKZEtzoYwLzEvUb5dQzRsrCpBfEtTca3l74EgC9OjrPGpgfib1XFp5zpRPksUt%2BA%2FgSoSEU%3D&pr=467 13 | source_ip - 10.0.2.15 14 | host - givishoolstome.com 15 | accept - */* 16 | user-agent - chrome/9.0 17 | connection - close 18 | version - 1.0 19 | method - GET 20 | 21 | destination_ip - 178.162.174.162 22 | uri - /logo.png?tq=gL5HtzoYwLzEpUb5fU3HxcaxAvU6EsazybMRtyFZ0umG8Ar0SsSA%2FgSoSEU%3D&pr=41 23 | source_ip - 10.0.2.15 24 | connection - close 25 | user-agent - chrome/9.0 26 | host - regfeedbackaccess.com 27 | version - 1.1 28 | method - GET 29 | 30 | destination_ip - 209.139.208.130 31 | uri - /lhous4.gif?pr=gJ4WK%2FSUh7TFmkR8oY%2BQtMWTUj26kJH7yZJTP7qVybhqtUn5CGFATA%3D%3D 32 | source_ip - 10.0.2.15 33 | host - classicbattletech.com 34 | accept - */* 35 | user-agent - chrome/9.0 36 | connection - close 37 | version - 1.0 38 | method - GET 39 | 40 | destination_ip - 216.92.12.78 41 | uri - /images/pages.jpg?sv=217&tq=gHZutDyMv5rJfSG1J8K%2B1MWCJbP4lltXIA%3D%3D 42 | source_ip - 10.0.2.15 43 | host - jointhenewworldorder.com 44 | accept - */* 45 | user-agent - chrome/9.0 46 | connection - close 47 | version - 1.0 48 | method - GET 49 | 50 | destination_ip - 46.4.30.143 51 | uri - /images/logo.png?tq=gFarqHoLmEqQTvWAbkiQEtFZ8KwrE8EGxy%2F2%2FGxKlxS1X%2FP9bEyXG8Nd9f0ZO4ARwh2jtnlJ4RDRWfCrL1%2BWZ4wb4%2FZqG9MGxy%2BoqzIfgBHCHKLhbz6VBsZdoLN5SeFMkg3j9moKylGATvWAakiXF8SiwG6%2BV%2BLvsw%3D%3D 52 | source_ip - 10.0.2.15 53 | connection - close 54 | user-agent - chrome/9.0 55 | host - xprstats.com 56 | version - 1.1 57 | method - GET 58 | 59 | destination_ip - 66.70.127.101 60 | uri - /png/intel.gif?sv=675&tq=gwY92w4A7jiwWknN94TRV9bvbNFjouNKzJI3XeHDW1%2BkfYlCM%2FfGvMazO425sOpHKXiiuVs0jzWmB9RwvNZwlFX63EHwPSWS5eOXmr08pGxcG7xBsIJ6ASctcX%2FvYkbSIIT%2BFInDxUZu16ObNa2JHav0HanfPrBw977AVUN 61 | source_ip - 10.0.2.15 62 | host - istockanalyst.com 63 | accept - */* 64 | user-agent - chrome/9.0 65 | connection - close 66 | version - 1.0 67 | method - GET 68 | 69 | destination_ip - 69.64.38.6 70 | uri - /img/135.png?tq=gK4QKH1O%2FQHS4l9mehOkFMfXUjY9SvIGtadXNz1M8gnDpVE3SDvlA8LqF2coSYQD0aFUZ2lf83XGoVc%2FKEj2QoD2Eis%2BPvEUxqUVaihJhAHRoVR8exTlArCmVCs%2FTKFH0aAmYGIUpReOoVAzPVyzDMW1Cnx%2BR%2FBag0pzQ4fB4w%3D%3D&pr=41 71 | source_ip - 10.0.2.15 72 | host - limfoklubs.com 73 | accept - */* 74 | user-agent - chrome/9.0 75 | connection - close 76 | version - 1.0 77 | method - GET 78 | 79 | destination_ip - 72.14.204.105 80 | source_ip - 10.0.2.15 81 | host - www.google.com 82 | uri - / 83 | connection - close 84 | version - 1.1 85 | pragma - no-cache 86 | user-agent - 87 | method - GET 88 | 89 | destination_ip - 72.14.204.147 90 | source_ip - 10.0.2.15 91 | host - www.google.com 92 | accept - */* 93 | uri - / 94 | connection - close 95 | version - 1.0 96 | user-agent - 97 | method - GET 98 | 99 | -------------------------------------------------------------------------------- /files/http_requests.txt: -------------------------------------------------------------------------------- 1 | 10.0.2.15 - 178.162.174.162 - GET - chrome/9.0 - /logo.png?tq=gKZEtzoYwLzEvUb5dQzRsrCpBfEtTca3l74EgC5OjrPGpgfib1XFp5zpRPksUt%2BA%2FgSoSEU%3D&pr=41 2 | 10.0.2.15 - 178.162.174.162 - GET - chrome/9.0 - /logo.png?tq=gKZEtzoYwLzEvUb5dQzRsrCpBfEtTca3l74EgC9OjrPGpgfib1XFp5zpRPksUt%2BA%2FgSoSEU%3D&pr=467 3 | 10.0.2.15 - 178.162.174.162 - GET - chrome/9.0 - /logo.png?tq=gL5HtzoYwLzEpUb5fU3HxcaxAvU6EsazybMRtyFZ0umG8Ar0SsSA%2FgSoSEU%3D&pr=41 4 | 10.0.2.15 - 209.139.208.130 - GET - chrome/9.0 - /lhous4.gif?pr=gJ4WK%2FSUh7TFmkR8oY%2BQtMWTUj26kJH7yZJTP7qVybhqtUn5CGFATA%3D%3D 5 | 10.0.2.15 - 216.92.12.78 - GET - chrome/9.0 - /images/pages.jpg?sv=217&tq=gHZutDyMv5rJfSG1J8K%2B1MWCJbP4lltXIA%3D%3D 6 | 10.0.2.15 - 46.4.30.143 - GET - chrome/9.0 - /images/logo.png?tq=gFarqHoLmEqQTvWAbkiQEtFZ8KwrE8EGxy%2F2%2FGxKlxS1X%2FP9bEyXG8Nd9f0ZO4ARwh2jtnlJ4RDRWfCrL1%2BWZ4wb4%2FZqG9MGxy%2BoqzIfgBHCHKLhbz6VBsZdoLN5SeFMkg3j9moKylGATvWAakiXF8SiwG6%2BV%2BLvsw%3D%3D 7 | 10.0.2.15 - 66.70.127.101 - GET - chrome/9.0 - /png/intel.gif?sv=675&tq=gwY92w4A7jiwWknN94TRV9bvbNFjouNKzJI3XeHDW1%2BkfYlCM%2FfGvMazO425sOpHKXiiuVs0jzWmB9RwvNZwlFX63EHwPSWS5eOXmr08pGxcG7xBsIJ6ASctcX%2FvYkbSIIT%2BFInDxUZu16ObNa2JHav0HanfPrBw977AVUN 8 | 10.0.2.15 - 69.64.38.6 - GET - chrome/9.0 - /img/135.png?tq=gK4QKH1O%2FQHS4l9mehOkFMfXUjY9SvIGtadXNz1M8gnDpVE3SDvlA8LqF2coSYQD0aFUZ2lf83XGoVc%2FKEj2QoD2Eis%2BPvEUxqUVaihJhAHRoVR8exTlArCmVCs%2FTKFH0aAmYGIUpReOoVAzPVyzDMW1Cnx%2BR%2FBag0pzQ4fB4w%3D%3D&pr=41 9 | 10.0.2.15 - 72.14.204.105 - GET - - / 10 | 10.0.2.15 - 72.14.204.147 - GET - - / 11 | -------------------------------------------------------------------------------- /json_summary.py: -------------------------------------------------------------------------------- 1 | 2 | #!/usr/bin/python 3 | 4 | __description__ = 'Summarize a PCAP file to standard out' 5 | __author__ = 'Brandon Dixon' 6 | __version__ = '1.0' 7 | __date__ = '2011/12/1' 8 | 9 | from libs.c2utils import pcap_miner 10 | import time, re, optparse, getpass, time 11 | 12 | def main(): 13 | oParser = optparse.OptionParser(usage='usage: %prog [options]\n' + __description__, version='%prog ' + __version__) 14 | oParser.add_option('-f', '--file', type='string', help='input PCAP file for processing') 15 | oParser.add_option('-v', '--verbose', action="store_true", default=False, help='verbose logging on performed actions') 16 | (options, args) = oParser.parse_args() 17 | 18 | if options.file: 19 | miner = pcap_miner(options.file) 20 | print miner.summary2json() 21 | 22 | else: 23 | oParser.print_help() 24 | return 25 | 26 | if __name__ == '__main__': 27 | main() 28 | -------------------------------------------------------------------------------- /libs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/9b/pcap_tools/01fc6f02078936bc39dfd0d490294a9e306d47d1/libs/__init__.py -------------------------------------------------------------------------------- /libs/c2utils.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import itertools 3 | import operator 4 | 5 | try: 6 | import dpkt 7 | except: 8 | print "Download dpkt" 9 | 10 | try: 11 | import cymruwhois 12 | except: 13 | print "Download cymruwhois" 14 | 15 | try: 16 | import simplejson as json 17 | except: 18 | print "Download simplejson" 19 | 20 | class pcap_miner(): 21 | def __init__(self,pcap_file): 22 | #declaration 23 | self._pcap_file = pcap_file 24 | self._http_request_data = [] 25 | self._source_ips = [] 26 | self._destination_ips = [] 27 | self._source_ip_details = [] 28 | self._destination_ip_details = [] 29 | self._dns_request_data = [] 30 | self._flows = [] 31 | self._packet_count = 0 32 | self._http_count = 0 33 | self._dns_count = 0 34 | 35 | #processing 36 | self._handle = self._get_dpkt_handle() 37 | self._extract_data() 38 | 39 | def _get_dpkt_handle(self): 40 | f = open(self._pcap_file) 41 | pcap = dpkt.pcap.Reader(f) 42 | return pcap 43 | 44 | def unpack_ip(self,packed_ip): 45 | ip = socket.inet_ntoa(packed_ip) 46 | return ip 47 | 48 | def quick_unique(self,seq): 49 | seen = set() 50 | return [ x for x in seq if x not in seen and not seen.add(x)] 51 | 52 | def _extract_data(self): 53 | pcap = self._handle 54 | eth = None 55 | ip = None 56 | protocol = None 57 | 58 | for ts, buf in pcap: 59 | try: 60 | eth = dpkt.ethernet.Ethernet(buf) 61 | ip = eth.data 62 | protocol = ip.data 63 | except dpkt.dpkt.NeedData: 64 | continue 65 | 66 | self._packet_count += 1 67 | 68 | try: 69 | source_ip = self.unpack_ip(ip.src) 70 | destination_ip = self.unpack_ip(ip.dst) 71 | self._source_ips.append(source_ip) 72 | self._destination_ips.append(destination_ip) 73 | except Exception, e: 74 | continue 75 | 76 | try: 77 | if protocol.dport == 80 or protocol.dport == 443: 78 | self._http_count += 1 79 | try: 80 | http = dpkt.http.Request(protocol.data) 81 | tmp = http.headers 82 | tmp["source_ip"] = source_ip 83 | tmp['destination_ip'] = destination_ip 84 | tmp['method'] = http.method 85 | tmp['version'] = http.version 86 | tmp['uri'] = http.uri 87 | self._http_request_data.append(tmp) 88 | except Exception, e: 89 | continue 90 | except Exception, e: 91 | continue 92 | 93 | try: 94 | if protocol.dport == 53 or protocol.sport == 53: 95 | self._dns_count += 1 96 | try: 97 | dns = dns = dpkt.dns.DNS(protocol.data) 98 | if dns.qr != dpkt.dns.DNS_R: continue 99 | if dns.opcode != dpkt.dns.DNS_QUERY: continue 100 | if dns.rcode != dpkt.dns.DNS_RCODE_NOERR: continue 101 | if len(dns.an) < 1: continue 102 | for answer in dns.an: 103 | if answer.type == 5: 104 | tmp = { "type": "CNAME", "request":answer.name, "response":answer.cname } 105 | self._dns_request_data.append(tmp) 106 | elif answer.type == 1: 107 | tmp = { "type": "A", "request":answer.name, "response":socket.inet_ntoa(answer.rdata) } 108 | self._dns_request_data.append(tmp) 109 | elif answer.type == 12: 110 | tmp = { "type": "PTR", "request":answer.name, "response":answer.ptrname } 111 | self._dns_request_data.append(tmp) 112 | 113 | except Exception, e: 114 | continue 115 | except Exception, e: 116 | continue 117 | try: 118 | self._flows.append(source_ip + "/" + str(protocol.sport) + "=>" + destination_ip + "/" + str(protocol.dport)) 119 | except Exception, e: 120 | continue 121 | 122 | def get_source_ips(self): 123 | return self.quick_unique(self._source_ips) 124 | 125 | def get_source_ip_details(self): 126 | ulist = self.quick_unique(self._source_ips) 127 | c = cymruwhois.Client() 128 | for item in c.lookupmany(ulist): 129 | try: 130 | if item.prefix == None: 131 | tmp = { "ip_address": item.ip, "block": "", "asn": "", "owner": "" } 132 | else: 133 | tmp = { "ip_address": item.ip, "block": item.prefix, "asn": item.asn, "owner": item.owner } 134 | self._source_ip_details.append(tmp) 135 | except Exception, e: 136 | continue 137 | 138 | return self._source_ip_details 139 | 140 | def get_destination_ips(self): 141 | return self.quick_unique(self._destination_ips) 142 | 143 | def get_destination_ip_details(self): 144 | ulist = self.quick_unique(self._destination_ips) 145 | c = cymruwhois.Client() 146 | for item in c.lookupmany(ulist): 147 | try: 148 | if item.prefix == None: 149 | tmp = { "ip_address": item.ip, "block": "", "asn": "", "owner": "" } 150 | else: 151 | tmp = { "ip_address": item.ip, "block": item.prefix, "asn": item.asn, "owner": item.owner } 152 | self._destination_ip_details.append(tmp) 153 | except Exception, e: 154 | continue 155 | 156 | return self._destination_ip_details 157 | 158 | def get_http_request_data(self): 159 | getvals = operator.itemgetter('source_ip','destination_ip', 'uri') 160 | self._http_request_data.sort(key=getvals) 161 | 162 | result = [] 163 | for k, g in itertools.groupby(self._http_request_data, getvals): 164 | result.append(g.next()) 165 | 166 | self._http_request_data[:] = result 167 | return self._http_request_data 168 | 169 | def get_dns_request_data(self): 170 | getvals = operator.itemgetter('type','request', 'response') 171 | self._dns_request_data.sort(key=getvals) 172 | 173 | result = [] 174 | for k, g in itertools.groupby(self._dns_request_data, getvals): 175 | result.append(g.next()) 176 | 177 | self._dns_request_data[:] = result 178 | return self._dns_request_data 179 | 180 | def get_flows(self): 181 | return self.quick_unique(self._flows) 182 | 183 | def get_packet_count(self): 184 | return self._packet_count 185 | 186 | def get_http_count(self): 187 | return self._http_count 188 | 189 | def get_dns_count(self): 190 | return self._dns_count 191 | 192 | def summary2json(self): 193 | self._dns_json = [] 194 | self._dest_json = [] 195 | self._http_json = [] 196 | self._flow_json = [] 197 | self._counts_json = [] 198 | 199 | self._counts_json.append({"packet_count":self._packet_count,"http_count":self._http_count,"dns_count":self._dns_count}) 200 | 201 | for dns in self.get_dns_request_data(): 202 | self._dns_json.append({"type": dns["type"], "request": dns["request"], "response": dns["response"]}) 203 | 204 | for ip in self.get_destination_ip_details(): 205 | self._dest_json.append({"ip_address" : ip['ip_address'], "owner": ip['owner'], "asn": ip['asn'], "netblock": ip['block']}) 206 | 207 | for info in self.get_http_request_data(): 208 | tmp = {} 209 | for key, value in info.items(): 210 | tmp[key] = value 211 | self._http_json.append(tmp) 212 | 213 | for flow in self.get_flows(): 214 | direction = flow.split("=>") 215 | source = direction[0].split("/") 216 | destination = direction[1].split("/") 217 | self._flow_json.append({"source_ip":source[0],"source_port":source[1],"destination_ip":destination[0],"destination_port":destination[1]}) 218 | 219 | #construct the output object 220 | obj = {"file":self._pcap_file, 221 | "dns_data":self._dns_json, 222 | "destination_ip_details":self._dest_json, 223 | "http_requests":self._http_json, 224 | "flows":self._flow_json, 225 | "counts":self._counts_json 226 | } 227 | 228 | return json.dumps(obj) 229 | -------------------------------------------------------------------------------- /output_summary.py: -------------------------------------------------------------------------------- 1 | 2 | #!/usr/bin/python 3 | 4 | __description__ = 'Summarize a PCAP file to standard out' 5 | __author__ = 'Brandon Dixon' 6 | __version__ = '1.0' 7 | __date__ = '2011/12/1' 8 | 9 | from libs.c2utils import pcap_miner 10 | import time, re, optparse, getpass, time 11 | 12 | def main(): 13 | oParser = optparse.OptionParser(usage='usage: %prog [options]\n' + __description__, version='%prog ' + __version__) 14 | oParser.add_option('-f', '--file', type='string', help='input PCAP file for processing') 15 | oParser.add_option('-v', '--verbose', action="store_true", default=False, help='verbose logging on performed actions') 16 | (options, args) = oParser.parse_args() 17 | 18 | if options.file: 19 | miner = pcap_miner(options.file) 20 | 21 | print "== DNS Queries and Domains ==\n" 22 | for dns in miner.get_dns_request_data(): 23 | print(dns['type'] + " - " + dns['request'] + " - " + dns['response']) 24 | 25 | print "\n== Destination Addresses ==\n" 26 | for ip in miner.get_destination_ip_details(): 27 | print(ip['ip_address'] + " - " + ip['owner'] + " - " + ip['asn'] + " - " + ip['block']) 28 | 29 | print "\n== Request Dump ==\n" 30 | for info in miner.get_http_request_data(): 31 | for key, value in info.items(): 32 | print(key + " - " + value) 33 | print("\n") 34 | 35 | print "\n== Flows ==\n" 36 | for info in miner.get_flows(): 37 | print(info) 38 | 39 | else: 40 | oParser.print_help() 41 | return 42 | 43 | if __name__ == '__main__': 44 | main() 45 | -------------------------------------------------------------------------------- /pcap_summary.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | __description__ = 'Summarize a PCAP file' 4 | __author__ = 'Brandon Dixon' 5 | __version__ = '1.0' 6 | __date__ = '2011/12/1' 7 | 8 | from libs.c2utils import pcap_miner 9 | import time, re, optparse, getpass, time, hashlib, os 10 | 11 | def generate(infile, outfile): 12 | miner = pcap_miner(infile) 13 | #file 1 - DNS queries and domains returned 14 | f = open(outfile + "dns_queries.txt","w") 15 | for dns in miner.get_dns_request_data(): 16 | f.write(dns['type'] + " - " + dns['request'] + " - " + dns['response'] + "\n") 17 | f.close() 18 | 19 | #file 2 - IPS of attackers without whois 20 | f = open(outfile + "attacker_ips.txt","w") 21 | for ip in miner.get_destination_ips(): 22 | f.write(ip + "\n") 23 | f.close() 24 | 25 | #file 3 - IPs of attackers with whois 26 | f = open(outfile + "attacker_ips_whois.txt","w") 27 | for ip in miner.get_destination_ip_details(): 28 | f.write(ip['ip_address'] + " - " + ip['owner'] + " - " + ip['asn'] + " - " + ip['block'] + "\n") 29 | f.close() 30 | 31 | #file 4 - what you called HTTPrequests but it can be other port just the requests back forh part 32 | f = open(outfile + "http_requests.txt","w") 33 | for info in miner.get_http_request_data(): 34 | if 'user-agent' not in info: 35 | info['user-agent'] = " " 36 | 37 | f.write(info['source_ip'] + " - " + info['destination_ip'] + " - " + info['method'] + " - " + info['user-agent'] + " - " + info['uri'] + "\n") 38 | f.close() 39 | 40 | #file 5 - whatever can be dumped from the request 41 | f = open(outfile + "full_http_requests.txt","w") 42 | for info in miner.get_http_request_data(): 43 | for key, value in info.items(): 44 | f.write(key + " - " + value + "\n") 45 | f.write("\n") 46 | f.close() 47 | 48 | #file 6 - dump flows 49 | f = open(outfile + "flows.txt","w") 50 | for info in miner.get_flows(): 51 | f.write(info + "\n") 52 | f.close() 53 | 54 | def main(): 55 | oParser = optparse.OptionParser(usage='usage: %prog [options]\n' + __description__, version='%prog ' + __version__) 56 | oParser.add_option('-f', '--file', type='string', help='input PCAP file for processing') 57 | oParser.add_option('-d', '--dir', type='string', help='input PCAP dir for processing') 58 | oParser.add_option('-o', '--out', type='string', help='output directory - absolute path only') 59 | oParser.add_option('-v', '--verbose', action="store_true", default=False, help='verbose logging on performed actions') 60 | (options, args) = oParser.parse_args() 61 | 62 | if options.file and options.out: 63 | generate(options.file,options.out) 64 | elif options.dir and options.out: 65 | files = [] 66 | dirlist = os.listdir(options.dir) 67 | for fname in dirlist: 68 | files.append(fname) 69 | files.sort() 70 | count = 0 71 | 72 | for file in files: 73 | outdir = options.out + hashlib.md5(file).hexdigest() + "/" 74 | if not os.path.exists(outdir): 75 | os.makedirs(outdir) 76 | generate(options.dir + file,outdir) 77 | else: 78 | oParser.print_help() 79 | return 80 | 81 | if __name__ == '__main__': 82 | main() 83 | -------------------------------------------------------------------------------- /pcaps/dump.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/9b/pcap_tools/01fc6f02078936bc39dfd0d490294a9e306d47d1/pcaps/dump.pcap -------------------------------------------------------------------------------- /pcaps/sample.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/9b/pcap_tools/01fc6f02078936bc39dfd0d490294a9e306d47d1/pcaps/sample.pcap --------------------------------------------------------------------------------