def loadData(self): """ Fetch data from database """ apiclient = APIClient.getInstance() self.users = apiclient.findInDb(apiclient.getCurrentPentest(), ActiveDirectory.collName, {"type": "user"}, True) if self.users is None: self.users = [] self.computers = apiclient.findInDb(apiclient.getCurrentPentest(), ActiveDirectory.collName, {"type": "computer"}, True) if self.computers is None: self.computers = [] self.shares = apiclient.findInDb(apiclient.getCurrentPentest(), ActiveDirectory.collName, {"type": "share"}, True) if self.shares is None: self.shares = [] ports = Port.fetchObjects({"port": str(445)}) for port in ports: self.loadInfoFromPort(port) ports = Port.fetchObjects({"port": str(88)}) for port in ports: self.addDCinDb(port.ip)
def loadData(self): """ Fetch data from database """ self.ports = Port.fetchObjects({}) self.ips = Ip.fetchObjects({}) self.tools = Tool.fetchObjects({})
def addPort(self, values): """ Add a port object to database associated with this Ip. Args: values: A dictionary crafted by PortView containg all form fields values needed. Returns:ret '_id': The mongo ObjectId _idret of the inserted port document or None if insertion failed (unicity broken). """ portToInsert = {"ip": self.ip, "port": str( values["Port"]), "proto": str(values["Protocole"]), "service": values["Service"], "product": values["Product"]} newPort = Port() newPort.initialize( self.ip, portToInsert["port"], portToInsert["proto"], portToInsert["service"], portToInsert["product"]) return newPort.addInDb()
def insertIp(self, ip): """Insert a new IP in the summary. Also insert its port Args: ip: an IP object to be inserted """ treevw = ttk.Treeview(self.frameTw) treevw.heading("#0", text=ip, anchor='w') treevw.column("#0", anchor='w') tags = Settings.getTags() for tag, color in tags.items(): treevw.tag_configure(tag, background=color) treevw.bind("<Double-Button-1>", self.OnDoubleClick) count = 0 self.treeviews[ip] = treevw ports = Port.fetchObjects({"ip": ip}) for port in ports: if port.proto.strip() != "" and str(port.port).strip() != "": port_text = port.port if port.proto == "udp": port_text = "udp/" + port_text treevw.insert('', 'end', str(port.getId()), text=port_text, tags=list(port.getTags())) count += 1 treevw.configure(height=count) treevw.update_idletasks()
def _insertChildrenPorts(self, ip_node): """Insert every children port in database as DefectView under this node directly""" ports = self.controller.getPorts() for port in ports: port_o = PortController(Port(port)) port_vw = PortView(self.appliTw, self.appliViewFrame, self.mainApp, port_o) port_vw.addInTreeview(ip_node)
def addPortCallback(self, _event): """ Create an empty port model and its attached view. Open this view insert window. Args: _event: Automatically generated with a button Callback, not used. """ for widget in self.appliViewFrame.winfo_children(): widget.destroy() modelData = self.controller.getData() pv = PortView(self.appliTw, self.appliViewFrame, self.mainApp, PortController(Port(modelData))) pv.openInsertWindow()
def main(apiclient): APIClient.setInstance(apiclient) apiclient.registerTag("unscanned", "yellow") ports = Port.fetchObjects({}) n = 0 for port in ports: port_key = port.getDbKey() res = Tool.fetchObject(port_key) if res is None: port.setTags(["unscanned"]) n += 1 return True, f"{n} ports found and marked as unscanned"
def getActions(self, toolmodel): """ Summary: Add buttons to the tool view. Args: toolmodel : the tool model opened in the pollenisator client. Return: A dictionary with buttons text as key and function callback as value. """ self.toolmodel = toolmodel self.port_m = Port.fetchObject( {"ip": toolmodel.ip, "port": toolmodel.port, "proto": toolmodel.proto}) if self.port_m is None: return {} return {"Open 200 in browser": self.openInBrowser}
def openInBrowser(self, _event=None): """Callback of action Open 200 in browser Open scanned host port in browser as tabs. Args: _event: not used but mandatory """ port_m = Port.fetchObject({ "ip": self.toolmodel.ip, "port": self.toolmodel.port, "proto": self.toolmodel.proto }) if port_m is None: return ssl = port_m.infos.get("SSL", None) == "True" or ("https" in port_m.service or "ssl" in port_m.service) url = "https://" if ssl else "http://" url += port_m.ip + ":" + str(port_m.port) + "/" webbrowser.open_new_tab(url)
def notify(self, db, collection, iid, action, _parent): """ Callback for the observer implemented in mongo.py. Each time an object is inserted, updated or deleted the standard way, this function will be called. Args: collection: the collection that has been modified iid: the mongo ObjectId _id that was modified/inserted/deleted action: string "update" or "insert" or "delete". It was the action performed on the iid _parent: Not used. the mongo ObjectId of the parent. Only if action in an insert. Not used anymore """ apiclient = APIClient.getInstance() if not apiclient.getCurrentPentest() != "": return if apiclient.getCurrentPentest() != db: return if collection == ActiveDirectory.collName: self.handleActiveDirectoryNotif(iid, action) elif collection == "ports" and action != "delete": port_o = Port.fetchObject({"_id": ObjectId(iid)}) if int(port_o.port) == 445: self.loadInfoFromPort(port_o) if int(port_o.port) == 88: self.addDCinDb(port_o.ip)
def _load(self): """ Load the treeview with database information """ apiclient = APIClient.getInstance() dialog = ChildDialogProgress( self.appli, "Loading " + str(apiclient.getCurrentPentest()), "Opening " + str(apiclient.getCurrentPentest()) + ". Please wait for a few seconds.", 200, "determinate") step = 0 dialog.show(100) nbObjects = apiclient.count("waves", ) nbObjects += apiclient.count("scopes") nbObjects += apiclient.count("intervals") nbObjects += apiclient.count("scopes") nbObjects += apiclient.count("ips") nbObjects += apiclient.count("ports") nbObjects += apiclient.count("tools") nbObjects += apiclient.count("commands") onePercentNbObject = nbObjects // 100 if nbObjects > 100 else 1 nbObjectTreated = 0 self.delete(*self.get_children()) self._hidden = [] self._detached = [] self.waves_node = self.insert("", "end", str("waves"), text="Waves", image=WaveView.getClassIcon()) # Loading every category separatly is faster than recursivly. # This is due to cursor.next function calls in pymongo # Adding wave objects self.commands_node = self.insert("", "end", "commands", text="Commands", image=CommandView.getClassIcon()) self.group_command_node = self.insert( "", "end", "groupcommands", text="Command Groups", image=CommandGroupView.getClassIcon()) self.my_group_command_node = self.insert( self.group_command_node, "end", "mygroupcommands", text="My Command Groups", image=CommandGroupView.getClassIcon()) self.worker_group_command_node = self.insert( self.group_command_node, "end", "workergroupcommands", text="Worker Command Groups", image=CommandGroupView.getClassIcon()) self.my_commands_node = self.insert(self.commands_node, "end", "mycommands", text="My commands", image=CommandView.getClassIcon()) self.worker_commands_node = self.insert( self.commands_node, "end", "workercommands", text="Worker commands", image=CommandView.getClassIcon()) self.others_commands_node = self.insert( self.commands_node, "end", "otherscommands", text="Others commands", image=CommandView.getClassIcon()) commands = Command.fetchObjects({}, apiclient.getCurrentPentest()) for command in commands: command_vw = CommandView(self, self.appli.viewframe, self.appli, CommandController(command)) command_vw.addInTreeview() group_commands = CommandGroup.fetchObjects( {}, apiclient.getCurrentPentest()) for command_groupe_vw in group_commands: command_groupe_vw = CommandGroupView( self, self.appli.viewframe, self.appli, CommandGroupController(command_groupe_vw)) command_groupe_vw.addInTreeview() waves = Wave.fetchObjects({}) for wave in waves: wave_o = WaveController(wave) wave_vw = WaveView(self, self.appli.viewframe, self.appli, wave_o) wave_vw.addInTreeview(self.waves_node, False) nbObjectTreated += 1 if nbObjectTreated % onePercentNbObject == 0: step += 1 dialog.update(step) scopes = Scope.fetchObjects({}) for scope in scopes: scope_o = ScopeController(scope) scope_vw = ScopeView(self, self.appli.viewframe, self.appli, scope_o) scope_vw.addInTreeview(None, False) nbObjectTreated += 1 if nbObjectTreated % onePercentNbObject == 0: step += 1 dialog.update(step) intervals = Interval.fetchObjects({}) for interval in intervals: interval_o = IntervalController(interval) interval_vw = IntervalView(self, self.appli.viewframe, self.appli, interval_o) interval_vw.addInTreeview(None, False) nbObjectTreated += 1 if nbObjectTreated % onePercentNbObject == 0: step += 1 dialog.update(step) #Adding ip objects self.ips_node = self.insert("", "end", str("ips"), text="IPs", image=IpView.getClassIcon()) ips = Ip.fetchObjects({}) for ip in ips: ip_o = IpController(ip) ip_vw = IpView(self, self.appli.viewframe, self.appli, ip_o) ip_vw.addInTreeview(None, False) self.appli.statusbar.notify(ip_vw.controller.getTags()) nbObjectTreated += 1 if nbObjectTreated % onePercentNbObject == 0: step += 1 dialog.update(step) # Adding port objects ports = Port.fetchObjects({}) for port in ports: port_o = PortController(port) port_vw = PortView(self, self.appli.viewframe, self.appli, port_o) port_vw.addInTreeview(None, False) self.appli.statusbar.notify(port_vw.controller.getTags()) nbObjectTreated += 1 if nbObjectTreated % onePercentNbObject == 0: step += 1 dialog.update(step) # Adding defect objects defects = Defect.fetchObjects({"ip": {"$ne": ""}}) for defect in defects: defect_o = DefectController(defect) defect_vw = DefectView(self, self.appli.viewframe, self.appli, defect_o) defect_vw.addInTreeview(None) nbObjectTreated += 1 if nbObjectTreated % onePercentNbObject == 0: step += 1 dialog.update(step) # Adding tool objects tools = Tool.fetchObjects({}) for tool in tools: tool_o = ToolController(tool) tool_vw = ToolView(self, self.appli.viewframe, self.appli, tool_o) tool_vw.addInTreeview(None, False) self.appli.statusbar.notify(tool_vw.controller.getTags()) nbObjectTreated += 1 if nbObjectTreated % onePercentNbObject == 0: step += 1 dialog.update(step) self.sort(self.ips_node) self.appli.statusbar.update() dialog.destroy()
def notify(self, db, collection, iid, action, _parent): """ Callback for the observer implemented in mongo.py. Each time an object is inserted, updated or deleted the standard way, this function will be called. Args: collection: the collection that has been modified iid: the mongo ObjectId _id that was modified/inserted/deleted action: string "update" or "insert" or "delete". It was the action performed on the iid _parent: Not used. the mongo ObjectId of the parent. Only if action in an insert. Not used anymore """ apiclient = APIClient.getInstance() if not apiclient.getCurrentPentest() != "": return if db == "pollenisator": if collection == "settings": self.configureTags() return if apiclient.getCurrentPentest() != db: return # Delete if action == "delete": if collection == "defects": view = self.getViewFromId(str(iid)) if view is not None: self.appli.statusbar.notify([], view.controller.getTags()) try: self.delete(ObjectId(iid)) except tk.TclError: pass # item was not inserted in the treeview # Insert if action == "insert": view = None res = apiclient.find(collection, {"_id": ObjectId(iid)}, False) if collection == "tools": view = ToolView(self, self.appli.viewframe, self.appli, ToolController(Tool(res))) elif collection == "waves": view = WaveView(self, self.appli.viewframe, self.appli, WaveController(Wave(res))) elif collection == "scopes": view = ScopeView(self, self.appli.viewframe, self.appli, ScopeController(Scope(res))) elif collection == "ports": view = PortView(self, self.appli.viewframe, self.appli, PortController(Port(res))) elif collection == "ips": view = IpView(self, self.appli.viewframe, self.appli, IpController(Ip(res))) elif collection == "intervals": view = IntervalView(self, self.appli.viewframe, self.appli, IntervalController(Interval(res))) elif collection == "defects": view = DefectView(self, self.appli.viewframe, self.appli, DefectController(Defect(res))) elif collection == "commands": view = CommandView(self, self.appli.viewframe, self.appli, CommandController(Command(res))) elif collection == "group_commands": view = CommandGroupView( self, self.appli.viewframe, self.appli, CommandGroupController(CommandGroup(res))) try: if view is not None: view.addInTreeview() view.insertReceived() self.appli.statusbar.notify(view.controller.getTags()) except tk.TclError: pass if action == "update": try: view = self.getViewFromId(str(iid)) if view is not None: item = self.item(str(iid)) oldTags = item["tags"] view.controller.actualize() self.appli.statusbar.notify(view.controller.getTags(), oldTags) self.item(str(iid), text=str(view.controller.getModelRepr()), image=view.getIcon()) except tk.TclError: if view is not None: view.addInTreeview() if str(self.appli.openedViewFrameId) == str(iid): for widget in self.appli.viewframe.winfo_children(): widget.destroy() view.openModifyWindow() if view is not None: view.updateReceived() self.appli.statusbar.update()
def displayData(self): """ Display loaded data in treeviews """ dialog = ChildDialogProgress( self.parent, "Loading dashboard ", "Refreshing dashboard. Please wait for a few seconds.", 200, "determinate") dialog.show(10) # Reset Ip treeview for children in self.treevw.get_children(): self.treevw.delete(children) dialog.update(1) listOfip = [] for ip in self.ips: servicesCount = len([x for x in Port.fetchObjects({"ip": ip.ip})]) listOfip.append((ip.ip, servicesCount)) dialog.update(2) listOfip.sort(key=lambda tup: tup[1], reverse=True) for i in range(len(listOfip)): self.treevw.insert('', 'end', i, text=listOfip[i][0], values=(listOfip[i][1])) dialog.update(3) # Reset Port treeview for children in self.treevwport.get_children(): self.treevwport.delete(children) dialog.update(4) portCounts = {} for port in self.ports: if port.port not in portCounts.keys(): portCounts[port.port] = 1 else: portCounts[port.port] += 1 dialog.update(5) port_id = 0 # Ordering dictionnary portCounts = { k: v for k, v in sorted( portCounts.items(), key=lambda item: item[1], reverse=True) } for portCount in portCounts: self.treevwport.insert('', 'end', port_id, text=str(portCount), values=(portCounts[portCount])) port_id += 1 dialog.update(6) # Tool part # Reset Tools treeview for children in self.treevwtools.get_children(): self.treevwtools.delete(children) dialog.update(7) listOfTools = [_ for _ in self.tools] listOfTools.sort(key=lambda x: x.status, reverse=True) result = APIClient.getInstance().aggregate("tools", [{ "$group": { "_id": { "name": "$name", "status": "$status", "wave": "$wave" }, "count": { "$sum": 1 } } }]) result = [_ for _ in result] tools_dashboard = {} for tool_result in result: tool_id = tool_result["_id"].get( "wave", "") + "::" + tool_result["_id"]["name"] tools_dashboard[tool_id] = tools_dashboard.get(tool_id, {}) tool_status = list(tool_result["_id"].get("status", "ready")) if not tool_status: tool_status = ["ready"] tools_dashboard[tool_id][tool_status[0]] = tool_result["count"] dialog.update(8) for tool_id in sorted(list(tools_dashboard.keys())): self.treevwtools.insert( '', 'end', None, text=str(tool_id), values=(tools_dashboard[tool_id].get("ready", 0), tools_dashboard[tool_id].get("running", 0), tools_dashboard[tool_id].get("done", 0), tools_dashboard[tool_id].get("error", 0) + tools_dashboard[tool_id].get("timedout", 0))) dialog.update(9) # Defect Part # reset defect TW for children in self.treevwDefaults.get_children(): self.treevwDefaults.delete(children) result = APIClient.getInstance().aggregate("defects", [{ "$group": { "_id": { "risk": "$risk", "type": "$type" }, "count": { "$sum": 1 } } }]) dialog.update(10) result = [_ for _ in result] result.sort(key=lambda x: x["count"], reverse=True) for defect in result: defectRisk = defect["_id"]["risk"] defectType = " ".join(defect["_id"]["type"]) defectCount = defect["count"] self.treevwDefaults.insert('', 'end', None, text=str(defectRisk), values=(defectType, defectCount)) dialog.destroy()