Exemplo n.º 1
0
 def delete(self):
     """
     Deletes the Ip represented by this model in database.
     Also deletes the tools associated with this ip
     Also deletes the ports associated with this ip
     Also deletes the defects associated with this ip and its ports
     """
     mongoInstance = MongoCalendar.getInstance()
     tools = mongoInstance.find("tools", {"ip": self.ip}, True)
     for tool in tools:
         tool_model = Tool(tool)
         tool_model.delete()
     defects = mongoInstance.find(
         "defects", {
             "ip": self.ip,
             "$or": [{
                 "port": {
                     "$exists": False
                 }
             }, {
                 "port": None
             }]
         }, True)
     for defect in defects:
         defect_model = Defect(defect)
         defect_model.delete()
     ports = mongoInstance.find("ports", {"ip": self.ip}, True)
     for port in ports:
         port_model = Port(port)
         port_model.delete()
     mongoInstance.delete("ips", {"_id": self._id})
Exemplo n.º 2
0
 def update(self, pipeline_set=None):
     """Update this object in database.
     Args:
         pipeline_set: (Opt.) A dictionnary with custom values. If None (default) use model attributes.
     """
     oldPort = Port.fetchObject({"_id": ObjectId(self._id)})
     if oldPort is None:
         return
     oldService = oldPort.service
     mongoInstance = MongoCalendar.getInstance()
     if oldService != self.service:
         mongoInstance.delete("tools", {
                              "lvl": "port", "ip": self.ip, "port": self.port, "proto": self.proto}, many=True)
         port_commands = mongoInstance.findInDb(
             "pollenisator", "commands", {"lvl": "port"})
         for port_command in port_commands:
             allowed_services = port_command["ports"].split(",")
             for i, elem in enumerate(allowed_services):
                 if not(elem.strip().startswith("tcp/") or elem.strip().startswith("udp/")):
                     allowed_services[i] = "tcp/"+str(elem)
             if self.proto+"/"+str(self.service) in allowed_services:
                 waves = mongoInstance.find("waves", {"wave_commands": {"$elemMatch": {
                     "$eq": port_command["name"].strip()}}})
                 for wave in waves:
                     tool_m = Tool().initialize(port_command["name"], wave["wave"], "",
                                                self.ip, self.port, self.proto, "port")
                     tool_m.addInDb()
     # Update variable instance. (this avoid to refetch the whole command in database)
     if pipeline_set is None:
         mongoInstance.update("ports", {"_id": ObjectId(self._id)}, {
             "$set": {"service": self.service, "product":self.product, "notes": self.notes, "tags": self.tags, "infos": self.infos}})
     else:
         mongoInstance.update("ports", {"_id": ObjectId(self._id)}, {
             "$set": pipeline_set})
Exemplo n.º 3
0
def resetUnfinishedTools():
    """
    Reset all tools running to a ready state. This is useful if a command was running on a worker and the auto scanning was interrupted.
    """
    # test all the cases if datef is defined or not.
    # Normally, only the first one is necessary
    from core.Models.Tool import Tool
    tools = Tool.fetchObjects({"datef": "None", "scanner_ip": {"$ne": "None"}})
    for tool in tools:
        tool.markAsNotDone()
    tools = Tool.fetchObjects({"datef": "None", "dated": {"$ne": "None"}})
    for tool in tools:
        tool.markAsNotDone()
    tools = Tool.fetchObjects({
        "datef": {
            "$exists": False
        },
        "dated": {
            "$ne": "None"
        }
    })
    for tool in tools:
        tool.markAsNotDone()
    tools = Tool.fetchObjects({
        "datef": {
            "$exists": False
        },
        "scanner_ip": {
            "$ne": "None"
        }
    })
    for tool in tools:
        tool.markAsNotDone()
Exemplo n.º 4
0
 def addInTreeview(self, parentNode=None, addChildren=True):
     """Add this view in treeview. Also stores infos in application treeview.
     Args:
         parentNode: if None, will calculate the parent. If setted, forces the node to be inserted inside given parentNode.
         addChildren: If False, skip the tool insert. Useful when displaying search results
     """
     parentDbId = parentNode
     if parentNode is None:
         parentNode = self.getParent()
     elif 'scopes' not in parentNode:
         parentNode = ScopeView.DbToTreeviewListId(parentDbId)
     self.appliTw.views[str(self.controller.getDbId())] = {"view": self}
     try:
         parentNode = self.appliTw.insert(self.controller.getParent(),
                                          0,
                                          parentNode,
                                          text="Scopes",
                                          image=self.getClassIcon())
     except TclError:  #  trigger if tools list node already exist
         pass
     self.appliTw.insert(parentNode,
                         "end",
                         str(self.controller.getDbId()),
                         text=str(self.controller.getModelRepr()),
                         tags=self.controller.getTags(),
                         image=self.getClassIcon())
     if addChildren:
         tools = self.controller.getTools()
         for tool in tools:
             tool_o = ToolController(Tool(tool))
             tool_vw = ToolView(self.appliTw, self.appliViewFrame,
                                self.mainApp, tool_o)
             tool_vw.addInTreeview(str(self.controller.getDbId()))
     if "hidden" in self.controller.getTags():
         self.hide()
Exemplo n.º 5
0
 def loadData(self):
     """
     Fetch data from database
     """
     self.ports = Port.fetchObjects({})
     self.ips = Ip.fetchObjects({})
     self.tools = Tool.fetchObjects({})
Exemplo n.º 6
0
def findLaunchableTools():
    """
    Try to find tools that matches all criteria.

    Returns:
        A tuple with two values:
            * A list of launchable tools as dictionary with values _id, name and priority
            * A dictionary of waiting tools with tool's names as keys and integer as value.
    """
    toolsLaunchable = []
    waiting = {}
    time_compatible_waves_id = Wave.searchForAddressCompatibleWithTime()
    for wave_id in time_compatible_waves_id:
        commandsLaunchableWave = Wave.getNotDoneTools(wave_id)
        for tool in commandsLaunchableWave:
            toolModel = Tool.fetchObject({"_id": tool})
            try:
                waiting[str(toolModel)] += 1
            except KeyError:
                waiting[str(toolModel)] = 1
            command = toolModel.getCommand()
            if command is None:
                prio = 0
            else:
                prio = int(command.get("priority", 0))
            toolsLaunchable.append({
                "_id": tool,
                "name": str(toolModel),
                "priority": prio
            })

    return toolsLaunchable, waiting
Exemplo n.º 7
0
 def delete(self):
     """
     Delete the Scope represented by this model in database.
     Also delete the tools associated with this scope
     Also remove this scope from ips in_scopes attributes
     """
     # deleting tool with scope lvl
     tools = Tool.fetchObjects({
         "scope":
         self.scope,
         "wave":
         self.wave,
         "$or": [{
             "lvl": "network"
         }, {
             "lvl": "domain"
         }]
     })
     for tool in tools:
         tool.delete()
     # Deleting this scope against every ips
     ips = Ip.getIpsInScope(self._id)
     for ip in ips:
         ip.removeScopeFitting(self._id)
     mongoInstance = MongoCalendar.getInstance()
     mongoInstance.delete("scopes", {"_id": self._id})
     parent_wave = mongoInstance.find("waves", {"wave": self.wave}, False)
     if parent_wave is None:
         return
     mongoInstance.notify(mongoInstance.calendarName, "waves",
                          parent_wave["_id"], "update", "")
Exemplo n.º 8
0
    def announce_failed_tasks(self, event):
        """
        Called when a celery task fails. Is used to reset dates and scanner of the targeted tool.

        Args:
            event: created automatically when the event occurs. Contains some info about the task
        """
        self.state.event(event)
        task = self.state.tasks.get(event['uuid'])  # get task
        # Get tasks arguments
        try:
            argsWere = json.loads(task.info()["args"].replace("'", "\""))
            args = argsWere[0]
            toolId = ObjectId(args[1])  # args[1] is the tool_id
            for task_running in self.tasks_running:
                if str(task_running[1]) == str(toolId):
                    task_running[0].revoke(terminate=True)
                    del task_running
            tool = Tool.fetchObject({"_id": ObjectId(toolId)})
            tool.markAsNotDone()
        except InvalidId:
            pass
        except json.decoder.JSONDecodeError:
            pass
        except KeyError:
            pass  # Plugin failed so "args" does not exist
Exemplo n.º 9
0
 def getAllTools(self):
     """Return all tools being part of this wave as a list of mongo fetched tools dict.
     Differs from getTools as it fetches all tools of the name and not only tools of level wave.
     Returns:
         list of defect raw mongo data dictionnaries
     """
     return Tool.fetchObjects({"wave": self.wave})
Exemplo n.º 10
0
 def _insertChildrenTools(self):
     """Create a tools list node and insert every children tools in database as ToolView under this node"""
     tools = self.controller.getTools()
     for tool in tools:
         tool_o = ToolController(Tool(tool))
         tool_vw = ToolView(self.appliTw, self.appliViewFrame, self.mainApp,
                            tool_o)
         tool_vw.addInTreeview(str(self.controller.getDbId()))
Exemplo n.º 11
0
 def setToolsInTime(self):
     """Get all OOT (Out of Time) tools in this wave and checks if this Interval makes them in time. 
     If it is the case, set them in time.
     """
     if Utils.fitNowTime(self.dated, self.datef):
         tools = Tool.fetchObjects({"wave": self.wave, "status": "OOT"})
         for tool in tools:
             tool.setInTime()
Exemplo n.º 12
0
 def delete(self):
     """
     Deletes the Port represented by this model in database.
     Also deletes the tools associated with this port
     Also deletes the defects associated with this port
     """
     mongoInstance = MongoCalendar.getInstance()
     tools = mongoInstance.find("tools", {"port": self.port, "proto": self.proto,
                                          "ip": self.ip}, True)
     for tool in tools:
         tool_model = Tool(tool)
         tool_model.delete()
     defects = mongoInstance.find("defects", {"port": self.port, "proto": self.proto,
                                              "ip": self.ip}, True)
     for defect in defects:
         defect_model = Defect(defect)
         defect_model.delete()
     mongoInstance.delete("ports", {"_id":  ObjectId(self._id)})
Exemplo n.º 13
0
 def removeScopeFitting(self, scopeId):
     """Remove the given scopeId from the list of scopes this IP fits in.
     Args:
         scopeId: a mongo ObjectId of a scope object.
     """
     if str(scopeId) in self.in_scopes:
         self.in_scopes.remove(str(scopeId))
         self.update()
         if not self.in_scopes:
             tools = Tool.fetchObjects({"ip": self.ip})
             for tool in tools:
                 tool.setOutOfScope()
Exemplo n.º 14
0
    def removeAllTool(self, command_name):
        """
        Remove from every member of this wave the old tool corresponding to given command name but only if the tool is not done.
        We preserve history

        Args:
            command_name: The command that we want to remove all the tools.
        """
        tools = Tool.fetchObjects({"name": command_name, "wave": self.wave})
        for tool in tools:
            if "done" not in tool.getStatus():
                tool.delete()
Exemplo n.º 15
0
 def addScopeFitting(self, scopeId):
     """Add the given scopeId to the list of scopes this IP fits in.
     Args:
         scopeId: a mongo ObjectId of a Scope object.
     """
     if not self.in_scopes:
         tools = Tool.fetchObjects({"ip": self.ip})
         for tool in tools:
             tool.setInScope()
     if str(scopeId) not in self.in_scopes:
         self.in_scopes.append(str(scopeId))
         self.update()
Exemplo n.º 16
0
def dispatchLaunchableTools(my_monitor, launchableTools):
    """
    Try to launch given tools within the monitor

    Args:
        my_monitor: A Monitor instance which knows what tools are already launched and online workers
        launchableTools: A list of tools within a Wave that passed the Intervals checking.
    """
    mongoInstance = MongoCalendar.getInstance()
    for launchableTool in launchableTools:
        tool = Tool.fetchObject({"_id": ObjectId(launchableTool["_id"])})
        my_monitor.launchTask(mongoInstance.calendarName, tool)
Exemplo n.º 17
0
    def addAllTool(self, command_name, wave_name, scope):
        """
        Kind of recursive operation as it will call the same function in its children ports.
        Add the appropriate tools (level check and wave's commands check) for this ip.
        Also add for all registered ports the appropriate tools.

        Args:
            command_name: The command that we want to create all the tools for.
            wave_name: the wave name from where we want to load tools
            scope: a scope object allowing to launch this command. Opt
        """
        # retrieve the command level
        mongoInstance = MongoCalendar.getInstance()
        command = mongoInstance.findInDb(mongoInstance.calendarName,
                                         "commands", {"name": command_name}, False)
        if command["lvl"] == "ip":
            # finally add tool
            newTool = Tool()
            newTool.initialize(command_name, wave_name,
                               "", self.ip, "", "", "ip")
            newTool.addInDb()
            return
        # Do the same thing for all children ports.
        ports = mongoInstance.find("ports", {"ip": self.ip})
        for port in ports:
            p = Port(port)
            p.addAllTool(command_name, wave_name, scope)
Exemplo n.º 18
0
 def refreshUI(self):
     """Reload informations and renew widgets"""
     mongoInstance = MongoCalendar.getInstance()
     workernames = self.monitor.getWorkerList()
     running_scans = Tool.fetchObjects({"status":"running"})
     for children in self.scanTv.get_children():
         self.scanTv.delete(children)
     for running_scan in running_scans:
         self.scanTv.insert('','end', running_scan.getId(), text=running_scan.name, values=(running_scan.dated), image=self.running_icon)
     for children in self.workerTv.get_children():
         self.workerTv.delete(children)
     registeredCommands = set()
     for workername in workernames:
         try:
             worker_node = self.workerTv.insert(
                 '', 'end', workername, text=workername, image=self.ok_icon)
         except tk.TclError:
             worker_node = self.workerTv.item(workername)
         worker_registered = mongoInstance.findInDb("pollenisator", "workers", {"name":workername}, False)
         commands_registered = worker_registered["registeredCommands"]
         for command in commands_registered:
             try:
                 self.workerTv.insert(
                     worker_node, 'end', command, text=command, image=self.ok_icon)
             except tk.TclError:
                 pass
             registeredCommands.add(str(command))
         allCommands = Command.getList(None, mongoInstance.calendarName)
         for command in allCommands:
             if command not in registeredCommands:
                 try:
                     self.workerTv.insert(
                         worker_node, '0', 'notRegistered|'+command, text=command, image=self.nok_icon)
                 except tk.TclError:
                     pass
             else:
                 try:
                     self.workerTv.delete('notRegistered|'+command)
                 except tk.TclError:
                     pass
     if len(registeredCommands) > 0 and self.btn_autoscan is None:
         if self.running_auto_scans:
             self.btn_autoscan = ttk.Button(
                 self.parent, text="Stop Scanning", command=self.stopAutoscan)
             self.btn_autoscan.pack()
         else:
             self.btn_autoscan = ttk.Button(
                 self.parent, text="Start Scanning", command=self.startAutoscan)
             self.btn_autoscan.pack()
Exemplo n.º 19
0
    def addInTreeview(self, parentNode=None, addChildren=True):
        """Add this view in treeview. Also stores infos in application treeview.
        Args:
            parentNode: if None, will calculate the parent. If setted, forces the node to be inserted inside given parentNode.
            addChildren: If False, skip the tool and defects insert. Useful when displaying search results
        """
        if parentNode is None:
            parentNode = self.getParent()
            nodeText = str(self.controller.getModelRepr())
        elif parentNode == '':
            nodeText = self.controller.getDetailedString()
        else:
            nodeText = str(self.controller.getModelRepr())
        self.appliTw.views[str(self.controller.getDbId())] = {"view": self}
        try:
            self.appliTw.insert(parentNode,
                                "end",
                                str(self.controller.getDbId()),
                                text=nodeText,
                                tags=self.controller.getTags(),
                                image=self.getClassIcon())
        except TclError:
            pass
        if addChildren:
            defects = self.controller.getDefects()
            for defect in defects:
                defect_o = DefectController(Defect(defect))
                defect_vw = DefectView(self.appliTw, self.appliViewFrame,
                                       self.mainApp, defect_o)
                defect_vw.addInTreeview(str(self.controller.getDbId()))

            tools = self.controller.getTools()
            for tool in tools:
                tool_o = ToolController(Tool(tool))
                tool_vw = ToolView(self.appliTw, self.appliViewFrame,
                                   self.mainApp, tool_o)
                tool_vw.addInTreeview(str(self.controller.getDbId()))
        tools = self.controller.getTools()
        atleastone = False
        for tool in tools:  # SALE
            atleastone = True
            break
        if not atleastone:
            if len(self.controller.getTags()) == 0:
                self.controller.addTag("unscanned")
        self.appliTw.sort(parentNode)
        if "hidden" in self.controller.getTags():
            self.hide()
Exemplo n.º 20
0
    def announce_offline_worker(self, event):
        """
        Called when a celery worker gets offline nicely. Is used to remove this worker from the worker_list

        Args:
            event: created automatically when the event occurs. Contains some info about the worker
        """
        worker_hostname = event["hostname"].strip()
        workers = self.getWorkerList()
        print("RECEIVE OFFLINE WORKER "+str(worker_hostname))

        if worker_hostname in list(workers):
            toolsToReset = Tool.fetchObjects(
                {"datef": "None", "scanner_ip": worker_hostname})
            for tool in toolsToReset:
                tool.markAsNotDone()
            self.removeWorker(worker_hostname)
Exemplo n.º 21
0
def findLaunchableToolsOnWorker(worker, calendarName):
    """ 
    Try to find tools that matches all criteria.
    Args:
        workerName: the current working worker
    Returns:
        A tuple with two values:
            * A list of launchable tools as dictionary with values _id, name and priority
            * A dictionary of waiting tools with tool's names as keys and integer as value.
    """
    mongoInstance = MongoCalendar.getInstance()
    mongoInstance.connectToDb(calendarName)
    toolsLaunchable = []
    worker_registered = mongoInstance.findInDb("pollenisator", "workers",
                                               {"name": worker.name}, False)
    commands_registered = worker_registered["registeredCommands"]

    waiting = {}
    time_compatible_waves_id = Wave.searchForAddressCompatibleWithTime()
    for wave_id in time_compatible_waves_id:
        commandsLaunchableWave = Wave.getNotDoneTools(wave_id)
        for tool in commandsLaunchableWave:

            toolModel = Tool.fetchObject({"_id": tool})
            if toolModel.name not in commands_registered:
                continue
            if worker.hasRegistered(toolModel):

                try:
                    waiting[str(toolModel)] += 1
                except KeyError:
                    waiting[str(toolModel)] = 1
                command = toolModel.getCommand()
                if command is None:
                    prio = 0
                else:
                    prio = int(command.get("priority", 0))
                toolsLaunchable.append({
                    "_id": tool,
                    "name": str(toolModel),
                    "priority": prio,
                    "errored": "error" in toolModel.status
                })

    return toolsLaunchable, waiting
Exemplo n.º 22
0
 def customCommand(self, _event=None):
     """
     Ask the user for a custom tool to launch and which parser it will use.
     Args:
         _event: not used but mandatory
     """
     mongoInstance = MongoCalendar.getInstance()
     workers = self.appli.scanManager.monitor.getWorkerList()
     workers.append("localhost")
     dialog = ChildDialogCustomCommand(self, workers, "localhost")
     self.wait_window(dialog.app)
     if isinstance(dialog.rvalue, tuple):
         commName = dialog.rvalue[0]
         commArgs = dialog.rvalue[1]
         parser = dialog.rvalue[2]
         worker = dialog.rvalue[3]
     for selected in self.selection():
         view_o = self.getViewFromId(selected)
         if view_o is not None:
             lvl = "network" if isinstance(view_o, ScopeView) else None
             lvl = "wave" if isinstance(view_o, WaveView) else lvl
             lvl = "ip" if isinstance(view_o, IpView) else lvl
             lvl = "port" if isinstance(view_o, PortView) else lvl
             if lvl is not None:
                 inst = view_o.controller.getData()
                 wave = inst.get("wave", "Custom commands")
                 if wave == "Custom commands":
                     Wave().initialize("Custom commands").addInDb()
                 tool = Tool()
                 tool.initialize(commName,
                                 wave,
                                 inst.get("scope", ""),
                                 inst.get("ip", None),
                                 inst.get("port", None),
                                 inst.get("proto", None),
                                 lvl,
                                 commArgs,
                                 dated="None",
                                 datef="None",
                                 scanner_ip="None",
                                 notes="Arguments: " + commArgs)
                 tool.addInDb()
                 if tool is None:
                     print("Tool already existing.")
                     return
                 self.appli.scanManager.monitor.launchTask(
                     mongoInstance.calendarName, tool, parser, False,
                     worker)
Exemplo n.º 23
0
    def addInDb(self):
        """
        Add this IP in database.

        Returns: a tuple with :
                * bool for success
                * mongo ObjectId : already existing object if duplicate, create object id otherwise 
        """
        # Checking unicity
        if self.ip.strip() == "":
            raise ValueError("Ip insertion error: Cannot insert empty ip")
        base = self.getDbKey()
        mongoInstance = MongoCalendar.getInstance()
        existing = mongoInstance.find(
            "ips", base, False)
        if existing is not None:
            return False, existing["_id"]
        # Add ip as it is unique
        base["parent"] = self.getParent()
        base["notes"] = self.notes
        base["tags"] = self.tags
        base["in_scopes"] = self.in_scopes
        base["infos"] = self.infos
        resInsert = mongoInstance.insert(
            "ips", base)
        self._id = resInsert.inserted_id
        # adding the appropriate tools for this port.
        # 1. fetching the wave's commands
        waves = mongoInstance.find("waves", {})
        for wave in waves:
            waveName = wave["wave"]
            commands = wave["wave_commands"]
            for commName in commands:
                # 2. finding the command only if lvl is port
                comm = mongoInstance.findInDb(mongoInstance.calendarName, "commands",
                                              {"name": commName, "lvl": "ip"}, False)
                if comm is not None:
                    # 3. checking if the added port fit into the command's allowed service
                    # 3.1 first, default the selected port as tcp if no protocole is defined.
                    newTool = Tool()
                    newTool.initialize(
                        comm["name"], waveName, "", self.ip, "", "", "ip")
                    newTool.addInDb()

        return True, self._id
Exemplo n.º 24
0
 def delete(self):
     """
     Delete the Interval represented by this model in database.
     """
     mongoInstance = MongoCalendar.getInstance()
     mongoInstance.delete(
         "intervals", {"_id": self._id})
     parent_wave = mongoInstance.find("waves", {"wave": self.wave}, False)
     self._id = None
     if parent_wave is None:
         return
     mongoInstance.notify(mongoInstance.calendarName,
                          "waves", parent_wave["_id"], "update", "")
     other_intervals = Interval.fetchObjects({"wave": self.wave})
     no_interval_in_time = True
     for other_interval in other_intervals:
         if Utils.fitNowTime(other_interval.dated, other_interval.datef):
             no_interval_in_time = False
             break
     if no_interval_in_time:
         tools = Tool.fetchObjects({"wave": self.wave})
         for tool in tools:
             tool.setOutOfTime()
Exemplo n.º 25
0
 def addAllTool(self, command_name):
     """
     Kind of recursive operation as it will call the same function in its children ports.
     Add the appropriate tools (level check and wave's commands check) for this wave.
     Also add for all registered scopes the appropriate tools.
     Args:
         command_name: The command that we want to create all the tools for.
     """
     mongoInstance = MongoCalendar.getInstance()
     command = mongoInstance.findInDb("pollenisator", "commands",
                                      {"name": command_name}, False)
     if command["lvl"] == "wave":
         newTool = Tool()
         newTool.initialize(command_name, self.wave, "", "", "", "", "wave")
         newTool.addInDb()
         return
     scopes = mongoInstance.find("scopes", {"wave": self.wave})
     for scope in scopes:
         h = Scope(scope)
         h.addAllTool(command_name)
Exemplo n.º 26
0
 def initUI(self, parent):
     """Create widgets and initialize them
     Args:
         parent: the parent tkinter widget container."""
     if self.workerTv is not None:
         self.refreshUI()
         return
     mongoInstance = MongoCalendar.getInstance()
     self.parent = parent
     ### WORKER TREEVIEW : Which worker knows which commands
     lblworker = ttk.Label(self.parent, text="Workers:")
     lblworker.pack(side=tk.TOP, padx=10, pady=5, fill=tk.X)
     self.workerTv = ttk.Treeview(self.parent)
     self.workerTv['columns'] = ('workers')
     self.workerTv.heading("#0", text='Workers', anchor=tk.W)
     self.workerTv.column("#0", anchor=tk.W)
     self.workerTv.pack(side=tk.TOP, padx=10, pady=10, fill=tk.X)
     registeredCommands = set()
     workernames = self.monitor.getWorkerList()
     for workername in workernames:
         worker_node = self.workerTv.insert('',
                                            'end',
                                            workername,
                                            text=workername,
                                            image=self.ok_icon)
         commands_registered = mongoInstance.getRegisteredCommands(
             workername)
         for command in commands_registered:
             self.workerTv.insert(worker_node,
                                  'end',
                                  None,
                                  text=command,
                                  image=self.ok_icon)
             registeredCommands.add(str(command))
     allCommands = Command.getList()
     for command in allCommands:
         if command not in registeredCommands:
             try:
                 self.workerTv.insert('',
                                      'end',
                                      'notRegistered',
                                      text='Laking commands',
                                      image=self.nok_icon)
             except tk.TclError:
                 self.workerTv.item('notRegistered')
             try:
                 self.workerTv.insert('notRegistered',
                                      'end',
                                      'notRegistered|' + str(command),
                                      text=str(command),
                                      image=self.nok_icon)
             except tk.TclError:
                 pass
     #### TREEVIEW SCANS : overview of ongoing auto scan####
     lblscan = ttk.Label(self.parent, text="Scan overview:")
     lblscan.pack(side=tk.TOP, padx=10, pady=5, fill=tk.X)
     self.scanTv = ttk.Treeview(self.parent)
     self.scanTv['columns'] = ('Started at')
     self.scanTv.heading("#0", text='Scans', anchor=tk.W)
     self.scanTv.column("#0", anchor=tk.W)
     self.scanTv.pack(side=tk.TOP, padx=10, pady=10, fill=tk.X)
     self.scanTv.bind("<Double-Button-1>", self.OnDoubleClick)
     running_scans = Tool.fetchObjects({"status": "running"})
     for running_scan in running_scans:
         self.scanTv.insert('',
                            'end',
                            running_scan.getId(),
                            text=running_scan.name,
                            values=(running_scan.dated),
                            image=self.running_icon)
     #### BUTTONS FOR AUTO SCANNING ####
     if len(registeredCommands) > 0:
         if self.running_auto_scans:
             self.btn_autoscan = ttk.Button(self.parent,
                                            text="Stop Scanning",
                                            command=self.stopAutoscan)
             self.btn_autoscan.pack()
         else:
             self.btn_autoscan = ttk.Button(self.parent,
                                            text="Start Scanning",
                                            command=self.startAutoscan)
             self.btn_autoscan.pack()
     btn_parse_scans = ttk.Button(self.parent,
                                  text="Parse existing files",
                                  command=self.parseFiles)
     btn_parse_scans.pack()
Exemplo n.º 27
0
 def getTools(self):
     """Return scope assigned tools as a list of mongo fetched tools dict
     Returns:
         list of defect raw mongo data dictionnaries
     """
     return Tool.fetchObjects({"wave": self.wave, "lvl": "wave"})
Exemplo n.º 28
0
def executeCommand(calendarName, toolId, parser=""):
    """
    CELERY remote task
    Execute the tool with the given toolId on the given calendar name.
    Then execute the plugin corresponding.
    Any unhandled exception will result in a task-failed event in the Monitor class.

    Args:
        calendarName: The calendar to search the given tool id for.
        toolId: the mongo Object id corresponding to the tool to execute.
        parser: plugin name to execute. If empty, the plugin specified in tools.d will be feteched.
    Raises:
        Terminated: if the task gets terminated
        OSError: if the output directory cannot be created (not if it already exists)
        Exception: if an exception unhandled occurs during the bash command execution.
        Exception: if a plugin considered a failure.
    """
    # Connect to given calendar
    mongoInstance = MongoCalendar.getInstance()
    mongoInstance.connectToDb(calendarName)
    msg = ""
    # retrieve tool from tool sid
    toolModel = Tool.fetchObject({"_id": ObjectId(toolId)})
    if toolModel is None:
        raise Exception("Tool does not exist : " + str(toolId))
    command = Command.fetchObject({"name": toolModel.name}, calendarName)
    # Get time limit and output directory
    if toolModel.wave == "Custom commands":
        timeLimit = None
    else:
        timeLimit = getWaveTimeLimit(toolModel.wave)
    if command is not None:
        timeLimit = min(datetime.now() + timedelta(0, int(command.timeout)),
                        timeLimit)
    outputRelDir = toolModel.getOutputDir(calendarName)
    abs_path = os.path.dirname(os.path.abspath(__file__))
    outputDir = os.path.join(abs_path, "./results", outputRelDir)
    # Create the output directory
    try:
        os.makedirs(outputDir)
    except OSError as exc:
        if exc.errno == errno.EEXIST and os.path.isdir(outputDir):
            pass
        else:
            raise exc
    # Read Tool config file
    tools_infos = Utils.loadToolsConfig()
    comm = toolModel.getCommandToExecute(outputDir)

    if parser.strip() == "":
        if toolModel.name not in list(tools_infos.keys()):
            msg = "TASK FAILED Received tool that was not registered : " + \
                str(toolModel.name)+" not in "+str(list(tools_infos.keys()))
            raise Exception(msg)
    # Fetch the command to execute
    if tools_infos.get(toolModel.name, None) is None:
        bin_path = ""
    else:
        bin_path = tools_infos[toolModel.name].get("bin")
        if bin_path is not None:
            if not bin_path.endswith(" "):
                bin_path = bin_path + " "
    comm = bin_path + comm
    if comm != "":
        try:

            # Load the plugin
            if parser.strip() == "":
                mod = Utils.loadPlugin(tools_infos[toolModel.name]["plugin"])
            elif parser.strip() == "auto-detect":
                mod = Utils.loadPluginByBin(toolModel.name.split("::")[0])
            else:
                mod = Utils.loadPlugin(parser)
            # Complete command with file output
            toolFileName = toolModel.name+"_" + \
                str(time.time())+mod.getFileOutputExt()
            comm = mod.changeCommand(comm, outputDir, toolFileName)
            print(('TASK STARTED:' + toolModel.name))
            print("Will timeout at " + str(timeLimit))
            # Execute the command with a timeout
            returncode = Utils.execute(comm, timeLimit, True)
        except Exception as e:
            raise e
        # Execute found plugin if there is one
        if mod is not None:
            filepath = mod.getFileOutputPath(comm)
            try:
                # Open generated file as utf8
                with io.open(filepath, "r", encoding="utf-8",
                             errors='ignore') as file_opened:
                    # Check return code by plugin (can be always true if the return code is inconsistent)
                    if mod.checkReturnCode(returncode):
                        notes, tags, _, _ = mod.Parse(file_opened)
                        if notes is None:
                            notes = "No results found by plugin."
                        if tags is None:
                            tags = []
                        if isinstance(tags, str):
                            tags = [tags]
                        # Success could be change to False by the plugin function (evaluating the return code for exemple)
                        # if the success is validated, mark tool as done
                        toolModel.markAsDone(
                            os.path.join(outputRelDir,
                                         os.path.basename(filepath)))
                        # And update the tool in database
                        toolModel.notes = notes
                        toolModel.tags = tags
                        toolModel.update()
                        # Upload file to SFTP
                        mod.centralizeFile(filepath, outputDir)
                        msg = "TASK SUCCESS : " + toolModel.name
                    else:  # BAS RESULT OF PLUGIN
                        msg = "TASK FAILED (says the mod) : " + toolModel.name
                        msg += "The return code was not the expected one. (" + str(
                            returncode) + ")."
                        toolModel.markAsError()
                        raise Exception(msg)
            except IOError as e:
                toolModel.tags = ["todo"]
                toolModel.notes = "Failed to read results file"
                toolModel.markAsDone()
        else:
            msg = "TASK FAILED (no plugin found) : " + toolModel.name
            toolModel.markAsNotDone()
            raise Exception(msg)
        # Delay
        if command is not None:
            if float(command.sleep_between) > 0.0:
                msg += " (will sleep for " + \
                    str(float(command.sleep_between))+")"
            print(msg)
            time.sleep(float(command.sleep_between))
        return
Exemplo n.º 29
0
 def addAllTool(self, command_name):
     """
     Add the appropriate tools (level check and wave's commands check) for this scope.
     Args:
         command_name: The command that we want to create all the tools for.
     """
     mongoInstance = MongoCalendar.getInstance()
     command = mongoInstance.findInDb("pollenisator", "commands",
                                      {"name": command_name}, False)
     if command["lvl"] == "network":
         newTool = Tool()
         newTool.initialize(command["name"], self.wave, self.scope, "", "",
                            "", "network")
         newTool.addInDb()
         return
     if command["lvl"] == "domain":
         if not Utils.isNetworkIp(self.scope):
             newTool = Tool()
             newTool.initialize(command["name"], self.wave, self.scope, "",
                                "", "", "domain")
             newTool.addInDb()
         return
     ips = self.getIpsFitting()
     for ip in ips:
         i = Ip(ip)
         i.addAllTool(command_name, self.wave, self.scope)
Exemplo n.º 30
0
    def addDomainInDb(self, checkDomain=True):
        """
        Add this scope domain in database.

        Args:
            checkDomain: boolean. If true (Default), checks that the domain IP is in scope

        Returns: a tuple with :
                * bool for success
                * mongo ObjectId : already existing object if duplicate, create object id otherwise 
        """
        # Checking unicity
        base = self.getDbKey()
        mongoInstance = MongoCalendar.getInstance()
        existing = mongoInstance.find("scopes", base, False)
        if existing is not None:
            return 0, None
        # Check if domain's ip fit in one of the Scope of the wave
        if checkDomain:
            if not Scope.checkDomainFit(self.wave, self.scope):
                return -1, None
        # insert the domains in the scopes
        parent = self.getParent()
        res_insert = mongoInstance.insert("scopes", base, parent)
        ret = res_insert.inserted_id
        self._id = ret
        # Adding appropriate tools for this scopes
        wave = mongoInstance.find("waves", {"wave": self.wave}, False)
        commands = wave["wave_commands"]
        for commName in commands:
            comm = mongoInstance.findInDb("pollenisator", "commands", {
                "name": commName,
                "lvl": "network"
            }, False)
            if comm is not None:
                newTool = Tool()
                newTool.initialize(comm["name"], self.wave, self.scope, "", "",
                                   "", "network")
                newTool.addInDb()
            else:
                comm = mongoInstance.findInDb("pollenisator", "commands", {
                    "name": commName,
                    "lvl": "domain"
                }, False)
                if comm is not None:
                    newTool = Tool()
                    newTool.initialize(comm["name"], self.wave, self.scope, "",
                                       "", "", "domain")
                    newTool.addInDb()
        # Testing this scope against every ips
        ips = Ip.fetchObjects({})
        for ip in ips:
            if self._id not in ip.in_scopes:
                if ip.fitInScope(self.scope):
                    ip.addScopeFitting(self.getId())
        ipToInsert = Ip()
        ipToInsert.initialize(self.scope)
        ipToInsert.addInDb()
        return 1, ret