def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) # self.ui.actionInterval.triggered.connect(self.onCaptureInterval) self.ui.actionStart.triggered.connect(self.onCaptureStart) self.ui.actionStop.triggered.connect(self.onCaptureStop) self.ui.actionReset.triggered.connect(self.onResetCapture) self.ui.actionQuit.triggered.connect(self.close) # self.arpPackets = list() self.ethPackets = list() # self.arpEntropies = list() self.ethEntropies = list() # self.sniffer = Sniffer() self.sniffer.packetCaptured.connect(self.onPacketCaptured) self.sniffer.timeout.connect(self.onSniffTimeout) self.thread = QThread() self.sniffer.moveToThread(self.thread) self.thread.started.connect(self.sniffer.sniff) self.sniffer.finished.connect(self.thread.quit) self.sniffer.finished.connect(self.onCaptureStop) # self.packets = 0 # self.maxArpEntropy = [0, -1] self.maxEthEntropy = [0, -1] # self.ethEntropyThread = QThread() self.ethEntropy = EtherEntropy() self.ethEntropyThread.started.connect(self.ethEntropy.entropy) self.ethEntropy.resultReady.connect(self.onEthEntropyReady) self.ethEntropy.resultReady.connect(self.ethEntropyThread.quit) # self.arpEntropyThread = QThread() self.arpEntropy = ArpEntropy() self.arpEntropyThread.started.connect(self.arpEntropy.entropy) self.arpEntropy.resultReady.connect(self.onArpEntropyReady) self.arpEntropy.resultReady.connect(self.arpEntropyThread.quit) # self.timer = QTimer(self) self.timer.timeout.connect(self.onCountDown) self.timer.start(ONE_SECOND) # self.entropyTimer = QTimer(self) self.entropyTimer.timeout.connect(self.updateEntropy) # self.timer2 = QTimer(self) self.timer2.timeout.connect(self.updateStatics) self.timer2.start(MILLIS_200) # self.ui.actionSaveCapture.triggered.connect(self.saveCapture) self.ui.actionSaveEntropy.triggered.connect(self.saveEntropy) # self.ui.statusbar.showMessage("Ready") # self.ui.progressBar.hide()
def backRun(self, signal): try: self._back_status = True # iface = self.iface.text() # if iface == '': # iface = 'en0' iface = self.iface.currentText() filter = self.filter.text() # session = self.session.text() session = self.comboBox.currentIndex() if session == 0: session = '' elif session == 1: session = 'IPSession' elif session == 2: session = 'TCPSession' else: session = '' count = 0 if self.count.text() == '' else eval(self.count.text()) if self.timeout.text() == '': timeout = None else: timeout = eval(self.timeout.text()) password = self.password.text() self.sniffer = Sniffer(iface=iface, filter=filter, session=session, count=count, timeout=timeout, prn=self.update_signal) self.sniffer.run() output = str(self.sniffer.dpkts ) + '\nExtract sessions from packets: ' + str( len(self.sniffer.dpkts.sessions().keys())) + '.' for dpkt in self.sniffer.dpkts: summary = dpkt.summary() self.summaries.append(summary) self.slm.setStringList(self.summaries) # 将数据设置到model self.output.setText(output) try: os.remove('tmp/test.jpg') except: pass self.sniffer.draw() self.feedback.setText("Sniff done.") # opencv图像 # pix = QPixmap.fromImage(frame) # self.item = QGraphicsPixmapItem(pix) # 创建像素图元 # # self.item.setScale(self.zoomscale) # self.scene = QGraphicsScene() # 创建场景 # self.scene.addItem(self.item) # self.picshow.setScene(self.scene) # 将场景添加至视图 self.update_frame.emit() self._back_status = False signal.emit() except: pass
def backRun(self): try: iface = self.comboBox.currentText() filter = self.lineEdit.text() self.sniffer = Sniffer(iface=iface, filter=filter, prn=self.update_signal) self.sniffer.run() except: pass
def detect_ps(): # === SHARED VARIABLES === # first_contacts = dict() lock = threading.Lock() # === INITIALIZE THREAD OBJECTS === # sniffer = Sniffer(first_contacts, lock) cleanup = DictCleaner(first_contacts, lock) fan_out_rate_calculator = FanOutRateCalculator(first_contacts, lock) # === START THE TREADS === # sniffer.start() cleanup.start() fan_out_rate_calculator.start() # === RUN UNTIL USER TELLS PROGRAM TO STOP === # print('[+] Enter \'x\' to Stop Detecting') while True: x = input() if x in 'xX': print('[*] Terminating Threads...') break # === ALLOW THREADS TO ESCAPE THEIR INFINITE LOOPS === # sniffer.is_running = False cleanup.is_running = False fan_out_rate_calculator.is_running = False # === JOIN TO MAIN THREAD TO PREVENT HANGING sniffer.join() cleanup.join() fan_out_rate_calculator.join() # === EXIT DRIVER FUNCTION === # return
def __init__(self, parent): self.figure = Figure(figsize=(5,5), dpi=100) self.a = self.figure.add_subplot(1,1,1,axisbg='black') self.canvas = FigureCanvasTkAgg(self.figure, parent) self.canvas.show() self.canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=True) self.ani = animation.FuncAnimation(self.figure, self.animate ,interval=1000) self.sniffer = Sniffer(1, 'Sniffer-1', 1) self.sniffer.start()
def malware_train(line): global malware_train_nb if (mta.check_if_link_is_in_downloaded_file(line) is False): pcap_file_name = mta.download_pcap([line]) for pcap in pcap_file_name: if (pcap is not None): if (check_if_already_trained(pcap) is False): attacker = AttackerCalc(pcap=mta.get_folder_name() + "/" + pcap) ip_to_consider = attacker.compute_attacker() flow_type = "malware" filter_1.set_ip_whitelist_filter(ip_to_consider) filter_2.set_ip_whitelist_filter(ip_to_consider) filter_3.set_ip_whitelist_filter(ip_to_consider) featuresCalc = FeaturesCalc(flow_type=flow_type, min_window_size=5) csv = CSV(file_name="features_" + flow_type, folder_name="Features") csv.create_empty_csv() csv.add_row(featuresCalc.get_features_name()) argument = { "features_calc": featuresCalc, "packets": [], 'filter': [filter_1, filter_2, filter_3], 'csv_obj': csv } sniffer = Sniffer(iface_sniffer, callback_prn=callback_sniffer, callback_prn_kwargs=argument) sniffer.start() while (sniffer.get_started_flag() is False): pass try: sender = Sender(iface_sender, fast=False, verbose=False, time_to_wait=10) sender.send(mta.get_folder_name() + "/" + pcap) sniffer.stop() except Exception as e: print(e) csv.close_csv() env.set_csv(csv.get_folder_name() + "/" + csv.get_current_file_name()) agent.train_agent( steps=csv.get_number_of_rows() - 1, log_interval=csv.get_number_of_rows() - 1, verbose=2, nb_max_episode_steps=csv.get_number_of_rows() - 1) malware_train_nb -= 1 trained_file.write(pcap + "\n") else: print("\nPcap gia' utilizzato in passato. Saltato.\n") else: pass else: pass
async def test_icmp(self, nursery): """ Test that the sniffer successfully sets itself up """ # Start the sniffer s = Sniffer( config=testConfig, databaser=None, ) s.start() # Do an ICMP request to a DNS resolver targets = ["9.9.9.9", "8.8.8.8", "1.1.1.1"] for ip in targets: send(IP(dst=ip) / ICMP()) # Let the logger handle whats up await trio.sleep(WAIT_TIME * 4) for ip in targets: assert ip in s.RECORD.keys() assert s.RECORD[ip][0].sourceIPAddress == ip assert s.RECORD[ip][0].trafficType == "ICMP" assert s.RECORD[ip][0].length == 28 print("check for {}".format(ip)) s.stop()
async def test_icmp(self, nursery): """ Test that the sniffer successfully sets itself up """ # Start the sniffer s = Sniffer( config="testing", openPorts=[], whitelist=[], honeypotIP="localhost", managementIPs=(), port_scan_window=60, port_scan_sensitivity=100, databaser=None, ) s.start() # Do an ICMP request to a DNS resolver targets = ["9.9.9.9", "8.8.8.8", "1.1.1.1"] for ip in targets: send(IP(dst=ip) / ICMP()) # Let the logger handle whats up await trio.sleep(WAIT_TIME * 4) for ip in targets: assert ip in s.RECORD.keys() assert s.RECORD[ip][0].sourceIPAddress == ip assert s.RECORD[ip][0].trafficType == "ICMP" assert s.RECORD[ip][0].length == 28 print("check for {}".format(ip)) s.stop()
async def test_init(self, nursery): """ Test that the sniffer successfully sets itself up """ # Start the sniffer s = Sniffer( config=testConfig, databaser=None, ) s.start() # Google IP; we'll be using this later IPPipe = os.popen("dig +short www.google.com") responseIPs = IPPipe.read()[:-1].split("\n") IPPipe.close() # Making sure we catch it os.system("curl -s www.google.com -o /dev/null") # Let the logger handle whats up await trio.sleep(WAIT_TIME) # Dig sometimes gives us multiple IPs, not all of which are used. # If one is used, that's a successful read. for ip in responseIPs: assert ip in s.RECORD.keys() assert s.RECORD[ip][0].sourceIPAddress == ip assert s.RECORD[ip][0].sourcePortNumber == 80 assert s.RECORD[ip][0].trafficType == "TCP" assert s.RECORD[ip][0].length != 0 s.stop()
class NetworkPlotter: def __init__(self, parent): self.figure = Figure(figsize=(5,5), dpi=100) self.a = self.figure.add_subplot(1,1,1,axisbg='black') self.canvas = FigureCanvasTkAgg(self.figure, parent) self.canvas.show() self.canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=True) self.ani = animation.FuncAnimation(self.figure, self.animate ,interval=1000) self.sniffer = Sniffer(1, 'Sniffer-1', 1) self.sniffer.start() def animate(self, i): pullData = open('sample_data.txt', 'r').read() dataArray = pullData.split('\n') xar = [] yar = [] for line in dataArray: if len(line)>1: x,y = line.split(',') xar.append(x) yar.append(y) self.a.clear() self.a.plot(xar,yar)
def __init__(self): super(SubWindow_analyze, self).__init__() self.setupUi(self) self.sniffer = Sniffer() self.worklog = '' self.summaries = [] self.slm = QtCore.QStringListModel() # 创建mode self.slm.setStringList(self.summaries) # 将数据设置到model self.pkt_list.setModel(self.slm) # 绑定 listView 和 model self.map_idx = [] self.hex1 = '' self.hex2 = '' self.hex1_orig = '' self.hex2_orig = '' self.nameDict = { 'IP.src': IP.src, 'IP.ttl': IP.ttl, 'TCP.sport': TCP.sport, 'TCP.dport': TCP.dport }
async def testConfigUpdate(self): """ Checks if updated options work """ host_ip = "192.168.42.51" # Start the sniffer s = Sniffer( config="onlyUDP", openPorts=[], whitelist=[], portWhitelist=[], honeypotIP=host_ip, managementIPs=("52.87.97.77", "54.80.228.0"), port_scan_window=60, port_scan_sensitivity=100, ) s.start() assert len(s.openPorts) == 0 assert len(s.whitelist) == 0 assert len(s.portWhitelist) == 0 assert s.config == "onlyUDP" assert len(s.managementIPs) == 2 assert s.honeypotIP == "192.168.42.51" s.configUpdate( openPorts=[80, 443], whitelist=["8.8.8.8", "9.9.9.9"], portWhitelist=[777, 888, 999], honeypotIP="192.168.42.42", managementIPs="54.80.228.0", port_scan_window=62, port_scan_sensitivity=101, ) # used to flush the Sniffer os.system("curl -s www.google.com -o /dev/null") assert len(s.openPorts) == 2 assert len(s.whitelist) == 2 assert len(s.portWhitelist) == 3 assert s.managementIPs == "54.80.228.0" assert s.honeypotIP == "192.168.42.42" s.stop()
def legitimate_train(line): global legitimate_train_nb if (check_if_already_trained(line) is False): flow_type = "legitimate" filter_1.set_ip_whitelist_filter([]) filter_2.set_ip_whitelist_filter([]) filter_3.set_ip_whitelist_filter([]) featuresCalc = FeaturesCalc(flow_type=flow_type, min_window_size=5) csv = CSV(file_name="features_" + flow_type, folder_name="Features") csv.create_empty_csv() csv.add_row(featuresCalc.get_features_name()) argument = { "features_calc": featuresCalc, "packets": [], 'filter': [filter_1, filter_2, filter_3], 'csv_obj': csv } sniffer = Sniffer(iface_sniffer, callback_prn=callback_sniffer, callback_prn_kwargs=argument) sniffer.start() while (sniffer.get_started_flag() is False): pass try: sender = Sender(iface_sender, fast=False, verbose=False, time_to_wait=10) sender.send(lg.get_folder_name() + "/" + line) sniffer.stop() except Exception as e: print(e) csv.close_csv() env.set_csv(csv.get_folder_name() + "/" + csv.get_current_file_name()) agent.train_agent(steps=csv.get_number_of_rows() - 1, log_interval=csv.get_number_of_rows() - 1, verbose=2, nb_max_episode_steps=csv.get_number_of_rows() - 1) legitimate_train_nb -= 1 trained_file.write(line + "\n") else: print("\nPcap gia' utilizzato in passato. Saltato.\n")
async def testConfigUpdate(self): """ Checks if updated options work """ host_ip = "192.168.42.51" # Start the sniffer s = Sniffer( config=testConfig, databaser=None, ) s.start() assert len(s.config.open_ports) == 0 assert len(s.config.whitelist_addrs) == 0 assert len(s.config.whitelist_ports) == 0 s.configUpdate(testConfig2) # used to flush the Sniffer os.system("curl -s www.google.com -o /dev/null") assert len(s.config.open_ports) == 2 assert len(s.config.whitelist_addrs) == 2 assert len(s.config.whitelist_ports) == 3 s.stop()
class MainApplication(tk.Frame): def __init__(self, parent, *args, **kwargs): tk.Frame.__init__(self, parent, *args, **kwargs) self.parent = parent self.uiMenu = UIMenu(self.parent) self.parent.config(menu=self.uiMenu.menu) # self.toolbar = ttk.Frame(self.parent) # self.toolbarButton1 = ttk.Button(self.toolbar, text='Button') # self.toolbarButton1.pack(side=LEFT, padx=2, pady=2) # self.toolbar.pack(side=TOP, fill=X) self.statusbar = Label(self.parent, text='Ready', bd=1, relief=SUNKEN, anchor=W) self.statusbar.pack(side=BOTTOM, fill=X) self.notebook = ttk.Notebook(self.parent) self.frameSniff = ttk.Frame(self.notebook) self.frameArp = ttk.Frame(self.notebook) self.frameDhcp = ttk.Frame(self.notebook) self.frameSysInfo = ttk.Frame(self.notebook) self.notebook.add(self.frameSniff, text='Sniffer') self.notebook.add(self.frameArp, text='ARP') self.notebook.add(self.frameDhcp, text='DHCP Servers') self.notebook.add(self.frameSysInfo, text='System Info') self.notebook.pack(fill=BOTH) self.sniffLabelFrame = ttk.LabelFrame(self.frameSniff, text="Sniffer") self.sniffLabelFrame.pack(padx=10, pady=10) self.sniffButton = ttk.Button(self.sniffLabelFrame, text="Sniff", command=self.beginSniff) self.sniffButton.pack(side=LEFT) self.stopSniffButton = ttk.Button(self.sniffLabelFrame, text="Stop sniffing", command=self.stopSniff, state="disabled") self.stopSniffButton.pack(side=LEFT) self.sniffTv = ttk.Treeview(self.frameSniff) ysb = ttk.Scrollbar(self, orient='vertical', command=self.sniffTv.yview) xsb = ttk.Scrollbar(self, orient='horizontal', command=self.sniffTv.xview) self.sniffTv.configure(yscroll=ysb.set, xscroll=xsb.set) self.sniffTv['columns'] = ('senderip', 'sendermac', 'received') self.sniffTv.heading('#0', text='Description', anchor='w') self.sniffTv.column('#0', anchor='w') self.sniffTv.heading('senderip', text='Sender IP') self.sniffTv.column('senderip', width=100) self.sniffTv.heading('sendermac', text='Sender MAC') self.sniffTv.column('sendermac', width=100) self.sniffTv.heading('received', text='Received at') self.sniffTv.column('received', width=100) self.sniffTv.pack(fill=BOTH) self.arpLabel = ttk.Label(self.frameArp, text="ARP cache") self.arpLabel.pack() self.arpTv = ttk.Treeview(self.frameArp) self.arpTv['columns'] = ('ip', 'status') self.arpTv.heading('#0', text='MAC address', anchor='w') self.arpTv.column('#0', anchor='w') self.arpTv.heading('ip', text='IP address') self.arpTv.column('ip', width=100) self.arpTv.heading('status', text='Status') self.arpTv.column('status', width=100) self.arpTv.pack(fill=X) self.addDhcpLabelFrame = ttk.LabelFrame(self.frameDhcp, text="Add trusted server") self.addDhcpLabelFrame.pack(padx=10, pady=10) self.addDhcpNameLabel = ttk.Label(self.addDhcpLabelFrame, text="Server name") self.addDhcpNameLabel.pack() self.addDhcpNameEntry = ttk.Entry(self.addDhcpLabelFrame) self.addDhcpNameEntry.pack() self.addDhcpIpLabel = ttk.Label(self.addDhcpLabelFrame, text="Server IP address") self.addDhcpIpLabel.pack() self.addDhcpIpEntry = ttk.Entry(self.addDhcpLabelFrame) self.addDhcpIpEntry.pack() self.addDhcpMacLabel = ttk.Label(self.addDhcpLabelFrame, text="Server Mac address") self.addDhcpMacLabel.pack() self.addDhcpMacEntry = ttk.Entry(self.addDhcpLabelFrame) self.addDhcpMacEntry.pack() self.addDhcpButton = ttk.Button(self.addDhcpLabelFrame, text="Add", command=self.addDhcpButtonPressed) self.addDhcpButton.pack() self.clrDhcpButton = ttk.Button(self.addDhcpLabelFrame, text="Clear", command=self.clrDhcpButtonPressed) self.clrDhcpButton.pack() self.dhcpTv = ttk.Treeview(self.frameDhcp) self.dhcpTv['columns'] = ('ip', 'mac', 'date') self.dhcpTv.heading('#0', text='Server name', anchor='w') self.dhcpTv.column('#0', anchor='w') self.dhcpTv.heading('ip', text='IP address') self.dhcpTv.column('ip', width=100) self.dhcpTv.heading('mac', text='MAC address') self.dhcpTv.column('mac', width=100) self.dhcpTv.heading('date', text='Date added') self.dhcpTv.column('date', width=100) self.dhcpTv.pack(fill=X) strVersion = 'Python ' + platform.python_version() self.versionLabel = ttk.Label(self.frameSysInfo, text=strVersion) self.versionLabel.pack() strPlatform = 'Platform: ' + platform.platform() self.platformLabel = ttk.Label(self.frameSysInfo, text=strPlatform) self.platformLabel.pack() self.dhcpDefender = DhcpDefender(self) self.arpDefender = ArpDefender(self) self.sniffer = Sniffer(1, 'Sniffer-1', 1, self) self.sniffer.start() self.updater = Updater(1, 'Updater-1', 1, self) self.updater.start() def addDhcpButtonPressed(self): name = self.addDhcpNameEntry.get() ip = self.addDhcpIpEntry.get() mac = self.addDhcpMacEntry.get().lower() isValidIp =re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$",ip) macRe = re.compile(r'^([0-9A-F]{1,2})' + '\:([0-9A-F]{1,2})'*5 + '$', re.IGNORECASE) isValidMac = macRe.match(mac) if isValidIp and isValidMac: self.dhcpDefender.add_trusted_server(name, ip, mac) def clrDhcpButtonPressed(self): self.dhcpDefender.clear_db() def beginSniff(self): self.sniffButton.config(state="disabled") self.stopSniffButton.config(state="normal") self.sniffer.resume() def stopSniff(self): self.stopSniffButton.config(state="disabled") self.sniffButton.config(state="normal") self.sniffer.pause() def updateSniffTv(self, packet): if packet[ARP].op == 1: response = 'Request: ' + packet[ARP].psrc + ' is asking about ' + packet[ARP].pdst elif packet[ARP].op == 2: response = 'Response: ' + packet[ARP].hwsrc + ' has address ' + packet[ARP].psrc timeStr = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") self.sniffTv.insert("", 0, text=response, values=(packet[ARP].psrc, packet[ARP].hwsrc, timeStr)) def updateDhcpTv(self, trusted_servers): self.dhcpTv.delete(*self.dhcpTv.get_children()) for server in trusted_servers: self.dhcpTv.insert("", 0, text=server['name'], values=(server['ip'], server['mac'], server['date'])) def import_arp_cache(self): self.arpTv.delete(*self.arpTv.get_children()) out, err = Popen(['arp', '-na'], stdout=PIPE, stderr=PIPE).communicate() out = out.splitlines() for line in out: ip = self.find_between(line, '(', ')') mac = self.find_between(line, 'at ', ' on') self.arpTv.insert("", 0, text=mac, values=(ip, "")) def find_between(self, s, first, last): try: start = s.index(first) + len(first) end = s.index(last, start) return s[start:end] except ValueError: return "" def process_arp(self, packet): result = self.arpDefender.arp_pkt_callback(packet) if result == -1: # inconsistent headers print("inconsistent headers") self.statusbar.config(text="Warning: Inconsistent header packet detected.") pass elif result == 0: # failed active check print("failed active check") self.statusbar.config(text="Warning: You might be under ARP spoof attack.") pass elif result == 1: # passed active check print("passed active check") pass def process_dhcp(self, packet): result = self.dhcpDefender.dhcp_pkt_callback(packet) if result == 0: # unknown dhcp server print("Unknown dhcp server") self.statusbar.config(text="Warning: Untrusted DHCP server present in network.") pass elif result == 1: print("Trusted dhcp server") pass
class HoundDaemon(): def __init__(self, *args, **kwargs): self.data_interface = DataInterface() self.twitter_interface = TwitterInterface(self.data_interface) self.sniffer = Sniffer(self.data_interface) def parse_and_execute_command(self, last_mention): command = last_mention['text'] if command[0] == 'SET_MODE': current_config = self.data_interface.get_hound_mode() try: if command[1] == 'SCAN': if current_config['Mode'] == 'SCAN': return else: self.data_interface.set_hound_mode(command[1]) self.twitter_interface.post('Mode Successfully Set: SCAN') return elif command[1] == current_config['Mode'] and command[2] == current_config['Args']: print 'No Change In New Command' return else: self.data_interface.set_hound_mode(command[1], command[2]) self.twitter_interface.post('Mode Successfully Set: {0}, {1}'.format(command[1], command[2])) except Exception: print 'Duplicate Twitter Status' print 'Mode Successfully Set: {0}, {1}'.format(command[1], command[2]) elif command[0] == 'REFRESH': if last_mention['created_at'] > datetime.utcnow() - timedelta(0,SLEEP_INTERVAL): current_config = self.data_interface.get_hound_mode() message = '{0} Refresh Complete'.format(current_config['Mode']) try: if current_config['Mode'] == 'SCAN': self.data_interface.refresh_scan() elif current_config['Mode'] == 'AP': self.data_interface.refresh_ap() else: self.data_interface.refresh_scan() self.twitter_interface.post(message) except Exception: print 'Duplicate Twitter Status' print message else: print 'REFRESH Command Stale, Skipping Refresh...' def mention_is_new(self, last_mention): current_config = self.data_interface.get_hound_mode() if last_mention['created_at'] > current_config['Set Time']: return True else: return False def run(self): loop_count = 1 while True: print 'Starting Sequence {0}:'.format(loop_count) print 'Getting Last Mentions From Twitter...' last_mention = self.twitter_interface.get_last_mention() print 'Last Mention Received: {0}'.format(' '.join(last_mention['text'])) if self.mention_is_new(last_mention): if last_mention['text'][0] != 'REFRESH': print 'Executing Command...' self.parse_and_execute_command(last_mention) else: print 'Last Mention Stale, Not Executing...' print 'Running Sniffer...' results = self.sniffer.execute() if len(results): print 'Posting Sniffer Results...' self.twitter_interface.post_many(results) else: print 'No New Sniffer Results...' print 'Sleeping for {0} Seconds...'.format(SLEEP_INTERVAL) time.sleep(SLEEP_INTERVAL) print '\n\n' loop_count += 1
class SubWindow_analyze(QtWidgets.QMainWindow, Ui_Analyze): def __init__(self): super(SubWindow_analyze, self).__init__() self.setupUi(self) self.sniffer = Sniffer() self.worklog = '' self.summaries = [] self.slm = QtCore.QStringListModel() # 创建mode self.slm.setStringList(self.summaries) # 将数据设置到model self.pkt_list.setModel(self.slm) # 绑定 listView 和 model self.map_idx = [] self.hex1 = '' self.hex2 = '' self.hex1_orig = '' self.hex2_orig = '' self.nameDict = { 'IP.src': IP.src, 'IP.ttl': IP.ttl, 'TCP.sport': TCP.sport, 'TCP.dport': TCP.dport } def go_on_clicked(self): pass def item_on_clicked(self): idx = self.pkt_list.currentIndex().row() # 这个值就是所选的列表值 tmp = self.sniffer.dpkts[idx] self.add_log('Choose {}'.format(tmp.summary())) self.summary.setText(tmp.show(dump=True)) self.edit_in(tmp) def hex_changed(self): try: if self.hex1_orig is not None and self.hex2_orig is not None: hex1_new = self.HexTextEdit.toPlainText() diff = find_diff(self.hex1_orig, hex1_new) print(diff) for i in diff: row = i // 57 col = i % 57 - 9 if 0 <= col <= 47: # print("self.hex1[0]\n" + self.hex1[0]) # print("self.hex1\n" + self.hex1) # print("hex1_new\n" + hex1_new) self.add_log( 'The {} th is changed from {} to {}.'.format( row * 32 + col - col // 3, self.hex1[row * 32 + col - col // 3], hex1_new[i])) self.hex1 = list(self.hex1) self.hex1[row * 32 + col - col // 3 - 1] = hex1_new[i] self.hex1 = ''.join(self.hex1) # pkt_new = import_hexcap(self.hex1+' '+self.hex2) # print('pkt_new:', pkt_new) # pkt_new.show() # idx = self.pkt_list.currentIndex().row() # 这个值就是所选的列表值 # print(hexdump(self.sniffer.dpkts[idx])) # print(hexdump(pkt_new)) # self.sniffer.dpkts[idx] = pkt_new except: print(len(self.hex1_orig), len(self.HexTextEdit.toPlainText())) return None def ascii_changed(self): print('ascii_changed') # chr(int("0x53", 16)) def save_on_clicked(self): self.sniffer.save() def recover_on_clicked(self): pass def send_on_clicked(self): pass def quick_modify_on_clicked(self): tmp = list(self.nameDict.keys()) res, flag = QMDialog.getResult(l=tmp) print('res=', res) print(str(self.sniffer.dpkts)) if flag: for r in res: if len(r) == 2: # self.sniffer.dpkts.replace(self.nameDict[r[0]], r[1]) if r[0] == 1: self.sniffer.dpkts = self.sniffer.dpkts.replace( self.nameDict[list(self.nameDict)[r[0]]], int(r[1])) else: self.sniffer.dpkts = self.sniffer.dpkts.replace( self.nameDict[list(self.nameDict)[r[0]]], r[1]) elif len(r) == 3: self.sniffer.dpkts = self.sniffer.dpkts.replace( self.nameDict[list(self.nameDict)[r[0]]], int(r[1]), int(r[2])) self.add_log('New dpkts Reload Done!') self.summaries = [] for dpkt in self.sniffer.dpkts: summary = dpkt.summary() self.summaries.append(summary) self.slm.setStringList(self.summaries) # 将数据设置到model def open_triggered(self): fname = QtWidgets.QFileDialog.getOpenFileName(self, 'open file', r'./pcap/') self.clear() f = self.filter_input.text() if fname[0]: try: print(fname) self.sniffer.load(fname[0], filter=f) self.add_log('Load {} Done!'.format(fname[0])) for dpkt in self.sniffer.dpkts: summary = dpkt.summary() self.summaries.append(summary) self.slm.setStringList(self.summaries) # 将数据设置到model except: self.workbench.setText("打开文件失败,可能是文件发生错误") def save_triggered(self): self.sniffer.save() def add_log(self, str): self.worklog = self.worklog + str + '\n\n' self.workbench.setText(self.worklog) row = self.workbench.height() - self.scrollArea_2.verticalScrollBar( ).height() + 200 self.scrollArea_2.verticalScrollBar().setValue(row) def clear(self): self.summaries = [] self.slm.setStringList(self.summaries) # 将数据设置到model self.summary.setText('') self.HexTextEdit.clear() self.AsciiTextEdit.clear() def edit_in(self, dpk): hex1, hex2 = hexstr(dpk).split(' ')[0:2] hex1_list = list(hex1) self.hex1 = hex1 self.hex2 = hex2 idx = 0 cnt = 0 for i in range(int(len(hex1) / 48) + 1): if cnt == 0: str_tmp = list('\n0000' + ' ') elif 0 < cnt < 100: str_tmp = list('\n00' + str(cnt) + ' ') elif 100 <= cnt < 1000: str_tmp = list('\n0' + str(cnt) + ' ') else: str_tmp = list('\n' + str(cnt) + ' ') for j in str_tmp: hex1_list.insert(idx, j) idx += 1 idx += 48 cnt += 10 hex1 = ''.join(hex1_list) self.hex1_orig = hex1 self.HexTextEdit.setPlainText(hex1) hex2_list = list("" + hex2) idx = 0 for i in range(int(len(hex2) / 16) + 1): hex2_list.insert(idx, '\n') idx += 17 hex2 = ' '.join(hex2_list) self.hex2_orig = hex2 self.AsciiTextEdit.setPlainText(hex2)
def main(args): sys.path.append(args.sniffer) from Sniffer import Sniffer # pylint: disable=import-error sniffer = Sniffer(concatMode=False) mage = Mage(sniffer.protocol, args.debug) sniffer.run(mage.handle, whitelist=mage.getWhitelist())
class Monitor(QtWidgets.QDialog, Ui_Monitor): update_signal = QtCore.pyqtSignal(str) max_num = 60 graph_signal = QtCore.pyqtSignal() def __init__(self, string=''): super(Monitor, self).__init__() self.setupUi(self) self.name = string self.update_signal.connect(self.counter) self.update_signal.connect(self.myupdate) self.interval = int(time.time()) self.series_ = [0] * self.max_num self.start = self.interval - self.max_num self.graphicsView.chart().setTitle('网络流量') self.graphicsView.setRenderHint(QPainter.Antialiasing) import psutil info = psutil.net_if_addrs() for k, _ in info.items(): self.comboBox.addItem(k) self.t = time.time() self.thread = threading.Thread(target=self.backRun) self.thread.setDaemon(True) self.thread.start() def myupdate(self): if time.time() - self.t > 0.5: self.graphicsView.chart().removeAllSeries() self.graphicsView.chart().setTitle("网络流量速率") series = QLineSeries(self.graphicsView.chart()) series.setName('{}'.format(self.name)) max = 0 min = 100000 for t_, cnt_ in zip( (i for i in range(self.start, self.start + self.max_num)), self.series_): if cnt_ > max: max = cnt_ if cnt_ < min: min = cnt_ series.append(t_, cnt_) self.graphicsView.chart().addSeries(series) self.graphicsView.chart().createDefaultAxes() self.t = time.time() def counter(self, string): t = time.time() if self.interval <= t < self.interval + 1: self.series_[-1] += 1 else: n = int(t - self.interval) while n: self.series_.pop(0) self.start += 1 self.series_.append(0) if self.interval <= t < self.interval + 1: self.series_[-1] += 1 n -= 1 self.interval += 1 self.interval = int(t) # print(self.series_) def backRun(self): try: iface = self.comboBox.currentText() filter = self.lineEdit.text() self.sniffer = Sniffer(iface=iface, filter=filter, prn=self.update_signal) self.sniffer.run() except: pass def iface_changed(self): pass def filter_changed(self): pass def start_on_clicked(self): stop_thread(self.thread) self.clear() self.thread = threading.Thread(target=self.backRun) self.thread.setDaemon(True) self.thread.start() def clear_on_clicked(self): pass def clear(self): self.interval = int(time.time()) self.series_ = [0] * self.max_num self.start = self.interval - self.max_num def closeEvent(self, event): try: stop_thread(self.thread) except: pass self.close()
class SubWindow_capture(QtWidgets.QMainWindow, Ui_Capture): signal = QtCore.pyqtSignal() update_signal = QtCore.pyqtSignal(str) time_signal = QtCore.pyqtSignal(str) update_frame = QtCore.pyqtSignal() def __init__(self): super(SubWindow_capture, self).__init__() self.setupUi(self) self.summaries = [] self.slm = QtCore.QStringListModel() # 创建mode self.slm.setStringList(self.summaries) # 将数据设置到model self.pkt_list.setModel(self.slm) # 绑定 listView 和 model self.pushButton_8.setVisible(False) self.zoomscale = 1.0 self.scene = QtWidgets.QGraphicsScene() # 创建场景 self.graphicsView.setScene(self.scene) # 将场景添加至视图 self.comboBox.addItems(['不进行整流', 'IPSession', 'TCPSession']) self.signal.connect(self.show_sessions) self.update_signal.connect(self.myupdate) self.time_signal.connect(self.update_time) self.update_frame.connect(self.add_pic) self.thread = None import psutil info = psutil.net_if_addrs() for k, _ in info.items(): self.iface.addItem(k) thread = threading.Thread(target=self.timer, args=(self.time_signal, )) thread.setDaemon(True) thread.start() self.feedback.setText('Ready to sniff.') self.feedback.setStyleSheet(''' border:none; font-size:16px; font-weight:700; font-family: "Helvetica Neue", Helvetica, Arial; color:green; ''') self.feedback_2.setStyleSheet(''' border:none; font-size:16px; font-weight:700; font-family: "Helvetica Neue", Helvetica, Arial; color:blue; ''') self.output.setStyleSheet(''' border:none; font-size:16px; font-weight:700; font-family: "Helvetica Neue", Helvetica, Arial; color:gray; ''') self.pushButton.setStyleSheet(''' QPushButton{ border:none; font-size:16px; font-weight:bold; } ''') self.pushButton_9.setStyleSheet(''' QPushButton{ border:none; font-size:16px; color:red; font-weight:bold; } ''') self.pushButton_6.setStyleSheet(''' QPushButton{ border:none; border-radius:10px; font-size:16px; color:green; padding-left:5px; padding-right:10px; text-align:hcenter; background:LightBlue; } QPushButton:hover{ color:black; border:1px solid #F3F3F5; border-radius:10px; background:LightGray; } ''') self.pushButton_7.setStyleSheet(''' QPushButton{ border:none; border-radius:10px; font-size:16px; color:green; padding-left:5px; padding-right:10px; text-align:hcenter; background:LightBlue; } QPushButton:hover{ color:black; border:1px solid #F3F3F5; border-radius:10px; background:LightGray; } ''') self.pushButton_8.setStyleSheet(''' QPushButton{ border:none; border-radius:10px; font-size:16px; color:green; padding-left:5px; padding-right:10px; text-align:hcenter; background:LightBlue; } QPushButton:hover{ color:black; border:1px solid #F3F3F5; border-radius:10px; background:LightGray; } ''') self.pushButton_4.setStyleSheet(''' QPushButton{ border:none; border-radius:10px; font-size:16px; padding-left:5px; padding-right:10px; text-align:hcenter; background:LightGreen; } QPushButton:hover{ color:black; border:1px solid #F3F3F5; border-radius:10px; background:LightGray; } ''') self.pushButton_5.setStyleSheet(''' QPushButton{ border:none; border-radius:10px; font-size:16px; padding-left:5px; padding-right:10px; text-align:hcenter; background:LightGreen; } QPushButton:hover{ color:black; border:1px solid #F3F3F5; border-radius:10px; background:LightGray; } ''') self._last_update = time.time() self._back_status = False self.cnt = [0, 0, 0, 0] def myupdate(self, string): # self.summaries.append(string) # old_method # t = time.time() # if self.init_once: # self._last_update = t # self.init_once = False # self.slm.setStringList(self.summaries) # 将数据设置到model # self.dpkts = PacketList(self.sniffer.dpkt_list) # output = str(self.dpkts) + '\nExtract sessions from packets: ' + str( # len(self.dpkts.sessions().keys())) + '.' # self.output.setText(output) # elif t - self._last_update >= 0.5: # self._last_update = t # self.slm.setStringList(self.summaries) # 将数据设置到model # self.dpkts = self.dpkts + PacketList([self.sniffer.packet]) # self.dpkts.listname = 'PacketList' # output = str(self.dpkts) + '\nExtract sessions from packets: ' + str( # len(self.dpkts.sessions().keys())) + '.' # self.output.setText(output) # self.slm.setStringList(self.summaries) # 将数据设置到model t = time.time() if t - self._last_update >= 0.5: self._last_update = t for str in self.summaries: count = self.slm.rowCount() self.slm.insertRow(count) index = self.slm.index(count, 0) self.slm.setData(index, str, QtCore.Qt.DisplayRole) self.summaries.clear() else: self.summaries.append(string) if 'TCP' in string: self.cnt[0] += 1 elif 'ICMP' in string: self.cnt[1] += 1 elif 'UDP' in string: self.cnt[2] += 1 else: self.cnt[3] += 1 output = 'PacketList: <TCP: {}, ICMP: {}, UDP: {}, Other: {}>'.format( self.cnt[0], self.cnt[1], self.cnt[2], self.cnt[3]) self.output.setText(output) def backRun(self, signal): try: self._back_status = True # iface = self.iface.text() # if iface == '': # iface = 'en0' iface = self.iface.currentText() filter = self.filter.text() # session = self.session.text() session = self.comboBox.currentIndex() if session == 0: session = '' elif session == 1: session = 'IPSession' elif session == 2: session = 'TCPSession' else: session = '' count = 0 if self.count.text() == '' else eval(self.count.text()) if self.timeout.text() == '': timeout = None else: timeout = eval(self.timeout.text()) password = self.password.text() self.sniffer = Sniffer(iface=iface, filter=filter, session=session, count=count, timeout=timeout, prn=self.update_signal) self.sniffer.run() output = str(self.sniffer.dpkts ) + '\nExtract sessions from packets: ' + str( len(self.sniffer.dpkts.sessions().keys())) + '.' for dpkt in self.sniffer.dpkts: summary = dpkt.summary() self.summaries.append(summary) self.slm.setStringList(self.summaries) # 将数据设置到model self.output.setText(output) try: os.remove('tmp/test.jpg') except: pass self.sniffer.draw() self.feedback.setText("Sniff done.") # opencv图像 # pix = QPixmap.fromImage(frame) # self.item = QGraphicsPixmapItem(pix) # 创建像素图元 # # self.item.setScale(self.zoomscale) # self.scene = QGraphicsScene() # 创建场景 # self.scene.addItem(self.item) # self.picshow.setScene(self.scene) # 将场景添加至视图 self.update_frame.emit() self._back_status = False signal.emit() except: pass def timer(self, signal): t_ = time.time() while True: t = time.time() if t - t_ >= 1: t_ = t signal.emit(TimeStamp2Time(t)) def update_time(self, string): self.feedback_2.setText(string) def start_on_clicked(self): self.go.setVisible(False) self.summaries = [] self.slm.setStringList(self.summaries) # 将数据设置到model self.cnt = [0, 0, 0, 0] self.output.clear() self.feedback.setText("Begin to sniff........Please wait.") self.thread = threading.Thread(target=self.backRun, args=(self.signal, )) self.thread.setDaemon(True) self.thread.start() def zoom_in_on_clicked(self): self.zoomscale = self.zoomscale + 0.05 self.QGP_item.setScale(self.zoomscale) def zoom_out_on_clicked(self): self.zoomscale = self.zoomscale - 0.05 if self.zoomscale <= 0: self.zoomscale = 0.2 self.QGP_item.setScale(self.zoomscale) def save_pcap_on_clicked(self): self.sniffer.save() def save_graph_on_clicked(self): copy_file() def add_pic(self): pix = QPixmap('./tmp/test.jpg') self.QGP_item = QtWidgets.QGraphicsPixmapItem(pix) # 创建像素图元 self.scene.clear() self.scene.addItem(self.QGP_item) def text_changed(self): # 没有语法检查器,所以不实现自动检测输入变化 pass def pkts_double_clicked(self): if not self._back_status: idx = self.pkt_list.currentIndex().row() # 这个值就是所选的列表值 tmp = self.sniffer.dpkts[idx] dialog = DetailDialog(tmp) dialog.exec() else: idx = self.pkt_list.currentIndex().row() # 这个值就是所选的列表值 tmp = self.sniffer.dpkt_list[idx] dialog = DetailDialog(tmp) dialog.exec() def show_sessions(self): try: dialog = ListDialog(self.sniffer.dpkts) dialog.exec() except: pass def KWsearch(self): # print('IPrefractor') # try: # try: # os.remove('tmp/reserved.pcap') # except: # pass # wrpcap('tmp/reserved.pcap', self.sniffer.dpkts) # self.dpkts = sniff(offline='tmp/reserved.pcap', session=IPSession, # filter=None if self.filter.text() == '' else self.filter.text()) # output = str(self.sniffer.dpkts) + '\nExtract sessions from packets: ' + str( # len(self.sniffer.dpkts.sessions().keys())) + '.' # for dpkt in self.sniffer.dpkts: # summary = dpkt.summary() # self.summaries.append(summary) # self.slm.setStringList(self.summaries) # 将数据设置到model # self.output.setText(output) # try: # os.remove('tmp/test.jpg') # except: # pass # self.sniffer.draw() # self.feedback.setText("Sniff done.") # pix = QPixmap('./tmp/test.jpg') # self.QGP_item = QtWidgets.QGraphicsPixmapItem(pix) # 创建像素图元 # self.scene.clear() # self.scene.addItem(self.QGP_item) # # self.signal.emit() # except: # pass try: dialog = KWFListDialog(self.sniffer.dpkts) dialog.exec() except: pass def tcp_refractor(self): print('TCPrefractor') try: try: os.remove('tmp/reserved.pcap') except: pass wrpcap('tmp/reserved.pcap', self.sniffer.dpkts) self.dpkts = sniff(offline='tmp/reserved.pcap', session=TCPSession, filter=None if self.filter.text() == '' else self.filter.text()) output = str(self.sniffer.dpkts ) + '\nExtract sessions from packets: ' + str( len(self.sniffer.dpkts.sessions().keys())) + '.' for dpkt in self.sniffer.dpkts: summary = dpkt.summary() self.summaries.append(summary) self.slm.setStringList(self.summaries) # 将数据设置到model self.output.setText(output) try: os.remove('tmp/test.jpg') except: pass self.sniffer.draw() self.feedback.setText("Sniff done.") pix = QPixmap('./tmp/test.jpg') self.QGP_item = QtWidgets.QGraphicsPixmapItem(pix) # 创建像素图元 self.scene.clear() self.scene.addItem(self.QGP_item) self.signal.emit() except: print('TCP failed') def stop_backrun(self): try: stop_thread(self.thread) except: pass def closeEvent(self, event): try: stop_thread(self.thread) except: pass self.close()
class HoundDaemon(): def __init__(self, *args, **kwargs): self.data_interface = DataInterface() self.twitter_interface = TwitterInterface(self.data_interface) self.sniffer = Sniffer(self.data_interface) def parse_and_execute_command(self, last_mention): command = last_mention['text'] if command[0] == 'SET_MODE': current_config = self.data_interface.get_hound_mode() try: if command[1] == 'SCAN': if current_config['Mode'] == 'SCAN': return else: self.data_interface.set_hound_mode(command[1]) self.twitter_interface.post( 'Mode Successfully Set: SCAN') return elif command[1] == current_config['Mode'] and command[ 2] == current_config['Args']: print 'No Change In New Command' return else: self.data_interface.set_hound_mode(command[1], command[2]) self.twitter_interface.post( 'Mode Successfully Set: {0}, {1}'.format( command[1], command[2])) except Exception: print 'Duplicate Twitter Status' print 'Mode Successfully Set: {0}, {1}'.format( command[1], command[2]) elif command[0] == 'REFRESH': if last_mention['created_at'] > datetime.utcnow() - timedelta( 0, SLEEP_INTERVAL): current_config = self.data_interface.get_hound_mode() message = '{0} Refresh Complete'.format(current_config['Mode']) try: if current_config['Mode'] == 'SCAN': self.data_interface.refresh_scan() elif current_config['Mode'] == 'AP': self.data_interface.refresh_ap() else: self.data_interface.refresh_scan() self.twitter_interface.post(message) except Exception: print 'Duplicate Twitter Status' print message else: print 'REFRESH Command Stale, Skipping Refresh...' def mention_is_new(self, last_mention): current_config = self.data_interface.get_hound_mode() if last_mention['created_at'] > current_config['Set Time']: return True else: return False def run(self): loop_count = 1 while True: print 'Starting Sequence {0}:'.format(loop_count) print 'Getting Last Mentions From Twitter...' last_mention = self.twitter_interface.get_last_mention() print 'Last Mention Received: {0}'.format(' '.join( last_mention['text'])) if self.mention_is_new(last_mention): if last_mention['text'][0] != 'REFRESH': print 'Executing Command...' self.parse_and_execute_command(last_mention) else: print 'Last Mention Stale, Not Executing...' print 'Running Sniffer...' results = self.sniffer.execute() if len(results): print 'Posting Sniffer Results...' self.twitter_interface.post_many(results) else: print 'No New Sniffer Results...' print 'Sleeping for {0} Seconds...'.format(SLEEP_INTERVAL) time.sleep(SLEEP_INTERVAL) print '\n\n' loop_count += 1
def __init__(self, *args, **kwargs): self.data_interface = DataInterface() self.twitter_interface = TwitterInterface(self.data_interface) self.sniffer = Sniffer(self.data_interface)
class MainWindow(QMainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) # self.ui.actionInterval.triggered.connect(self.onCaptureInterval) self.ui.actionStart.triggered.connect(self.onCaptureStart) self.ui.actionStop.triggered.connect(self.onCaptureStop) self.ui.actionReset.triggered.connect(self.onResetCapture) self.ui.actionQuit.triggered.connect(self.close) # self.arpPackets = list() self.ethPackets = list() # self.arpEntropies = list() self.ethEntropies = list() # self.sniffer = Sniffer() self.sniffer.packetCaptured.connect(self.onPacketCaptured) self.sniffer.timeout.connect(self.onSniffTimeout) self.thread = QThread() self.sniffer.moveToThread(self.thread) self.thread.started.connect(self.sniffer.sniff) self.sniffer.finished.connect(self.thread.quit) self.sniffer.finished.connect(self.onCaptureStop) # self.packets = 0 # self.maxArpEntropy = [0, -1] self.maxEthEntropy = [0, -1] # self.ethEntropyThread = QThread() self.ethEntropy = EtherEntropy() self.ethEntropyThread.started.connect(self.ethEntropy.entropy) self.ethEntropy.resultReady.connect(self.onEthEntropyReady) self.ethEntropy.resultReady.connect(self.ethEntropyThread.quit) # self.arpEntropyThread = QThread() self.arpEntropy = ArpEntropy() self.arpEntropyThread.started.connect(self.arpEntropy.entropy) self.arpEntropy.resultReady.connect(self.onArpEntropyReady) self.arpEntropy.resultReady.connect(self.arpEntropyThread.quit) # self.timer = QTimer(self) self.timer.timeout.connect(self.onCountDown) self.timer.start(ONE_SECOND) # self.entropyTimer = QTimer(self) self.entropyTimer.timeout.connect(self.updateEntropy) # self.timer2 = QTimer(self) self.timer2.timeout.connect(self.updateStatics) self.timer2.start(MILLIS_200) # self.ui.actionSaveCapture.triggered.connect(self.saveCapture) self.ui.actionSaveEntropy.triggered.connect(self.saveEntropy) # self.ui.statusbar.showMessage("Ready") # self.ui.progressBar.hide() def onSniffTimeout(self): self.ui.progressBar.hide() msg = QMessageBox(self) msg.setText("Capture Done!") msg.setWindowTitle("Sniffer") msg.exec_() def saveCapture(self): fileName = QFileDialog.getSaveFileName(self, "Save Capture", QDir.homePath(), "Text File (*.txt)") fileName = fileName[0] if fileName != "": fle = open(fileName, 'w+') for packet in self.ethPackets: hwsrc = packet[Ether].src hwdst = packet[Ether].dst etype = str(packet[Ether].type) # eth macfuente macdestino tipo line = '{} {} {} {}\n'.format('eth', hwsrc, hwdst, etype) fle.write(line) for packet in self.arpPackets: psrc = packet[ARP].psrc pdst = packet[ARP].pdst hwsrc = packet[ARP].hwsrc hwdst = packet[ARP].hwdst operation = str(packet[ARP].op) # arp ipfuente ipdestino macfuente macdestino operacion(request/reply) line = '{} {} {} {} {} {}\n'.format('arp', psrc, pdst, hwsrc, hwdst, operation) fle.write(line) fle.close() def saveEntropy(self): fileName = QFileDialog.getSaveFileName(self, "Save Entropy", QDir.homePath(), "Text File (*.txt)") fileName = fileName[0] if fileName != "": fle = open(fileName, 'w+') min = len(self.ethEntropies) if len(self.ethEntropies) < len(self.arpEntropies) else len(self.ethEntropies) for i in range(min): line = '{} {} {}\n'.format(i, self.ethEntropies[i], self.arpEntropies[i]) fle.write(line) fle.close() def X(self): # top 10 ip replies, por logica si una ip manda muchas replies es que tiene muchas request por lo que es muy solicitada, un server? # de esa forma podemos destacar ip replies pass def calcEthernetEntropy(self): #self.ethEntropy.addAll(self.ethPackets) self.ethEntropyThread.start() def onEthEntropyReady(self, ans): self.ui.ethEntropyLabel.setText('Ethernet: {:.4f}'.format(ans)) if self.maxEthEntropy[1] < ans: now = datetime.strftime(datetime.now(), '%H:%M:%S') #%Y-%m-%d %H:%M:%S self.maxEthEntropy = [ now, ans ] self.ui.maxEthEntropyLabel.setText( 'Max: {:.4f} ({})'.format( self.maxEthEntropy[1], self.maxEthEntropy[0])) self.ethEntropies.append(ans) def onArpEntropyReady(self, ans): self.ui.arpEntropyLabel.setText('ARP: {:.4f}'.format(ans)) if self.maxArpEntropy[1] < ans: now = datetime.strftime(datetime.now(), '%H:%M:%S') self.maxArpEntropy = [ now, ans ] self.ui.maxArpEntropyLabel.setText( 'Max: {:.4f} ({})'.format( self.maxArpEntropy[1], self.maxArpEntropy[0])) self.arpEntropies.append(ans) def calcArpEntropy(self): #self.arpEntropy.addAll(self.arpPackets) self.arpEntropyThread.start() def updateEntropy(self): self.calcArpEntropy() self.calcEthernetEntropy() def updateStatics(self): self.ui.packetsLabel.setText('Packets: {:d}'.format(self.packets)) self.ui.ethPacketsLabel.setText('Ethernet Packets: {:d}'.format(len(self.ethPackets))) self.ui.arpPacketsLabel.setText('ARP Packets: {:d}'.format(len(self.arpPackets))) def onPacketCaptured(self, packet): self.packets += 1 if Ether in packet: self.processEthernetPacket(packet) if ARP in packet: self.processArpPacket(packet) def onCaptureInterval(self): minutes, ok = QInputDialog.getInt(self, "Capture", "Minutes") if ok: seconds = minutes * 60 self.sniffer.setTimeout(seconds) self.onCaptureStart() self.ui.progressBar.show() self.ui.progressBar.setRange(0, seconds) self.ui.progressBar.setValue(0) def onCountDown(self): value = self.ui.progressBar.value() max = self.ui.progressBar.maximum() if value < max: self.ui.progressBar.setValue(value + 1) def onCaptureStart(self): self.ui.actionInterval.setEnabled(False) self.ui.actionStart.setEnabled(False) self.ui.actionStop.setEnabled(True) self.thread.start() self.entropyTimer.start(ONE_SECOND) def onCaptureStop(self): self.ui.actionInterval.setEnabled(True) self.ui.actionStart.setEnabled(True) self.ui.actionStop.setEnabled(False) self.entropyTimer.stop() self.sniffer.stop() def onResetCapture(self): self.packets = 0 self.ethPackets = list() self.arpPackets = list() self.arpEntropy.clean() self.ethEntropy.clean() self.maxArpEntropy = [0, -1] self.maxEthEntropy = [0, -1] self.updateStatics() def processEthernetPacket(self, packet): self.ethPackets.append(packet) # Por ahora solo guardo el paquete self.ethEntropy.add(packet) def processArpPacket(self, packet): self.arpPackets.append(packet) # Por ahora solo guardo el paquete self.arpEntropy.add(packet)
filterStr = "" if args.channel != None: #os.system("systemctl stop networking") os.system("ifconfig %s down" % (args.interface)) os.system("iw dev %s set channel %d" % (args.interface, int(args.channel))) os.system("ifconfig %s up" % (args.interface)) if args.bssid != None: bssid = args.bssid if args.interface != None: interface = args.interface sniffer = Sniffer() # channel_set = False # if args.channel != None: # p = Process(target = channel_hopper(args.channel)) # channel_set = True print("-=-=-=-=-=-= cinnamon.py =-=-=-=-=-=-") print("CH ENC BSSID SSID") #if channel_set == False: # p = Process(target = channel_hopper(None)) # p.start() signal.signal(signal.SIGINT, signal_handler) if bssid != None: sniff(lfilter=filterFunc, iface=args.interface,
class HoundDaemon(Daemon): def __init__(self, *args, **kwargs): super(HoundDaemon, self).__init__(*args, **kwargs) self.data_interface = DataInterface() self.twitter_interface = TwitterInterface(self.data_interface) self.sniffer = Sniffer(self.data_interface) def parse_and_execute_command(self, last_mention): command = last_mention['text'] if command[0] == 'SET_MODE': current_config = self.data_interface.get_hound_mode() try: if command[1] == 'SCAN': if current_config['Mode'] == 'SCAN': return else: self.data_interface.set_hound_mode(command[1]) self.twitter_interface.post('Mode Successfully Set: SCAN') return elif command[1] == current_config['Mode'] and command[2] == current_config['Args']: print 'No Change In New Command' return else: self.data_interface.set_hound_mode(command[1], command[2]) self.twitter_interface.post('Mode Successfully Set: {0}, {1}'.format(command[1], command[2])) except Exception: print 'Duplicate Twitter Status' elif command[0] == 'REFRESH': if last_mention['created_at'] > datetime.utcnow() - timedelta(0,SLEEP_INTERVAL): current_config = self.data_interface.get_hound_mode() try: if current_config['Mode'] == 'SCAN': self.data_interface.refresh_scan() self.twitter_interface.post('SCAN Refresh Complete') elif current_config['Mode'] == 'AP': self.data_interface.refresh_ap() self.twitter_interface.post('AP Refresh Complete') else: self.data_interface.refresh_scan() self.twitter_interface.post('MAC Refresh Complete') except Exception: print 'Duplicate Twitter Status' def mention_is_new(self, last_mention): current_config = self.data_interface.get_hound_mode() if last_mention['created_at'] > current_config['Set Time']: return True else: return False def run(self): while True: last_mention = self.twitter_interface.get_last_mention() if self.mention_is_new(last_mention): self.parse_and_execute_command(last_mention) results = self.sniffer.execute() if len(results): self.twitter_interface.post_many(results) time.sleep(SLEEP_INTERVAL)
async def activate(self, updateSniffer=False, updateOpenPorts=False, user="", task_status=trio.TASK_STATUS_IGNORED, send_channel=None, receive_channel=None): """ Start a thread that does the following - for each port in the config file - connects to the database - runs sniffer class Returns: 0 if no changes 1 if only Sniffer changed 2 if only sockets changed 3 if both changed """ # Gets the info from config file initially conf = self.getConfigData() # Return code retCode = 0 # Setup way to cancel these tasks with trio.CancelScope() as scope: # --- Start Async Sniffer ---# if self.sniffer is None: # TODO: Switch config="testing" to "base" when in production self.sniffer = Sniffer(config=conf, mode="base", databaser=self.db, send_channel=send_channel) self.sniffer.start() elif updateSniffer: oldHash = self.sniffer.currentHash self.sniffer.configUpdate(conf) if not self.sniffer.currentHash == oldHash: retCode = 1 # Mark trio task as started (and pass cancel scope back to nursery) task_status.started(scope) udp_services = self.config.udp_services tcp_services = self.config.tcp_services # Convience method to help with setting up TCP & UDP modules async def replay_server(sockets, protocol, nursery): print("Testing", protocol) print(str(sockets)) try: for service in sockets: port = service.port print("Port", port) self.processList[port] = Listener( port, service, protocol, self.config.response_delay, nursery, ) nursery.start_soon(self.processList[port].handler) except Exception as ex: print("Replay_server exception", str(ex)) print("UDP", udp_services) print("TCP", tcp_services) # --- Actually Start up listeners --- # try: async with trio.open_nursery() as nursery: nursery.start_soon(replay_server, udp_services, "UDP", nursery) nursery.start_soon(replay_server, tcp_services, "TCP", nursery) except Exception as ex: print("listener nursery exception: ", str(ex)) finally: print("Listeners have been killed") # return the code here; # 0 means no changes, # 1 means only sniffer changed, # 2 means only TCP ports were changed, # 3 means both were changed if retCode == 1: self.db.saveAlertObject( Alert( variant="admin", message="Sniffer updated during runtime by " + user, )) elif retCode == 2: self.db.saveAlertObject( Alert( variant="admin", message="TCP sockets updated during runtime by " + user, )) elif retCode == 3: self.db.saveAlertObject( Alert( variant="admin", message= "TCP sockets and Sniffer updated during runtime by " + user, )) elif retCode == 0: self.db.saveAlertObject( Alert( variant="admin", message= "Attempted configuration change during runtime by " + user, )) return retCode
from Sniffer import Sniffer from Analyzer import Analyzer if __name__ == "__main__": target_ip = str(input("Enter the target IP >> ")) filename = "capture_demo.pcap" sniffer = Sniffer(target_ip, filename) sniffer.sniff_packets(10000) analyzer = Analyzer() analyzer.parse_pcap_file(filename) analyzer.print_visited_websites() analyzer.print_credentials() analyzer.print_target_info()
class PortThreadManager: """ Initialize and control the sniffer, modules, database connection, and configtunnel """ def __init__(self): self.portList = [] # self.ip = str(get("https://api.ipify.org").text) self.processList = dict() # where the async sniffer will be kept self.sniffer = None # delay specified by config file self.response_delay = None # whitelist of ports self.portWhitelist = None # whitelist of IPs self.whitelist = None # used to tell it to quit # self.keepRunning = True # port for ConfigTunnel self.confport = None # certfile for ConfigTunnel self.confcert = None # list containing socket responses self.responseData = None # database interface object self.db = Databaser() def getConfigTunnelData(self): """ Retrieve config data just for the configtunnel TODO: decide if configtunnel is still necessary/used """ conf = self.db.getConfig() # Configtunnel config options self.confport = conf["configtunnel"]["port"] self.confcert = conf["configtunnel"]["cert_file"] def getConfigData(self): """ Gets config information ran when PortThreadManager configuration changes """ conf = self.db.getConfig() # A bunch of config options self.HONEY_IP = conf["ip_addresses"]["honeypotIP"] self.MGMT_IPs = conf["ip_addresses"]["managementIPs"] self.response_delay = float(conf["attributes"]["response_delay"]) self.port_scan_window = int(conf["attributes"]["port_scan_window"]) self.port_scan_sensitivity = int(conf["attributes"]["port_scan_sensitivity"]) self.whitelist = conf["allowlist"]["addresses"] self.portWhitelist = conf["allowlist"]["ports"] self.responseData = conf["response_config"] async def activate( self, updateSniffer=False, updateOpenPorts=False, user="", task_status=trio.TASK_STATUS_IGNORED, ): """ Start a thread that does the following - for each port in the config file - connects to the database - runs sniffer class Returns: 0 if no changes 1 if only Sniffer changed 2 if only sockets changed 3 if both changed """ # Gets the info from config file initially self.getConfigData() # Return code retCode = 0 # Convience reference replayPorts = self.responseData.keys() # Setup way to cancel these tasks with trio.CancelScope() as scope: # --- Start Async Sniffer ---# if self.sniffer is None: # TODO: Switch config="testing" to "base" when in production self.sniffer = Sniffer( config="base", openPorts=list(replayPorts), whitelist=self.whitelist, portWhitelist=self.portWhitelist, honeypotIP=self.HONEY_IP, managementIPs=self.MGMT_IPs, port_scan_window=self.port_scan_window, port_scan_sensitivity=self.port_scan_sensitivity, databaser=self.db, ) self.sniffer.start() elif updateSniffer: oldHash = self.sniffer.currentHash self.sniffer.configUpdate( openPorts=list(replayPorts), whitelist=self.whitelist, portWhitelist=self.portWhitelist, honeypotIP=self.HONEY_IP, managementIPs=self.MGMT_IPs, port_scan_window=self.port_scan_window, port_scan_sensitivity=self.port_scan_sensitivity, ) if not self.sniffer.currentHash == oldHash: retCode = 1 # Mark trio task as started (and pass cancel scope back to nursery) task_status.started(scope) # --- Open async UDP & TCP Sockets ---# udp_sockets = list( filter(lambda x: "UDP" in self.responseData[x].keys(), replayPorts) ) tcp_sockets = list( filter(lambda x: "TCP" in self.responseData[x].keys(), replayPorts) ) # Convience method to help with setting up TCP & UDP modules async def replay_server(listener_class, sockets, config_path, nursery): for port in sockets: self.processList[port] = listener_class( port, self.responseData[port][config_path], self.response_delay, nursery, ) nursery.start_soon(self.processList[port].handler) # --- Actually Start up listeners ---# try: async with trio.open_nursery() as nursery: nursery.start_soon( replay_server, UDPPortListener, udp_sockets, "UDP", nursery ) nursery.start_soon( replay_server, TCPPortListener, tcp_sockets, "TCP", nursery ) except Exception as ex: print("listener nursery exception: ", str(ex)) finally: print("Listeners have been killed") # return the code here; # 0 means no changes, # 1 means only sniffer changed, # 2 means only TCP ports were changed, # 3 means both were changed if retCode == 1: self.db.alert( Alert( variant="admin", message="Sniffer updated during runtime by " + user, ) ) elif retCode == 2: self.db.alert( Alert( variant="admin", message="TCP sockets updated during runtime by " + user, ) ) elif retCode == 3: self.db.alert( Alert( variant="admin", message="TCP sockets and Sniffer updated during runtime by " + user, ) ) elif retCode == 0: self.db.alert( Alert( variant="admin", message="Attempted configuration change during runtime by " + user, ) ) return retCode
def __init__(self, parent, *args, **kwargs): tk.Frame.__init__(self, parent, *args, **kwargs) self.parent = parent self.uiMenu = UIMenu(self.parent) self.parent.config(menu=self.uiMenu.menu) # self.toolbar = ttk.Frame(self.parent) # self.toolbarButton1 = ttk.Button(self.toolbar, text='Button') # self.toolbarButton1.pack(side=LEFT, padx=2, pady=2) # self.toolbar.pack(side=TOP, fill=X) self.statusbar = Label(self.parent, text='Ready', bd=1, relief=SUNKEN, anchor=W) self.statusbar.pack(side=BOTTOM, fill=X) self.notebook = ttk.Notebook(self.parent) self.frameSniff = ttk.Frame(self.notebook) self.frameArp = ttk.Frame(self.notebook) self.frameDhcp = ttk.Frame(self.notebook) self.frameSysInfo = ttk.Frame(self.notebook) self.notebook.add(self.frameSniff, text='Sniffer') self.notebook.add(self.frameArp, text='ARP') self.notebook.add(self.frameDhcp, text='DHCP Servers') self.notebook.add(self.frameSysInfo, text='System Info') self.notebook.pack(fill=BOTH) self.sniffLabelFrame = ttk.LabelFrame(self.frameSniff, text="Sniffer") self.sniffLabelFrame.pack(padx=10, pady=10) self.sniffButton = ttk.Button(self.sniffLabelFrame, text="Sniff", command=self.beginSniff) self.sniffButton.pack(side=LEFT) self.stopSniffButton = ttk.Button(self.sniffLabelFrame, text="Stop sniffing", command=self.stopSniff, state="disabled") self.stopSniffButton.pack(side=LEFT) self.sniffTv = ttk.Treeview(self.frameSniff) ysb = ttk.Scrollbar(self, orient='vertical', command=self.sniffTv.yview) xsb = ttk.Scrollbar(self, orient='horizontal', command=self.sniffTv.xview) self.sniffTv.configure(yscroll=ysb.set, xscroll=xsb.set) self.sniffTv['columns'] = ('senderip', 'sendermac', 'received') self.sniffTv.heading('#0', text='Description', anchor='w') self.sniffTv.column('#0', anchor='w') self.sniffTv.heading('senderip', text='Sender IP') self.sniffTv.column('senderip', width=100) self.sniffTv.heading('sendermac', text='Sender MAC') self.sniffTv.column('sendermac', width=100) self.sniffTv.heading('received', text='Received at') self.sniffTv.column('received', width=100) self.sniffTv.pack(fill=BOTH) self.arpLabel = ttk.Label(self.frameArp, text="ARP cache") self.arpLabel.pack() self.arpTv = ttk.Treeview(self.frameArp) self.arpTv['columns'] = ('ip', 'status') self.arpTv.heading('#0', text='MAC address', anchor='w') self.arpTv.column('#0', anchor='w') self.arpTv.heading('ip', text='IP address') self.arpTv.column('ip', width=100) self.arpTv.heading('status', text='Status') self.arpTv.column('status', width=100) self.arpTv.pack(fill=X) self.addDhcpLabelFrame = ttk.LabelFrame(self.frameDhcp, text="Add trusted server") self.addDhcpLabelFrame.pack(padx=10, pady=10) self.addDhcpNameLabel = ttk.Label(self.addDhcpLabelFrame, text="Server name") self.addDhcpNameLabel.pack() self.addDhcpNameEntry = ttk.Entry(self.addDhcpLabelFrame) self.addDhcpNameEntry.pack() self.addDhcpIpLabel = ttk.Label(self.addDhcpLabelFrame, text="Server IP address") self.addDhcpIpLabel.pack() self.addDhcpIpEntry = ttk.Entry(self.addDhcpLabelFrame) self.addDhcpIpEntry.pack() self.addDhcpMacLabel = ttk.Label(self.addDhcpLabelFrame, text="Server Mac address") self.addDhcpMacLabel.pack() self.addDhcpMacEntry = ttk.Entry(self.addDhcpLabelFrame) self.addDhcpMacEntry.pack() self.addDhcpButton = ttk.Button(self.addDhcpLabelFrame, text="Add", command=self.addDhcpButtonPressed) self.addDhcpButton.pack() self.clrDhcpButton = ttk.Button(self.addDhcpLabelFrame, text="Clear", command=self.clrDhcpButtonPressed) self.clrDhcpButton.pack() self.dhcpTv = ttk.Treeview(self.frameDhcp) self.dhcpTv['columns'] = ('ip', 'mac', 'date') self.dhcpTv.heading('#0', text='Server name', anchor='w') self.dhcpTv.column('#0', anchor='w') self.dhcpTv.heading('ip', text='IP address') self.dhcpTv.column('ip', width=100) self.dhcpTv.heading('mac', text='MAC address') self.dhcpTv.column('mac', width=100) self.dhcpTv.heading('date', text='Date added') self.dhcpTv.column('date', width=100) self.dhcpTv.pack(fill=X) strVersion = 'Python ' + platform.python_version() self.versionLabel = ttk.Label(self.frameSysInfo, text=strVersion) self.versionLabel.pack() strPlatform = 'Platform: ' + platform.platform() self.platformLabel = ttk.Label(self.frameSysInfo, text=strPlatform) self.platformLabel.pack() self.dhcpDefender = DhcpDefender(self) self.arpDefender = ArpDefender(self) self.sniffer = Sniffer(1, 'Sniffer-1', 1, self) self.sniffer.start() self.updater = Updater(1, 'Updater-1', 1, self) self.updater.start()
async def activate( self, updateSniffer=False, updateOpenPorts=False, user="", task_status=trio.TASK_STATUS_IGNORED, ): """ Start a thread that does the following - for each port in the config file - connects to the database - runs sniffer class Returns: 0 if no changes 1 if only Sniffer changed 2 if only sockets changed 3 if both changed """ # Gets the info from config file initially self.getConfigData() # Return code retCode = 0 # Convience reference replayPorts = self.responseData.keys() # Setup way to cancel these tasks with trio.CancelScope() as scope: # --- Start Async Sniffer ---# if self.sniffer is None: # TODO: Switch config="testing" to "base" when in production self.sniffer = Sniffer( config="base", openPorts=list(replayPorts), whitelist=self.whitelist, portWhitelist=self.portWhitelist, honeypotIP=self.HONEY_IP, managementIPs=self.MGMT_IPs, port_scan_window=self.port_scan_window, port_scan_sensitivity=self.port_scan_sensitivity, databaser=self.db, ) self.sniffer.start() elif updateSniffer: oldHash = self.sniffer.currentHash self.sniffer.configUpdate( openPorts=list(replayPorts), whitelist=self.whitelist, portWhitelist=self.portWhitelist, honeypotIP=self.HONEY_IP, managementIPs=self.MGMT_IPs, port_scan_window=self.port_scan_window, port_scan_sensitivity=self.port_scan_sensitivity, ) if not self.sniffer.currentHash == oldHash: retCode = 1 # Mark trio task as started (and pass cancel scope back to nursery) task_status.started(scope) # --- Open async UDP & TCP Sockets ---# udp_sockets = list( filter(lambda x: "UDP" in self.responseData[x].keys(), replayPorts) ) tcp_sockets = list( filter(lambda x: "TCP" in self.responseData[x].keys(), replayPorts) ) # Convience method to help with setting up TCP & UDP modules async def replay_server(listener_class, sockets, config_path, nursery): for port in sockets: self.processList[port] = listener_class( port, self.responseData[port][config_path], self.response_delay, nursery, ) nursery.start_soon(self.processList[port].handler) # --- Actually Start up listeners ---# try: async with trio.open_nursery() as nursery: nursery.start_soon( replay_server, UDPPortListener, udp_sockets, "UDP", nursery ) nursery.start_soon( replay_server, TCPPortListener, tcp_sockets, "TCP", nursery ) except Exception as ex: print("listener nursery exception: ", str(ex)) finally: print("Listeners have been killed") # return the code here; # 0 means no changes, # 1 means only sniffer changed, # 2 means only TCP ports were changed, # 3 means both were changed if retCode == 1: self.db.alert( Alert( variant="admin", message="Sniffer updated during runtime by " + user, ) ) elif retCode == 2: self.db.alert( Alert( variant="admin", message="TCP sockets updated during runtime by " + user, ) ) elif retCode == 3: self.db.alert( Alert( variant="admin", message="TCP sockets and Sniffer updated during runtime by " + user, ) ) elif retCode == 0: self.db.alert( Alert( variant="admin", message="Attempted configuration change during runtime by " + user, ) ) return retCode
def __init__(self, *args, **kwargs): super(HoundDaemon, self).__init__(*args, **kwargs) self.data_interface = DataInterface() self.twitter_interface = TwitterInterface(self.data_interface) self.sniffer = Sniffer(self.data_interface)
class HoundDaemon(Daemon): def __init__(self, *args, **kwargs): super(HoundDaemon, self).__init__(*args, **kwargs) self.data_interface = DataInterface() self.twitter_interface = TwitterInterface(self.data_interface) self.sniffer = Sniffer(self.data_interface) def parse_and_execute_command(self, last_mention): command = last_mention['text'] if command[0] == 'SET_MODE': current_config = self.data_interface.get_hound_mode() try: if command[1] == 'SCAN': if current_config['Mode'] == 'SCAN': return else: self.data_interface.set_hound_mode(command[1]) self.twitter_interface.post( 'Mode Successfully Set: SCAN') return elif command[1] == current_config['Mode'] and command[ 2] == current_config['Args']: print 'No Change In New Command' return else: self.data_interface.set_hound_mode(command[1], command[2]) self.twitter_interface.post( 'Mode Successfully Set: {0}, {1}'.format( command[1], command[2])) except Exception: print 'Duplicate Twitter Status' elif command[0] == 'REFRESH': if last_mention['created_at'] > datetime.utcnow() - timedelta( 0, SLEEP_INTERVAL): current_config = self.data_interface.get_hound_mode() try: if current_config['Mode'] == 'SCAN': self.data_interface.refresh_scan() self.twitter_interface.post('SCAN Refresh Complete') elif current_config['Mode'] == 'AP': self.data_interface.refresh_ap() self.twitter_interface.post('AP Refresh Complete') else: self.data_interface.refresh_scan() self.twitter_interface.post('MAC Refresh Complete') except Exception: print 'Duplicate Twitter Status' def mention_is_new(self, last_mention): current_config = self.data_interface.get_hound_mode() if last_mention['created_at'] > current_config['Set Time']: return True else: return False def run(self): while True: last_mention = self.twitter_interface.get_last_mention() if self.mention_is_new(last_mention): self.parse_and_execute_command(last_mention) results = self.sniffer.execute() if len(results): self.twitter_interface.post_many(results) time.sleep(SLEEP_INTERVAL)