def addPath(self,src,dst): if src.lower() != "local": if src not in self.getHostsNames(): print("Not a known Host name.") return hosts = Host.findByName(src) if len(hosts) > 1: print("Several hosts corresponding. Add failed") return src = hosts[0] if src is None: print("The source Host provided doesn't exist in this workspace") return else: src = None try: dst = Endpoint.findByIpPort(dst) except: print("Please specify valid destination endpoint in the IP:PORT form") if dst is None: print("The destination endpoint provided doesn't exist in this workspace") return p = Path(src,dst) p.save() print("Path saved")
def initConnect(self, gateway="auto", verbose=False, target=False): if gateway is not None: if isinstance(gateway, asyncssh.SSHClientConnection): gw = gateway elif gateway == "auto": gateway = self.getEndpoint().findGatewayConnection() if gateway is not None: gw = gateway.initConnect(verbose=verbose) else: gw = None else: gw = gateway.initConnect(verbose=verbose) else: gw = None try: c = asyncio.get_event_loop().run_until_complete( self.async_openConnection(gw, verbose=verbose, target=target)) except: raise if c is not None: if not isinstance(gateway, asyncssh.SSHClientConnection): if gateway is None: pathSrc = None else: if gateway.getEndpoint().getHost() is not None: pathSrc = gateway.getEndpoint().getHost() p = Path(pathSrc, self.getEndpoint()) p.save() return c
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 getClosestEndpoint(self): from baboossh.path import Path endpoints = self.getEndpoints() shortestLen = None shortest = None for endpoint in endpoints: if Path.hasDirectPath(endpoint): return endpoint chain = Path.getPath(None, endpoint) if shortestLen is None or len(chain) < shortestLen: shortest = endpoint shortestLen = len(chain) return shortest
def hostnameToIP(self, hostname, port=None): endpoints = [] #Check if hostname is IP or Hostname : try: ipobj = ipaddress.ip_address(hostname) except ValueError: chan = self.connection.transport.open_channel("session", timeout=3) ips = "" chan.exec_command("getent hosts " + hostname + " | awk '{ print $1 }'") try: x = u(chan.recv(1024)) while len(x) != 0: ips = ips + x x = u(chan.recv(1024)) except socket.timeout: pass chan.close() ips = ips.splitlines() for ip in ips: ipobj = ipaddress.ip_address(ip) if ipobj.is_loopback: continue endpoint = Endpoint(ip, port if port is not None else 22) if endpoint.id is None: endpoint.found = self.connection.endpoint if not self.connection.scope: endpoint.scope = False try: path = Path(self.connection.endpoint.host, endpoint) except ValueError: pass else: endpoint.save() path.save() endpoints.append(endpoint) else: if ipobj.is_loopback: return [] endpoint = Endpoint(hostname, port if port is not None else 22) if endpoint.id is None: endpoint.found = self.connection.endpoint if not self.connection.scope: endpoint.scope = False if endpoint.id is None: endpoint.save() self.newEndpoints.append(endpoint) try: path = Path(self.connection.endpoint.host, endpoint) except ValueError: pass else: path.save() endpoints.append(endpoint) return endpoints
def scan(self, gateway="auto", silent=False): if gateway == "auto": gateway = self.findGatewayConnection() if gateway is not None: gw = gateway.initConnect() else: gw = None done = asyncio.get_event_loop().run_until_complete( self.asyncScan(gw, silent)) try: gw.close() except: pass if gateway is None: gwHost = None else: gwHost = gateway.getEndpoint().getHost() if gwHost is None: return done from baboossh.path import Path p = Path(gwHost, self) if done: p.save() else: if p.getId() is not None: p.delete() return done
def run(cls, stmt, workspace): nmapfile = getattr(stmt, 'nmapfile') from_host = getattr(stmt, 'from', "Local") if from_host is None: print("No source host specified, ignoring paths") distance = None elif from_host == "Local": src = None distance = 0 else: host = Host.find_one(name=from_host) if host is None: print("No host corresponding.") return False src = host distance = src.distance + 1 try: report = NmapParser.parse_fromfile(nmapfile) except Exception as e: print("Failed to read source file: " + str(e)) return False count = 0 count_new = 0 for host in report.hosts: for s in host.services: if s.service == "ssh" and s.open(): count = count + 1 new_endpoint = Endpoint(host.address, s.port) if new_endpoint.id is None: count_new = count_new + 1 new_endpoint.save() if distance is not None: if new_endpoint.distance is None or new_endpoint.distance > distance: new_endpoint.distance = distance new_endpoint.save() new_path = Path(src, new_endpoint) new_path.save() print( str(count) + " endpoints found, " + str(count_new) + " new endpoints saved") return True
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 run(cls, stmt, workspace): nmapfile = getattr(stmt, 'nmapfile') fromHost = getattr(stmt, 'from', "Local") if fromHost is None: src = None print("No source host specified, using Local") elif fromHost == "Local": src = None else: hosts = Host.findByName(fromHost) if len(hosts) > 1: print("Several hosts corresponding.") return False elif len(hosts) == 0: print("No host corresponding.") return False src = hosts[0] try: report = NmapParser.parse_fromfile(nmapfile) except Exception as e: print("Failed to read source file: " + str(e)) return False count = 0 countNew = 0 for host in report.hosts: for s in host.services: if s.service == "ssh": count = count + 1 newEndpoint = Endpoint(host.address, s.port) if newEndpoint.getId() is None: countNew = countNew + 1 newEndpoint.save() newPath = Path(src, newEndpoint) newPath.save() print( str(count) + " endpoints found, " + str(countNew) + " new endpoints saved") return True
def delete(self): from baboossh.path import Path if self.id is None: return for path in Path.findBySrc(self): path.delete() for endpoint in self.getEndpoints(): endpoint.setHost(None) endpoint.save() c = dbConn.get().cursor() c.execute('DELETE FROM hosts WHERE id = ?', (self.id, )) c.close() dbConn.get().commit() return
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
def getPathToDst(self,dst): 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 from the host") return chain = Path.getPath(None,dst) if chain is None: print("No path could be found to the destination") return for path in chain: print(path)
async def hostnameToIP(self, hostname, port=None): endpoints = [] #Check if hostname is IP or Hostname : try: ipobj = ipaddress.ip_address(hostname) except ValueError: res = await self.socket.run("getent hosts " + hostname + " | awk '{ print $1 }'") ips = res.stdout.splitlines() for ip in ips: ipobj = ipaddress.ip_address(ip) if ipobj.is_loopback: continue endpoint = Endpoint(ip, port if port is not None else 22) if endpoint.getId() is None: endpoint.setFound(self.connection.getEndpoint()) if not self.connection.inScope(): endpoint.unscope() try: path = Path(self.connection.getEndpoint().getHost(), endpoint) except ValueError: pass else: endpoint.save() path.save() endpoints.append(endpoint) else: if ipobj.is_loopback: return [] endpoint = Endpoint(hostname, port if port is not None else 22) if endpoint.getId() is None: endpoint.setFound(self.connection.getEndpoint()) if not self.connection.inScope(): endpoint.unscope() if endpoint.getId() is None: endpoint.save() self.newEndpoints.append(endpoint) try: path = Path(self.connection.getEndpoint().getHost(), endpoint) except ValueError: pass else: path.save() endpoints.append(endpoint) return endpoints
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 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 getPaths(self): return Path.findAll()