def getTargetsList(self,scope=None): connections = [] for connection in Connection.findAll(): if scope is None: connections.append(str(connection)) elif connection.inScope() == scope: connections.append(str(connection)) return connections
def findGatewayConnection(self): from baboossh.path import Path from baboossh.connection import Connection if not Path.hasDirectPath(self): paths = Path.getPath(None, self) if paths is None: return None else: prevHop = paths[-1].getSrc().getClosestEndpoint() return Connection.findWorkingByEndpoint(prevHop) return None
def delete(self): from baboossh.connection import Connection if self.id is None: return for connection in Connection.findByUser(self): connection.delete() c = dbConn.get().cursor() c.execute('DELETE FROM users WHERE id = ?', (self.id, )) c.close() dbConn.get().commit() return
def openTunnel(self,target,port=None): if port is not None and port in self.tunnels.keys(): print("A tunnel is already opened at port "+str(port)) return False connection = Connection.fromTarget(target) try: t = Tunnel(connection,port) except Exception as e: print("Error opening tunnel: "+str(e)) return False self.tunnels[t.getPort()] = t return True
def scanTarget(self,target,gateway=None): if not isinstance(target,Endpoint): target = Endpoint.findByIpPort(target) if gateway is not None: if gateway == "local": gateway = None else: gateway = Connection.fromTarget(gateway) else: gateway = "auto" working = target.scan(gateway=gateway) return working
def connectTarget(self,arg,verbose,gateway): if gateway is not None: if gateway == "local": gateway = None else: gateway = Connection.fromTarget(gateway) else: gateway = "auto" connection = Connection.fromTarget(arg) working = connection.testConnect(gateway=gateway,verbose=verbose) if working: if gateway != "auto": if gateway is None: pathSrc = None elif gateway.getEndpoint().getHost() is None: return working else: pathSrc = gateway.getEndpoint().getHost() p = Path(pathSrc,connection.getEndpoint()) p.save() return working
def runTarget(self,arg,payloadName,stmt): if arg in self.getHostsNames(): hosts = Host.findByName(arg) if len(hosts) > 1: print("Several hosts corresponding. Please target endpoint.") return False arg = str(hosts[0].getClosestEndpoint()) connection = Connection.fromTarget(arg) if not connection.working: print("Please check connection "+str(connection)+" with connect first") return False payload = Extensions.getPayload(payloadName) return connection.run(payload,self.workspaceFolder,stmt)
def threadConnect(self,verbose,endpoint,users,creds): try: loop = asyncio.get_event_loop() except: loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) c = dbConn.get() if Path.hasDirectPath(endpoint): gw = None else: gateway = endpoint.findGatewayConnection() if gateway is not None: if verbose: print("Connecting to gateway "+str(gateway)+" to reach "+str(endpoint)+"...") gw = gateway.initConnect(verbose=verbose) else: gw = None workingQueue = [] dunnoQueue = [] for user in users: for cred in creds: connection = Connection(endpoint,user,cred) if connection.isWorking(): workingQueue.append(connection) else: dunnoQueue.append(connection) queue = workingQueue + dunnoQueue for connection in queue: try: working = connection.testConnect(gw,verbose=True) except: print("Due to timeout, subsequent connections to endpoint will be ignored.") break if working: break if gw is not None: gw.close() dbConn.close()
def setOption(self,option,value): if option == 'connection': if value is None: self.options['endpoint'] = None self.options['user'] = None self.options['creds'] = None for option in ['endpoint','user','creds']: print(option+" => "+str(self.getOption(option))) return if '@' not in value or ':' not in value: return connection = Connection.fromTarget(value) if connection == None: return self.options['endpoint'] = connection.getEndpoint() self.options['user'] = connection.getUser() self.options['creds'] = connection.getCred() for option in ['endpoint','user','creds']: print(option+" => "+str(self.getOption(option))) return if not option in list(self.options.keys()): raise ValueError(option+" isn't a valid option.") if value != None: value = value.strip() if option == "endpoint": endpoint = Endpoint.findByIpPort(value) if endpoint is None: raise ValueError value = endpoint elif option == "user": user = User.findByUsername(value) if user is None: raise ValueError value = user elif option == "creds": if value[0] == '#': credId = value[1:] else: credId = value creds = Creds.find(credId) if creds is None: raise ValueError value = creds elif option == "payload": value = Extensions.getPayload(value) self.options[option] = value else: self.options[option] = None print(option+" => "+str(self.getOption(option)))
def delete(self): from baboossh.path import Path from baboossh.connection import Connection if self.id is None: return if self.host is not None: endpoints = self.host.getEndpoints() if len(endpoints) == 1: self.host.delete() for connection in Connection.findByEndpoint(self): connection.delete() for path in Path.findByDst(self): path.delete() c = dbConn.get().cursor() c.execute('DELETE FROM endpoints WHERE id = ?', (self.id, )) c.close() dbConn.get().commit() return
def getConnection(self, working=True, scope=True): from baboossh.connection import Connection c = dbConn.get().cursor() if working: req = c.execute( '''SELECT id FROM connections WHERE endpoint=? AND working=? ORDER BY root DESC''', (self.getId(), 1)) else: req = c.execute( '''SELECT id FROM connections WHERE endpoint=? ORDER BY root DESC''', (self.getId(), )) for row in req: connection = Connection.find(row[0]) if scope is None: c.close() return connection elif scope == connection.inScope(): c.close() return connection c.close() return None
def findPath(self,dst): #DST is HOST #if dst in self.getHostsNames(): # hosts = Host.findByName(dst) # if len(hosts) > 1: # print("Several hosts corresponding. Please target endpoint.") # return False # dst = str(hosts[0].getClosestEndpoint()) try: dst = Endpoint.findByIpPort(dst) except: print("Please specify a valid endpoint in the IP:PORT form") return if dst is None: print("The endpoint provided doesn't exist in this workspace") return if Path.hasDirectPath(dst): print("The destination should be reachable directly from the host.") return workingDirect = dst.scan(gateway=None,silent=True) if workingDirect: p = Path(None,dst) p.save() print("Could reach target directly, path added.") return for h in Path.getHostsOrderedClosest(): e = h.getClosestEndpoint() gateway = Connection.findWorkingByEndpoint(e) working = dst.scan(gateway=gateway,silent=True) if working: p = Path(h,dst) p.save() print("Working with gw "+str(e)+" (host "+str(h)+")") return return
async def gatherFromConfig(self): lootFolder = os.path.join(self.wspaceFolder, "loot") filename = str(self.connection.getEndpoint()).replace( ":", "-") + "_" + str(self.connection.getUser()) + "_.ssh_config" filepath = os.path.join(lootFolder, filename) try: await asyncssh.scp((self.socket, ".ssh/config"), filepath) except Exception as e: return None with open(filepath, 'r', errors='replace') as f: data = f.read() lines = data.split('\n') curHost = None for line in lines: if line == '': continue if line[:5].lower() == "Host ".lower(): if curHost != None and curHost["name"] != "*": if "host" in curHost.keys(): host = curHost["host"] else: host = curHost["name"] if "port" in curHost.keys(): port = curHost["port"] else: port = None endpoints = await self.hostnameToIP(host, port) user = None identity = None if "user" in curHost.keys(): user = User(curHost["user"]) if not self.connection.inScope(): user.unscope() if user.getId() is None: user.setFound(self.connection.getEndpoint()) user.save() self.newUsers.append(user) if "identity" in curHost.keys(): identity = await self.getKeyToCreds( curHost["identity"], ".") if user is not None and identity is not None: for endpoint in endpoints: conn = Connection(endpoint, user, identity) conn.save() self.newConnections.append(conn) curHost = {} curHost["name"] = line.split()[1] else: [key, val] = line.strip().split(' ', 1) key = key.lower() if key == "user": curHost['user'] = val elif key == "port": curHost['port'] = val elif key == "hostname": curHost['host'] = val elif key == "identityfile": if val[:2] == '~/': val = val[2:] curHost['identity'] = val if curHost != None and curHost["name"] != "*": print("Not None") if "host" in curHost.keys(): host = curHost["host"] else: host = curHost["name"] if "port" in curHost.keys(): port = curHost["port"] else: port = None endpoints = await self.hostnameToIP(host, port) user = None identity = None if "user" in curHost.keys(): user = User(curHost["user"]) if not self.connection.inScope(): user.unscope() if user.getId() is None: user.setFound(self.connection.getEndpoint()) self.newUsers.append(user) user.save() if "identity" in curHost.keys(): identity = await self.getKeyToCreds(curHost["identity"], ".") if user is not None and identity is not None: for endpoint in endpoints: conn = Connection(endpoint, user, identity) conn.save() self.newConnections.append(conn) print("End")
def delConnection(self,target): connection = Connection.fromTarget(target) if connection is None: print("Connection not found.") return false return connection.delete()
def connect(self,endpoint,user,cred,verbose): connection = Connection(endpoint,user,cred) return connection.testConnect(verbose=verbose)
def getConnections(self,tested=False,working=False): if working: return Connection.findWorking() if tested: return Connection.findTested() return Connection.findAll()
def run(self,endpoint,user,cred,payload,stmt): connection = Connection(endpoint,user,cred) if not connection.working: #print("Please check connection "+str(connection)+" with connect first") return False return connection.run(payload,self.workspaceFolder,stmt)
async def gatherFromHistory(self, historyFile): lootFolder = os.path.join(self.wspaceFolder, "loot") filename = str(self.connection.getEndpoint()).replace( ":", "-") + "_" + str( self.connection.getUser()) + "_" + historyFile.replace( "/", "_") filepath = os.path.join(lootFolder, filename) try: await asyncssh.scp((self.socket, historyFile), filepath) except Exception as e: print(e) return None with open(filepath, "r", errors="ignore") as dledFile: data = dledFile.read() lines = data.splitlines() for line in lines: if re.search(r'^ *ssh ', line): option = "" words = line.split() host = False port = None user = None identity = None for i in range(1, len(words)): if option != "": if option == "identity": identity = words[i] if identity[:2] == '~/': identity = identity[2:] elif option == "port": port = words[i] option = "" elif words[i][0] == "-": if words[i] == "-i": option = "identity" elif words[i] == "-p": option = "port" else: option = words[i] elif not host: if '@' in words[i]: user, hostname = words[i].split("@", 1) else: hostname = words[i] host = True if not host: continue endpoints = await self.hostnameToIP(hostname, port) if user is not None: user = User(user) if not self.connection.inScope(): user.unscope() if user.getId() is None: user.setFound(self.connection.getEndpoint()) user.save() self.newUsers.append(user) if identity is not None: identity = await self.getKeyToCreds(identity, ".") if user is not None and identity is not None: for endpoint in endpoints: conn = Connection(endpoint, user, identity) conn.save() self.newConnections.append(conn)