{"id":13537989,"url":"https://github.com/ropnop/windapsearch","last_synced_at":"2025-04-13T00:48:41.109Z","repository":{"id":43552312,"uuid":"65418458","full_name":"ropnop/windapsearch","owner":"ropnop","description":"Python script to enumerate users, groups and computers from a Windows domain through LDAP queries","archived":false,"fork":false,"pushed_at":"2022-04-20T07:40:42.000Z","size":48,"stargazers_count":859,"open_issues_count":17,"forks_count":152,"subscribers_count":22,"default_branch":"master","last_synced_at":"2025-04-13T00:48:37.566Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ropnop.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-08-10T21:43:30.000Z","updated_at":"2025-04-12T06:39:49.000Z","dependencies_parsed_at":"2022-09-01T05:40:29.706Z","dependency_job_id":null,"html_url":"https://github.com/ropnop/windapsearch","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ropnop%2Fwindapsearch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ropnop%2Fwindapsearch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ropnop%2Fwindapsearch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ropnop%2Fwindapsearch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ropnop","download_url":"https://codeload.github.com/ropnop/windapsearch/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248650436,"owners_count":21139672,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T09:01:05.566Z","updated_at":"2025-04-13T00:48:41.089Z","avatar_url":"https://github.com/ropnop.png","language":"Python","funding_links":[],"categories":["\u003ca id=\"9eee96404f868f372a6cbc6769ccb7f8\"\u003e\u003c/a\u003e新添加的","LDAP + Pentesting","Python (1887)","Python","\u003ca id=\"3ed50213c2818f1455eff4e30372c542\"\u003e\u003c/a\u003e工具","Operating Systems"],"sub_categories":["\u003ca id=\"31185b925d5152c7469b963809ceb22d\"\u003e\u003c/a\u003e新添加的","Kubernetes","\u003ca id=\"caab36bba7fa8bb931a9133e37d397f6\"\u003e\u003c/a\u003eWindows","Windows"],"readme":"Check out the new and improved `windapsearch` - rewritten in Go with some new features (including JSON support)!\n\nhttps://github.com/ropnop/go-windapsearch\n\n# windapsearch\n`windapsearch` is a Python script to help enumerate users, groups and computers from a Windows domain through LDAP queries. \nBy default, Windows Domain Controllers support basic LDAP operations through port 389/tcp. With any valid domain account (regardless of privileges), it is possible to perform LDAP queries against a domain controller for any AD related information.\n\nYou can always use a tool like `ldapsearch` to perform custom LDAP queries against a Domain Controller. I found myself running different LDAP commands over and over again, and it was difficult to memorize all the custom LDAP queries. So this tool was born to help automate some of the most useful LDAP queries a pentester would want to perform in an AD environment.\n\n### Requirements\n`windapsearch` requires the `python-ldap` module. You should be able to get up and running with two commands:\n\n```\n$ git clone https://github.com/ropnop/windapsearch.git\n$ pip install python-ldap #or apt-get install python-ldap\n$ ./windapsearch.py\n```\nThe latest version is designed to be used with Python 3, but if you are stuck with Python 2, you can use the `windapsearch_py2.py` script.\n\n## Usage\n```\n$ python windapsearch.py -h\nusage: windapsearch.py [-h] [-d DOMAIN] [--dc-ip DC_IP] [-u USER]\n                       [-p PASSWORD] [--functionality] [-G] [-U] [-C]\n                       [-m GROUP_NAME] [--da] [--admin-objects] [--user-spns]\n                       [--unconstrained-users] [--unconstrained-computers]\n                       [--gpos] [-s SEARCH_TERM] [-l DN]\n                       [--custom CUSTOM_FILTER] [-r] [--attrs ATTRS] [--full]\n                       [-o output_dir]\n\nScript to perform Windows domain enumeration through LDAP queries to a Domain\nController\n\noptional arguments:\n  -h, --help            show this help message and exit\n\nDomain Options:\n  -d DOMAIN, --domain DOMAIN\n                        The FQDN of the domain (e.g. 'lab.example.com'). Only\n                        needed if DC-IP not provided\n  --dc-ip DC_IP         The IP address of a domain controller\n\nBind Options:\n  Specify bind account. If not specified, anonymous bind will be attempted\n\n  -u USER, --user USER  The full username with domain to bind with (e.g.\n                        'ropnop@lab.example.com' or 'LAB\\ropnop'\n  -p PASSWORD, --password PASSWORD\n                        Password to use. If not specified, will be prompted\n                        for\n\nEnumeration Options:\n  Data to enumerate from LDAP\n\n  --functionality       Enumerate Domain Functionality level. Possible through\n                        anonymous bind\n  -G, --groups          Enumerate all AD Groups\n  -U, --users           Enumerate all AD Users\n  -PU, --privileged-users\n                        Enumerate All privileged AD Users. Performs recursive\n                        lookups for nested members.\n  -C, --computers       Enumerate all AD Computers\n  -m GROUP_NAME, --members GROUP_NAME\n                        Enumerate all members of a group\n  --da                  Shortcut for enumerate all members of group 'Domain\n                        Admins'. Performs recursive lookups for nested\n                        members.\n  --admin-objects       Enumerate all objects with protected ACLs (i.e.\n                        admins)\n  --user-spns           Enumerate all users objects with Service Principal\n                        Names (for kerberoasting)\n  --unconstrained-users\n                        Enumerate all user objects with unconstrained\n                        delegation\n  --unconstrained-computers\n                        Enumerate all computer objects with unconstrained\n                        delegation\n  --gpos                Enumerate Group Policy Objects\n  -s SEARCH_TERM, --search SEARCH_TERM\n                        Fuzzy search for all matching LDAP entries\n  -l DN, --lookup DN    Search through LDAP and lookup entry. Works with fuzzy\n                        search. Defaults to printing all attributes, but\n                        honors '--attrs'\n  --custom CUSTOM_FILTER\n                        Perform a search with a custom object filter. Must be\n                        valid LDAP filter syntax\n\nOutput Options:\n  Display and output options for results\n\n  -r, --resolve         Resolve IP addresses for enumerated computer names.\n                        Will make DNS queries against system NS\n  --attrs ATTRS         Comma separated custom atrribute names to search for\n                        (e.g. 'badPwdCount,lastLogon')\n  --full                Dump all atrributes from LDAP.\n  -o output_dir, --output output_dir\n                        Save results to TSV files in \u003cOUTPUT_DIR\u003e\n\n```\n### Specifying Domain and Account\nTo begin you need to specify a Domain Controller to connect to with `--dc-ip`, or a domain with `-d`.\nIf no Domain Controller IP address is specified, the script will attempt to do a DNS `host` lookup on the domain and take the top result.\n\nA valid domain username and password are required for most lookups. If none are specififed the script will attempt an anonymous bind and enumerate the default namingContext, but most additional queries will fail.\nThe username needs to include the full domain, e.g. `ropnop@lap.example.com` or `EXAMPLE\\ropnop`\n\nThe password can be specified on the command line with `-p` or if left out it will be prompted for.\n\n### Enumerate Users\nThe `-U` option performs an LDAP search for all entries where `objectCategory=user`. By default, it will only display the commonName and the userPrincipalName.\nThe `--attrs` option can be used to specify custom or additional attributes to display, or the `--full` option will display everythin for all users.\n\nWARNING: in a large domain this can get very big, very fast\n\nExample:\n```\n$  ./windapsearch.py -d lab.ropnop.com -u ropnop\\\\ldapbind -p GoCubs16 -U\n[+] No DC IP provided. Will try to discover via DNS lookup.\n[+] Using Domain Controller at: 172.16.13.10\n[+] Getting defaultNamingContext from Root DSE\n[+]     Found: DC=lab,DC=ropnop,DC=com\n[+] Attempting bind\n[+]     ...success! Binded as:\n[+]      u:ROPNOP\\ldapbind\n\n[+] Enumerating all AD users\n[+]     Found 2754 users:\n\ncn: Administrator\n\ncn: Guest\n\ncn: krbtgt\n\ncn: Andy Green\nuserPrincipalName: agreen@lab.ropnop.com\n\n\u003csnipped...\u003e\n```\nTo save the results to a tab-separated file, use the `-o` option and specify a directory.\n\n### Enumerate Groups and Group Memberships\nUse the `-G` option to enumerate all entries where `objectCategory=group`. This will output the DN and CN of all groups.\n\nTo query group membership, use the `-m` option with either the DN or CN of the group you wish to query. The tool supports fuzzy search matching so even a partial CN will work. If it matches more than one group, the tool will specify which group to query.\n\nExample:\n```\n$ ./windapsearch.py -d lab.ropnop.com -u ropnop\\\\ldapbind -p GoCubs16 -m IT               \n[+] No DC IP provided. Will try to discover via DNS lookup.                                                       \n[+] Using Domain Controller at: 172.16.13.10                                                                      \n[+] Getting defaultNamingContext from Root DSE                                                                    \n[+]     Found: DC=lab,DC=ropnop,DC=com                                                                            \n[+] Attempting bind                                                                                               \n[+]     ...success! Binded as:                                                                                    \n[+]      u:ROPNOP\\ldapbind                                                                                        \n[+] Attempting to enumerate full DN for group: IT                                                                 \n[+] Found 2 results:                                                                                              \n                                                                                                                  \n0: CN=IT Admins,OU=Groups,OU=Lab,DC=lab,DC=ropnop,DC=com                                                          \n1: CN=Ismael Titus,OU=US,OU=Users,OU=Lab,DC=lab,DC=ropnop,DC=com                                                  \n                                                                                                                  \nWhich DN do you want to use? : 0                                                                                  \n[+]      Found 5 members:                                                                                         \n                                                                                                                  \nCN=James Doyle,OU=US,OU=Users,OU=Lab,DC=lab,DC=ropnop,DC=com                                                      \nCN=Edward Sotelo,OU=US,OU=Users,OU=Lab,DC=lab,DC=ropnop,DC=com                                                    \nCN=Cheryl Perry,OU=US,OU=Users,OU=Lab,DC=lab,DC=ropnop,DC=com                                                     \nCN=Anthony Gordon,OU=US,OU=Users,OU=Lab,DC=lab,DC=ropnop,DC=com                                                   \nCN=Desktop Support,OU=Groups,OU=Lab,DC=lab,DC=ropnop,DC=com                                                       \n                                                                                                                  \n[*] Bye!                                                                                                          \n```\n\n#### Domain Admins\nYou can enumerate Domain Admins through two methods. One is to use `-m` with \"Domain Admins\". This will query LDAP for the \"Domain Admins\" entry and display all the members.\n\nThe more thorough way is to do a lookup of all users and determine if they or a group they belong to are part of \"Domain Admins\". This has the added benefit of discovering users who have inherited DA rights through nested group memberships. It's much slower, however.\nSee this link for more details on the technique used: https://labs.mwrinfosecurity.com/blog/active-directory-users-in-nested-groups-reconnaissance/\nTo do a recursive lookup for Domain Admins, you can use the \"--da\" option.\n\nExample:\n```\nroot@kali:~/windapsearch# ./windapsearch.py -d lab.ropnop.com -u ropnop\\\\ldapbind -p GoCubs16 --da\n[+] No DC IP provided. Will try to discover via DNS lookup.\n[+] Using Domain Controller at: 172.16.13.10\n[+] Getting defaultNamingContext from Root DSE\n[+]     Found: DC=lab,DC=ropnop,DC=com\n[+] Attempting bind\n[+]     ...success! Binded as:\n[+]      u:ROPNOP\\ldapbind\n[+] Attempting to enumerate all Domain Admins\n[+] Using DN: CN=Domain Admins,CN=Users.CN=Domain Admins,CN=Users,DC=lab,DC=ropnop,DC=com\n[+]     Found 12 Domain Admins:\n\ncn: Administrator\n\ncn: Andy Green\nuserPrincipalName: agreen@lab.ropnop.com\n\ncn: Natasha Strong\nuserPrincipalName: nstrong@lab.ropnop.com\n\ncn: Linda Alton\nuserPrincipalName: lalton@lab.ropnop.com\n\n\u003csnipped...\u003e\n```\n\n### Enumerating Computers\nLDAP queries can be used to enumerate domain joined computers. This is very useful when trying to build a list of targets without running a portscan or ping sweep.\n\nUse the `-C` option to list all matching entries where `objectClass=Computer`. By default, the attributes displayed are 'cn', 'dNSHostName', 'operatingSystem', 'operatingSystemVersion', and 'operatingSystemServicePack'\n\nIf you specify the `-r` or `--resolve` option, the tool will perform a DNS lookup on every enumerated dNSHostName found and output the computer information, including IP address in CSV format. This can then be fed to other tools like nmap or CrackMapExec.\n\nExample:\n```\n$ ./windapsearch.py -d lab.ropnop.com -u ropnop\\\\ldapbind -p GoCubs16 -C -r\n[+] No DC IP provided. Will try to discover via DNS lookup.\n[+] Using Domain Controller at: 172.16.13.10\n[+] Getting defaultNamingContext from Root DSE\n[+]     Found: DC=lab,DC=ropnop,DC=com\n[+] Attempting bind\n[+]     ...success! Binded as:\n[+]      u:ROPNOP\\ldapbind\n\n[+] Enumerating all AD computers\n[+]     Found 4 computers:\n\ncn, IP, dNSHostName, operatingSystem, operatingSystemVersion, operatingSystemServicePack\nWS03WIN10,172.16.13.53,ws03win10.lab.ropnop.com,Windows 10 Enterprise,10.0 (10240),\nWS02WIN7,172.16.13.50,WS02WIN7.lab.ropnop.com,Windows 7 Enterprise,6.1 (7601),Service Pack 1\nWS01WIN7,172.16.13.52,WS01WIN7.lab.ropnop.com,Windows 7 Enterprise,6.1 (7601),Service Pack 1\nDC01,172.16.13.10,dc01.lab.ropnop.com,Windows Server 2012 R2 Standard,6.3 (9600),\n\n[*] Bye!                               \n```\n\n### Custom Searching\nThe tool allows for custom, fuzzy matching. You can perform a search and see results (DNs) with the `-s` option:\n\n```\n$ ./windapsearch.py -d lab.ropnop.com -u ropnop\\\\ldapbind -p GoCubs16 -s albert\n[+] No DC IP provided. Will try to discover via DNS lookup.\n[+] Using Domain Controller at: 172.16.13.10\n[+] Getting defaultNamingContext from Root DSE\n[+]     Found: DC=lab,DC=ropnop,DC=com\n[+] Attempting bind\n[+]     ...success! Binded as:\n[+]      u:ROPNOP\\ldapbind\n[+] Doing fuzzy search for: \"albert\"\n[+]     Found 6 results:\n\nCN=Kathi Albert,OU=US,OU=Users,OU=Lab,DC=lab,DC=ropnop,DC=com\nCN=Albert Woodell,OU=US,OU=Users,OU=Lab,DC=lab,DC=ropnop,DC=com\nCN=Albert Lyons,OU=US,OU=Users,OU=Lab,DC=lab,DC=ropnop,DC=com\nCN=Alberta Henshaw,OU=US,OU=Users,OU=Lab,DC=lab,DC=ropnop,DC=com\nCN=Alberta Taylor,OU=US,OU=Users,OU=Lab,DC=lab,DC=ropnop,DC=com\nCN=Alberto Mitchell,OU=US,OU=Users,OU=Lab,DC=lab,DC=ropnop,DC=com\n\n[*] Bye!\n```\n\nTo query the DN and display the attributes, use the lookup option, `-l`. You can provide this with a full DN, or a search term. If the search matches more than one DN, the tool will prompt you for which to use:\n\n```\n$ ./windapsearch.py -d lab.ropnop.com -u ropnop\\\\ldapbind -p GoCubs16 -l albert --attrs telephoneNumber\n[+] No DC IP provided. Will try to discover via DNS lookup.\n[+] Using Domain Controller at: 172.16.13.10\n[+] Getting defaultNamingContext from Root DSE\n[+]     Found: DC=lab,DC=ropnop,DC=com\n[+] Attempting bind\n[+]     ...success! Binded as:\n[+]      u:ROPNOP\\ldapbind\n[+] Searching for matching DNs for term: \"albert\"\n[+] Found 6 results:\n\n0: CN=Kathi Albert,OU=US,OU=Users,OU=Lab,DC=lab,DC=ropnop,DC=com\n1: CN=Albert Woodell,OU=US,OU=Users,OU=Lab,DC=lab,DC=ropnop,DC=com\n2: CN=Albert Lyons,OU=US,OU=Users,OU=Lab,DC=lab,DC=ropnop,DC=com\n3: CN=Alberta Henshaw,OU=US,OU=Users,OU=Lab,DC=lab,DC=ropnop,DC=com\n4: CN=Alberta Taylor,OU=US,OU=Users,OU=Lab,DC=lab,DC=ropnop,DC=com\n5: CN=Alberto Mitchell,OU=US,OU=Users,OU=Lab,DC=lab,DC=ropnop,DC=com\n\nWhich DN do you want to use? : 2\ntelephoneNumber: 716-825-5021\n\n\n[*] Bye!\n```\n\n### Credits\nHeavily influenced by this post and research done by MWR Labs:\nhttps://labs.mwrinfosecurity.com/blog/active-directory-users-in-nested-groups-reconnaissance/\n\nand their tool to perform offline querying of LDAP:\nhttps://labs.mwrinfosecurity.com/blog/offline-querying-of-active-directory/\n\nalso, after I wrote the majority of this tool I discovered a very similar project here: \nhttps://github.com/CroweCybersecurity/ad-ldap-enum\nDefinitely check that tool out too! I sniped some of the code to get paging working with my tool anyway :)\n\nFor some more LDAP searching goodness, check out this Microsoft article on other AD queries you can perform (hint: use the `--custom` flag)\nhttps://social.technet.microsoft.com/wiki/contents/articles/5392.active-directory-ldap-syntax-filters.aspx\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fropnop%2Fwindapsearch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fropnop%2Fwindapsearch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fropnop%2Fwindapsearch/lists"}