def sigCHLDHandler(self, sig, frame): """SIGCHLD handler :signal: int :frame: frame object Automatically called upon SIGCHLD. Normally you do not need to do anything with this function but if your application needs to disable SIGCHLD for some time for reasons beyond your control, you should call this function afterwards to make sure that no SIGCHLDs where missed. """ found = False # iterating the list doesn't perform any system call for process in self.process_list: if process.pid is None: continue if not process.running: continue try: wpid, status = os.waitpid(process.pid, os.WNOHANG) except OSError: # [Errno 10] No child processes # XXX: bug in process.py ? continue if wpid > 0: os.write(self.fd[1], struct.pack('II', wpid, status)) devlog("sigCHLDHandler - signal = %d - wpid = %d - status = %d" % (sig, wpid, status)) found = True if (not found and not self.old_sigCHLDHandler in (signal.SIG_IGN, signal.SIG_DFL)): self.old_sigCHLDHandler(sig) # call the old handler
def _checkDate(self,rowdate): mret=True msave=True if not self._lsdate: if self._sdate: self._lsdate=self._sdate else: self._lsdate=rowdate if self._cdate(self._lsdate,rowdate): msave=False if self._sdate: self._mwhere =" and updated_at > to_timestamp('"+self._sdate+"','YYYY-MM-DD HH24:MI:SS.US');" if msave: try: f=open(self.path,"w") f.write(rowdate) f.close() self._lsdate=rowdate except: api.devlog ("Can't save metasploit lastupdate file") return return mret
def parseOutputString(self, output, debug=False): host_info = re.search(r"Connected to (.+)\.", output) banner = re.search("220?([\w\W]+)$", output) if re.search("Connection timed out", output) is None and host_info is not None: hostname = host_info.group(1) ip_address = self.resolve(hostname) self._version = banner.groups(0) if banner else "" if debug: print ip_address h_id = self.createAndAddHost(ip_address) i_id = self.createAndAddInterface( h_id, ip_address, ipv4_address=ip_address, hostname_resolution=hostname) s_id = self.createAndAddServiceToInterface( h_id, i_id, "ftp", "tcp", ports=[self._port], status="open") if debug is True: api.devlog("Debug is active") return True
def _importVulnsCvs(self,item): filename = qt.QFileDialog.getOpenFileName( CONF.getDefaultTempPath(), "Csv vulnerability file (*.*)", None, "open file dialog", "Choose a vulnerability file" ); if os.path.isfile(filename): with open(filename) as f: data = f.read() f.close() for l in data.split("\n"): api.devlog(l) if re.search("^#",l): api.devlog("ERROR FILE") continue d = l.split("|") if len(d) <=8: api.log("Error vuln line: ("+l+")" ) else: self._newVulnImport(d[1],d[2],d[3],d[4],d[5],d[6],d[7])
def _showRepositoryConfigDialog(self): repoconfig_dialog = RepositoryConfigDialog(self, CONF.getCouchURI(), CONF.getCouchIsReplicated(), CONF.getCouchReplics(), callback=None) result = repoconfig_dialog.exec_loop() if result == qt.QDialog.Accepted: repourl, isReplicated, replics = repoconfig_dialog.getData() api.devlog("repourl = %s" % repourl) wm = self._main_app.getWorkspaceManager() if not CouchDbManager.testCouch(repourl): self.showPopup(""" Repository URL Not valid, check if service is available and that connection string is from the form: http[s]://hostname:port""") return CONF.setCouchUri(repourl) CONF.setCouchIsReplicated(isReplicated) CONF.setCouchReplics(replics) CONF.saveConfig() wm.closeWorkspace() wm.resource() wm.openWorkspace('untitled') mwin = self._main_app.getMainWindow() mwin.getWorkspaceTreeView().loadAllWorkspaces() mwin.getWorkspaceTreeView().setDefaultWorkspace()
def parseOutputString(self, output, debug=False): host_info = re.search( r"(\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b)", output) host_mac_addr = re.search(r"([\dA-F]{2}(?:[-:][\dA-F]{2}){5})", output) if host_info is None: api.devlog("No hosts detected") else: for line in output.split('\n'): vals = line.split("\t") if len(vals[0].split(".")) == 4: host = vals[0] h_id = self.createAndAddHost(host) i_id = self.createAndAddInterface( h_id, host, ipv4_address=host, mac=vals[1]) n_id = self.createAndAddNoteToHost( h_id, "NIC VENDOR:", vals[2]) return True
def _openWorkspace(self, item): api.devlog("Opening workspace %s selected on the Workspace Perspective" % item.name) self._getMainApp().openWorkspace(item.object.name) self.loadAllWorkspaces()
def _showContextMenu(self, item, pos, val): """Pop up a context menu when an item is right-clicked on the list view.""" popup = qt.QPopupMenu(self) selected_items = self._getSelectedItems() if not selected_items: popup.insertItem('Create Workspace', 100) else: if len(selected_items) == 1: if item.object.isActive(): popup.insertItem('Save', self._saveWorkspace) popup.insertItem('Synchronize', self._syncWorkspace) popup.insertItem('Close', 300) else: popup.insertItem('Open', lambda: self._openWorkspace(item)) popup.insertItem('Delete', lambda: self._deleteWorkspace(item)) popup.insertItem('Properties', lambda: self._showWorkspaceProperties(item)) elif len(selected_items) > 1: popup.insertItem('Delete', lambda: self._deleteWorkspaces(selected_items)) else: api.devlog("ERROR: right click on an valid item (%r) which has a null object" % item) ret = popup.exec_loop(pos) api.devlog("contextMenuEvent WorkspaceItem - item: %s - ret %s" % (self.name, ret))
def _delValue(self, attrName, valID): # attribute passed as a parameter MUST BE the name # of an internal attribute which is a dictionary indexed # with a string ID api.devlog("(%s)._delValue(%s, %s)" % (self, attrName, valID)) ref = self.__getattribute__(attrName) api.devlog("ref.keys() = %s" % ref.keys()) if valID in ref: val = ref[valID] del ref[valID] val.delete() return True hash_id = get_hash([valID]) if hash_id in ref: val = ref[hash_id] del ref[hash_id] val.delete() return True for element in ref.itervalues(): if valID == element.name: val = ref[element.getID()] del ref[element.getID()] val.delete() return True # none of the ids were found return False
def _doSql(self, db, sql): try: api.devlog("SQL:" + sql) db.execute(sql) except Exception, e: print ("Error SQL[" + e.pgcode + "] - " + e.pgerror) return None
def _showContextMenu(self, item, pos, val): """Pop up a context menu when an item is right-clicked on the list view.""" popup = qt.QPopupMenu(self) selected_items = self._getSelectedItems() if not selected_items: popup.insertItem("No action available", 100) else: if len(selected_items) == 1: if item.is_active: popup.insertItem("No action available", 100) else: popup.insertItem("Open", lambda: self._openWorkspace(item)) popup.insertItem("Delete", lambda: self._deleteWorkspace(item)) # popup.insertItem('Properties', lambda: self._showWorkspaceProperties(item)) elif len(selected_items) > 1: popup.insertItem("Delete", lambda: self._deleteWorkspaces(selected_items)) else: api.devlog("ERROR: right click on an valid item (%r) which has a null object" % item) ret = popup.exec_loop(pos) api.devlog("contextMenuEvent WorkspaceItem - item: %s - ret %s" % (self.name, ret))
def _checkFullDelete(self): api.devlog("Doing service checkFullDelete") if not self._interfaces and not self._applications: if self.getParent() is not None: self.getParent().delService(self.getID())
def close(self, session, status, *args): #TODO: por alguna razon queda colgado un QSocketNotifier # QSocketNotifier: invalid socket 17 and type 'Read', disabling... # y eso cuelga la aplicacion api.devlog("ShellEnvironment close was called - session = %r, status = %r , *args = %r" % (session, status, args)) if self._close_callback is not None: self._close_callback(self.name, self) else: api.devlog("close was call but callback is not set")
def setPorts(self, ports): if ports is not None: if isinstance(ports, (str,unicode)): self._ports = [int(ports)] elif isinstance(ports, int): self._ports = [ports] elif isinstance(ports, list): self._ports = [int(p) for p in ports] else: api.devlog("ports must be a string, an int o a list of any of those types")
def setSavingModel(self, value): api.devlog("setSavingModel: %s" % value) self._saving_model_flag = value if value: self._saving_model_lock.acquire() else: try: self._saving_model_lock.release() except RuntimeError: pass
def _newVuln(self, item): api.devlog("newVuln") if item is not None and item.object is not None: vuln_web_enabled = False if item.object.class_signature == "Service": vuln_web_enabled = True dialog = NewVulnDialog( self, callback=self._newVulnSelectedCallback, vuln_web_enabled=vuln_web_enabled) dialog.exec_loop()
def __matchesCustomPrompt(self, txt): """ checks if the current text matches our custom prompt format and returns true in that case, false otherwise """ if not self._custom_prompt_format: api.devlog("prompt format (PS1) is not defined.\nThis may cause unexpected results...") return False txt = txt.strip() m = self._custom_prompt_format.search(txt) return (m is not None)
def do_checkin(self): try: revision_up = revision_commit = self._client.checkin(self.persistence_path, log_message="", recurse=True) api.devlog("[SVN] revision after commit %s" % str(revision_up)[23:-2]) except pysvn.ClientError, e: api.devlog("[SVN] Commit action failed: %s" % str(e)) for message, code in e.args[1]: if code != 155015: raise
def _removeHost(self, host_id): item = self._host_items.get(host_id, None) if host_id in self._host_items: del self._host_items[host_id] for category in self._category_tree.keys(): if host_id in self._category_tree.get(category): self._category_tree[category].remove(host_id) category_item = self._getCategoryListViewItem(category) try: category_item.takeItem(item) except Exception: api.devlog("Exception taking item from category")
def parseOutputString(self, output, debug=False): """ This method will discard the output the shell sends, it will read it from the xml where it expects it to be present. NOTE: if 'debug' is true then it is being run from a test case and the output being sent is valid. """ try: f = urllib2.urlopen(self.getSetting( "Host") + "/api/hooks?token=" + self.getSetting("Authkey")) data = json.loads(f.read()) except: api.devlog("[BeEF] - Connection with api") return if "hooked-browsers" in data: for t in ["online", "offlne"]: for h in data["hooked-browsers"][t]: name = str(data["hooked-browsers"][t][h]['name']) version = str(data["hooked-browsers"][t][h]['version']) os = str(data["hooked-browsers"][t][h]['os']) platform = str(data["hooked-browsers"][t][h]['platform']) session = str(data["hooked-browsers"][t][h]['session']) ip = str(data["hooked-browsers"][t][h]['ip']) domain = str(data["hooked-browsers"][t][h]['domain']) port = str(data["hooked-browsers"][t][h]['port']) page_uri = str(data["hooked-browsers"][t][h]['page_uri']) desc = "Client ip:" + ip + \ " has been injected with BeEF using the url:" + page_uri + "\n" desc += "More information:" desc += "\ntype:" + t desc += "\nname:" + name desc += "\nversion:" + version desc += "\nos:" + os desc += "\nplatform:" + platform desc += "\nsession:" + session desc += "\nip:" + ip desc += "\ndomain:" + domain desc += "\nport:" + port desc += "\npage_uri:" + page_uri h_id = self.createAndAddHost(ip) v_id = self.createAndAddVulnToHost( h_id, "BeEF injected " + t + " session:" + session, desc=desc, ref=["http://http://beefproject.com/"], severity=3)
def rename(self, old, new): """ Renames/Moves a file or folder """ result = False try: self._client.move(old, new) result = True api.devlog("[SVN] moved %s to %s" % (old, new)) except Exception: pass return result
def addUpdate(self, old_object, new_object): # Returns True if the update was resolved without user interaction res = True try: mergeAction = old_object.addUpdate(new_object) if mergeAction: if old_object not in self.objects_with_updates: self.objects_with_updates.append(old_object) notifier.conflictUpdate(1) res = False except: res = False api.devlog("(%s).addUpdate(%s, %s) - failed" % (self, old_object, new_object)) return res
def _importCreds(self, item): filename = qt.QFileDialog.getOpenFileName( CONF.getDefaultTempPath(), "Csv user,pass or user:pass (*.*)", None, "open file dialog", "Choose a password file" ); if os.path.isfile(filename): with open(filename) as f: data = f.read() f.close() for l in data.split(): api.devlog(l) if re.search("^#",l): api.devlog("ERROR FILE") continue d = l.split(",") if len(d)<=1: d = l.split(":") api.devlog(d) if len(d) <=1: api.devlog("Error password line: ("+l+")" ) else: self._newCredSelectedCallback(d[0],d[1])
def _delSelectedCallback(self,item): for i in self.items_selected: if i.type == "Host": api.devlog("delcallbackHost %s " % (i.object.name)) guiapi.delHost(i.object.getID()) elif i.type == "Application": api.devlog("delcallbackApplication %s " % (i.object.name)) _parent=i.object.getParent() _object=i.object guiapi.delApplication(_parent.getID(),_object.getID()) elif i.type == "Interface": api.devlog("delcallbackInterface %s " % (i.object.name)) _parent=i.object.getParent() _object=i.object guiapi.delInterface(_parent.getID(), _object.getID()) elif i.type == "Service": api.devlog("delcallbackService %s " % (i.name)) _object=i.object parent_interface = self._getParentForType(i, "Interface").object parent_host = self._getParentForType(i, "Host").object guiapi.delServiceFromInterface(parent_host.getID(), parent_interface.getID(), _object.getID()) self.listview.setCurrentItem(self.rootitem) self._itemSelected()
def clearTree(self): """ clear all the items in the tree """ api.devlog("clearTree called") i = self.listview.firstChild() items_to_remove = [] while i is not None: items_to_remove.append(i) i = i.nextSibling() for i in items_to_remove: self.listview.takeItem(i)
def processCommandString(self, username, current_path, command_string): """ Adds the -m parameter to get machine readable output. """ arg_match = self.file_arg_re.match(command_string) self._file_output_path=os.path.join(self.data_path,"f_output-%s.txt" % random.uniform(1,10)) parser = argparse.ArgumentParser() parser.add_argument('-e') parser.add_argument('-o') if arg_match is None: final= re.sub(r"(^.*?fplugin)", r"\1 -o %s" % self._file_output_path, command_string) else: final= re.sub(arg_match.group(1), r"-o %s" % self._file_output_path, command_string) cmd=shlex.split(re.sub(r'\-h|\-\-help', r'', final)) try: self.args, unknown = parser.parse_known_args(cmd) except SystemExit: pass if self.args.e: buffer = StringIO() sys.stdout = buffer exec(self.args.e) sys.stdout = sys.__stdout__ try: f=open(self._file_output_path,"w") f.write(buffer.getvalue()) f.close() except: api.devlog ("[Faraday] Can't save faraday plugin output file") return print buffer.getvalue() return final
def _delHostFromCategory(self, host, category): id = host.getID() item = self._host_items.get(id, None) if id in self._host_items: del self._host_items[id] if category in self._category_tree: if id in self._category_tree[category]: self._category_tree[category].remove(id) category_item = self._getCategoryListViewItem(category) api.devlog("_delHostFromCategory: about to call takeItem for category %s" % category) try: category_item.takeItem(item) except Exception: pass api.devlog("_delHostFromCategory: after takeItem")
def addUpdate(self, old_object, new_object, command_id): # Returns True if the update was resolved without user interaction try: mergeAction = old_object.addUpdate(new_object, command_id) if mergeAction: if old_object not in self.objects_with_updates: self.objects_with_updates.append(old_object) notifier.conflictUpdate(1) return False except Exception as ex: api.devlog("(%s).addUpdate(%s, %s) - failed" % (self, old_object, new_object)) return False self.mappers_manager.update(old_object, command_id) notifier.editHost(old_object) return True
def _newVulnImport(self,ip,port,protocol,name,desc,severity,type): if port == "": #vuln host h_id = guiapi.createAndAddHost(ip) v_id = guiapi.createAndAddVulnToHost(h_id, name, desc, [],severity) else: #vuln port h_id = guiapi.createAndAddHost(ip) if self._isIPV4(ip): i_id = guiapi.createAndAddInterface(h_id,ip,ipv4_address=ip) else: i_id = guiapi.createAndAddInterface(h_id,ip,ipv6_address=ip) s_id = guiapi.createAndAddServiceToInterface(h_id,i_id,port,protocol,ports=[port]) if type == "2": v_id = guiapi.createAndAddVulnWebToService(h_id,s_id, name, desc, [], severity, "/", "/") else: v_id = guiapi.createAndAddVulnToService(h_id,s_id, name, desc, [],severity) api.devlog("type:" + type)
def _showContextMenu(self, item, pos, val): """Pop up a context menu when an item is clicked on the list view.""" ret = None if item is not None: if self.items_type['Interface']: if (self.items_type['Category_General'] or self.items_type['Workspace']): popname="CategoryWorkspace_Interface" elif (self.items_type['Host'] or self.items_type['Service']): popname="ServiceHost_Interface" else: popname=item.type elif (self.items_type['Host'] or self.items_type['Service']): if (self.items_type['Category_General'] or self.items_type['Workspace']): popname="CategoryWorkspace_ServiceHost" elif (self.items_type['Host'] >1 or self.items_type['Service'] >1): popname="Service_Host" elif (self.items_type['Host'] and self.items_type['Service']): popname="Service_Host" else: if item.type is "Category": popname="Host" else: popname=item.type else: if item.type is "Category": popname=item.type + "_" + item.name else: popname=item.type ret = self.contextpopups[popname].exec_loop(pos) if ret in self.contextdispatchers: self.contextdispatchers[ret](item) api.devlog("contextMenuEvent - item: %s - ret %s" % (self.name, ret))
def run(self): self.serve_forever() api.devlog("serve_forever ended") return
def serve_forever(self): while not self._stop: self.handle_request() api.devlog("server forever stopped by flag")
def stop_server(self): api.devlog("server stopping...") self._stop = True
def __do_cleanup(self): """SVN Cleanup call""" api.devlog("[SVN] starting sync") self._client.cleanup(self.persistence_path) api.devlog("[SVN] clean up done")
api.devlog(e) new_cmd = None if new_cmd is None: # the output MUST BE processed self.__ignore_process_output = False self.__ignore_process_output_once = False else: # means the plugin changed command and we are going to send # ALT + r to delete current line. That produces an empty output # which has to be ignored self.__ignore_process_output_once = True self.__ignore_process_output = False else: api.devlog("IGNORING BECAUSE INTERACTIVE FLAG WAS SET") new_cmd = None return new_cmd,command_string,command_len def ignoreDueResize(self): self.__ignore_process_output = True def __parseUserInput(self, user_input="", get_spaces=False): """ parses the user input buffer and returns the following values: * current user prompt * current username * current path
def parseOutputString(self, output, debug=False): """ This method will discard the output the shell sends, it will read it from the xml where it expects it to be present. NOTE: if 'debug' is true then it is being run from a test case and the output being sent is valid. """ try: conn = psycopg2.connect("dbname='" + self.getSetting("Database") + "' user='******' password='******' host='" + self.getSetting("Server") + "'") cur = conn.cursor() except: api.devlog("Error Connection database") return cur = self._doSql( cur, "select * from hosts inner join workspaces ON (hosts.workspace_id=workspaces.id) where workspaces.name like '" + self.getSetting("Wordspace") + "';") if cur is None: return self.path = self.data_path + "/" + api.getActiveWorkspace( ).name + "_metasploit_last" if os.path.isfile(self.path): f = open(self.path, "r") self._sdate = f.readline() f.close for h in cur.fetchall(): h_id = self.createAndAddHost(str(h[2]), str(h[7])) if self._isIPV4(str(h[2])): i_id = self.createAndAddInterface(h_id, str(h[2]), mac=str(h[3]), ipv4_address=str(h[2]), hostname_resolution=str( h[5])) else: i_id = self.createAndAddInterface(h_id, str(h[2]), mac=str(h[3]), ipv6_address=str(h[2]), hostname_resolution=str( h[5])) self._checkDate(str(h[13])) cur = self._doSql( cur, "select * from vulns where host_id=" + str(h[0]) + " and service_id is null" + self._mwhere + ";") if cur is None: return for v in cur.fetchall(): self._checkDate(str(v[5])) cur = self._doSql( cur, "select * from vulns_refs inner join refs ON (vulns_refs.id=refs.id) where vulns_refs.vuln_id=" + str(v[0]) + ";") if cur is None: return refs = [] for r in cur.fetchall(): self._checkDate(str(r[5])) refs.append(r[6]) self.createAndAddVulnToHost(h_id, str(v[4]), str(v[6]), refs) cur = self._doSql( cur, "select * from notes where host_id=" + str(h[0]) + " and service_id is null" + self._mwhere + ";") if cur is None: return for n in cur.fetchall(): self._checkDate(str(n[6])) self.createAndAddNoteToHost(h_id, str(n[2]), str(n[9])) cur = self._doSql( cur, "select * from services where host_id=" + str(h[0])) if cur is None: return for s in cur.fetchall(): self._checkDate(str(s[7])) s_id = self.createAndAddServiceToInterface( h_id, i_id, name=str(s[6]), ports=[str(s[3])], protocol=str(s[4]), status=str(s[5]), description=str(s[8]), version=str(s[8]), ) cur = self._doSql( cur, "select * from creds where service_id=" + str(s[0]) + self._mwhere + ";") creds = [] if cur is None: return for c in cur.fetchall(): self._checkDate(str(c[3])) self.createAndAddCredToService(h_id, s_id, c[4], c[5]) cur = self._doSql( cur, "select * from vulns where host_id=" + str(h[0]) + " and service_id=" + str(s[0]) + self._mwhere + ";") if cur is None: return for v in cur.fetchall(): self._checkDate(str(v[5])) cur = self._doSql( cur, "select * from vulns_refs inner join refs ON (vulns_refs.id=refs.id) where vulns_refs.vuln_id=" + str(v[0]) + ";") if cur is None: return refs = [] for r in cur.fetchall(): self._checkDate(str(r[5])) refs.append(r[6]) self.createAndAddVulnToService(h_id, s_id, name=str(v[4]), desc=str(v[6]), ref=refs) mwhere = re.sub("updated_at", "web_vulns.updated_at", self._mwhere) cur = self._doSql( cur, "select * from web_vulns INNER JOIN web_sites ON (web_vulns.web_site_id=web_sites.id) INNER JOIN web_vuln_category_metasploits as category ON (web_vulns.category_id=category.id) where web_sites.service_id=" + str(s[0]) + mwhere + ";") for v in cur.fetchall(): self._checkDate(str(v[3])) self.createAndAddVulnWebToService(h_id, s_id, name=str(v[28]), desc=str(v[29]), website=str(v[24]), path=str(v[4]), request=str(v[15]), method=str(v[5]), pname=str(v[7]), params=str(v[6]), query=str(v[10])) cur = self._doSql( cur, "select * from notes where host_id=" + str(h[0]) + " and service_id=" + str(s[0]) + self._mwhere) if cur is None: return for n in cur.fetchall(): self._checkDate(str(n[6])) self.createAndAddNoteToService(h_id, s_id, str(n[2]), str(n[9])) cur = self._doSql( cur, "select * from web_sites where service_id=" + str(s[0]) + self._mwhere) for w in cur.fetchall(): self._checkDate(str(w[3])) n_id = self.createAndAddNoteToService( h_id, s_id, "website", "") n2_id = self.createAndAddNoteToNote( h_id, s_id, n_id, str(w[4]), "") cur.close() conn.close()
def onKeyPress(self, ev): """char received from the gui""" if not self._connected: # Someone else gets the keys return self.myemit("notifySessionState", (NOTIFYNORMAL, )) ev_state = ev.state() try: entry = self._key_trans.findEntry( ev.key(), self.getMode(screen.MODE_NewLine), self.getMode(MODE_Ansi), self.getMode(MODE_AppCuKeys), ev_state & ControlButton == ControlButton, ev_state & ShiftButton == ShiftButton, ev_state & AltButton == AltButton) except kt.EntryNotFound: cmd = kt.CMD_none # if it ends up here the key is skipped else: cmd = entry.cmd if cmd == kt.CMD_emitClipboard: self._gui.emitSelection(False, False) elif cmd == kt.CMD_emitSelection: self._gui.emitSelection(True, False) elif cmd == kt.CMD_scrollPageUp: self._gui.doScroll(-self._gui.lines / 2) elif cmd == kt.CMD_scrollPageDown: self._gui.doScroll(+self._gui.lines / 2) elif cmd == kt.CMD_scrollLineUp: self._gui.doScroll(-1) elif cmd == kt.CMD_scrollLineDown: self._gui.doScroll(+1) elif cmd == kt.CMD_prevSession: if qt.QApplication.reverseLayout(): self.myemit("nextSession") else: self.myemit("prevSession") elif cmd == kt.CMD_nextSession: if qt.QApplication.reverseLayout(): self.myemit("prevSession") else: self.myemit("nextSession") elif cmd == kt.CMD_newSession: self.myemit("newSession") elif cmd == kt.CMD_renameSession: self.myemit("renameSession") elif cmd == kt.CMD_activateMenu: self.myemit("activateMenu") elif cmd == kt.CMD_moveSessionLeft: if qt.QApplication.reverseLayout(): self.myemit("moveSessionRight") else: self.myemit("moveSessionLeft") elif cmd == kt.CMD_moveSessionRight: if qt.QApplication.reverseLayout(): self.myemit("moveSessionLeft") else: self.myemit("moveSessionRight") elif cmd == kt.CMD_scrollLock: self._onScrollLock() # Revert to non-history when typing if self._scr.hist_cursor != self._scr.getHistLines() and not ev.text().isEmpty() or \ ev.key() == qt.QEvent.Key_Down or ev.key() == qt.QEvent.Key_Up or \ ev.key() == qt.QEvent.Key_Left or ev.key() == qt.QEvent.Key_Right or \ ev.key() == qt.QEvent.Key_PageUp or ev.key() == qt.QEvent.Key_PageDown: self._scr.hist_cursor = self._scr.getHistLines() if cmd == kt.CMD_send: #TODO: check whats up with the ALT escape... should we sendENTER too?? if ev_state & AltButton and not entry.metaspecified(): self.sendString("\033") # ESC this is the ALT prefix s_input = entry.txt api.devlog(">>>> CMD_send - s_input = %s" % s_input.encode("hex")) # if ENTER key was pressed we call this to emit a signal to process # user input if ev.key() == qt.Qt.Key_Return or ev.key() == qt.Qt.Key_Enter: new_input, old_input, old_len = self.sendENTER() # if input was changed (this could be due to a plugin that processed # the user input as a command and changed the options), we have to # verify it and send it to the tty if new_input is not None: # means something changed self.sendString(new_input, True, old_len) #api.devlog("Keypress:" + str(ev.key()) ) if ev.key() == 32: self.sendCTRLSPACE() elif ev.key() == 4114: #left self.sendLEFT() elif ev.key() == 4116: #right self.sendRIGHT() elif ev.key() == 4115: #up self.sendUP() elif ev.key() == 4117: #down self.sendDOWN() self.sendString(s_input) return # fall back handling if not ev.text().isEmpty(): if ev_state & AltButton: self.sendString("\033") # ESC this is the ALT prefix s = self._codec.fromUnicode(ev.text()) # Encode for application # FIXME: In Qt 2, QKeyEvent::text() would return "\003" for Ctrl-C etc. # while in Qt 3 it returns the actual key ("c" or "C") which caused # the ControlButton to be ignored. This hack seems to work for # latin1 locales at least. Please anyone find a clean solution (malte) if ev_state & ControlButton: #print ev.ascii(), ev.key() s.fill(chr(ev.ascii()), 1) self.sendString(str(s))
def _newHost(self, item): api.devlog("newHost") dialog = NewHostDialog(self, self._newHostCallback) dialog.exec_loop()
def lv_parameters_currentChanged(self,a0): devlog("PluginSettingsUi.lv_parameters_currentChanged(QListViewItem*): Not implemented yet")
def _newService(self,item): api.devlog("newService") dialog = NewServiceDialog(self, self._newServiceSelectedCallback) dialog.exec_loop()
def _openWorkspace(self, item): api.devlog( "Opening workspace %s selected on the Workspace Perspective" % item.objname) self._getMainApp().openWorkspace(item.objname) self.loadAllWorkspaces()
def _renCategory(self,item): api.devlog("renCategory")
def _newCred(self, item): api.devlog("newCred") dialog = NewCredDialog(self, self._newCredSelectedCallback) dialog.exec_loop()
def processOutputHandler(self, output): """ This method is called when processOutput signal is emitted It sends the process output to the plugin controller so it can pass it to the corresponding plugin """ # the output comes with escape chars for example to show things with colors # those escape chars are messing the text and plugins may not handle that # correctly. #TODO: implement some way of removing the escape sequences # if we get the output from the screen image we have some issues when the # output is longer than the actual size and scrolls the window #TODO: check how to handle the window scrolling #output = self.session.em.getLastOutputFromScreenImage(1) #api.devlog("-"*50) #api.devlog("processOutputHandler called - output =\n%r" % self.session.em.getLastOutputFromScreenImage(1)) #api.devlog("processOutputHandler called - hist lines = %r" % self.session.em._scr.getHistLines()) #api.devlog("-"*50) #TODO: is this really needed??? (to save first prompt output) if self.__first_process_output: # save the output as prompt #api.devlog("Saving prompt for the first time\n\tPROMPT: %r" % output) # then mark flag because it won't be the first anymore self._initial_prompt = output.strip() self.__first_process_output = False # after getting first output which is the default prompt # we change it and clear screen self.__setCurrentShellPromptFormat() self.session.updateLastUserInputLine() return if self.__save_output_prompt_format: # means the output is the PS1 format and we have to store it # The output is the result of running "echo $PS1" so 2 lines are # generated: one with the actual value of PS1 and one more # that is the prompt just because the echo finished # So we have to keep the first line only self._initial_prompt = ouput.splitlines()[0].strip() self.__save_output_prompt_format = False #strip_control_sequences(output) #print "AAAAAAAAAAAAAaaa: ", repr(output) #for word in wordsFound: # output = self.highligthword(word, output) # check if output has to be ignored if not self.__ignore_process_output and not self.__ignore_process_output_once: api.devlog("processOutputHandler (PROCESSED):\n%r" % output) command_finished, output = self.check_command_end(output) #IMPORTANT: if no plugin was selected to process this output # we don't need to send to controller if self.plugin_controller.getActivePluginStatus(): # always send all output to the plugin controller self.plugin_controller.storeCommandOutput(output) # if command ended we notify the plugin if command_finished: api.devlog("calling plugin_controller.onCommandFinished()") self.plugin_controller.onCommandFinished() else: api.devlog("<<< no active plugin...IGNORING OUTPUT >>>") else: #if re.search("export PS1",output) == None: # self.__command += output #if re.search("export PS1",output) == None: # self.__command += output # #if self.__command != "": # api.devlog("processOutputHandler (Allcommand): (%s)" % self.__command) # # #TODO: hacer un regex inicial, y verificar si es el lugar exacto para poner esto. # #TODO: No soporta el backspace o caracteres especiales # #TODO: Recorrer todo no es performante, hay que revisar # for h in self._model_controller._hosts.itervalues(): # if re.search(self.__command,h.name,flags=re.IGNORECASE): # api.devlog("Host name found: " + h.name + " id ("+h.id+")"); # for o in h.getAllInterfaces(): # if re.search(self.__command,o.name,flags=re.IGNORECASE): # api.devlog("Host name found: " + h.name + " id ("+h.id+") - Interface ("+o.name+") id ("+o.id+")"); # for o in h.getAllApplications(): # if re.search(self.__command,o.name,flags=re.IGNORECASE): # api.devlog("Host name found: " + h.name + " id ("+h.id+") - Application ("+o.name+") id ("+o.id+")"); api.devlog("processOutputHandler (IGNORED by flags): \n%r" % output) #api.devlog("self.__ignore_process_output_once = %s" % self.__ignore_process_output_once) #api.devlog("self.__ignore_process_output = %s" % self.__ignore_process_output) self.__ignore_process_output_once = False
def _delCategoryCallback(self, item): api.devlog("delcallbackCategory %s " % (item.name))
def handle(self): try: api.devlog("-" * 60) api.devlog("[XMLRPCHandler] - request = %s" % str(self.request)) api.devlog("[XMLRPCHandler] - client_address = %s" % str(self.client_address)) api.devlog("[XMLRPCHandler] - server = %s" % str(self.server)) api.devlog("-" * 60) SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.handle(self) except Exception: api.devlog( "[XMLRPCHandler] - An error ocurred while handling a request\n%s" % traceback.format_exc())
def _delHostCallback(self, item): api.devlog("delcallbackHost %s " % (item.object.name)) guiapi.delHost(item.object.getID())
def reportErrorToken(self, token, p, q): api.devlog('undecodable %r, %r, %r' % (token, p, q))
def _newInterface(self, item): api.devlog("newInterface") dialog = NewInterfaceDialog(self, self._newInterfaceCallback) dialog.exec_loop()
def processCtrlSpace(self): """ this method is called when the Ctrl+Space is pressed """ if not self.__interactive: # get the complete user input from screen image (this is done so we don't # have to worry about handling any key) user_input = self.session.em.getLastOutputFromScreenImage(get_spaces=True) # parse input to get the prompt and command in separated parts prompt, username, current_path, command_string, command_len = self.__parseUserInput(user_input,get_spaces=True) api.devlog("processCtrlSpace info("+user_input+")("+command_string+")") api.devlog("-"*60) api.devlog("CTRL + SPACE \nprompt = %r\ncommand = %r" % (prompt, command_string)) api.devlog("self.__interactive = %s" % self.__interactive ) api.devlog("-"*60) words=command_string.split(" ") #words2=command_string.split(" ") cword=words[len(words)-1] #obtengo la ultima palabra #words.remove(cword) #elimino la ultima palabra options=[] search=0 mindex=0 try: # si encuentra la palabra significa que se encuentra en una interaccion mindex = self._options.index(cword) #api.devlog("El tname es:" + self._tname) # Si no es la misma herramienta o cambio la cantidad de palabra significa que tengo que empezar de nuevo if (self._tname != words[1] and self._tname != "") or (self._lcount != len(words)): mindex = -1 except ValueError: mindex = -1 if mindex == -1: # si no la encuentra inicia de nuevo. self._options=[] self._optionsh={} search=1 else: options=self._options #Guardo la cantidad palabras para comparar despues self._lcount = len(words) #save first command if len(words) >2: self._tname = words[1] #guardo el nombre de la tool else: self._tname = "" if search ==1 and cword !="": #Busqueda de Hosts (ignore si el comando que escribi es blanco) for h in self._model_controller.getAllHosts(): if re.search(str("^"+cword),h.name,flags=re.IGNORECASE): if len(options) == 0: options.append(cword) api.devlog("Host name found: " + h.name + " id ("+h.id+")"); options.append(h.name) #Busqueda de Hostname dentro de las interfaces for i in h.getAllInterfaces(): for hostname in i.getHostnames(): if re.search(str("^"+cword),hostname,flags=re.IGNORECASE): if len(options) == 0: options.append(cword) api.devlog("Hostname found: " + hostname + " id ("+i.id+")"); options.append(hostname) self._options = options new_options={} api.devlog("Cantidad de _options" + str(len(self._options))) #Si no se encontro nada, busco opciones en el plugin if len(self._options) == 0: #try: if 1==1: #Llamo al controller para ver si hay algun plugin que pueda dar opciones #Devuelve un dict del estilo 'option' : 'help de la option' new_options = self.plugin_controller.getPluginAutocompleteOptions(prompt, username, current_path, command_string, self.__interactive) if new_options != None: if len(new_options) >= 1: #Si encontro plugin que maneje y trae opciones hago iteracciones. api.devlog("Options de plugin encontradas: ("+str(len(new_options))+") valores ("+str(new_options)+")") options = [cword]+new_options.keys() #Guardo las opciones (agrego la word inicial) self._options = options self._optionsh = new_options api.devlog("getPluginAutocompleteOptions: %r" % user_input) api.devlog("new_options:" + str(options)) if 1==2: #except Exception: api.devlog("Exception: Plugin") # if anything in the plugins fails and raises an exception we continue wihout doing anything new_cmd = None # Recorro las opciones disponibles #TODO: Reemplazar esto por una ventana desplegable o i=0 newword="" if len(options) > 1: # Reemplazar solo si hay opciones for w in options: #api.devlog("Por la palabra ("+ w +") (" + str(i)+") la palabra(" + cword+")") if cword==w: if len(options) > i+1: newword=options[i+1] #api.devlog("La encontre next ("+ newword +") (" + str(i)+")"+ str(options) ) else: newword=options[0] #api.devlog("La encontre last ("+ newword +") (" + str(i)+")"+ str(options) ) #newword="-h" i+=1 if self._optionsh.has_key(newword): #TODO: reemplazar esto por un help distinto no usar el devlog api.showPopup( newword + " :" + self._optionsh[newword]) #api.devlog("pluginhelp: " + newword + " :" + self._optionsh[newword]) #Hago el cambio en la shell self.session.sh.sendBytes("\b" * len(cword) + newword)
def _delInterfaceCallback(self, item): api.devlog("delcallbackInterface %s " % (item.object.name)) _parent=item.object.getParent() guiapi.delInterface(_parent.getID(), item.object.getID())
def _delCategorymenu(self,item): api.devlog("delCategorymenu") if item is not None: dialog = MessageDialog(self,title="Category delete",callback=self._delCategoryCallback,item=item) dialog.exec_loop()
def processUserInputBuffer(self): """ this method is called when the ENTER is pressed It processes the user input buffer and then it clears it for future if a new command is returned by a plugin this is returned to the caller (which is onKeyPress in module emuVt102) """ command_string="" command_len = 0 if not self.__interactive: # get the complete user input from screen image (this is done so we don't # have to worry about handling any key) user_input = self.session.em.getLastOutputFromScreenImage(get_full_content=True) api.devlog("user_input parsed from screen(0) = %s" % user_input) # parse input to get the prompt and command in separated parts prompt, username, current_path, command_string, command_len = self.__parseUserInput(user_input) api.devlog("user_input parsed from screen(1) =%s" % self.session.em.getLastOutputFromScreenImage(index=1, get_full_content=True)) # we send the buffer to the plugin controller to determine # if there is a plugin suitable to handle it api.devlog("-"*60) api.devlog("about to call plugin controller\nprompt = %r\ncommand = %r" % (prompt, command_string)) api.devlog("self.__interactive = %s" % self.__interactive ) api.devlog("-"*60) # when calling the plugin, the command string may be changed # if the configuration allows this we send it instead of the typed one #TODO: validate config to allow this try: new_cmd = self.plugin_controller.processCommandInput(prompt, username, current_path, command_string, self.__interactive) # we set it to interactive until we make sure the command has finished # this check is done in processOutputHandler self.__interactive = True api.devlog("processUserInputBuffer: %r" % user_input) api.devlog("new_cmd: %r" % new_cmd) except Exception, e: # if anything in the plugins fails and raises an exception we continue wihout doing anything api.devlog("ERROR: processCommandString") api.devlog(e) new_cmd = None if new_cmd is None: # the output MUST BE processed self.__ignore_process_output = False self.__ignore_process_output_once = False else: # means the plugin changed command and we are going to send # ALT + r to delete current line. That produces an empty output # which has to be ignored self.__ignore_process_output_once = True self.__ignore_process_output = False
def _newCategory(self,item): api.devlog("newCategory")
def _allowPlugins(self): api.devlog("<TabManager> plugins are allowed for current shell (%s)" % self.parent().activeWindow())
def _delServiceCallback(self, item): api.devlog("delcallbackService %s " % (item.name)) _object=item.object _host=_object.getParent() guiapi.delServiceFromHost(_host.getID(), _object.getID())
def _delInterface(self,item): api.devlog("delInterface") if item is not None and item.object is not None: dialog = MessageDialog(self,title="Interface delete",callback=self._delSelectedCallback) dialog.exec_loop()
def processCommandString(self, username, current_path, command_string): """ Adds the -m parameter to get machine readable output. """ arg_match = self.file_arg_re.match(command_string) self._file_output_path=os.path.join(self.data_path,"f_output-%s.txt" % random.uniform(1,10)) parser = argparse.ArgumentParser() parser.add_argument('-e') parser.add_argument('-f') parser.add_argument('-o') #NO support -h --help style parameters. #Need "" in all parameter. Example script.py -p "parameter1 parameter2" parser.add_argument('-p') if arg_match is None: final = re.sub(r"(^.*?fplugin)", r"\1 -o %s" % self._file_output_path, command_string) else: final = re.sub(arg_match.group(1), r"-o %s" % self._file_output_path, command_string) cmd = shlex.split(re.sub(r'\-h|\-\-help', r'', final)) try: self.args, unknown = parser.parse_known_args(cmd) except SystemExit: pass codeEx = "" if self.args.e: codeEx = self.args.e elif self.args.f: with open(current_path + "/" + self.args.f) as f: codeEx = f.read() f.close() if codeEx: buffer = StringIO() sys.stdout = buffer try: locales = locals() locales.update({'script_parameters' : self.args.p}) exec(codeEx, globals(), locales) except Exception: api.devlog("[Error] - Faraday plugin") api.devlog(traceback.format_exc()) sys.stdout = sys.__stdout__ try: f=open(self._file_output_path,"w") f.write(buffer.getvalue()) f.close() except: api.devlog ("[Faraday] Can't save faraday plugin output file") return print buffer.getvalue() return final