-
Notifications
You must be signed in to change notification settings - Fork 0
/
S2D.py
executable file
·201 lines (169 loc) · 6.35 KB
/
S2D.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
#!/usr/bin/env python
# -----------------------------------------------------------
# Filename : S2D.py
# Created By : Joe Pistone
# Date Created : 16-Mar-2016 18:16
# Date Modified :
#------------------------------------------------------------
# License : Development
#
# Description : Network Discovery and fingerprinting tool
#
# (c) Copyright 2015, TheKillingTime all rights reserved.
#-----------------------------------------------------------
__author__ = "Joe Pistone"
__version__ = "1.5"
try:
import sys
import time
import logging
# Cleans up a little of scapy's run time mess.
logging.getLogger('scapy.runtime').setLevel(logging.ERROR)
import pygeoip
import proto_to_numbers
from netaddr import *
from scapy.all import *
except ImportError, err:
print "[!] ImportError: %s " % err
sys.exit(1)
# Moar scapy clean up
conf.verb=0
class Inspect_Traffic(object):
def __init__(self, p2c, interface):
# MaxMind GeoIP database
self.geodb = '/usr/local/geo/GeoLiteCity.dat'
self.count = int(p2c)
self.interface = interface
print "\033[32;3m[*]\033[0m Capturing %d packets to analyze on interface %s ..." % (self.count, self.interface)
# Building timestamp
self.time = time.strftime("%H:%M:%S")
self.date = (time.strftime("%m/%d/%Y "))
self.time_stamp = self.date + self.time
# To log or to print, or both
self.log = True
self.print_to_screen = False
# Log to this location
self.log_to = '/var/log/packet_direction/'
self.log_to_file = 'network.log'
self.network_log = self.log_to + self.log_to_file
def check_log_path(self):
"""
Checks to see if log path exists. Then creates it.
"""
if not os.path.exists(self.log_to):
print "[+] Directory does not exist. Creating %s" % self.log_to
os.makedirs(self.log_to)
network_log = self.log_to + self.log_to_file
open(self.network_log, 'a').close()
def log_file(self, log_to_write):
"""
Log data to a file.
"""
# This is temporary <= I bet it's not.
# Re factor with the logging library later on.
self.check_log_path()
a = open(self.network_log, 'a')
a.write(log_to_write)
a.close()
def sniff_packets(self):
"""
Let's Sniff some packets!!
"""
try:
self.packets = sniff(iface=self.interface, count=self.count)
except OSError, err:
print "\n\033[31;3m[!!]\033[0m Error: Interface %s is invalid. " % self.interface
def geo_lookup(self, ip_address):
"""
This method will do a geo lookup
against an ip address.
"""
try:
gic = pygeoip.GeoIP(self.geodb)
except IOError:
print "\033[31;3m[!!]\033[0m Error: Cannot open %s." % self.geodb
sys.exit(1)
try:
geo_json = gic.record_by_addr(ip_address)
output = ", ".join([geo_json['country_name'], geo_json['region_code']])
except:
output = "Unregistered"
return output
def hardware_vendor(self, mac):
"""
This method will take a mac address
The pull out the oui and analyze it.
"""
try:
hw_id = EUI(mac)
oui = hw_id.oui
return oui.registration().org
except NotRegisteredError, err:
return 'Error="%s"' % err
def setup_output(self):
"""
This method should parse the output
from the packet capture.
"""
for packet in self.packets[IP]:
pkt = packet[0][IP]
hw_id = packet[0]['Ethernet']
# Geo look-ups on source and dest.
src_geo = self.geo_lookup(str(pkt.src))
dst_geo = self.geo_lookup(str(pkt.dst))
# Source and destination Mac addresses
self.src_mac = 'Source Mac="%s"' % hw_id.src
self.dst_mac = 'Destination Mac="%s"' % hw_id['Ethernet'].dst
# Source and destination IP Address
src = 'Source="%s"' % packet[0][IP].src
dst = 'Destination="%s"' % packet[0][IP].dst
# Source and destination Geolookups
src_location = 'Location="%s"' % src_geo
dst_location = 'Location="%s"' % dst_geo
# Protocol to number lookup, also packing timestamp here
proto_2_num = str(packet[0][IP].proto)
time = 'Timestamp="%s"' % self.time_stamp
proto = 'Protocol="%s"' % proto_to_numbers.protocols[proto_2_num]
# Hardware ID lookups
src_vendor = 'HW_Vendor="%s"' % self.hardware_vendor(hw_id.src)
dst_vendor = 'HW_Vendor="%s"' % self.hardware_vendor(hw_id.dst)
# Join it all together for a log line
self.value = " ".join([time, proto, src, src_location, self.src_mac,
src_vendor, dst, dst_location, self.dst_mac, dst_vendor])
# Built in logic for printing or logging to a file (or both)
self.print_and_or_log()
def print_and_or_log(self):
"""
Will check to either print, log,
or both.
"""
# Log
if self.log:
self.log_file(str(self.value) + "\n")
# Screen
if self.print_to_screen:
print self.value
def main(self):
"""
Main method.
"""
self.sniff_packets()
self.setup_output()
if __name__ == '__main__':
# Checks for root
if os.getuid() == 0:
# Checks for command line args
if len(sys.argv) != 3:
print "Usage: %s <interface> <number of packets to capture>" % sys.argv[0]
sys.exit(1)
# Get command line args for interface and packets to capture.
interface = sys.argv[1]
p2c = sys.argv[2]
# Validating user input for packets is a digit.
if p2c.isdigit():
inspect = Inspect_Traffic(p2c, interface)
inspect.main()
else:
print "\033[31;3m[!!]\033[0m Packet count must be a digit."
else:
print "\033[31;3m[!!]\033[0m Please run as root."