1
2
3
4
5
6 import gps, time, os, signal, sys, operator, threading
7 import string, socket, struct, datetime
8
9 from killerbee import *
10 import Queue
11
12
13 session = ""
14 active_queues = []
15 arg_verbose = False
16 arg_ppi = False
17 arg_db = False
18 arg_gps = False
19 arg_gps_devstring = ""
20 latitude = ""
21 longitude = ""
22 altitude = ""
23 last_seen = ""
24
26 ''' Send broadcast data to all active threads '''
27 print "\nShutting down threads."
28 for q in active_queues:
29 q.put(data)
30
32 ''' Thread to update gps location from gpsd '''
38
67
68
70 ''' Thread to capture on a given channel, using a given device, to a given pcap file, exits when it receives a broadcast shutdown message via Queue.Queue'''
81
83 global active_queues
84 global longitude, latitude, altitude
85 self.kb = KillerBee(device=self.dev)
86 self.kb.set_channel(self.channel)
87 self.kb.sniffer_on()
88
89
90 message = ""
91 while (True):
92 try:
93 message = self.mesg.get(timeout=.00001)
94 except Queue.Empty:
95 pass
96 if message == "shutdown":
97 break
98 packet = self.kb.pnext()
99 if packet != None:
100 self.packetcount+=1
101 if arg_gps:
102 gpsdata = (longitude, latitude, altitude)
103 self.pd.pcap_dump(packet['bytes'], ant_dbm=packet['dbm'], freq_mhz=self.freq, location=map(float, gpsdata))
104 if arg_db:self.kb.dblog.add_packet(full=packet, location=gpsdata)
105 else:
106 self.pd.pcap_dump(packet['bytes'])
107 if arg_db:self.kb.dblog.add_packet(full=packet)
108 print chr(0x1b) + "[%d;5fChannel %d: %d packets captured." % (self.channel - 6, self.channel, self.packetcount)
109
110 if arg_verbose:
111 print "%s on channel %d shutting down..." % (threading.currentThread().getName(), self.channel)
112 self.kb.sniffer_off()
113 self.kb.close()
114 self.pd.close()
115 print "%d packets captured on channel %d" % (self.packetcount, self.channel)
116
118 ''' Signal handler called on keyboard interrupt to exit threads and exit scanner script'''
119 os.system('clear')
120 broadcast_event("shutdown")
121 time.sleep(1)
122 sys.exit(0)
123
125 global arg_verbose
126 global arg_gps, arg_gps_devstring
127 global session
128 global longitude, latitude, altitude
129
130 while len(args) > 1:
131 op = args.pop(1)
132 if op == '-v':
133 arg_verbose = True
134 if op == '-g':
135 arg_gps_devstring = sys.argv.pop(1)
136 arg_gps = True
137 if op == '-p':
138 arg_ppi = True
139 if op == '-d':
140 arg_db = True
141
142 signal.signal(signal.SIGINT, signal_handler)
143
144 if arg_gps:
145 kbdev_info = kbutils.devlist(gps=arg_gps_devstring)
146 else:
147 kbdev_info = kbutils.devlist()
148 channel = 11
149 print "Found %d devices." % len(kbdev_info)
150 if len(kbdev_info) < 1:
151 exit(1)
152 if arg_gps == True:
153 print "Initializing GPS device %s ... "% (arg_gps_devstring),
154 session = gps.gps()
155 session.poll()
156 session.stream()
157 print "Waiting for fix... ",
158 while(session.fix.mode == 1):
159 session.poll()
160 print "Fix acquired!"
161 t = LocationThread()
162 t.start()
163 time.sleep(2)
164 for i in range(0, len(kbdev_info)):
165 if kbdev_info[i][0] == arg_gps_devstring:
166 print "Skipping device %s" % arg_gps_devstring
167 else:
168 print 'Device at %s: \'%s\'' % (kbdev_info[i][0], kbdev_info[i][1])
169 if channel <= 26:
170 print '\tAssigning to channel %d.' % channel
171 timeLabel = datetime.datetime.now().strftime('%Y%m%d-%H%M')
172 fname = 'zb_c%s_%s.pcap' % (channel, timeLabel)
173 pcap = PcapDumper(DLT_IEEE802_15_4, fname, ppi=arg_ppi)
174 t = CaptureThread(kbdev_info[i][0], channel, pcap)
175 t.start()
176 channel += 1
177 os.system('clear')
178 print chr(0x1b) + "[1;5fLive Stats:"
179 while True: pass
180