Esempio n. 1
0
    def get_membersof(self, kwargs):
        """
		List the members of `group`.

		Arguments:
			@verbose:bool
				Results will contain full information
			#group:string
				Group to list members
		"""
        group = kwargs["group"]
        verbose = kwargs.get("verbose", False)

        results = self.ldap.query(GROUP_DN_FILTER.format(group=group),
                                  ["distinguishedName", "objectSid"])
        if results:
            group_dn = results[0]["distinguishedName"]
        else:
            error("Group {group} does not exists".format(group=group))

        primary_group_id = results[0]["objectSid"].split('-')[-1]
        results = self.ldap.query(
            USERS_IN_GROUP_FILTER.format(group=group_dn,
                                         primary_group_id=primary_group_id))
        self.display(results, verbose)
Esempio n. 2
0
    def __init__(self, ldap_connection, format="json"):
        try:
            self.ldap = ldap_connection
        except ActiveDirectoryView.ActiveDirectoryLdapException as e:
            error(e)

        if format == "json":
            self.__display = self.__display_json
Esempio n. 3
0
	def action_unlock(self, kwargs):
		"""
		Unlock `user`.

		Arguments:
			#user:string
				User to unlock
		"""
		user = kwargs["user"]

		if self.engine.unlock(user):
			info("User {username} unlocked (or was already unlocked)".format(username=user))
		else:
			error("Unable to unlock {username}, check privileges".format(username=user))
Esempio n. 4
0
    def get_from_guid(self, kwargs):
        """
		Return the object associated with the given `guid`.

		Arguments:
			@verbose:bool
				Results will contain full information
			#guid:string
				GUID to search for
		"""
        guid = kwargs["guid"]
        verbose = kwargs.get("verbose", False)

        try:
            self.display(self.engine.resolve_guid(guid), verbose)
        except ActiveDirectoryView.ActiveDirectoryLdapInvalidGUID:
            error("Invalid GUID")
Esempio n. 5
0
    def get_memberships(self, kwargs):
        """
		List the group for which `users` belongs to.

		Arguments:
			#user:string
				User to list memberships
			@recursive:bool
				List recursively the groups
		"""
        user = kwargs["user"]
        recursive = kwargs.get("recursive", False)

        already_printed = set()

        def lookup_groups(dn, leading_sp, already_treated):
            groups = []
            results = self.ldap.query("(distinguishedName={})".format(dn),
                                      ["memberOf"])
            for result in results:
                if "memberOf" in result:
                    for group_dn in result["memberOf"]:
                        if group_dn not in already_treated:
                            print("{g:>{width}}".format(g=group_dn,
                                                        width=leading_sp +
                                                        len(group_dn)))
                            already_treated.add(group_dn)
                            treated = lookup_groups(group_dn, leading_sp + 4,
                                                    already_treated)
                            return treated

            return already_treated

        results = self.ldap.query(USER_IN_GROUPS_FILTER.format(username=user),
                                  ["memberOf"])
        for result in results:
            if "memberOf" in result:
                for group_dn in result["memberOf"]:
                    print(group_dn)
                    if recursive:
                        already_printed.add(group_dn)
                        s = lookup_groups(group_dn, 4, already_printed)
                        already_printed.union(s)
            else:
                error("No groups for user {}".format(user))
Esempio n. 6
0
	def get_zone(self, kwargs):
		"""
		Return the records of a DNS zone.

		Arguments:
			#dns_zone:string
				DNS zone to retrieve records
		"""
		dns_zone = kwargs["dns_zone"]
		try:
			results = self.engine.query(
				self.engine.ZONE_FILTER(),
				base=','.join([f"DC={dns_zone}", "CN=MicrosoftDNS,DC=DomainDNSZones", self.engine.base_dn])
			)
		except LdapActiveDirectoryView.ActiveDirectoryLdapException as e:
			error(e)
		else:
			self.display(results)
Esempio n. 7
0
    def get_memberships(self, kwargs):
        """
		List the group for which `account` belongs to.

		Arguments:
			#account:string
				User to list memberships
			@recursive:bool
				List recursively the groups
		"""
        account = kwargs["account"]
        recursive = kwargs.get("recursive", False)

        already_printed = set()

        def lookup_groups(dn, leading_sp, already_treated):
            groups = []
            results = self.engine.query(self.engine.DISTINGUISHED_NAME(dn),
                                        ["memberOf"])
            for result in results:
                if "memberOf" in result:
                    for group_dn in result["memberOf"]:
                        if group_dn not in already_treated:
                            print("{g:>{width}}".format(g=group_dn,
                                                        width=leading_sp +
                                                        len(group_dn)))
                            already_treated.add(group_dn)
                            lookup_groups(group_dn, leading_sp + 4,
                                          already_treated)

            return already_treated

        results = self.engine.query(self.engine.USER_IN_GROUPS_FILTER(account),
                                    ["memberOf"])
        for result in results:
            if "memberOf" in result:
                for group_dn in result["memberOf"]:
                    print(group_dn)
                    if recursive:
                        already_printed.add(group_dn)
                        s = lookup_groups(group_dn, 4, already_printed)
                        already_printed.union(s)
            else:
                error(f"Account {account} doesn't belong to any group")
Esempio n. 8
0
    def misc_search(self, kwargs):
        """
		Query the LDAP with `filter` and retrieve ALL or `attributes` if specified.

		Arguments:
			#filter:string
				LDAP filter to search for
			#attributes:string = 'ALL'
				Comma separated list of attributes to display, ALL for every possible attribute
		"""
        attr = kwargs["attributes"]
        filter_ = kwargs["filter"]

        try:
            if attr and attr != "ALL":
                results = self.engine.query(filter_, attr.split(","))
            else:
                results = self.engine.query(filter_)
            self.display(results, True)
        except Exception as e:
            error(e)
Esempio n. 9
0
    def get_from_sid(self, kwargs):
        """
		Return the object associated with the given `sid`.

		Arguments:
			@verbose:bool
				Results will contain full information
			#sid:string
				SID to search for
		"""
        sid = kwargs["sid"]
        verbose = kwargs.get("verbose", False)

        try:
            result = self.engine.resolve_sid(sid)
            if isinstance(result, str):
                print(result)
            else:
                self.display(result, verbose)
        except ActiveDirectoryView.ActiveDirectoryInvalidSID:
            error("Invalid SID")
Esempio n. 10
0
	def misc_search(self, kwargs):
		"""
		Query the LDAP with `filter` and retrieve ALL or `attributes` if specified.

		Arguments:
			#filter:string
				LDAP filter to search for
			#attributes:string = 'ALL'
				Comma separated list of attributes to display, ALL for every possible attribute
		"""
		attr = kwargs["attributes"]
		filter_ = kwargs["filter"]

		try:
			if attr and attr != "ALL":
				results = self.engine.query(filter_, attr.split(","))
			else:
				results = self.engine.query(filter_)
			self.display(results, True)
		except PyAsn1UnicodeDecodeError as e:
			error("Decoding error with the filter")
		except Exception as e:
			if e.__str__() == "":
				error("An exception occurred with the provided filter")
			else:
				error(e)
Esempio n. 11
0
	def action_modify_password(self, kwargs):
		"""
		Change `user`'s password.

		Arguments:
			#user:string
				User to unlock
			#newpassword:string
				New password
			#currpassword:string = None
				Current password
		"""
		user = kwargs["user"]
		new = kwargs["newpassword"]
		curr = kwargs.get("currpassword", None)
		if curr == "None":
			curr = None

		if self.engine.modify_password(user, curr, new):
			info("Password of {username} changed".format(username=user))
		else:
			error("Unable to change {username}'s password, check privileges or try with ldaps://".format(username=user))
Esempio n. 12
0
def main():
    parser = ArgumentParser()
    parser.add_argument("-o",
                        "--outfile",
                        default="",
                        help="Store the results in a file")
    parser.add_argument(
        "--security_desc",
        action="store_true",
        help="Enable the retrieval of security descriptors in ldeep results")

    sub = parser.add_subparsers(title="Mode",
                                dest="mode",
                                description="Available modes",
                                help="Backend engine to retrieve data")
    sub.required = True

    ldap = sub.add_parser("ldap", description="LDAP mode")
    cache = sub.add_parser("cache", description="Cache mode")

    ldap.add_argument("-d",
                      "--domain",
                      required=True,
                      help="The domain as NetBIOS or FQDN")
    ldap.add_argument("-s",
                      "--ldapserver",
                      required=True,
                      help="The LDAP path (ex : ldap://corp.contoso.com:389)")
    ldap.add_argument(
        "-b",
        "--base",
        default="",
        help=
        "LDAP base for query (by default, this value is pulled from remote Ldap)"
    )

    cache.add_argument(
        "-d",
        "--dir",
        default=".",
        type=str,
        help="Use saved JSON files in specified directory as cache")
    cache.add_argument("-p",
                       "--prefix",
                       required=True,
                       type=str,
                       help="Prefix of ldeep saved files")

    ntlm = ldap.add_argument_group("NTLM authentication")
    ntlm.add_argument("-u", "--username", help="The username")
    ntlm.add_argument("-p",
                      "--password",
                      help="The password or the corresponding NTLM hash")

    kerberos = ldap.add_argument_group("Kerberos authentication")
    kerberos.add_argument(
        "-k",
        "--kerberos",
        action="store_true",
        help=
        "For Kerberos authentication, ticket file should be pointed by $KRB5NAME env variable"
    )

    anonymous = ldap.add_argument_group("Anonymous authentication")
    anonymous.add_argument("-a",
                           "--anonymous",
                           action="store_true",
                           help="Perform anonymous binds")

    Ldeep.add_subparsers(ldap,
                         "ldap", ["list_", "get_", "misc_", "action_"],
                         title="commands",
                         description="available commands")
    Ldeep.add_subparsers(cache,
                         "cache", ["list_", "get_"],
                         title="commands",
                         description="available commands")

    args = parser.parse_args()

    # Output
    if args.outfile:
        sys.stdout = Logger(args.outfile, quiet=False)

    cache = "prefix" in args  # figuring out whether we use the cache or not

    # main
    if cache:
        try:
            query_engine = CacheActiveDirectoryView(args.dir, args.prefix)
        except CacheActiveDirectoryView.CacheActiveDirectoryDirNotFoundException as e:
            error(e)

    else:
        try:
            # Authentication
            method = "NTLM"
            if args.kerberos:
                method = "Kerberos"
            elif args.username:
                method = "NTLM"
            elif args.anonymous:
                method = "anonymous"
            else:
                error(
                    "Lack of authentication options: either Kerberos, Username with Password (can be a NTLM hash) or Anonymous."
                )

            query_engine = LdapActiveDirectoryView(args.ldapserver,
                                                   args.domain, args.base,
                                                   args.username,
                                                   args.password, method)

        except LdapActiveDirectoryView.ActiveDirectoryLdapException as e:
            error(e)

    # If `security_desc` are requested, enable LDAP Security Descriptor flags and modify the default attributes
    # In cache mode, the security_desc corresponding JSON field will be kept
    if args.security_desc:
        query_engine.set_controls(LDAP_SERVER_SD_FLAGS_OID_SEC_DESC)
        query_engine.set_all_attributes([
            ALL_ATTRIBUTES, ALL_OPERATIONAL_ATTRIBUTES, "ntSecurityDescriptor"
        ])

    ldeep = Ldeep(query_engine)

    try:
        ldeep.dispatch_command(args)
    except CacheActiveDirectoryView.CacheActiveDirectoryException as e:
        error(e)
    except NotImplementedError:
        error("Feature not yet available")
Esempio n. 13
0
def main():
    parser = ArgumentParser()
    parser.add_argument("-d",
                        "--fqdn",
                        help="The domain FQDN (ex : domain.local)",
                        required=True)
    parser.add_argument(
        "-s",
        "--ldapserver",
        help="The LDAP path (ex : ldap://corp.contoso.com:389)",
        required=True)
    parser.add_argument("-b", "--base", default="", help="LDAP base for query")
    parser.add_argument("-o",
                        "--outfile",
                        default="",
                        help="Store the results in a file")

    ntlm = parser.add_argument_group("NTLM authentication")
    ntlm.add_argument("-u", "--username", help="The username")
    ntlm.add_argument("-p",
                      "--password",
                      help="The password or the corresponding NTLM hash")

    kerberos = parser.add_argument_group("Kerberos authentication")
    kerberos.add_argument(
        "-k",
        "--kerberos",
        action="store_true",
        help=
        "For Kerberos authentication, ticket file should be pointed by $KRB5NAME env variable"
    )

    anonymous = parser.add_argument_group("Anonymous authentication")
    anonymous.add_argument("-a",
                           "--anonymous",
                           action="store_true",
                           help="Perform anonymous binds")

    Ldeep.add_subparsers(parser, ["list_", "get_", "misc_", "action_"],
                         title="commands",
                         description="available commands")
    args = parser.parse_args()

    # Authentication
    method = "NTLM"
    if args.kerberos:
        method = "Kerberos"
    elif args.username:
        method = "NTLM"
    elif args.anonymous:
        method = "anonymous"
    else:
        error(
            "Lack of authentication options: either Kerberos or Username with Password (can be a NTLM hash)."
        )

    # Output
    if args.outfile:
        sys.stdout = Logger(args.outfile, quiet=False)

    # main
    try:
        ldap_connection = ActiveDirectoryView(args.ldapserver, args.fqdn,
                                              args.base, args.username,
                                              args.password, method)
    except ActiveDirectoryView.ActiveDirectoryLdapException as e:
        error(e)

    ldeep = Ldeep(ldap_connection)
    ldeep.dispatch_command(args)