예제 #1
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})
예제 #2
0
파일: Ip.py 프로젝트: sec-js/Pollenisator
    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)
예제 #3
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)
예제 #4
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
예제 #5
0
    def addAllTool(self, command_name, wave_name, scope, check=True):
        """
        Add the appropriate tools (level check and wave's commands check) for this port.

        Args:
            command_name: The command that we want to create all the tools for.
            wave_name: name of the was to fetch allowed commands from
            scope: a scope matching this tool (should only be used by network level tools)
            check: A boolean to bypass checks. Force adding this command tool to this port if False. Default is True
        """
        if check == False:
            newTool = Tool()
            newTool.initialize(command_name, wave_name, scope,
                               self.ip, self.port, self.proto, "port")
            newTool.addInDb()
            return
        # retrieve wave's command
        mongoInstance = MongoCalendar.getInstance()
        wave = mongoInstance.find(
            "waves", {"wave": wave_name}, False)
        commands = wave["wave_commands"]
        try:
            index = commands.index(command_name)
            # retrieve the command level
            command = mongoInstance.findInDb("pollenisator",
                                             "commands", {"name": commands[index]}, False)
            if command["lvl"] == "port":
                # 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.
                allowed_ports_services = command["ports"].split(",")
                for i, elem in enumerate(allowed_ports_services):
                    if not(elem.strip().startswith("tcp/") or elem.strip().startswith("udp/")):
                        allowed_ports_services[i] = "tcp/"+str(elem.strip())
                for allowed in allowed_ports_services:
                    protoRange = "udp" if allowed.startswith("udp/") else "tcp"
                    maybeRange = str(allowed)[4:].split("-")
                    startAllowedRange = -1
                    endAllowedRange = -1
                    if len(maybeRange) == 2:
                        try:
                            startAllowedRange = int(maybeRange[0])
                            endAllowedRange = int(maybeRange[1])
                        except ValueError:
                            pass
                    if (self.proto+"/"+self.port == allowed) or \
                       (self.proto+"/"+self.service == allowed) or \
                       (self.proto == protoRange and
                           int(self.port) >= int(startAllowedRange) and
                            int(self.port) <= int(endAllowedRange)):
                        # finally add tool
                        newTool = Tool()
                        newTool.initialize(
                            command_name, wave_name, scope, self.ip, self.port, self.proto, "port")
                        newTool.addInDb()
        except ValueError:
            pass
예제 #6
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)
예제 #7
0
파일: Ip.py 프로젝트: sec-js/Pollenisator
    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
예제 #8
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)
예제 #9
0
    def onOk(self, _event=None):
        """
        Called when the user clicked the validation button.
        launch parsing with selected parser on selected file/directory.
        Close the window.

        Args:
            _event: not used but mandatory
        """
        res, msg = self.form.checkForm()
        if not res:
            tk.messagebox.showwarning("Form not validated",
                                      msg,
                                      parent=self.app)
            return
        notes = None
        tags = None
        form_values = self.form.getValue()
        form_values_as_dicts = ViewElement.list_tuple_to_dict(form_values)
        file_path = form_values_as_dicts["File"]
        plugin = form_values_as_dicts["Plugin"]
        wave = form_values_as_dicts["Wave"]
        files = []
        if os.path.isdir(file_path):
            # r=root, d=directories, f = files
            for r, _d, f in os.walk(file_path):
                for fil in f:
                    files.append(os.path.join(r, fil))
        else:
            files.append(file_path)
        results = {}
        dialog = ChildDialogProgress(
            self.parent, "Importing files", "Importing " + str(len(files)) +
            " files. Please wait for a few seconds.", 200, "determinate")
        dialog.show(len(files))
        # LOOP ON FOLDER FILES
        for f_i, file_path in enumerate(files):
            md5File = md5(file_path)
            toolName = os.path.splitext(
                os.path.basename(file_path))[0] + md5File[:6]
            dialog.update(f_i)
            if plugin == "auto-detect":
                # AUTO DETECT
                foundPlugin = "Ignored"
                for pluginName in listPlugin():
                    if foundPlugin != "Ignored":
                        break
                    mod = loadPlugin(pluginName)
                    if mod.autoDetectEnabled():
                        with io.open(file_path, 'r', encoding="utf-8") as f:
                            notes, tags, lvl, targets = mod.Parse(f)
                            if notes is not None and tags is not None:
                                foundPlugin = pluginName
                results[foundPlugin] = results.get(foundPlugin,
                                                   []) + [file_path]
            else:
                # SET PLUGIN
                mod = loadPlugin(plugin)
                with io.open(file_path, 'r', encoding="utf-8") as f:
                    notes, tags, lvl, targets = mod.Parse(f)
                    results[plugin] = results.get(plugin, []) + [file_path]
            # IF PLUGIN FOUND SOMETHING
            if notes is not None and tags is not None:
                # ADD THE RESULTING TOOL TO AFFECTED
                for target in targets.values():
                    date = datetime.fromtimestamp(os.path.getmtime(
                        file_path)).strftime("%d/%m/%Y %H:%M:%S")
                    if target is None:
                        scope = None
                        ip = None
                        port = None
                        proto = None
                    else:
                        scope = target.get("scope", None)
                        ip = target.get("ip", None)
                        port = target.get("port", None)
                        proto = target.get("proto", None)
                    Wave().initialize(wave, []).addInDb()
                    tool_m = Tool().initialize(toolName,
                                               wave,
                                               scope=scope,
                                               ip=ip,
                                               port=port,
                                               proto=proto,
                                               lvl=lvl,
                                               text="",
                                               dated=date,
                                               datef=date,
                                               scanner_ip="Imported file",
                                               status="done",
                                               notes=notes,
                                               tags=tags)
                    tool_m.addInDb()
                    mongoInstance = MongoCalendar.getInstance()
                    outputRelDir = tool_m.getOutputDir(
                        mongoInstance.calendarName)
                    abs_path = os.path.dirname(os.path.abspath(__file__))
                    outputDir = os.path.join(abs_path, "../../../results",
                                             outputRelDir)
                    mod.centralizeFile(file_path, outputDir)
                    tool_m.update({
                        "resultfile":
                        os.path.join(outputRelDir, os.path.basename(file_path))
                    })

        dialog.destroy()
        # DISPLAY RESULTS
        presResults = ""
        filesIgnored = 0
        for key, value in results.items():
            presResults += str(len(value)) + " " + str(key) + ".\n"
            if key == "Ignored":
                filesIgnored += 1
        if plugin == "auto-detect":
            if filesIgnored > 0:
                tk.messagebox.showwarning("Auto-detect ended",
                                          presResults,
                                          parent=self.app)
            else:
                tk.messagebox.showinfo("Auto-detect ended",
                                       presResults,
                                       parent=self.app)
        else:
            if filesIgnored > 0:
                tk.messagebox.showwarning("Parsing ended",
                                          presResults,
                                          parent=self.app)
            else:
                tk.messagebox.showinfo("Parsing ended",
                                       presResults,
                                       parent=self.app)

        self.rvalue = None
        self.app.destroy()
예제 #10
0
    def addInDb(self):
        """
        Add this Port in database.

        Returns: a tuple with :
                * bool for success
                * mongo ObjectId : already existing object if duplicate, create object id otherwise 
        """
        base = self.getDbKey()
        mongoInstance = MongoCalendar.getInstance()
        existing = mongoInstance.find("ports", base, False)
        if existing is not None:
            return False, existing["_id"]
        # Inserting port
        parent = self.getParent()
        base["parent"] = parent
        base["service"] = self.service
        base["product"] = self.product
        base["notes"] = self.notes
        base["tags"] = self.tags
        base["infos"] = self.infos
        res = mongoInstance.insert("ports", base, parent)
        ret = res.inserted_id
        self._id = ret
        # 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("pollenisator", "commands",
                                              {"name": commName, "lvl": "port"}, 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.
                    allowed_ports_services = comm["ports"].split(",")
                    for i, elem in enumerate(allowed_ports_services):
                        if not(elem.strip().startswith("tcp/") or elem.strip().startswith("udp/")):
                            allowed_ports_services[i] = "tcp/"+str(elem.strip())
                    for allowed in allowed_ports_services:
                        protoRange = "udp" if allowed.startswith("udp/") else "tcp"
                        maybeRange = str(allowed)[4:].split("-")
                        startAllowedRange = -1
                        endAllowedRange = -1
                        if len(maybeRange) == 2:
                            try:
                                startAllowedRange = int(maybeRange[0])
                                endAllowedRange = int(maybeRange[1])
                            except ValueError:
                                pass
                        if (self.proto+"/"+self.port == allowed) or \
                        (self.proto+"/"+self.service == allowed) or \
                        (self.proto == protoRange and int(self.port) >= int(startAllowedRange) and int(self.port) <= int(endAllowedRange)):
                            # finally add tool
                            newTool = Tool()
                            newTool.initialize(
                                comm["name"], waveName, "", self.ip, self.port, self.proto, "port")
                            newTool.addInDb()
        return True, ret
예제 #11
0
def main():
    """Main function. Start pollenisator application
    """
    parser = argparse.ArgumentParser(
        description="Edit database stored in mongo database")
    parser.add_argument("--import", dest="importName",
                        action="store", nargs="?")
    parser.add_argument("--calendar", dest="calendarName", action="store")
    parser.add_argument("--exec", dest="execCmd", action="store")
    args, remainingArgs = parser.parse_known_args()
    if args.importName:
        mongoInstance = MongoCalendar.getInstance()
        mongoInstance.importDatabase(args.importName)
        return
    if args.execCmd and args.calendarName:
        mongoInstance = MongoCalendar.getInstance()
        mongoInstance.connectToDb(args.calendarName)
        cmdName = os.path.splitext(os.path.basename(args.execCmd.split(" ")[0]))[0]
        cmdName +="::"+str(time.time()).replace(" ","-")
        wave = Wave().initialize("Custom commands")
        wave.addInDb()
        tool = Tool()
        tool.initialize(cmdName, "Custom commands", "", None, None, None, "wave", args.execCmd+" "+(" ".join(remainingArgs)), dated="None", datef="None", scanner_ip="localhost")
        tool.updateInfos({"args":args.execCmd})
        res, iid = tool.addInDb()
        if res:
            slave.executeCommand(args.calendarName, str(iid), "auto-detect")
        return
    print("""
.__    ..              ,       
[__) _ || _ ._ * __ _.-+- _ ._.
|   (_)||(/,[ )|_) (_] | (_)[  
                               
""")
    root = tk.Tk()
    root.resizable(True, True)
    dir_path = os.path.dirname(os.path.realpath(__file__))
    dir_path = os.path.join(dir_path, "icon/favicon.png")
    img = tk.PhotoImage(file=dir_path)
    root.iconphoto(True, img)

    root.minsize(width=400, height=400)
    root.resizable(True, True)
    root.title("Pollenisator")
    root.geometry("1220x830")
    gc = None
    app = Appli(root)
    try:
        root.protocol("WM_DELETE_WINDOW", app.onClosing)
        gc = GracefulKiller(app)
        root.mainloop()
        print("Exiting tkinter main loop")
    except tk.TclError:
        pass
    try:
        root.destroy()
        print("Destroying app window")
    except tk.TclError:
        pass
    app.onClosing()
    if gc is not None:
        gc.kill_now = True