Ejemplo n.º 1
0
    def find_one(cls,
                 connection_id=None,
                 endpoint=None,
                 scope=None,
                 gateway_to=None):
        """Find a `Connection` by its id, endpoint or if it can be used as a gateway to an :class:`Endpoint`

        Args:
            connection_id (int): the `Connection` id to search
            endpoint (:class:`Endpoint`): the `Connection` endpoint to search
            gateway_to (:class:`Endpoint`): the Endpoint to which you want to find a gateway
            scope (bool): whether to include only in scope Connections (`True`), out of scope Connections (`False`) or both (`None`)

        Returns:
            A single `Connection` or `None`.
        """

        if gateway_to is not None:
            if gateway_to.distance is not None and gateway_to.distance == 0:
                return None
            try:
                closest_host = Host.find_one(prev_hop_to=gateway_to)
            except NoPathError as exc:
                raise exc
            if closest_host is None:
                return None
            return cls.find_one(endpoint=closest_host.closest_endpoint,
                                scope=True)

        cursor = Db.get().cursor()
        if connection_id is not None:
            req = cursor.execute(
                'SELECT endpoint, user, cred FROM connections WHERE id=?',
                (connection_id, ))
        elif endpoint is not None:
            req = cursor.execute(
                'SELECT endpoint, user, cred FROM connections WHERE endpoint=? ORDER BY root ASC',
                (endpoint.id, ))
        else:
            cursor.close()
            return None
        if scope is None:
            row = cursor.fetchone()
            cursor.close()
            if row is None:
                return None
            return Connection(Endpoint.find_one(endpoint_id=row[0]),
                              User.find_one(user_id=row[1]),
                              Creds.find_one(creds_id=row[2]))
        for row in req:
            conn = Connection(Endpoint.find_one(endpoint_id=row[0]),
                              User.find_one(user_id=row[1]),
                              Creds.find_one(creds_id=row[2]))
            if scope == conn.scope:
                cursor.close()
                return conn
        cursor.close()
        return None
Ejemplo n.º 2
0
    def from_target(cls, arg):
        if '@' in arg and ':' in arg:
            auth, sep, endpoint = arg.partition('@')
            endpoint = Endpoint.find_one(ip_port=endpoint)
            if endpoint is None:
                raise ValueError("Supplied endpoint isn't in workspace")
            user, sep, cred = auth.partition(":")
            if sep == "":
                raise ValueError("No credentials supplied")
            user = User.find_one(name=user)
            if user is None:
                raise ValueError("Supplied user isn't in workspace")
            if cred[0] == "#":
                cred = cred[1:]
            cred = Creds.find_one(creds_id=cred)
            if cred is None:
                raise ValueError("Supplied credentials aren't in workspace")
            return Connection(endpoint, user, cred)

        if ':' not in arg:
            arg = arg + ':22'
        endpoint = Endpoint.find_one(ip_port=arg)
        if endpoint is None:
            raise ValueError("Supplied endpoint isn't in workspace")
        connection = cls.find_one(endpoint=endpoint)
        if connection is None:
            raise ValueError("No working connection for supplied endpoint")
        return connection
Ejemplo n.º 3
0
    def creds_edit(self, creds_id):
        """Edit a :class:`Creds` ' properties

        Args:
            creds_id (str): The `Creds` ' id
        """

        if creds_id[0] == '#':
            creds_id = creds_id[1:]
        creds = Creds.find_one(creds_id=creds_id)
        if creds is None:
            print("Specified creds not found")
            return
        creds.edit()
Ejemplo n.º 4
0
    def creds_del(self, creds_id):
        """Delete a :class:`Creds` ' from the workspace

        Args:
            creds_id (str): The `Creds` ' id
        """

        if creds_id[0] == '#':
            creds_id = creds_id[1:]
        creds = Creds.find_one(creds_id=creds_id)
        if creds is None:
            print("Specified creds not found")
            return False
        if self.options["creds"] == creds:
            self.set_option("creds", None)
        self.unstore(creds.delete())
        return True
Ejemplo n.º 5
0
    def enum_run(self, target=None):
        if target is not None:
            if '@' not in target:
                host = Host.find_one(name=target)
                if host is not None:
                    conn = Connection.find_one(endpoint=host.closest_endpoint)
                    if conn is not None:
                        return [conn]
                raise ValueError("Supplied value doesn't match a known host or a connection string")

            auth, sep, endpoint = target.partition('@')
            if endpoint == "*":
                endpoint = None
            elif endpoint[0] == "!":
                tag = Tag(endpoint[1:])
                endpoints = tag.endpoints
            else:
                endpoint = Endpoint.find_one(ip_port=endpoint)
                if endpoint is None:
                    raise ValueError("Supplied endpoint isn't in workspace")

            user, sep, cred = auth.partition(":")
            if sep == "":
                raise ValueError("No credentials supplied")
            if user == "*":
                user = None
            else:
                user = User.find_one(name=user)
                if user is None:
                    raise ValueError("Supplied user isn't in workspace")
            if cred == "*":
                cred = None
            else:
                if cred[0] == "#":
                    cred = cred[1:]
                cred = Creds.find_one(creds_id=cred)
                if cred is None:
                    raise ValueError("Supplied credentials aren't in workspace")
        else:
            user = self.options["user"]
            endpoint = self.options["endpoint"]
            cred = self.options["creds"]

        return Connection.find_all(endpoint=endpoint, user=user, creds=cred)
Ejemplo n.º 6
0
 def identify_object(self, target):
     if target[0] == "#":
         creds_id = target[1:]
     else:
         creds_id = target
     creds = Creds.find_one(creds_id=creds_id)
     if creds is not None:
         return creds
     user = User.find_one(name=target)
     if user is not None:
         return user
     try:
         dst = Endpoint.find_one(ip_port=target)
         if dst is not None:
             return dst
     except:
         pass
     host = Host.find_one(name=target)
     if host is not None:
         return host
     print("Could not identify object.")
     return None
Ejemplo n.º 7
0
    def enum_connect(self, target=None, force=False, unprobed=False):
        if target is not None:
            if '@' not in target:
                host = Host.find_one(name=target)
                if host is not None:
                    conn = Connection.find_one(endpoint=host.closest_endpoint)
                    if conn is not None:
                        return [conn]
                raise ValueError("Supplied value doesn't match a known host or a connection string")

            auth, sep, endpoint = target.partition('@')
            if endpoint == "*":
                endpoints = Endpoint.find_all(scope=True)
            elif endpoint[0] == "!":
                tag = Tag(endpoint[1:])
                endpoints = tag.endpoints
            else:
                endpoint = Endpoint.find_one(ip_port=endpoint)
                if endpoint is None:
                    raise ValueError("Supplied endpoint isn't in workspace")
                endpoints = [endpoint]

            user, sep, cred = auth.partition(":")
            if sep == "":
                raise ValueError("No credentials supplied")
            if user == "*":
                users = User.find_all(scope=True)
            else:
                user = User.find_one(name=user)
                if user is None:
                    raise ValueError("Supplied user isn't in workspace")
                users = [user]
            if cred == "*":
                creds = Creds.find_all(scope=True)
            else:
                if cred[0] == "#":
                    cred = cred[1:]
                cred = Creds.find_one(creds_id=cred)
                if cred is None:
                    raise ValueError("Supplied credentials aren't in workspace")
                creds = [cred]
            if len(endpoints)*len(users)*len(creds) == 1:
                return [Connection(endpoints[0], users[0], creds[0])]
        else:
            user = self.options["user"]
            if user is None:
                users = User.find_all(scope=True)
            else:
                users = [user]
            endpoint = self.options["endpoint"]
            if isinstance(endpoint, Tag):
                endpoints = endpoint.endpoints
            elif endpoint is None:
                endpoints = Endpoint.find_all(scope=True)
            else:
                endpoints = [endpoint]
            cred = self.options["creds"]
            if cred is None:
                creds = Creds.find_all(scope=True)
            else:
                creds = [cred]
            if len(endpoints)*len(users)*len(creds) == 1:
                return [Connection(endpoints[0], users[0], creds[0])]

        ret = []
        for endpoint in endpoints:
            if not unprobed and not endpoint.reachable:
                continue
            for user in users:
                if len(creds) != 1:
                    working_connections = Connection.find_all(endpoint=endpoint, user=user)
                    if not force and working_connections:
                        print("Connection already found with user "+str(user)+" on endpoint "+str(endpoint)+", creds bruteforcing is disabled. Specify creds or use --force.")
                        continue
                for cred in creds:
                    conn = Connection(endpoint, user, cred)
                    if force:
                        ret.append(conn)
                    else:
                        if conn.id is None:
                            ret.append(conn)
        return ret
Ejemplo n.º 8
0
    def set_option(self, option, value):
        """Set an option for the `Workspace`

        Args:
            option (str): the option to set
            value (str): the new value
        """

        if option == 'connection':
            if value is None:
                self.options['endpoint'] = None
                self.options['user'] = None
                self.options['creds'] = None

                print("endpoint => "+str(self.options['endpoint']))
                print("user => "+str(self.options['user']))
                print("creds => "+str(self.options['creds']))

            elif '@' not in value or ':' not in value:
                return
            connection = Connection.from_target(value)
            if connection is None:
                return
            self.options['endpoint'] = connection.endpoint
            self.options['user'] = connection.user
            self.options['creds'] = connection.creds

            print("endpoint => "+str(self.options['endpoint']))
            print("user => "+str(self.options['user']))
            print("creds => "+str(self.options['creds']))
            return

        if not option in list(self.options.keys()):
            raise ValueError(option+" isn't a valid option.")

        if value is not None:
            value = value.strip()
            if option == "endpoint":
                if value[0] == "!":
                    value = Tag(value[1:])
                else:
                    endpoint = Endpoint.find_one(ip_port=value)
                    if endpoint is None:
                        raise ValueError
                    value = endpoint
            elif option == "user":
                user = User.find_one(name=value)
                if user is None:
                    raise ValueError
                value = user
            elif option == "creds":
                if value[0] == '#':
                    creds_id = value[1:]
                else:
                    creds_id = value
                creds = Creds.find_one(creds_id=creds_id)
                if creds is None:
                    raise ValueError
                value = creds
            elif option == "payload":
                value = Extensions.payloads[value]
            self.options[option] = value
        else:
            self.options[option] = None
        print(option+" => "+str(self.options[option]))
Ejemplo n.º 9
0
    def find_all(cls, endpoint=None, user=None, creds=None, scope=None):
        """Find all `Connection` matching the criteria

        If two or more arguments are specified, the returned Connections must match each ("AND")

        Args:
            endpoint (:class:`Endpoint` or :class:`Tag`): the `Connection` endpoint to search or a :class:`Tag` of endpoints to search
            user (:class:`User`): the `Connection` user to search
            creds (:class:`Creds`): the `Connection` creds to search
            scope (bool): whether to include only in scope Connections (`True`), out of scope Connections (`False`) or both (`None`)

        Returns:
            A list of matching `Connection`.
        """

        ret = []
        cursor = Db.get().cursor()

        query = 'SELECT endpoint, user, cred FROM connections'
        params = []
        first = True
        if endpoint is not None and not isinstance(endpoint, Tag):
            if first:
                query = query + ' WHERE '
                first = False
            else:
                query = query + ' AND '
            query = query + 'endpoint=?'
            params.append(endpoint.id)
        elif endpoint is not None and isinstance(endpoint, Tag):
            if first:
                query = query + ' WHERE ('
                first = False
            else:
                query = query + ' AND ('
            first_endpoint = True
            for end in endpoint.endpoints:
                if not first_endpoint:
                    query = query + ' OR '
                else:
                    first_endpoint = False
                query = query + 'endpoint=?'
                params.append(end.id)
            query = query + ' )'
        if user is not None:
            if first:
                query = query + ' WHERE '
                first = False
            else:
                query = query + ' AND '
            query = query + 'user=?'
            params.append(user.id)
        if creds is not None:
            if first:
                query = query + ' WHERE '
                first = False
            else:
                query = query + ' AND '
            query = query + 'cred=?'
            params.append(creds.id)

        req = cursor.execute(query, tuple(params))

        for row in req:
            conn = Connection(Endpoint.find_one(endpoint_id=row[0]),
                              User.find_one(user_id=row[1]),
                              Creds.find_one(creds_id=row[2]))
            if scope is None or conn.scope == scope:
                ret.append(conn)
        cursor.close()
        return ret