commit fb11bd65eb9982f136960f685a7915df7da57811 Author: R Nanda Kumar Date: Wed Dec 8 17:07:48 2021 +0530 Packet Sniffing diff --git a/AUNMS.py b/AUNMS.py new file mode 100644 index 0000000..1ede6ad --- /dev/null +++ b/AUNMS.py @@ -0,0 +1,40 @@ +import sys +from PyQt5.QtGui import * +from PyQt5.QtCore import * +from PyQt5.QtWidgets import * +from scapy.all import * + +from ping import Ping +from trace_route import TraceRoute +from network_monitor import NetworkMonitor + +class AUNMS(QWidget): + def __init__(self): + super().__init__() + + self.setWindowTitle("AU Network Monitor") + self.width = 1600 + self.height = 900 + + self.setMinimumSize(self.width, self.height) + + self.tabwidget = QTabWidget() + self.tabwidget.setStyleSheet('font-size: 12pt') + + self.tabwidget.addTab(NetworkMonitor(), "Network Monitor") + self.tabwidget.addTab(TraceRoute(), "Trace Route") + self.tabwidget.addTab(Ping(), "Ping") + + self.layout = QVBoxLayout() + self.layout.addWidget(self.tabwidget) + + self.setLayout(self.layout) + +def main(): + app = QApplication(sys.argv) + aunms = AUNMS() + aunms.show() + app.exec() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/network_monitor.py b/network_monitor.py new file mode 100644 index 0000000..fcddff2 --- /dev/null +++ b/network_monitor.py @@ -0,0 +1,186 @@ +import sys +from PyQt5.QtGui import * +from PyQt5.QtCore import * +from PyQt5.QtWidgets import * +from network_monitor_thread import NetworkMonitorThread +from scapy.all import * + +class NetworkMonitor(QMainWindow): + def __init__(self): + super().__init__() + self.interfaceSelected = None + + self.layout = QVBoxLayout() + + self._createToolBar() + self._createTable() + self.setLayout(self.layout) + + def _createTable(self): + self.tableWidget = QTableWidget() + self.tableWidget.setTabKeyNavigation(False) + self.tableWidget.setProperty("showDropIndicator", False) + self.tableWidget.setDragDropOverwriteMode(False) + self.tableWidget.setSelectionMode(QAbstractItemView.SingleSelection) + self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows) + self.tableWidget.setShowGrid(False) + self.tableWidget.setGridStyle(Qt.NoPen) + self.tableWidget.setRowCount(0) + self.tableWidget.setColumnCount(7) + self.tableWidget.setHorizontalHeaderLabels(["No", "Time", "Source", "Destination", "Protocol", "Length", "Info"]) + self.tableWidget.horizontalHeader().setVisible(True) + self.tableWidget.horizontalHeader().setCascadingSectionResizes(True) + self.tableWidget.horizontalHeader().setHighlightSections(False) + self.tableWidget.horizontalHeader().setSortIndicatorShown(True) + self.tableWidget.verticalHeader().setVisible(False) + self.tableWidget.setSortingEnabled(True) + self.tableWidget.setEditTriggers(QTableWidget.NoEditTriggers) + + self.tableWidget.horizontalHeader(). setSectionResizeMode(6, QHeaderView.Stretch) + sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.tableWidget.sizePolicy().hasHeightForWidth()) + self.tableWidget.setSizePolicy(sizePolicy) + + self.treeWidget = QTreeWidget() + self.treeWidget.setMinimumSize(QSize(0, 0)) + self.treeWidget.setColumnCount(1) + self.treeWidget.setHeaderHidden(True) + + def _createToolBar(self): + self.toolbar = QToolBar(self) + self.addToolBar(self.toolbar) + + self.toolbar.setStyleSheet('font-size: 9pt') + + self.actionStart = QAction('Start', self) + + self.actionStart.triggered.connect(self.packetSniff) + self.toolbar.addAction(self.actionStart) + + self.toolbar.addSeparator() + + self.actionStop = QAction('Stop', self) + self.toolbar.addAction(self.actionStop) + + self.toolbar.addSeparator() + + self.actionPickInterface = QAction('Choose Interface', self) + self.actionPickInterface.triggered.connect(self.interfaceDialog) + self.toolbar.addAction(self.actionPickInterface) + + self.actionClear = QAction('Clear', self) + self.actionClear.triggered.connect(self.packetClear) + self.toolbar.addAction(self.actionClear) + + self.toolbar.addSeparator() + self.toolbar.addAction("Save") + + def _createDataBox(self): + self.treeWidget = QtGui.QTreeWidget(self.splitter) + self.treeWidget.setMinimumSize(QtCore.QSize(0, 0)) + self.treeWidget.setObjectName(_fromUtf8("treeView")) + self.treeWidget.setColumnCount(1) + self.treeWidget.setHeaderHidden(True) + def packetSniff(self): + if self.interfaceSelected == None: + self.interfaceDialog() + + print(f"Monitoring - {self.interfaceSelected}") + + self.actionStart.setEnabled(False) + self.actionStop.setEnabled(True) + self.actionClear.setEnabled(True) + self.actionPickInterface.setEnabled(False) + + self.thread = QThread() + self.worker = NetworkMonitorThread(interface = self.interfaceSelected) + self.worker.moveToThread(self.thread) + + self.thread.started.connect(self.worker.startSniff) + self.actionStop.triggered.connect(self.worker.endSniff) + + self.worker.packetData.connect(self.addPacketToTableWidget) + self.worker.quitBool.connect(self.stopSniff) + self.thread.start() + + quitBool = pyqtSignal() + def stopSniff(self, quitBool): + print(quitBool) + if(quitBool == 1): + self.actionStart.setEnabled(True) + self.actionStop.setEnabled(False) + self.actionPickInterface.setEnabled(True) + + print("Terminating thread") + self.thread.terminate() + + def packetClear(self): + self.actionStart.setEnabled(False) + self.actionStop.setEnabled(True) + self.actionStop.setEnabled(True) + + self.thread.terminate() + self.tableWidget.clearContents() + self.tableWidget.setRowCount(0) + self.thread.start() + + def interfaceDialog(self): + self.interfaceDiag = InterfacePick() + self.interfaceDiag.exec_() + if hasattr(self.interfaceDiag, 'interfaceName'): + self.interfaceSelected = self.interfaceDiag.interfaceName + print(self.interfaceSelected) + + packetData = pyqtSignal() + def addPacketToTableWidget(self, packetData): + tableData = packetData[1] + rowpos = self.tableWidget.rowCount() + self.tableWidget.insertRow(rowpos) + self.tableWidget.setItem(rowpos, 0, QTableWidgetItem(str(rowpos+1))) + self.tableWidget.setItem(rowpos, 1, QTableWidgetItem(str(tableData['timestamp']))) + self.tableWidget.setItem(rowpos, 2, QTableWidgetItem(tableData['source'])) + self.tableWidget.setItem(rowpos, 3, QTableWidgetItem(tableData['destination'])) + self.tableWidget.setItem(rowpos, 4, QTableWidgetItem(tableData['Protocol'])) + self.tableWidget.setItem(rowpos, 5, QTableWidgetItem(str(tableData['length']))) + self.tableWidget.setItem(rowpos, 6, QTableWidgetItem(tableData['info'])) + +class InterfacePick(QDialog): + def __init__(self, parent=None): + super().__init__() + self.setWindowTitle('Choose Interface to Monitor') + self.width = 400 + self.height = 400 + + self.setMinimumSize(self.width, self.height) + + self.interfaceList = QListWidget() + self.listInterfaces() + + self.acceptInterface = QPushButton() + self.acceptInterface.setText('Accept') + self.acceptInterface.clicked.connect(self.acceptInterfaceFn) + + self.layout = QVBoxLayout() + self.layout.addWidget(self.interfaceList) + self.layout.addWidget(self.acceptInterface) + self.setLayout(self.layout) + + def listInterfaces(self): + for iface_name in sorted(ifaces.keys()): + dev = ifaces[iface_name] + mac = dev.mac + if iface_name != LOOPBACK_NAME: + mac = conf.manufdb._resolve_MAC(mac) + + if str(dev.ip) != "None" and not str(dev.name).startswith("VM"): + item = '{:40s}\t{}'.format(str(dev.name).strip(), str(dev.ip).strip()) + self.interfaceList.addItem(item) + + + def acceptInterfaceFn(self): + self.idx = self.interfaceList.selectedIndexes() + self.interfaceName = self.idx[0].data().split('\t')[0].strip() + self.close() + diff --git a/network_monitor_thread.py b/network_monitor_thread.py new file mode 100644 index 0000000..cf4cd9b --- /dev/null +++ b/network_monitor_thread.py @@ -0,0 +1,109 @@ +import sys +from PyQt5.QtGui import * +from PyQt5.QtCore import * +from PyQt5.QtWidgets import * +from scapy.all import * + +class NetworkMonitorThread(QObject): + def __init__(self, interface, parent=None): + QObject.__init__(self, parent=parent) + self.interface = interface + self.packetList = [] + self.end = False + + quitBool = pyqtSignal(int) + def endSniff(self): + QApplication.processEvents() + print("Ending") + self.end = True + self.quitBool.emit(1) + + def sniffStatus(self): + QApplication.processEvents() + return self.end + + def getLayers(self,packet): + QApplication.processEvents() + layers = [] + counter = 0 + while True: + layer = packet.getlayer(counter) + if layer != None: + if layer.name != "Padding": + layers.append(layer.name) + else: + break + counter += 1 + return layers + + packetData = pyqtSignal(tuple) + def handlePacket(self,packet): + self.packetList.append(packet) + QApplication.processEvents() + tableViewPart = dict() + tableViewPart['timestamp'] = packet.time + try: + tableViewPart['source'] = packet.getlayer("IP").src + tableViewPart['destination'] = packet.getlayer("IP").dst + except: + tableViewPart['source'] = packet.src + tableViewPart['destination'] = packet.dst + tableViewPart['length'] = len(packet) + tableViewPart['layers'] = self.getLayers(packet) + + QApplication.processEvents() + (protocol,info) = self.getInfo(packet) + tableViewPart['info'] = info + if protocol: + tableViewPart['Protocol'] = protocol + elif IP in packet: + tableViewPart['Protocol'] = "IP" + else: + tableViewPart['Protocol'] = "Other" + QApplication.processEvents() + self.packetData.emit((packet, tableViewPart)) + + def getInfo(self,packet): + QApplication.processEvents() + info = "" + protocol = "" + if UDP in packet: + protocol = "UDP" + info = "{} -> {} len={} chksum={}".format(packet[UDP].sport, + packet[UDP].dport, + packet[UDP].len, + packet[UDP].chksum) + elif TCP in packet: + flags = { + 'F': 'FIN', + 'S': 'SYN', + 'R': 'RST', + 'P': 'PSH', + 'A': 'ACK', + 'U': 'URG', + 'E': 'ECE', + 'C': 'CWR', + } + + flgs = str([flags[x] for x in packet.sprintf('%TCP.flags%')]) + protocol = "TCP" + info = "{} -> {} {} seq={} ack={} window={}".format(packet[TCP].sport, + packet[TCP].dport, + flgs, + packet[TCP].seq, + packet[TCP].ack, + packet[TCP].window) + elif ARP in packet: + protocol = "ARP" + info = "hwtype={} ptype={} hwlen={} plen={} op={}".format(packet[ARP].hwtype, + packet[ARP].ptype, + packet[ARP].hwlen, + packet[ARP].plen, + packet[ARP].op) + QApplication.processEvents() + return (protocol,info) + + + def startSniff(self): + QApplication.processEvents() + self.pkts = sniff(count=0, iface=self.interface, prn=self.handlePacket, stop_filter=lambda x: self.sniffStatus()) \ No newline at end of file