Ejemplo n.º 1
0
def autoScan(databaseName, endless, useReprinter=False):
    """
    Search tools to launch within defined conditions and attempts to launch them on celery workers.
    Gives a visual feedback on stdout

    Args:
        databaseName: The database to search tools in
        endless: a boolean that indicates if the autoscan will be endless or if it will stop at the moment it does not found anymore launchable tools.
        useReprinter: a boolean that indicates if the array outpur will be entirely reprinted or if it will be overwritten.
    """
    mongoInstance = MongoCalendar.getInstance()
    mongoInstance.connectToDb(databaseName)
    my_monitor = Monitor(databaseName)
    Utils.resetUnfinishedTools()
    time_compatible_waves_id = Wave.searchForAddressCompatibleWithTime()
    killer = GracefulKiller()
    if not endless:
        killer.kill_now = len(time_compatible_waves_id) <= 0
        print("No wave compatible")
    else:
        killer.kill_now = False
    if useReprinter:
        reprinter = Reprinter()
    else:
        reprinter = None
    max_tabulation = _getMaxColumnLen()
    while not killer.kill_now:
        # Extract commands with compatible time and not yet done
        launchableTools, waiting = findLaunchableTools()
        # Sort by command priority
        launchableTools.sort(key=lambda tup: int(tup["priority"]))
        dispatchLaunchableTools(my_monitor, launchableTools)
        printStatus(max_tabulation, waiting, reprinter)
        time.sleep(3)
    my_monitor.stop()
Ejemplo n.º 2
0
 def __init__(self, nbk, linkedTreeview, calendarToScan, settings):
     """Constructor, initialize a Monitor object"""
     self.monitor = Monitor(calendarToScan)
     self.calendarToScan = calendarToScan
     self.nbk = nbk
     self.running_auto_scans = []
     self.settings = settings
     self.btn_autoscan = None
     
     self.parent = None
     self.workerTv = None
     self.linkTw = linkedTreeview
     abs_path = os.path.dirname(os.path.abspath(__file__))
     path = os.path.join(abs_path, "../../icon/")
     self.ok_icon = ImageTk.PhotoImage(Image.open(path+"tool.png"))
     self.nok_icon = ImageTk.PhotoImage(Image.open(path+"cross.png"))
     self.running_icon = ImageTk.PhotoImage(Image.open(path+"running.png"))
Ejemplo n.º 3
0
class ScanManager:
    """Scan model class"""
    def __init__(self, nbk, linkedTreeview, calendarToScan, settings):
        """Constructor, initialize a Monitor object"""
        self.monitor = Monitor(calendarToScan)
        self.calendarToScan = calendarToScan
        self.nbk = nbk
        self.running_auto_scans = []
        self.settings = settings
        self.btn_autoscan = None

        self.parent = None
        self.workerTv = None
        self.linkTw = linkedTreeview
        abs_path = os.path.dirname(os.path.abspath(__file__))
        path = os.path.join(abs_path, "../../icon/")
        self.ok_icon = ImageTk.PhotoImage(Image.open(path + "tool.png"))
        self.nok_icon = ImageTk.PhotoImage(Image.open(path + "cross.png"))
        self.running_icon = ImageTk.PhotoImage(Image.open(path +
                                                          "running.png"))

    def startAutoscan(self):
        """Start an automatic scan. Will try to launch all undone tools."""

        if self.settings.db_settings.get("include_all_domains", False):
            answer = tk.messagebox.askyesno(
                "Autoscan warning",
                "The current settings will add every domain found in attack's scope. Are you sure ?"
            )
            if not answer:
                return
        from core.Components.AutoScanMaster import sendStartAutoScan
        self.btn_autoscan.configure(text="Stop Scanning",
                                    command=self.stopAutoscan)
        tasks = sendStartAutoScan(MongoCalendar.getInstance().calendarName)
        self.running_auto_scans = tasks

    def stop(self):
        """Stop an automatic scan. Will try to stop running tools."""

        self.stopAutoscan()
        if self.monitor is not None:
            self.monitor.stop()

    def refreshUI(self):
        """Reload informations and renew widgets"""
        registeredCommands = set()
        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)
        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()
        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:
                    pass
                try:
                    self.workerTv.insert('notRegistered',
                                         'end',
                                         '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()

    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()

    def OnDoubleClick(self, event):
        """Callback for a double click on ongoing scan tool treeview. Open the clicked tool in main view and focus on it.
        Args:
            event: Automatically filled when event is triggered. Holds info about which line was double clicked
        """
        if self.scanTv is not None:
            self.nbk.select(0)
            tv = event.widget
            item = tv.identify("item", event.x, event.y)
            self.linkTw.see(item)
            self.linkTw.selection_set(item)
            self.linkTw.focus(item)

    def stopAutoscan(self):
        """
        Stop an automatic scan. Will terminate celery running tasks.
        """
        try:
            if self.btn_autoscan is not None:
                self.btn_autoscan.configure(text="Start Scanning",
                                            command=self.startAutoscan)
        except tk.TclError:
            pass
        print("Stopping auto... ")
        for task in self.running_auto_scans:
            task.revoke(terminate=True)

    def parseFiles(self):
        """
        Ask user to import existing files to import.
        """
        dialog = ChildDialogFileParser(self.parent)
        self.parent.wait_window(dialog.app)

    def notify(self, _iid, _action):
        """
        Reload UI when notified
        """
        if self.workerTv is not None:
            self.refreshUI()
Ejemplo n.º 4
0
class ScanManager:
    """Scan model class"""
    def __init__(self, nbk, linkedTreeview, calendarToScan, settings):
        """Constructor, initialize a Monitor object"""
        self.monitor = Monitor(calendarToScan)
        self.calendarToScan = calendarToScan
        self.nbk = nbk
        self.running_auto_scans = []
        self.settings = settings
        self.btn_autoscan = None

        self.parent = None
        self.workerTv = None
        self.linkTw = linkedTreeview
        abs_path = os.path.dirname(os.path.abspath(__file__))
        path = os.path.join(abs_path, "../../icon/")
        self.tool_icon = ImageTk.PhotoImage(Image.open(path + "tool.png"))
        self.nok_icon = ImageTk.PhotoImage(Image.open(path + "cross.png"))
        self.ok_icon = ImageTk.PhotoImage(Image.open(path + "done_tool.png"))
        self.running_icon = ImageTk.PhotoImage(Image.open(path +
                                                          "running.png"))

    def startAutoscan(self):
        """Start an automatic scan. Will try to launch all undone tools."""
        mongoInstance = MongoCalendar.getInstance()
        workers = mongoInstance.getWorkers(
            {"excludedDatabases": {
                "$nin": [mongoInstance.calendarName]
            }})
        workers = [w for w in workers]
        if len(workers) == 0:
            tk.messagebox.showwarning(
                "No selected worker found",
                "Check worker treeview to see if there are workers registered and double click on the disabled one to enable them"
            )
            return
        if self.settings.db_settings.get("include_all_domains", False):
            answer = tk.messagebox.askyesno(
                "Autoscan warning",
                "The current settings will add every domain found in attack's scope. Are you sure ?"
            )
            if not answer:
                return
        from core.Components.AutoScanMaster import sendStartAutoScan
        self.btn_autoscan.configure(text="Stop Scanning",
                                    command=self.stopAutoscan)
        tasks = sendStartAutoScan(MongoCalendar.getInstance().calendarName)
        self.running_auto_scans = tasks

    def stop(self):
        """Stop an automatic scan. Will try to stop running tools."""

        self.stopAutoscan()
        if self.monitor is not None:
            self.monitor.stop()

    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.ok_icon)
        for children in self.workerTv.get_children():
            self.workerTv.delete(children)
        registeredCommands = set()
        for workername in workernames:
            try:
                if self.monitor.isWorkerExcludedFrom(
                        workername, mongoInstance.calendarName):
                    worker_node = self.workerTv.insert('',
                                                       'end',
                                                       workername,
                                                       text=workername,
                                                       image=self.nok_icon)
                else:
                    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.tool_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()

    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)
        self.workerTv.bind("<Double-Button-1>", self.OnWorkerDoubleClick)
        self.workerTv.bind("<Delete>", self.OnWorkerDelete)
        workernames = self.monitor.getWorkerList()
        total_registered_commands = 0
        registeredCommands = set()
        for workername in workernames:
            try:
                if self.monitor.isWorkerExcludedFrom(
                        workername, mongoInstance.calendarName):
                    worker_node = self.workerTv.insert('',
                                                       'end',
                                                       workername,
                                                       text=workername,
                                                       image=self.nok_icon)
                else:
                    worker_node = self.workerTv.insert('',
                                                       'end',
                                                       workername,
                                                       text=workername,
                                                       image=self.ok_icon)
            except tk.TclError:
                pass
            commands_registered = mongoInstance.getRegisteredCommands(
                workername)
            for command in commands_registered:
                try:
                    self.workerTv.insert(worker_node,
                                         'end',
                                         'registered|' + str(command),
                                         text=command,
                                         image=self.tool_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|' + str(command),
                                             text=str(command),
                                             image=self.nok_icon)
                    except tk.TclError:
                        pass
            total_registered_commands += len(registeredCommands)
        #### 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.ok_icn)
        #### BUTTONS FOR AUTO SCANNING ####
        if total_registered_commands > 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()

    def OnDoubleClick(self, event):
        """Callback for a double click on ongoing scan tool treeview. Open the clicked tool in main view and focus on it.
        Args:
            event: Automatically filled when event is triggered. Holds info about which line was double clicked
        """
        if self.scanTv is not None:
            self.nbk.select(0)
            tv = event.widget
            item = tv.identify("item", event.x, event.y)
            self.linkTw.see(item)
            self.linkTw.selection_set(item)
            self.linkTw.focus(item)

    def stopAutoscan(self):
        """
        Stop an automatic scan. Will terminate celery running tasks.
        """
        try:
            if self.btn_autoscan is not None:
                self.btn_autoscan.configure(text="Start Scanning",
                                            command=self.startAutoscan)
        except tk.TclError:
            pass
        print("Stopping auto... ")
        for task in self.running_auto_scans:
            task.revoke(terminate=True)

    def parseFiles(self):
        """
        Ask user to import existing files to import.
        """
        dialog = ChildDialogFileParser(self.parent)
        self.parent.wait_window(dialog.app)

    def notify(self, _iid, _action):
        """
        Reload UI when notified
        """
        if self.workerTv is not None:
            self.refreshUI()

    def sendEditToolConfig(self, worker, command_name, remote_bin, plugin):
        mongoInstance = MongoCalendar.getInstance()
        queueName = str(mongoInstance.calendarName)+"&" + \
            worker
        self.monitor.app.control.add_consumer(queue=queueName,
                                              reply=True,
                                              exchange="celery",
                                              exchange_type="direct",
                                              routing_key="transient",
                                              destination=[worker])
        from AutoScanWorker import editToolConfig
        result_async = editToolConfig.apply_async(
            args=[command_name, remote_bin, plugin],
            queue=queueName,
            retry=False,
            serializer="json")
        if self.monitor is not None:
            self.monitor.workerRegisterCommands(worker)

    def OnWorkerDoubleClick(self, event):
        """Callback for treeview double click.
        If a link treeview is defined, open mainview and focus on the item with same iid clicked.
        Args:
            event: used to identified which link was clicked. Auto filled
        """
        if self.workerTv is not None:
            tv = event.widget
            item = tv.identify("item", event.x, event.y)
            parent = self.workerTv.parent(item)
            if str(parent) != "":  # child node = tool
                print(str(item))
                command_name = item.split("|")[1]
                dialog = ChildDialogEditCommandSettings(
                    self.parent, "Edit worker tools config")
                self.parent.wait_window(dialog.app)
                if isinstance(dialog.rvalue, tuple):
                    tasks = self.sendEditToolConfig(parent, command_name,
                                                    dialog.rvalue[0],
                                                    dialog.rvalue[1])
            else:  # no parent node = worker node
                self.setUseForPentest(item)

    def setUseForPentest(self, worker_hostname):
        mongoInstance = MongoCalendar.getInstance()
        isExcluded = self.monitor.isWorkerExcludedFrom(
            worker_hostname, mongoInstance.calendarName)
        mongoInstance.setWorkerExclusion(worker_hostname,
                                         mongoInstance.calendarName,
                                         not (isExcluded))

    def OnWorkerDelete(self, event):
        """Callback for a delete key press on a worker.
        Force deletion of worker
        Args:
            event: Auto filled
        """
        mongoInstance = MongoCalendar.getInstance()
        if "@" in str(self.workerTv.selection()[0]):
            mongoInstance.deleteWorker(self.workerTv.selection()[0])