Exemple #1
0
 def __init__(self, netzob):
     super(NetworkCapturer, self).__init__("NETWORK CAPTURER", netzob)
     # create logger with the given configuration
     self.bpfFilter = None
     self.importLayer = 4
     self._payloadDict = {}
     self.envDeps = EnvironmentalDependencies()
    def __init__(self, netzob):
        AbstractImporter.__init__(self, "THIRD PARTY IMPORT")
        self.netzob = netzob

        # create the environmental dependancy object
        self.envDeps = EnvironmentalDependencies()

        # create logger with the given configuration
        self.log = logging.getLogger('netzob.Import.ThirdPartyImporter.py')
        self.messages = []

        ospyImporter = OSpy()

        # Creates the list of third parties
        self.thirdParties = [ospyImporter]
        self.plugins = []
        # Load plugins
        for plugin in self.thirdParties:
            self.plugins.append(plugin)

        self.init()

        self.dialog = Gtk.Dialog(title=_("Import data from third parties"), flags=0, buttons=None)
        self.dialog.show()
        self.dialog.vbox.pack_start(self.getPanel(), True, True, 0)
        self.dialog.set_size_request(1000, 600)
Exemple #3
0
    def __init__(self, netzob):
        super(IpcCapturer, self).__init__("IPC CAPTURER", netzob)
        self.netzob = netzob
        self.pid = None
        self.sniffOption = None
        self.stracePid = None
        self.aSniffThread = None
        self.doSniff = False
        self._payloadDict = {}
        self.envDeps = EnvironmentalDependencies()

        self.selected_fds = set()
Exemple #4
0
    def __init__(self, netzob):
        AbstractImporter.__init__(self, "THIRD PARTY IMPORT")
        self.netzob = netzob

        # create the environmental dependancy object
        self.envDeps = EnvironmentalDependencies()

        # create logger with the given configuration
        self.log = logging.getLogger('netzob.Import.ThirdPartyImporter.py')
        self.messages = []

        ospyImporter = OSpy()

        # Creates the list of third parties
        self.thirdParties = [ospyImporter]
        self.plugins = []
        # Load plugins
        for plugin in self.thirdParties:
            self.plugins.append(plugin)

        self.init()

        self.dialog = gtk.Dialog(title=_("Import data from third parties"), flags=0, buttons=None)
        self.dialog.show()
        self.dialog.vbox.pack_start(self.getPanel(), True, True, 0)
        self.dialog.set_size_request(1000, 600)
Exemple #5
0
    def __init__(self, netzob):
        AbstractImporter.__init__(self, "FILE IMPORT")
        self.netzob = netzob
        self.log = logging.getLogger('netzob.Import.FileImport.py')

        # create the environmental dependancy object
        self.envDeps = EnvironmentalDependencies()
        self.filesToBeImported = []
    def __init__(self, netzob):
        super(DelimiterSeparatedImporter, self).__init__("FILE IMPORT", netzob)
        self.log = logging.getLogger('netzob.Import.FileImporter.py')

        # create the environmental dependancy object
        self.envDeps = EnvironmentalDependencies()
        self.importedFiles = []
        self.messageSeparator = ""
        self.messageSeparatorStrategy = None
Exemple #7
0
    def __init__(self, netzob):
        super(IpcCapturer, self).__init__("IPC CAPTURER", netzob)
        self.netzob = netzob
        self.pid = None
        self.sniffOption = None
        self.stracePid = None
        self.aSniffThread = None
        self.doSniff = False
        self._payloadDict = {}
        self.envDeps = EnvironmentalDependencies()

        self.selected_fds = set()
Exemple #8
0
class IpcCapturer(AbstractCapturer):

    def kill(self):
        if self.stracePid is not None and self.stracePid.poll() is not None:
            self.stracePid.kill()
        if self.aSniffThread is not None and self.aSniffThread.isAlive():
            self.aSniffThread._Thread__stop()

    #+----------------------------------------------
    #| Constructor:
    #+----------------------------------------------
    def __init__(self, netzob):
        super(IpcCapturer, self).__init__("IPC CAPTURER", netzob)
        self.netzob = netzob
        self.pid = None
        self.sniffOption = None
        self.stracePid = None
        self.aSniffThread = None
        self.doSniff = False
        self._payloadDict = {}
        self.envDeps = EnvironmentalDependencies()

        self.selected_fds = set()

    @property
    def payloadDict(self):
        return self._payloadDict.copy()

    def getProcessList(self):
        """getProcessList:
                Return the process list
        """
        processList = []
        uidUser = self.getUidOfCurrentUser()
        for pid in readProcesses():
            if (uidUser == "0") or (uidUser == self.getUidOfProcess(pid)):
                processList.append(str(pid) + "\t" + str(readProcessCmdline(pid)[0]))
        return processList

    def getUidOfProcess(self, pid):
        cmd = "ps -p " + str(pid) + " -o uid= |tr -d \" \""
        uid = os.popen(cmd).read().strip()
        return uid

    def getUidOfCurrentUser(self):
        cmd = "id"
        idResult = os.popen(cmd).read()
        m = re.search("uid=(\d+)\(.*", idResult)
        uid = m.group(1)
        return uid

    #+----------------------------------------------
    #| Retrieve the filtered FD
    #+----------------------------------------------
    def retrieveFDs(self, f_fs=True, f_net=True, f_proc=True):
        if self.pid is None:
            return []
        if False:  # f_net and (not f_fs) and (not f_proc): # -i for optimization
            cmd = "/usr/bin/lsof -i -a -d 0-1024 -a -p " + str(self.pid) + " | grep -v \"SIZE/OFF\" |awk -F \" \" {' print $5 \" \" $8 \" \" $9 \" \" $7'}"
        else:
            grep = "."
            if f_fs:
                grep += "DIR\|REG\|"
            if f_net:
                grep += "IPv4\|IPv6\|"
            if f_proc:
                grep += "CHR\|unix\|FIFO\|"
            grep = grep[:-2]
            cmd = "/usr/bin/lsof -d 0-1024 -a -p " + str(self.pid) + " | grep -v \"SIZE/OFF\" |awk -F \" \" {' print $4 \"##\" $5 \"##\" $9'} | grep \"" + grep + "\""

        lines = os.popen(cmd).readlines()
        fdescrs = []
        for fd in lines:
            elts = fd[:-1].split("##")
            fdescrs.append(elts)
        return fdescrs

    #+----------------------------------------------
    #| Called when launching sniffing process
    #+----------------------------------------------
    def startSniff(self, callback_readMessage):
        self.callback_readMessage = callback_readMessage
        self.selected_fds.clear()
        self.doSniff = True
        self.envDeps.captureEnvData()  # Retrieve the environmental data (os specific, system specific, etc.)
        self.messages = []

        if self.sniffOption == "filtered":
            (model, paths) = self.fdTreeview.get_selection().get_selected_rows()
            for path in paths:
                iter = model.get_iter(path)
                if(model.iter_is_valid(iter)):
                    # Extract the fd number
                    self.selected_fds.add(int(re.match("(\d+)", model.get_value(iter, 0)).group(1)))
        self.packets = []
        self.aSniffThread = threading.Thread(None, self.sniffThread, None, (), {})
        self.aSniffThread.start()

    #+----------------------------------------------
    #| Called when stopping sniffing process
    #+----------------------------------------------
    def stopSniff(self):
        self.doSniff = False

        if self.stracePid is not None:
            self.stracePid.kill()
        self.stracePid = None
        if self.aSniffThread is not None and self.aSniffThread.isAlive():
            self.aSniffThread._Thread__stop()
        self.aSniffThread = None

    #+----------------------------------------------
    #| Thread for sniffing a process
    #+----------------------------------------------
    def sniffThread(self):
        logging.info("Launching sniff process")
        self.stracePid = subprocess.Popen(["/usr/bin/strace", "-xx", "-s", "65536", "-e", "read,write", "-p", str(self.pid)], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        GObject.io_add_watch(self.stracePid.stderr, GObject.IO_IN | GObject.IO_HUP, self.handle_new_pkt)

    #+----------------------------------------------
    #| Handle new packet received by strace
    #+----------------------------------------------
    def handle_new_pkt(self, src, event):
        # Retrieve details from the captured paket
        data = src.readline()
        compiledRegex = re.compile("(read|write)\((\d+), \"(.*)\", \d+\)[ \t]*=[ \t]*(\d+)")
        m = compiledRegex.match(data)
        if m is None:
            return self.doSniff
        direction = data[m.start(1): m.end(1)]
        fd = int(data[m.start(2): m.end(2)])
        pkt = data[m.start(3): m.end(3)]
        pkt = pkt.replace("\\x", "")
        returnCode = int(data[m.start(4): m.end(4)])

        # Apply filter
        if self.sniffOption == "fs":
            if not self.getTypeFromFD(int(fd)) == "fs":
                return self.doSniff
        elif self.sniffOption == "network":
            if not self.getTypeFromFD(int(fd)) == "network":
                return self.doSniff
        elif self.sniffOption == "ipc":
            if not self.getTypeFromFD(int(fd)) == "ipc":
                return self.doSniff
        elif self.sniffOption == "filtered":
            if not fd in self.selected_fds:
                return self.doSniff

        mUuid = str(uuid.uuid4())
        mTimestamp = int(time.time())
        message = IPCMessage(mUuid, mTimestamp, pkt, self.getTypeFromFD(int(fd)), fd, direction)
        self._payloadDict[mUuid] = pkt
        self.messages.append(message)
        self.callback_readMessage(message)
        return self.doSniff

    #+----------------------------------------------
    #| GETTERS
    #+----------------------------------------------
    def getTypeFromFD(self, fd):
        path = "/proc/" + str(self.pid) + "/fd/" + str(fd)
        if os.path.realpath(path).find("socket:[", 0) != -1:
            return "network"
        elif os.path.isfile(os.path.realpath(path)) or os.path.isdir(os.path.realpath(path)):
            return "fs"
        else:
            return "ipc"

    def getMessageDetails(self, messageID):
        if not messageID in self._payloadDict:
            errorMessage = _("Message ID: {0} not found in importer " +
                             "message list").format(messageID)
            logging.error(errorMessage)
            raise NetzobImportException("IPC", errorMessage, ERROR)
        payload = self._payloadDict[messageID]
        return TypeConvertor.hexdump(TypeConvertor.netzobRawToPythonRaw(payload))
Exemple #9
0
class ThirdPartyImport(AbstractImporter):

    def new(self):
        pass

    def update(self):
        pass

    def clear(self):
        pass

    def kill(self):
        pass

    #+----------------------------------------------
    #| Constructor:
    #+----------------------------------------------
    def __init__(self, netzob):
        AbstractImporter.__init__(self, "THIRD PARTY IMPORT")
        self.netzob = netzob

        # create the environmental dependancy object
        self.envDeps = EnvironmentalDependencies()

        # create logger with the given configuration
        self.log = logging.getLogger('netzob.Import.ThirdPartyImporter.py')
        self.messages = []

        ospyImporter = OSpy()

        # Creates the list of third parties
        self.thirdParties = [ospyImporter]
        self.plugins = []
        # Load plugins
        for plugin in self.thirdParties:
            self.plugins.append(plugin)

        self.init()

        self.dialog = gtk.Dialog(title=_("Import data from third parties"), flags=0, buttons=None)
        self.dialog.show()
        self.dialog.vbox.pack_start(self.getPanel(), True, True, 0)
        self.dialog.set_size_request(1000, 600)

    def init(self):
        self.fileName = ""
        self.thirdParty = ""

        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # Main panel
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        self.panel = gtk.Table(rows=10, columns=8, homogeneous=True)
        self.panel.show()

        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # Select a file
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        label_selectSource = gtk.Label(_("Select data source"))
        label_selectSource.show()

        entry_filepath = gtk.Entry()
        entry_filepath.set_text("")
        entry_filepath.show()

        but_source = gtk.Button("...")
        but_source.show()
        but_source.connect("clicked", self.selectFiles, entry_filepath)

        self.panel.attach(label_selectSource, 0, 1, 0, 1, xoptions=gtk.FILL | gtk.EXPAND, yoptions=gtk.FILL | gtk.EXPAND, xpadding=5, ypadding=5)
        self.panel.attach(entry_filepath, 1, 5, 0, 1, xoptions=gtk.FILL | gtk.EXPAND, yoptions=gtk.FILL | gtk.EXPAND, xpadding=5, ypadding=5)
        self.panel.attach(but_source, 5, 6, 0, 1, xoptions=gtk.FILL | gtk.EXPAND, yoptions=gtk.FILL | gtk.EXPAND, xpadding=5, ypadding=5)

        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # Select a third party
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        label_thirdParty = gtk.Label(_("Select a third party"))
        label_thirdParty.show()
        self.thirdPartyStore = gtk.combo_box_entry_new_text()
        self.thirdPartyStore.show()
        self.thirdPartyStore.set_size_request(500, -1)
        self.thirdPartyStore.set_model(gtk.ListStore(str))

        # register all the available plugins
        for plugin in self.plugins:
            self.thirdPartyStore.append_text(plugin.getName())

        but_import = gtk.Button(_("Load"))
        but_import.show()
        but_import.connect("clicked", self.load_file, entry_filepath)

        self.panel.attach(label_thirdParty, 0, 1, 1, 2, xoptions=gtk.FILL | gtk.EXPAND, yoptions=gtk.FILL | gtk.EXPAND, xpadding=5, ypadding=5)
        self.panel.attach(self.thirdPartyStore, 1, 5, 1, 2, xoptions=gtk.FILL | gtk.EXPAND, yoptions=gtk.FILL | gtk.EXPAND, xpadding=5, ypadding=5)
        self.panel.attach(but_import, 5, 6, 1, 2, xoptions=gtk.FILL | gtk.EXPAND, yoptions=gtk.FILL | gtk.EXPAND, xpadding=5, ypadding=5)

        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # File details
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        scroll = gtk.ScrolledWindow()
        self.textview = gtk.TextView()
        self.textview.show()
        self.textview.get_buffer().create_tag("normalTag", family="Courier")

        scroll.add(self.textview)
        scroll.show()
        scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.panel.attach(scroll, 0, 6, 2, 10, xoptions=gtk.FILL | gtk.EXPAND, yoptions=gtk.FILL | gtk.EXPAND, xpadding=5, ypadding=5)

        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # Extracted data
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        scroll2 = gtk.ScrolledWindow()
        self.lineView = gtk.TreeView(gtk.TreeStore(str, str))  # line number, content
        self.lineView.get_selection().set_mode(gtk.SELECTION_SINGLE)
        self.lineView.connect('button-press-event', self.button_press_on_message)
        cell = gtk.CellRendererText()
        # Col file descriptor
        column = gtk.TreeViewColumn(_("Message ID"))
        column.pack_start(cell, True)
        column.set_attributes(cell, text=0)
        self.lineView.append_column(column)
        self.lineView.show()

        scroll2.add(self.lineView)
        scroll2.show()
        scroll2.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.panel.attach(scroll2, 6, 8, 0, 10, xoptions=gtk.FILL, yoptions=gtk.FILL | gtk.EXPAND, xpadding=5, ypadding=5)

        # Button select packets for further analysis
        but = gtk.Button(label=_("Import"))
        but.show()
        but.connect("clicked", self.import_file)
        self.panel.attach(but, 2, 3, 10, 11, xoptions=0, yoptions=0, xpadding=5, ypadding=5)

    def button_press_on_message(self, treeview, event):
        x = int(event.x)
        y = int(event.y)

        info = treeview.get_path_at_pos(x, y)
        idMessage = None
        if info is not None:
            path = info[0]
            iter = treeview.get_model().get_iter(path)
            idMessage = str(treeview.get_model().get_value(iter, 0))

        if idMessage == None:
            return

        # Search for the selected message
        selectedMessage = None
        for message in self.messages:
            if str(message.getID()) == idMessage:
                selectedMessage = message

        if selectedMessage == None:
            self.log.warn(_("Impossible to retrieve the message the user clicked on. Hum ?"))
            return

        self.displayMessage(selectedMessage)

    def load_file(self, button, entryPath):
        # First we retrieve the provided files
        filesToBeImported = []

        # Computes the selected file(s)
        strPaths = entryPath.get_text().split(";")
        for strPath in strPaths:
            filename = unicode(strPath, "utf-8")
            if filename != None and filename != "" and os.path.isfile(filename):
                filesToBeImported.append(filename)
            else:
                logging.warning(
                    _("Cannot load file {0}, its not a file.").format(filename))

        # Start to load
        parsedMessages = self.loadMessagesFromPlugin(self.thirdPartyStore.get_active_text(), filesToBeImported)

        if parsedMessages == None:
            logging.warning(_("Impossible to find a plugin to import data from."))
        else:
            logging.debug(_("A number of {0} messages were extracted.").format(len(parsedMessages)))
            for message in parsedMessages:
                self.messages.append(message)
                self.lineView.get_model().append(None, [message.getID(), message.getData()])

                # We clean the display
                self.textview.get_buffer().insert_with_tags_by_name(self.textview.get_buffer().get_start_iter(), "", "normalTag")

    def loadMessagesFromPlugin(self, pluginName, files):
        for plugin in self.plugins:
            if plugin.getName() == pluginName:
                return plugin.parse(files)
        return None

    #+----------------------------------------------
    #| Called when user select a list of packet
    #+----------------------------------------------
    def import_file(self, button):
        currentProject = self.netzob.getCurrentProject()

        # We ask the confirmation
        dialog = gtk.MessageDialog(None,
                                   gtk.DIALOG_DESTROY_WITH_PARENT,
                                   gtk.MESSAGE_QUESTION,
                                   gtk.BUTTONS_OK_CANCEL,
                                   _("Are you sure to import the {0} computed messages in project {1}?").format(str(len(self.messages)), currentProject.getName()))

        # Checkbox for session
        vbox = gtk.VBox()
        vbox.show()
        hbox = gtk.HBox()
        hbox.show()
        vbox.pack_start(hbox)
        isSession = gtk.CheckButton(_("Check if this trace is a session"))
        isSession.set_active(False)
        isSession.show()
#        hbox.pack_start(isSession)

        dialog.vbox.pack_end(vbox, True, True, 0)
        resp = dialog.run()
        dialog.destroy()

        if resp == gtk.RESPONSE_OK:
            self.saveMessagesInProject(self.netzob.getCurrentWorkspace(), currentProject, self.messages)
            self.dialog.destroy()
            # We update the gui
            self.netzob.update()

    #+----------------------------------------------
    #| Called when user import files
    #+----------------------------------------------
    def selectFiles(self, button, label):
        aFile = ""
        chooser = gtk.FileChooserDialog(title=_("Select one or multiple file"), action=gtk.FILE_CHOOSER_ACTION_OPEN,
                                        buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK))
        chooser.set_select_multiple(True)

        filesToBeImported = []

        # Computes the selected file(s)
        res = chooser.run()
        if res == gtk.RESPONSE_OK:
            for filename in chooser.get_filenames():
                filename = unicode(filename, "utf-8")
                if filename != None and filename != "" and os.path.isfile(filename):
                    filesToBeImported.append(filename)
        chooser.destroy()

        # We update the label with the list of the selected files
        label.set_text(";".join(filesToBeImported))

    #+----------------------------------------------
    #| Retrieve messages from files
    #+----------------------------------------------
    def retrieveMessagesFromFiles(self):
        # We capture the current environment
        self.envDeps.captureEnvData()

        # We read each file and create one message for each file
        fileNumber = 0
        self.messages = []
        self.lineView.get_model().clear()

        for file in self.filesToBeImported:
            # Extraction of the metadata
            fileName = file.strip()
            size = os.path.getsize(file)
            creationDate = datetime.datetime.fromtimestamp(os.path.getctime(file))
            modificationDate = datetime.datetime.fromtimestamp(os.path.getmtime(file))
            owner = "none"

            # Retrieve the binary content of the file
            content = self.getNetzobRawContentOfFile(file)
            if not len(content) > 0:
                continue

            # Create a message
            message = FileMessage(uuid.uuid4(), 0, content, fileName, creationDate, modificationDate, owner, size, 0)
            self.messages.append(message)
            self.lineView.get_model().append(None, [message.getID(), content])
            fileNumber += 1

        # We clean the display
        self.textview.get_buffer().insert_with_tags_by_name(self.textview.get_buffer().get_start_iter(), "", "normalTag")

    def getNetzobRawContentOfFile(self, filename):
        file = open(filename, "rb")
        content = file.read()
        file.close()
        return TypeConvertor.stringToNetzobRaw(content)

    def entry_separator_callback(self, widget, entry):
        entry_text = widget.get_text()
        self.lineSeparator = entry_text
        self.updateMessageList()

    def updateMessageList(self):
        # We read each file and create one message for each file
        fileNumber = 0

        # We split the content of each message and retrieve new messages
        self.retrieveMessagesFromFiles()
        new_messages = []
        for message in self.messages:
            lineNumber = 0
            if len(self.lineSeparator) > 0:
                splittedStrHexData = message.getData().split(self.lineSeparator)
            else:
                splittedStrHexData = [message.getData()]
            for s in splittedStrHexData:
                if len(s) > 0:
                    message = FileMessage(uuid.uuid4(), 0, s, message.getFilename(), message.getCreationDate(), message.getModificationDate(), message.getOwner(), message.getSize(), lineNumber)
                    new_messages.append(message)
                    lineNumber += 1

        # We save the new messages
        self.messages = []
        self.messages.extend(new_messages)
        self.lineView.get_model().clear()
        for message in self.messages:
            self.lineView.get_model().append(None, [message.getID(), message.getData()])
        # We clean the display
        self.textview.get_buffer().delete(self.textview.get_buffer().get_start_iter(), self.textview.get_buffer().get_end_iter())

    def displayMessage(self, message):
        # Clean the hexdump view
        self.textview.get_buffer().delete(self.textview.get_buffer().get_start_iter(), self.textview.get_buffer().get_end_iter())
        # Fecth the content of the message to display
        hexContent = TypeConvertor.hexdump(TypeConvertor.netzobRawToPythonRaw(message.getData()))
        # Update the hexdump
        self.textview.get_buffer().insert_with_tags_by_name(self.textview.get_buffer().get_start_iter(), hexContent, "normalTag")

    #+----------------------------------------------
    #| GETTERS
    #+----------------------------------------------
    def getPanel(self):
        return self.panel
Exemple #10
0
class IpcCapturer(AbstractCapturer):
    def kill(self):
        if self.stracePid is not None and self.stracePid.poll() is not None:
            self.stracePid.kill()
        if self.aSniffThread is not None and self.aSniffThread.isAlive():
            self.aSniffThread._Thread__stop()

    #+----------------------------------------------
    #| Constructor:
    #+----------------------------------------------
    def __init__(self, netzob):
        super(IpcCapturer, self).__init__("IPC CAPTURER", netzob)
        self.netzob = netzob
        self.pid = None
        self.sniffOption = None
        self.stracePid = None
        self.aSniffThread = None
        self.doSniff = False
        self._payloadDict = {}
        self.envDeps = EnvironmentalDependencies()

        self.selected_fds = set()

    @property
    def payloadDict(self):
        return self._payloadDict.copy()

    def getProcessList(self):
        """getProcessList:
                Return the process list
        """
        processList = []
        uidUser = self.getUidOfCurrentUser()
        for pid in readProcesses():
            if (uidUser == "0") or (uidUser == self.getUidOfProcess(pid)):
                processList.append(
                    str(pid) + "\t" + str(readProcessCmdline(pid)[0]))
        return processList

    def getUidOfProcess(self, pid):
        cmd = "ps -p " + str(pid) + " -o uid= |tr -d \" \""
        uid = os.popen(cmd).read().strip()
        return uid

    def getUidOfCurrentUser(self):
        cmd = "id"
        idResult = os.popen(cmd).read()
        m = re.search("uid=(\d+)\(.*", idResult)
        uid = m.group(1)
        return uid

    #+----------------------------------------------
    #| Retrieve the filtered FD
    #+----------------------------------------------
    def retrieveFDs(self, f_fs=True, f_net=True, f_proc=True):
        if self.pid is None:
            return []
        if False:  # f_net and (not f_fs) and (not f_proc): # -i for optimization
            cmd = "/usr/bin/lsof -i -a -d 0-1024 -a -p " + str(
                self.pid
            ) + " | grep -v \"SIZE/OFF\" |awk -F \" \" {' print $5 \" \" $8 \" \" $9 \" \" $7'}"
        else:
            grep = "."
            if f_fs:
                grep += "DIR\|REG\|"
            if f_net:
                grep += "IPv4\|IPv6\|"
            if f_proc:
                grep += "CHR\|unix\|FIFO\|"
            grep = grep[:-2]
            cmd = "/usr/bin/lsof -d 0-1024 -a -p " + str(
                self.pid
            ) + " | grep -v \"SIZE/OFF\" |awk -F \" \" {' print $4 \"##\" $5 \"##\" $9'} | grep \"" + grep + "\""

        lines = os.popen(cmd).readlines()
        fdescrs = []
        for fd in lines:
            elts = fd[:-1].split("##")
            fdescrs.append(elts)
        return fdescrs

    #+----------------------------------------------
    #| Called when launching sniffing process
    #+----------------------------------------------
    def startSniff(self, callback_readMessage):
        self.callback_readMessage = callback_readMessage
        self.selected_fds.clear()
        self.doSniff = True
        self.envDeps.captureEnvData(
        )  # Retrieve the environmental data (os specific, system specific, etc.)
        self.messages = []

        if self.sniffOption == "filtered":
            (model,
             paths) = self.fdTreeview.get_selection().get_selected_rows()
            for path in paths:
                iter = model.get_iter(path)
                if (model.iter_is_valid(iter)):
                    # Extract the fd number
                    self.selected_fds.add(
                        int(
                            re.match("(\d+)", model.get_value(iter,
                                                              0)).group(1)))
        self.packets = []
        self.aSniffThread = threading.Thread(None, self.sniffThread, None, (),
                                             {})
        self.aSniffThread.start()

    #+----------------------------------------------
    #| Called when stopping sniffing process
    #+----------------------------------------------
    def stopSniff(self):
        self.doSniff = False

        if self.stracePid is not None:
            self.stracePid.kill()
        self.stracePid = None
        if self.aSniffThread is not None and self.aSniffThread.isAlive():
            self.aSniffThread._Thread__stop()
        self.aSniffThread = None

    #+----------------------------------------------
    #| Thread for sniffing a process
    #+----------------------------------------------
    def sniffThread(self):
        logging.info("Launching sniff process")
        self.stracePid = subprocess.Popen([
            "/usr/bin/strace", "-xx", "-s", "65536", "-e", "read,write", "-p",
            str(self.pid)
        ],
                                          stdout=subprocess.PIPE,
                                          stderr=subprocess.PIPE)
        GObject.io_add_watch(self.stracePid.stderr,
                             GObject.IO_IN | GObject.IO_HUP,
                             self.handle_new_pkt)

    #+----------------------------------------------
    #| Handle new packet received by strace
    #+----------------------------------------------
    def handle_new_pkt(self, src, event):
        # Retrieve details from the captured paket
        data = src.readline()
        compiledRegex = re.compile(
            "(read|write)\((\d+), \"(.*)\", \d+\)[ \t]*=[ \t]*(\d+)")
        m = compiledRegex.match(data)
        if m is None:
            return self.doSniff
        direction = data[m.start(1):m.end(1)]
        fd = int(data[m.start(2):m.end(2)])
        pkt = data[m.start(3):m.end(3)]
        pkt = pkt.replace("\\x", "")
        returnCode = int(data[m.start(4):m.end(4)])

        # Apply filter
        if self.sniffOption == "fs":
            if not self.getTypeFromFD(int(fd)) == "fs":
                return self.doSniff
        elif self.sniffOption == "network":
            if not self.getTypeFromFD(int(fd)) == "network":
                return self.doSniff
        elif self.sniffOption == "ipc":
            if not self.getTypeFromFD(int(fd)) == "ipc":
                return self.doSniff
        elif self.sniffOption == "filtered":
            if not fd in self.selected_fds:
                return self.doSniff

        mUuid = str(uuid.uuid4())
        mTimestamp = int(time.time())
        message = IPCMessage(mUuid, mTimestamp, pkt,
                             self.getTypeFromFD(int(fd)), fd, direction)
        self._payloadDict[mUuid] = pkt
        self.messages.append(message)
        self.callback_readMessage(message)
        return self.doSniff

    #+----------------------------------------------
    #| GETTERS
    #+----------------------------------------------
    def getTypeFromFD(self, fd):
        path = "/proc/" + str(self.pid) + "/fd/" + str(fd)
        if os.path.realpath(path).find("socket:[", 0) != -1:
            return "network"
        elif os.path.isfile(os.path.realpath(path)) or os.path.isdir(
                os.path.realpath(path)):
            return "fs"
        else:
            return "ipc"

    def getMessageDetails(self, messageID):
        if not messageID in self._payloadDict:
            errorMessage = _("Message ID: {0} not found in importer " +
                             "message list").format(messageID)
            logging.error(errorMessage)
            raise NetzobImportException("IPC", errorMessage, ERROR)
        payload = self._payloadDict[messageID]
        return TypeConvertor.hexdump(
            TypeConvertor.netzobRawToPythonRaw(payload))
Exemple #11
0
class ThirdPartyImport(AbstractImporter):

    def new(self):
        pass

    def update(self):
        pass

    def clear(self):
        pass

    def kill(self):
        pass

    #+----------------------------------------------
    #| Constructor:
    #+----------------------------------------------
    def __init__(self, netzob):
        AbstractImporter.__init__(self, "THIRD PARTY IMPORT")
        self.netzob = netzob

        # create the environmental dependancy object
        self.envDeps = EnvironmentalDependencies()

        # create logger with the given configuration
        self.log = logging.getLogger('netzob.Import.ThirdPartyImporter.py')
        self.messages = []

        ospyImporter = OSpy()

        # Creates the list of third parties
        self.thirdParties = [ospyImporter]
        self.plugins = []
        # Load plugins
        for plugin in self.thirdParties:
            self.plugins.append(plugin)

        self.init()

        self.dialog = Gtk.Dialog(title=_("Import data from third parties"), flags=0, buttons=None)
        self.dialog.show()
        self.dialog.vbox.pack_start(self.getPanel(), True, True, 0)
        self.dialog.set_size_request(1000, 600)

    def init(self):
        self.fileName = ""
        self.thirdParty = ""

        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # Main panel
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        self.panel = Gtk.Table(rows=10, columns=8, homogeneous=True)
        self.panel.show()

        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # Select a file
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        label_selectSource = Gtk.Label(label=_("Select data source"))
        label_selectSource.show()

        entry_filepath = Gtk.Entry()
        entry_filepath.set_text("")
        entry_filepath.show()

        but_source = Gtk.Button("...")
        but_source.show()
        but_source.connect("clicked", self.selectFiles, entry_filepath)

        self.panel.attach(label_selectSource, 0, 1, 0, 1, xoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, yoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, xpadding=5, ypadding=5)
        self.panel.attach(entry_filepath, 1, 5, 0, 1, xoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, yoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, xpadding=5, ypadding=5)
        self.panel.attach(but_source, 5, 6, 0, 1, xoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, yoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, xpadding=5, ypadding=5)

        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # Select a third party
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        label_thirdParty = Gtk.Label(label=_("Select a third party"))
        label_thirdParty.show()
        self.thirdPartyStore = Gtk.ComboBoxText.new_with_entry()
        self.thirdPartyStore.show()
        self.thirdPartyStore.set_size_request(500, -1)
        self.thirdPartyStore.set_model(Gtk.ListStore(str))

        # register all the available plugins
        for plugin in self.plugins:
            self.thirdPartyStore.append_text(plugin.getName())

        but_import = Gtk.Button(_("Load"))
        but_import.show()
        but_import.connect("clicked", self.load_file, entry_filepath)

        self.panel.attach(label_thirdParty, 0, 1, 1, 2, xoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, yoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, xpadding=5, ypadding=5)
        self.panel.attach(self.thirdPartyStore, 1, 5, 1, 2, xoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, yoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, xpadding=5, ypadding=5)
        self.panel.attach(but_import, 5, 6, 1, 2, xoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, yoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, xpadding=5, ypadding=5)

        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # File details
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        scroll = Gtk.ScrolledWindow()
        self.textview = Gtk.TextView()
        self.textview.show()
        self.textview.get_buffer().create_tag("normalTag", family="Courier")

        scroll.add(self.textview)
        scroll.show()
        scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        self.panel.attach(scroll, 0, 6, 2, 10, xoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, yoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, xpadding=5, ypadding=5)

        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # Extracted data
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        scroll2 = Gtk.ScrolledWindow()
        self.lineView = Gtk.TreeView(Gtk.TreeStore(str, str))  # line number, content
        self.lineView.get_selection().set_mode(Gtk.SelectionMode.SINGLE)
        self.lineView.connect('button-press-event', self.button_press_on_message)
        cell = Gtk.CellRendererText()
        # Col file descriptor
        column = Gtk.TreeViewColumn(_("Message ID"))
        column.pack_start(cell, True)
        column.add_attribute(cell, "text", 0)
        self.lineView.append_column(column)
        self.lineView.show()

        scroll2.add(self.lineView)
        scroll2.show()
        scroll2.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        self.panel.attach(scroll2, 6, 8, 0, 10, xoptions=Gtk.AttachOptions.FILL, yoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, xpadding=5, ypadding=5)

        # Button select packets for further analysis
        but = Gtk.Button(label=_("Import"))
        but.show()
        but.connect("clicked", self.import_file)
        self.panel.attach(but, 2, 3, 10, 11, xoptions=0, yoptions=0, xpadding=5, ypadding=5)

    def button_press_on_message(self, treeview, event):
        x = int(event.x)
        y = int(event.y)

        info = treeview.get_path_at_pos(x, y)
        idMessage = None
        if info is not None:
            path = info[0]
            iter = treeview.get_model().get_iter(path)
            idMessage = str(treeview.get_model().get_value(iter, 0))

        if idMessage is None:
            return

        # Search for the selected message
        selectedMessage = None
        for message in self.messages:
            if str(message.getID()) == idMessage:
                selectedMessage = message

        if selectedMessage is None:
            self.log.warn("Impossible to retrieve the message the user clicked on. Hum?")
            return

        self.displayMessage(selectedMessage)

    def load_file(self, button, entryPath):
        # First we retrieve the provided files
        filesToBeImported = []

        # Computes the selected file(s)
        strPaths = entryPath.get_text().split(";")
        for strPath in strPaths:
            filename = unicode(strPath, "utf-8")
            if filename is not None and filename != "" and os.path.isfile(filename):
                filesToBeImported.append(filename)
            else:
                logging.warning("Cannot load file {0}, its not a file.".format(filename))

        # Start to load
        parsedMessages = self.loadMessagesFromPlugin(self.thirdPartyStore.get_active_text(), filesToBeImported)

        if parsedMessages is None:
            logging.warning("Impossible to find a plugin to import data from.")
        else:
            logging.debug("A number of {0} messages were extracted.".format(len(parsedMessages)))
            for message in parsedMessages:
                self.messages.append(message)
                self.lineView.get_model().append(None, [message.getID(), message.getData()])

                # We clean the display
                self.textview.get_buffer().insert_with_tags_by_name(self.textview.get_buffer().get_start_iter(), "", "normalTag")

    def loadMessagesFromPlugin(self, pluginName, files):
        for plugin in self.plugins:
            if plugin.getName() == pluginName:
                return plugin.parse(files)
        return None

    #+----------------------------------------------
    #| Called when user select a list of packet
    #+----------------------------------------------
    def import_file(self, button):
        currentProject = self.netzob.getCurrentProject()

        # We ask the confirmation
        dialog = Gtk.MessageDialog(None,
                                   Gtk.DialogFlags.DESTROY_WITH_PARENT,
                                   Gtk.MessageType.QUESTION,
                                   Gtk.ButtonsType.OK_CANCEL,
                                   "Are you sure to import the " + str(len(self.messages)) + " computed messages in project " + currentProject.getName() + ".")

        # Checkbox for session
        vbox = Gtk.VBox()
        vbox.show()
        hbox = Gtk.HBox()
        hbox.show()
        vbox.pack_start(hbox, True, True, 0)
        isSession = Gtk.CheckButton(_("Check if this trace is a session"))
        isSession.set_active(False)
        isSession.show()
#        hbox.pack_start(isSession, True, True, 0)

        dialog.vbox.pack_end(vbox, True, True, 0)
        resp = dialog.run()
        dialog.destroy()

        if resp == Gtk.ResponseType.OK:
            self.saveMessagesInProject(self.netzob.getCurrentWorkspace(), currentProject, self.messages)
            self.dialog.destroy()
            # We update the gui
            self.netzob.update()

    #+----------------------------------------------
    #| Called when user import files
    #+----------------------------------------------
    def selectFiles(self, button, label):
        aFile = ""
        chooser = Gtk.FileChooserDialog(title=_("Select one or multiple file"), action=Gtk.FileChooserAction.OPEN,
                                        buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
        chooser.set_select_multiple(True)

        filesToBeImported = []

        # Computes the selected file(s)
        res = chooser.run()
        if res == Gtk.ResponseType.OK:
            for filename in chooser.get_filenames():
                filename = unicode(filename, "utf-8")
                if filename is not None and filename != "" and os.path.isfile(filename):
                    filesToBeImported.append(filename)
        chooser.destroy()

        # We update the label with the list of the selected files
        label.set_text(";".join(filesToBeImported))

    #+----------------------------------------------
    #| Retrieve messages from files
    #+----------------------------------------------
    def retrieveMessagesFromFiles(self):
        # We capture the current environment
        self.envDeps.captureEnvData()

        # We read each file and create one message for each file
        fileNumber = 0
        self.messages = []
        self.lineView.get_model().clear()

        for file in self.filesToBeImported:
            # Extraction of the metadata
            fileName = file.strip()
            size = os.path.getsize(file)
            creationDate = datetime.datetime.fromtimestamp(os.path.getctime(file))
            modificationDate = datetime.datetime.fromtimestamp(os.path.getmtime(file))
            owner = "none"

            # Retrieve the binary content of the file
            content = self.getNetzobRawContentOfFile(file)
            if not len(content) > 0:
                continue

            # Create a message
            message = FileMessage(str(uuid.uuid4()), 0, content, fileName, creationDate, modificationDate, owner, size, 0)
            self.messages.append(message)
            self.lineView.get_model().append(None, [message.getID(), content])
            fileNumber += 1

        # We clean the display
        self.textview.get_buffer().insert_with_tags_by_name(self.textview.get_buffer().get_start_iter(), "", "normalTag")

    def getNetzobRawContentOfFile(self, filename):
        file = open(filename, "rb")
        content = file.read()
        file.close()
        return TypeConvertor.stringToNetzobRaw(content)

    def entry_separator_callback(self, widget, entry):
        entry_text = widget.get_text()
        self.lineSeparator = entry_text
        self.updateMessageList()

    def updateMessageList(self):
        # We read each file and create one message for each file
        fileNumber = 0

        # We split the content of each message and retrieve new messages
        self.retrieveMessagesFromFiles()
        new_messages = []
        for message in self.messages:
            lineNumber = 0
            if len(self.lineSeparator) > 0:
                splittedStrHexData = message.getData().split(self.lineSeparator)
            else:
                splittedStrHexData = [message.getData()]
            for s in splittedStrHexData:
                if len(s) > 0:
                    message = FileMessage(str(uuid.uuid4()), 0, s, message.getFilename(), message.getCreationDate(), message.getModificationDate(), message.getOwner(), message.getSize(), lineNumber)
                    new_messages.append(message)
                    lineNumber += 1

        # We save the new messages
        self.messages = []
        self.messages.extend(new_messages)
        self.lineView.get_model().clear()
        for message in self.messages:
            self.lineView.get_model().append(None, [message.getID(), message.getData()])
        # We clean the display
        self.textview.get_buffer().delete(self.textview.get_buffer().get_start_iter(), self.textview.get_buffer().get_end_iter())

    def displayMessage(self, message):
        # Clean the hexdump view
        self.textview.get_buffer().delete(self.textview.get_buffer().get_start_iter(), self.textview.get_buffer().get_end_iter())
        # Fecth the content of the message to display
        hexContent = TypeConvertor.hexdump(TypeConvertor.netzobRawToPythonRaw(message.getData()))
        # Update the hexdump
        self.textview.get_buffer().insert_with_tags_by_name(self.textview.get_buffer().get_start_iter(), hexContent, "normalTag")

    #+----------------------------------------------
    #| GETTERS
    #+----------------------------------------------
    def getPanel(self):
        return self.panel
Exemple #12
0
class FileImport(AbstractImporter):

    #+----------------------------------------------
    #| Constructor:
    #+----------------------------------------------
    def __init__(self, netzob):
        AbstractImporter.__init__(self, "FILE IMPORT")
        self.netzob = netzob
        self.log = logging.getLogger('netzob.Import.FileImport.py')

        # create the environmental dependancy object
        self.envDeps = EnvironmentalDependencies()
        self.filesToBeImported = []

    #+----------------------------------------------
    #| Retrieve messages from files
    #+----------------------------------------------
    def retrieveMessagesFromFiles(self):
        # We capture the current environment
        self.envDeps.captureEnvData()

        # We read each file and create one message for each file
        fileNumber = 0
        self.messages = []

        for file in self.filesToBeImported:
            # Extraction of the metadata
            fileName = file.strip()
            size = os.path.getsize(file)
            creationDate = datetime.datetime.fromtimestamp(os.path.getctime(file))
            modificationDate = datetime.datetime.fromtimestamp(os.path.getmtime(file))
            owner = "none"

            # Retrieve the binary content of the file
            content = self.getNetzobRawContentOfFile(file)
            if not len(content) > 0:
                continue

            # Create a message
            message = FileMessage(uuid.uuid4(), 0, content, fileName, creationDate, modificationDate, owner, size, 0)
            self.messages.append(message)
            fileNumber += 1

    def getNetzobRawContentOfFile(self, filename):
        file = open(filename, "rb")
        content = file.read()
        file.close()
        return TypeConvertor.stringToNetzobRaw(content)

    def applySeparatorOnFiles(self, lineSeparator):
        # We read each file and create one message for each file
        fileNumber = 0

        # We split the content of each message and retrieve new messages
        self.retrieveMessagesFromFiles()
        new_messages = []
        for message in self.messages:
            lineNumber = 0
            if len(lineSeparator) > 0:
                splittedStrHexData = message.getData().split(lineSeparator)
            else:
                splittedStrHexData = [message.getData()]
            for s in splittedStrHexData:
                if len(s) > 0:
                    message = FileMessage(uuid.uuid4(), 0, s, message.getFilename(), message.getCreationDate(), message.getModificationDate(), message.getOwner(), message.getSize(), lineNumber)
                    new_messages.append(message)
                    lineNumber += 1

        # We save the new messages
        self.messages = []
        self.messages.extend(new_messages)
Exemple #13
0
class NetworkCapturer(AbstractCapturer):
    """NetworkCapturer: This class offers the capability to capture
    traffic from live network.
    """

    INVALID_BPF_FILTER = 0
    INVALID_LAYER2 = 1
    INVALID_LAYER3 = 2
    INVALID_LAYER4 = 3

    def __init__(self, netzob):
        super(NetworkCapturer, self).__init__("NETWORK CAPTURER", netzob)
        # create logger with the given configuration
        self.bpfFilter = None
        self.importLayer = 4
        self._payloadDict = {}
        self.envDeps = EnvironmentalDependencies()

    @property
    def payloadDict(self):
        return self._payloadDict.copy()

    def setBPFFilter(self, bpfFilter):
        self.bpfFilter = bpfFilter

    def setImportLayer(self, importLayer):
        if not importLayer in [1, 2, 3, 4]:
            raise
        self.importLayer = importLayer

    def getNetworkDevices(self):
        interfaces = []
        # list of interfaces
        try:
            interfaces = pcapy.findalldevs()
        except:
            logging.warn("You don't have enough permissions to open any network interface on this system. Please look at the README.rst file for more information.")
        return interfaces

    def readMessages(self, callback_readMessage, device, count, time):
        """Read all messages from all opened PCAP files"""
        self.callback_readMessage = callback_readMessage
        self.envDeps.captureEnvData()  # Retrieve the environmental data (os specific, system specific, etc.)
        self.messages = []
        aSniffThread = threading.Thread(None, self.sniffingThread, None, (device, count, time), {})
        aSniffThread.start()

    #+----------------------------------------------
    #| Thread for sniffing work
    #+----------------------------------------------
    def sniffingThread(self, device, count, time):
        logging.info("Launching sniff process on dev {0} with: count={1}, timeout={2}, filter=\"{3}\"".format(device, count, time, self.bpfFilter))
        sniffer = pcapy.open_live(device, 1024, False, int(time))
        try:
            sniffer.setfilter(self.bpfFilter)
        except:
            logging.warn("The provided filter is not valid (it should respects the BPF format")
            return

        self.datalink = sniffer.datalink()
        if self.datalink != pcapy.DLT_EN10MB and self.datalink != pcapy.DLT_LINUX_SLL:
            errorMessage = _("This device cannot be sniffed since the "
                             + "layer 2 is not supported ({0})").format(str(self.datalink))
            self.log.warn(errorMessage)
            raise NetzobImportException("PCAP", errorMessage, ERROR,
                                        self.INVALID_LAYER2)
        else:
            sniffer.loop(int(count), self._packetHandler)

    def _packetHandler(self, header, payload):
        """Decode a packet"""
        mUuid = str(uuid.uuid4())
        mTimestamp = int(time.time())
        message = None
        if self.importLayer == 1:
            if len(payload) == 0:
                return
            message = RawMessage(
                mUuid,
                mTimestamp,
                payload.encode("hex"))
            self._payloadDict[mUuid] = payload
        elif self.importLayer == 2:
            (l2Proto, l2SrcAddr, l2DstAddr, l2Payload, etherType) = \
                self.decodeLayer2(header, payload)
            if len(l2Payload) == 0:
                return
            message = L2NetworkMessage(
                mUuid,
                mTimestamp,
                l2Payload.encode("hex"),
                l2Proto,
                l2SrcAddr,
                l2DstAddr)
            self._payloadDict[mUuid] = payload
        elif self.importLayer == 3:
            (l2Proto, l2SrcAddr, l2DstAddr, l2Payload, etherType) = \
                self.decodeLayer2(header, payload)
            try:
                (l3Proto, l3SrcAddr, l3DstAddr, l3Payload, ipProtocolNum) = \
                    self.decodeLayer3(etherType, l2Payload)
            except TypeError:
                return
            if len(l3Payload) == 0:
                return
            message = L3NetworkMessage(
                mUuid,
                mTimestamp,
                l3Payload.encode("hex"),
                l2Proto,
                l2SrcAddr,
                l2DstAddr,
                l3Proto,
                l3SrcAddr,
                l3DstAddr)
            self._payloadDict[mUuid] = payload
        else:
            (l2Proto, l2SrcAddr, l2DstAddr, l2Payload, etherType) = \
                self.decodeLayer2(header, payload)
            try:
                (l3Proto, l3SrcAddr, l3DstAddr, l3Payload, ipProtocolNum) = \
                    self.decodeLayer3(etherType, l2Payload)
                (l4Proto, l4SrcPort, l4DstPort, l4Payload) = \
                    self.decodeLayer4(ipProtocolNum, l3Payload)
            except TypeError:
                return
            if l4Payload.encode("hex") == "":
                return
            if len(l4Payload) == 0:
                return
            message = L4NetworkMessage(
                mUuid,
                mTimestamp,
                l4Payload.encode("hex"),
                l2Proto,
                l2SrcAddr,
                l2DstAddr,
                l3Proto,
                l3SrcAddr,
                l3DstAddr,
                l4Proto,
                l4SrcPort,
                l4DstPort)
            self._payloadDict[mUuid] = payload
        self.messages.append(message)
        self.callback_readMessage(message)

    def decodeLayer2(self, header, payload):
        def formatMacAddress(arrayMac):
            return ":".join("{0:0>2}".format(
                hex(b)[2:]) for b in arrayMac.tolist())

        if self.datalink == pcapy.DLT_EN10MB:
            l2Decoder = Decoders.EthDecoder()
            l2Proto = "Ethernet"
            layer2 = l2Decoder.decode(payload)
            l2SrcAddr = formatMacAddress(layer2.get_ether_shost())
            l2DstAddr = formatMacAddress(layer2.get_ether_dhost())
        elif self.datalink == pcapy.DLT_LINUX_SLL:
            l2Decoder = Decoders.LinuxSLLDecoder()
            l2Proto = "Linux SLL"
            layer2 = l2Decoder.decode(payload)
            l2SrcAddr = layer2.get_addr()
            l2DstAddr = None
        l2Payload = payload[layer2.get_header_size():]
        etherType = layer2.get_ether_type()
        return (l2Proto, l2SrcAddr, l2DstAddr, l2Payload, etherType)

    def decodeLayer3(self, etherType, l2Payload):
        if etherType == Packets.IP.ethertype:
            l3Proto = "IP"
            l3Decoder = Decoders.IPDecoder()
            layer3 = l3Decoder.decode(l2Payload)
            l3SrcAddr = layer3.get_ip_src()
            l3DstAddr = layer3.get_ip_dst()
            l3Payload = l2Payload[layer3.get_header_size():]
            ipProtocolNum = layer3.get_ip_p()
            return (l3Proto, l3SrcAddr, l3DstAddr, l3Payload, ipProtocolNum)
        else:
            warnMessage = _("Cannot import one of the provided packets since " +
                            "its layer 3 is unsupported (Only IP is " +
                            "currently supported, packet ethernet " +
                            "type = {0})").format(etherType)
            logging.warn(warnMessage)

    def decodeLayer4(self, ipProtocolNum, l3Payload):
            if ipProtocolNum == Packets.UDP.protocol:
                l4Proto = "UDP"
                l4Decoder = Decoders.UDPDecoder()
                layer4 = l4Decoder.decode(l3Payload)
                l4SrcPort = layer4.get_uh_sport()
                l4DstPort = layer4.get_uh_dport()
                l4Payload = layer4.get_data_as_string()
                return (l4Proto, l4SrcPort, l4DstPort, l4Payload)
            elif ipProtocolNum == Packets.TCP.protocol:
                l4Proto = "TCP"
                l4Decoder = Decoders.TCPDecoder()
                layer4 = l4Decoder.decode(l3Payload)
                l4SrcPort = layer4.get_th_sport()
                l4DstPort = layer4.get_th_dport()
                l4Payload = layer4.get_data_as_string()
                return (l4Proto, l4SrcPort, l4DstPort, l4Payload)
            else:
                warnMessage = "Cannot import one of the provided packets since its layer 4 is unsupported (Only UDP and TCP are currently supported, packet IP protocol number = {0})".format(ipProtocolNum)
                logging.warn(warnMessage)

    def getMessageDetails(self, messageID):
        if not messageID in self._payloadDict:
            errorMessage = "Message ID: {0} not found in importer message list".format(messageID)
            logging.error(errorMessage)
            raise NetzobImportException("PCAP", errorMessage, ERROR)
        decoder = Decoders.EthDecoder()
        payload = self._payloadDict[messageID]
        return decoder.decode(payload)
Exemple #14
0
    def init(self):
        # create the environmental dependancy object
        self.envDeps = EnvironmentalDependencies()

        # Default line separator is <CR>
        self.fileName = ""

        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # Main panel
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        self.panel = Gtk.Table(rows=10, columns=8, homogeneous=True)
        self.panel.show()

        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # Select a file
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        but = Gtk.Button(_("Select file(s)"))
        but.show()
        entry_filepath = Gtk.Entry()
        #        entry_filepath.set_width_chars(50)
        entry_filepath.set_text("")
        entry_filepath.show()
        but.connect("clicked", self.selectFiles, entry_filepath)
        self.panel.attach(
            but,
            0,
            2,
            0,
            1,
            xoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND,
            yoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND,
            xpadding=5,
            ypadding=5)

        self.panel.attach(
            entry_filepath,
            2,
            6,
            0,
            1,
            xoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND,
            yoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND,
            xpadding=5,
            ypadding=5)

        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        # Extracted data
        # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        scroll2 = Gtk.ScrolledWindow()
        self.lineView = Gtk.TreeView(Gtk.TreeStore(
            str, str, str))  # id message, type, content
        self.lineView.get_selection().set_mode(Gtk.SelectionMode.SINGLE)
        #self.lineView.connect('button-press-event', self.button_press_on_message)
        cell = Gtk.CellRendererText()
        # Col file descriptor
        column = Gtk.TreeViewColumn(_("Message ID"))
        column.pack_start(cell, True)
        column.add_attribute(cell, "text", 0)
        self.lineView.append_column(column)
        column = Gtk.TreeViewColumn(_("Type"))
        column.pack_start(cell, True)
        column.add_attribute(cell, "text", 1)
        self.lineView.append_column(column)
        column = Gtk.TreeViewColumn(_("Content"))
        column.pack_start(cell, True)
        column.add_attribute(cell, "text", 2)
        self.lineView.append_column(column)
        self.lineView.show()

        scroll2.add(self.lineView)
        scroll2.show()
        scroll2.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        self.panel.attach(scroll2,
                          0,
                          6,
                          1,
                          10,
                          xoptions=Gtk.AttachOptions.FILL,
                          yoptions=Gtk.AttachOptions.FILL
                          | Gtk.AttachOptions.EXPAND,
                          xpadding=5,
                          ypadding=5)

        # Button select packets for further analysis
        but = Gtk.Button(label=_("Import"))
        but.show()
        but.connect("clicked", self.import_file)
        self.panel.attach(but,
                          2,
                          3,
                          10,
                          11,
                          xoptions=0,
                          yoptions=0,
                          xpadding=5,
                          ypadding=5)
Exemple #15
0
    def init(self):

        # create the environmental dependancy object
        self.envDeps = EnvironmentalDependencies()

        # Network Capturing Panel
        self.panel = gtk.Table(rows=7, columns=4, homogeneous=False)
        self.panel.show()

        # Network devices
        label = gtk.Label(_("Network devices"))
        label.show()
        listNetworkDevice = gtk.combo_box_entry_new_text()
        listNetworkDevice.show()
        listNetworkDevice.set_size_request(300, -1)
        listNetworkDevice.set_model(gtk.ListStore(str))
        listNetworkDevice.get_model().clear()

        # list of interfaces
        try:
            interfaces = pcapy.findalldevs()
        except:
            self.log.warn(_("You don't have enough permissions to open any network interface on this system."))
            interfaces = []

        for interface in interfaces:
            listNetworkDevice.append_text(str(interface))

        self.panel.attach(label, 0, 1, 0, 1, xoptions=gtk.FILL, yoptions=0, xpadding=5, ypadding=5)
        self.panel.attach(listNetworkDevice, 1, 2, 0, 1, xoptions=gtk.FILL, yoptions=0, xpadding=5, ypadding=5)

        # BPF filter
        label = gtk.Label(_("BPF filter"))
        label.show()
        entry_filter = gtk.Entry()
        entry_filter.set_width_chars(50)
        entry_filter.show()
        entry_filter.set_text("tcp port 80")
        self.panel.attach(label, 0, 1, 1, 2, xoptions=gtk.FILL, yoptions=0, xpadding=5, ypadding=5)
        self.panel.attach(entry_filter, 1, 2, 1, 2, xoptions=gtk.FILL, yoptions=0, xpadding=5, ypadding=5)

        # Count capturing limit
        label = gtk.Label(_("Count limit"))
        label.show()
        entry_count = gtk.Entry()
        entry_count.show()
        entry_count.set_text("10")
        self.panel.attach(label, 0, 1, 2, 3, xoptions=0, yoptions=0, xpadding=5, ypadding=5)
        self.panel.attach(entry_count, 1, 2, 2, 3, xoptions=0, yoptions=0, xpadding=5, ypadding=5)

        # Time capturing limit
        label = gtk.Label(_("Timeout"))
        label.show()
        entry_time = gtk.Entry()
        entry_time.show()
        entry_time.set_text("10")
        self.panel.attach(label, 0, 1, 3, 4, xoptions=0, yoptions=0, xpadding=5, ypadding=5)
        self.panel.attach(entry_time, 1, 2, 3, 4, xoptions=0, yoptions=0, xpadding=5, ypadding=5)

        # Sniff launching button
        but = gtk.Button(label=_("Sniff traffic"))
        but.show()
        but.connect("clicked", self.launch_sniff, listNetworkDevice, entry_filter, entry_count, entry_time)
        self.panel.attach(but, 1, 2, 5, 6, xoptions=0, yoptions=0, xpadding=5, ypadding=5)

        # Packet list
        scroll = gtk.ScrolledWindow()
        self.treestore = gtk.TreeStore(int, str, str, str, str, str, int)  # pktID, proto (udp/tcp), IP.src, IP.dst, sport, dport, timestamp
        treeview = gtk.TreeView(self.treestore)
        treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
        treeview.connect("cursor-changed", self.packet_details)
        cell = gtk.CellRendererText()
        # Col proto
        column = gtk.TreeViewColumn(_("Proto"))
        column.pack_start(cell, True)
        column.set_attributes(cell, text=1)
        treeview.append_column(column)
        # Col IP.src
        column = gtk.TreeViewColumn(_("IP source"))
        column.pack_start(cell, True)
        column.set_attributes(cell, text=2)
        treeview.append_column(column)
        # Col IP.dst
        column = gtk.TreeViewColumn(_("IP dest"))
        column.pack_start(cell, True)
        column.set_attributes(cell, text=3)
        treeview.append_column(column)
        # Col {TCP,UDP}.sport
        column = gtk.TreeViewColumn(_("sport"))
        column.pack_start(cell, True)
        column.set_attributes(cell, text=4)
        treeview.append_column(column)
        # Col {TCP,UDP}.dport
        column = gtk.TreeViewColumn(_("dport"))
        column.pack_start(cell, True)
        column.set_attributes(cell, text=5)
        treeview.append_column(column)
        treeview.show()
        scroll.add(treeview)
        scroll.show()
        scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.panel.attach(scroll, 0, 2, 4, 5, xoptions=gtk.FILL, yoptions=gtk.FILL | gtk.EXPAND, xpadding=5, ypadding=5)
        # Button select packets for further analysis
        but = gtk.Button(label=_("Save selected packets"))
        but.show()
        but.connect("clicked", self.save_packets, treeview)
        self.panel.attach(but, 1, 2, 6, 7, xoptions=0, yoptions=0, xpadding=5, ypadding=5)

        # Packet detail
        scroll = gtk.ScrolledWindow()
        self.textview = gtk.TextView()
        self.textview.show()
        self.textview.get_buffer().create_tag("normalTag", family="Courier")
        scroll.add(self.textview)
        scroll.show()
        scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.panel.attach(scroll, 2, 4, 0, 7, xoptions=gtk.FILL | gtk.EXPAND, yoptions=gtk.FILL | gtk.EXPAND, xpadding=5, ypadding=5)
Exemple #16
0
class NetworkImport(AbstractImporter):

    def new(self):
        pass

    def update(self):
        pass

    def clear(self):
        pass

    def kill(self):
        pass

    #+-----------------------------------------------------------------------+
    #| Constructor:
    #| @param zob: a reference to the main netzob.py
    #+-----------------------------------------------------------------------+
    def __init__(self, zob):
        AbstractImporter.__init__(self, "NETWORK IMPORT")
        self.zob = zob
        # create logger with the given configuration
        self.log = logging.getLogger('netzob.Import.Network.py')
        self.packets = []

        self.init()

        self.dialog = gtk.Dialog(title=_("Capture network trafic"), flags=0, buttons=None)
        self.dialog.show()
        self.dialog.vbox.pack_start(self.getPanel(), True, True, 0)
        self.dialog.set_size_request(900, 700)

    def init(self):

        # create the environmental dependancy object
        self.envDeps = EnvironmentalDependencies()

        # Network Capturing Panel
        self.panel = gtk.Table(rows=7, columns=4, homogeneous=False)
        self.panel.show()

        # Network devices
        label = gtk.Label(_("Network devices"))
        label.show()
        listNetworkDevice = gtk.combo_box_entry_new_text()
        listNetworkDevice.show()
        listNetworkDevice.set_size_request(300, -1)
        listNetworkDevice.set_model(gtk.ListStore(str))
        listNetworkDevice.get_model().clear()

        # list of interfaces
        try:
            interfaces = pcapy.findalldevs()
        except:
            self.log.warn(_("You don't have enough permissions to open any network interface on this system."))
            interfaces = []

        for interface in interfaces:
            listNetworkDevice.append_text(str(interface))

        self.panel.attach(label, 0, 1, 0, 1, xoptions=gtk.FILL, yoptions=0, xpadding=5, ypadding=5)
        self.panel.attach(listNetworkDevice, 1, 2, 0, 1, xoptions=gtk.FILL, yoptions=0, xpadding=5, ypadding=5)

        # BPF filter
        label = gtk.Label(_("BPF filter"))
        label.show()
        entry_filter = gtk.Entry()
        entry_filter.set_width_chars(50)
        entry_filter.show()
        entry_filter.set_text("tcp port 80")
        self.panel.attach(label, 0, 1, 1, 2, xoptions=gtk.FILL, yoptions=0, xpadding=5, ypadding=5)
        self.panel.attach(entry_filter, 1, 2, 1, 2, xoptions=gtk.FILL, yoptions=0, xpadding=5, ypadding=5)

        # Count capturing limit
        label = gtk.Label(_("Count limit"))
        label.show()
        entry_count = gtk.Entry()
        entry_count.show()
        entry_count.set_text("10")
        self.panel.attach(label, 0, 1, 2, 3, xoptions=0, yoptions=0, xpadding=5, ypadding=5)
        self.panel.attach(entry_count, 1, 2, 2, 3, xoptions=0, yoptions=0, xpadding=5, ypadding=5)

        # Time capturing limit
        label = gtk.Label(_("Timeout"))
        label.show()
        entry_time = gtk.Entry()
        entry_time.show()
        entry_time.set_text("10")
        self.panel.attach(label, 0, 1, 3, 4, xoptions=0, yoptions=0, xpadding=5, ypadding=5)
        self.panel.attach(entry_time, 1, 2, 3, 4, xoptions=0, yoptions=0, xpadding=5, ypadding=5)

        # Sniff launching button
        but = gtk.Button(label=_("Sniff traffic"))
        but.show()
        but.connect("clicked", self.launch_sniff, listNetworkDevice, entry_filter, entry_count, entry_time)
        self.panel.attach(but, 1, 2, 5, 6, xoptions=0, yoptions=0, xpadding=5, ypadding=5)

        # Packet list
        scroll = gtk.ScrolledWindow()
        self.treestore = gtk.TreeStore(int, str, str, str, str, str, int)  # pktID, proto (udp/tcp), IP.src, IP.dst, sport, dport, timestamp
        treeview = gtk.TreeView(self.treestore)
        treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
        treeview.connect("cursor-changed", self.packet_details)
        cell = gtk.CellRendererText()
        # Col proto
        column = gtk.TreeViewColumn(_("Proto"))
        column.pack_start(cell, True)
        column.set_attributes(cell, text=1)
        treeview.append_column(column)
        # Col IP.src
        column = gtk.TreeViewColumn(_("IP source"))
        column.pack_start(cell, True)
        column.set_attributes(cell, text=2)
        treeview.append_column(column)
        # Col IP.dst
        column = gtk.TreeViewColumn(_("IP dest"))
        column.pack_start(cell, True)
        column.set_attributes(cell, text=3)
        treeview.append_column(column)
        # Col {TCP,UDP}.sport
        column = gtk.TreeViewColumn(_("sport"))
        column.pack_start(cell, True)
        column.set_attributes(cell, text=4)
        treeview.append_column(column)
        # Col {TCP,UDP}.dport
        column = gtk.TreeViewColumn(_("dport"))
        column.pack_start(cell, True)
        column.set_attributes(cell, text=5)
        treeview.append_column(column)
        treeview.show()
        scroll.add(treeview)
        scroll.show()
        scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.panel.attach(scroll, 0, 2, 4, 5, xoptions=gtk.FILL, yoptions=gtk.FILL | gtk.EXPAND, xpadding=5, ypadding=5)
        # Button select packets for further analysis
        but = gtk.Button(label=_("Save selected packets"))
        but.show()
        but.connect("clicked", self.save_packets, treeview)
        self.panel.attach(but, 1, 2, 6, 7, xoptions=0, yoptions=0, xpadding=5, ypadding=5)

        # Packet detail
        scroll = gtk.ScrolledWindow()
        self.textview = gtk.TextView()
        self.textview.show()
        self.textview.get_buffer().create_tag("normalTag", family="Courier")
        scroll.add(self.textview)
        scroll.show()
        scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.panel.attach(scroll, 2, 4, 0, 7, xoptions=gtk.FILL | gtk.EXPAND, yoptions=gtk.FILL | gtk.EXPAND, xpadding=5, ypadding=5)

    #+----------------------------------------------
    #| Called when user select a list of packet
    #+----------------------------------------------
    def save_packets(self, button, treeview):
        currentProject = self.zob.getCurrentProject()
        # We compute the selected messages
        # Create the new XML structure
        messages = []
        selection = treeview.get_selection()
        (model, paths) = selection.get_selected_rows()
        for path in paths:
            iter = model.get_iter(path)
            if(model.iter_is_valid(iter)):
                packetID = model.get_value(iter, 0)
                proto = model.get_value(iter, 1)
                timestamp = str(model.get_value(iter, 6))
                packetPayload = self.packets[packetID]

                eth_decoder = Decoders.EthDecoder()
                ip_decoder = Decoders.IPDecoder()
                udp_decoder = Decoders.UDPDecoder()
                tcp_decoder = Decoders.TCPDecoder()

                IPsrc = None
                IPdst = None
                Sport = None
                Dport = None
                Data = None

                ethernet = eth_decoder.decode(packetPayload)
                if ethernet.get_ether_type() == Packets.IP.ethertype:
                    ip = ip_decoder.decode(packetPayload[ethernet.get_header_size():])
                    IPsrc = ip.get_ip_src()
                    IPdst = ip.get_ip_dst()

                    if ip.get_ip_p() == Packets.UDP.protocol:
                        udp = udp_decoder.decode(packetPayload[ethernet.get_header_size() + ip.get_header_size():])
                        Sport = udp.get_uh_sport()
                        Dport = udp.get_uh_dport()
                        Data = udp.get_data_as_string()
                    if ip.get_ip_p() == Packets.TCP.protocol:
                        tcp = tcp_decoder.decode(packetPayload[ethernet.get_header_size() + ip.get_header_size():])
                        Sport = tcp.get_th_sport()
                        Dport = tcp.get_th_dport()
                        Data = tcp.get_data_as_string()

                # Compute the messages
                message = NetworkMessage(uuid.uuid4(), timestamp, Data.encode("hex"), IPsrc, IPdst, proto, Sport, Dport)
                messages.append(message)

        # We ask the confirmation
        md = gtk.MessageDialog(None,
                               gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION,
                               gtk.BUTTONS_OK_CANCEL, (_("Are you sure to import the %s selected packets in project %s?") % (str(len(messages)), currentProject.getName())))
#        md.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
        resp = md.run()
        md.destroy()

        if resp == gtk.RESPONSE_OK:
            self.saveMessagesInProject(self.zob.getCurrentWorkspace(), currentProject, messages)
        self.dialog.destroy()

        # We update the gui
        self.zob.update()

    #+----------------------------------------------
    #| Called when user select a packet for details
    #+----------------------------------------------
    def packet_details(self, treeview):
        (model, paths) = treeview.get_selection().get_selected_rows()
        decoder = Decoders.EthDecoder()
        for path in paths[:1]:
            iter = model.get_iter(path)
            if(model.iter_is_valid(iter)):
                packetID = model.get_value(iter, 0)
                payload = self.packets[packetID]
                self.textview.get_buffer().set_text("")
                self.textview.get_buffer().insert_with_tags_by_name(self.textview.get_buffer().get_start_iter(), str(decoder.decode(payload)), "normalTag")

    #+----------------------------------------------
    #| Called when launching sniffing process
    #+----------------------------------------------
    def launch_sniff(self, button, dev, filter, count, time):
        button.set_sensitive(False)
        self.envDeps.captureEnvData()  # Retrieve the environmental data (os specific, system specific, etc.)
        self.packets = []
        self.treestore.clear()
        self.textview.get_buffer().set_text("")
        aSniffThread = threading.Thread(None, self.sniffingThread, None, (button, dev, filter, count, time), {})
        aSniffThread.start()

    #+----------------------------------------------
    #| Thread for sniffing work
    #+----------------------------------------------
    def sniffingThread(self, button, devstore, filter, count, time):
        modele = devstore.get_model()
        est_actif = devstore.get_active()
        dev = ""
        if est_actif < 0:
            dev = ""
        dev = modele[est_actif][0]

        self.log.info(_("Launching sniff process on dev {0} with : count={1}, timeout={2}, filter=\"{3}\"").format(dev, count.get_text(), time.get_text(), filter.get_text()))

        sniffer = pcapy.open_live(dev, 1024, False, int(time.get_text()))

        try:
            sniffer.setfilter(filter.get_text())
        except:
            self.log.warn(_("The provided filter is not valid (it should respects the BPF format"))
            button.set_sensitive(True)
            return

        sniffer.loop(int(count.get_text()), self.packetHandler)
        button.set_sensitive(True)

    def packetHandler(self, header, payload):
        # Definition of the protocol decoders (impacket)
        eth_decoder = Decoders.EthDecoder()
        ip_decoder = Decoders.IPDecoder()
        udp_decoder = Decoders.UDPDecoder()
        tcp_decoder = Decoders.TCPDecoder()

        ethernet = eth_decoder.decode(payload)
        if ethernet.get_ether_type() == Packets.IP.ethertype:
            ip = ip_decoder.decode(payload[ethernet.get_header_size():])
            if ip.get_ip_p() == Packets.UDP.protocol:
                udp = udp_decoder.decode(payload[ethernet.get_header_size() + ip.get_header_size():])
                if len(udp.get_data_as_string()) > 0:
                    self.treestore.append(None, [len(self.packets), "UDP", ip.get_ip_src(), ip.get_ip_dst(), udp.get_uh_sport(), udp.get_uh_dport(), int(time.time())])
                    self.packets.append(payload)

            if ip.get_ip_p() == Packets.TCP.protocol:
                tcp = tcp_decoder.decode(payload[ethernet.get_header_size() + ip.get_header_size():])
                if len(tcp.get_data_as_string()) > 0:
                    self.treestore.append(None, [len(self.packets), "TCP", ip.get_ip_src(), ip.get_ip_dst(), tcp.get_th_sport(), tcp.get_th_dport(), int(time.time())])
                    self.packets.append(payload)

    #+----------------------------------------------
    #| GETTERS
    #+----------------------------------------------
    def getPanel(self):
        return self.panel