Credentialed Enumeration - from Linux
Now that we have acquired a foothold in the domain, it is time to dig deeper using our low privilege domain user credentials. Since we have a general idea about the domain's userbase and machines, it's time to enumerate the domain in depth. We are interested in information about domain user and computer attributes, group membership, Group Policy Objects, permissions, ACLs, trusts, and more. We have various options available, but the most important thing to remember is that most of these tools will not work without valid domain user credentials at any permission level. So at a minimum, we will have to have acquired a user's cleartext password, NTLM password hash, or SYSTEM access on a domain-joined host.
To follow along, spawn the target at the bottom of this section and SSH to the Linux attack host as the htb-student
user. For enumeration of the INLANEFREIGHT.LOCAL domain using the tools installed on the ATTACK01 Parrot Linux host, we will use the following credentials: User=forend
and password=Klmcargo2
. Once our access is established, it's time to get to work. We'll start with CrackMapExec
.
CrackMapExec
CrackMapExec (CME) is a powerful toolset to help with assessing AD environments. It utilizes packages from the Impacket and PowerSploit toolkits to perform its functions. For detailed explanations on using the tool and accompanying modules, see the wiki. Don't be afraid to use the -h
flag to review the available options and syntax.
CME Help Menu
Credentialed Enumeration - from Linux
We can see that we can use the tool with MSSQL, SMB, SSH, and WinRM credentials. Let's look at our options for CME with the SMB protocol:
CME Options (SMB)
Credentialed Enumeration - from Linux
CME offers a help menu for each protocol (i.e., crackmapexec winrm -h
, etc.). Be sure to review the entire help menu and all possible options. For now, the flags we are interested in are:
-u Username
The user whose credentials we will use to authenticate
-p Password
User's password
Target (IP or FQDN)
Target host to enumerate
(in our case, the Domain Controller)--users
Specifies to enumerate Domain Users
--groups
Specifies to enumerate domain groups
--loggedon-users
Attempts to enumerate what users are logged on to a target, if any
We'll start by using the SMB protocol to enumerate users and groups. We will target the Domain Controller (whose address we uncovered earlier) because it holds all data in the domain database that we are interested in. Make sure you preface all commands with sudo
.
CME - Domain User Enumeration
We start by pointing CME at the Domain Controller and using the credentials for the forend
user to retrieve a list of all domain users. Notice when it provides us the user information, it includes data points such as the badPwdCount attribute. This is helpful when performing actions like targeted password spraying. We could build a target user list filtering out any users with their badPwdCount
attribute above 0 to be extra careful not to lock any accounts out.
Credentialed Enumeration - from Linux
We can also obtain a complete listing of domain groups. We should save all of our output to files to easily access it again later for reporting or use with other tools.
CME - Domain Group Enumeration
Credentialed Enumeration - from Linux
The above snippet lists the groups within the domain and the number of users in each. The output also shows the built-in groups on the Domain Controller, such as Backup Operators
. We can begin to note down groups of interest. Take note of key groups like Administrators
, Domain Admins
, Executives
, any groups that may contain privileged IT admins, etc. These groups will likely contain users with elevated privileges worth targeting during our assessment.
CME - Logged On Users
We can also use CME to target other hosts. Let's check out what appears to be a file server to see what users are logged in currently.
Credentialed Enumeration - from Linux
We see that many users are logged into this server which is very interesting. We can also see that our user forend
is a local admin because (Pwn3d!)
appears after the tool successfully authenticates to the target host. A host like this may be used as a jump host or similar by administrative users. We can see that the user svc_qualys
is logged in, who we earlier identified as a domain admin. It could be an easy win if we can steal this user's credentials from memory or impersonate them.
As we will see later, BloodHound
(and other tools such as PowerView
) can be used to hunt for user sessions. BloodHound is particularly powerful as we can use it to view Domain User sessions graphically and quickly in many ways. Regardless, tools such as CME are great for more targeted enumeration and user hunting.
CME Share Searching
We can use the --shares
flag to enumerate available shares on the remote host and the level of access our user account has to each share (READ or WRITE access). Let's run this against the INLANEFREIGHT.LOCAL Domain Controller.
Share Enumeration - Domain Controller
Credentialed Enumeration - from Linux
We see several shares available to us with READ
access. The Department Shares
, User Shares
, and ZZZ_archive
shares would be worth digging into further as they may contain sensitive data such as passwords or PII. Next, we can dig into the shares and spider each directory looking for files. The module spider_plus
will dig through each readable share on the host and list all readable files. Let's give it a try.
Spider_plus
Credentialed Enumeration - from Linux
In the above command, we ran the spider against the Department Shares
. When completed, CME writes the results to a JSON file located at /tmp/cme_spider_plus/<ip of host>
. Below we can see a portion of the JSON output. We could dig around for interesting files such as web.config
files or scripts that may contain passwords. If we wanted to dig further, we could pull those files to see what all resides within, perhaps finding some hardcoded credentials or other sensitive information.
Credentialed Enumeration - from Linux
CME is powerful, and this is only a tiny look at its capabilities; it is worth experimenting with it more against the lab targets. We will utilize CME in various ways as we progress through the remainder of this module. Let's move on and take a look at SMBMap now.
SMBMap
SMBMap is great for enumerating SMB shares from a Linux attack host. It can be used to gather a listing of shares, permissions, and share contents if accessible. Once access is obtained, it can be used to download and upload files and execute remote commands.
Like CME, we can use SMBMap and a set of domain user credentials to check for accessible shares on remote systems. As with other tools, we can type the command smbmap
-h
to view the tool usage menu. Aside from listing shares, we can use SMBMap to recursively list directories, list the contents of a directory, search file contents, and more. This can be especially useful when pillaging shares for useful information.
SMBMap To Check Access
Credentialed Enumeration - from Linux
The above will tell us what our user can access and their permission levels. Like our results from CME, we see that the user forend
has no access to the DC via the ADMIN$
or C$
shares (this is expected for a standard user account), but does have read access over IPC$
, NETLOGON
, and SYSVOL
which is the default in any domain. The other non-standard shares, such as Department Shares
and the user and archive shares, are most interesting. Let's do a recursive listing of the directories in the Department Shares
share. We can see, as expected, subdirectories for each department in the company.
Recursive List Of All Directories
Credentialed Enumeration - from Linux
As the recursive listing dives deeper, it will show you the output of all subdirectories within the higher-level directories. The use of --dir-only
provided only the output of all directories and did not list all files. Try this against other shares on the Domain Controller and see what you can find.
Now that we've covered shares, let's look at RPCClient
.
rpcclient
rpcclient is a handy tool created for use with the Samba protocol and to provide extra functionality via MS-RPC. It can enumerate, add, change, and even remove objects from AD. It is highly versatile; we just have to find the correct command to issue for what we want to accomplish. The man page for rpcclient is very helpful for this; just type man rpcclient
into your attack host's shell and review the options available. Let's cover a few rpcclient functions that can be helpful during a penetration test.
Due to SMB NULL sessions (covered in-depth in the password spraying sections) on some of our hosts, we can perform authenticated or unauthenticated enumeration using rpcclient in the INLANEFREIGHT.LOCAL domain. An example of using rpcclient from an unauthenticated standpoint (if this configuration exists in our target domain) would be:
Code: bash
The above will provide us with a bound connection, and we should be greeted with a new prompt to start unleashing the power of rpcclient.
SMB NULL Session with rpcclient
From here, we can begin to enumerate any number of different things. Let's start with domain users.
rpcclient Enumeration
While looking at users in rpcclient, you may notice a field called rid:
beside each user. A Relative Identifier (RID) is a unique identifier (represented in hexadecimal format) utilized by Windows to track and identify objects. To explain how this fits in, let's look at the examples below:
The SID for the INLANEFREIGHT.LOCAL domain is:
S-1-5-21-3842939050-3880317879-2865463114
.When an object is created within a domain, the number above (SID) will be combined with a RID to make a unique value used to represent the object.
So the domain user
htb-student
with a RID:[0x457] Hex 0x457 would = decimal1111
, will have a full user SID of:S-1-5-21-3842939050-3880317879-2865463114-1111
.This is unique to the
htb-student
object in the INLANEFREIGHT.LOCAL domain and you will never see this paired value tied to another object in this domain or any other.
However, there are accounts that you will notice that have the same RID regardless of what host you are on. Accounts like the built-in Administrator for a domain will have a RID [administrator] rid:[0x1f4], which, when converted to a decimal value, equals 500
. The built-in Administrator account will always have the RID value Hex 0x1f4
, or 500. This will always be the case. Since this value is unique to an object, we can use it to enumerate further information about it from the domain. Let's give it a try again with rpcclient. We will dig a bit targeting the htb-student
user.
RPCClient User Enumeration By RID
Credentialed Enumeration - from Linux
When we searched for information using the queryuser
command against the RID 0x457
, RPC returned the user information for htb-student
as expected. This wasn't hard since we already knew the RID for htb-student
. If we wished to enumerate all users to gather the RIDs for more than just one, we would use the enumdomusers
command.
Enumdomusers
Credentialed Enumeration - from Linux
Using it in this manner will print out all domain users by name and RID. Our enumeration can go into great detail utilizing rpcclient. We could even start performing actions such as editing users and groups or adding our own into the domain, but this is out of scope for this module. For now, we just want to perform domain enumeration to validate our findings. Take some time to play with the other rpcclient functions and see the results they produce. For more information on topics such as SIDs, RIDs, and other core components of AD, it would be worthwhile to check out the Introduction to Active Directory module. Now, it's time to plunge into Impacket in all its glory.
Impacket Toolkit
Impacket is a versatile toolkit that provides us with many different ways to enumerate, interact, and exploit Windows protocols and find the information we need using Python. The tool is actively maintained and has many contributors, especially when new attack techniques arise. We could perform many other actions with Impacket, but we will only highlight a few in this section; wmiexec.py and psexec.py. Earlier in the poisoning section, we grabbed a hash for the user wley
with Responder
and cracked it to obtain the password transporter@4
. We will see in the next section that this user is a local admin on the ACADEMY-EA-FILE
host. We will utilize the credentials for the next few actions.
Psexec.py
One of the most useful tools in the Impacket suite is psexec.py
. Psexec.py is a clone of the Sysinternals psexec executable, but works slightly differently from the original. The tool creates a remote service by uploading a randomly-named executable to the ADMIN$
share on the target host. It then registers the service via RPC
and the Windows Service Control Manager
. Once established, communication happens over a named pipe, providing an interactive remote shell as SYSTEM
on the victim host.
Using psexec.py
To connect to a host with psexec.py, we need credentials for a user with local administrator privileges.
Code: bash
Once we execute the psexec module, it drops us into the system32
directory on the target host. We ran the whoami
command to verify, and it confirmed that we landed on the host as SYSTEM
. From here, we can perform most any task on this host; anything from further enumeration to persistence and lateral movement. Let's give another Impacket module a try: wmiexec.py
.
wmiexec.py
Wmiexec.py utilizes a semi-interactive shell where commands are executed through Windows Management Instrumentation. It does not drop any files or executables on the target host and generates fewer logs than other modules. After connecting, it runs as the local admin user we connected with (this can be less obvious to someone hunting for an intrusion than seeing SYSTEM executing many commands). This is a more stealthy approach to execution on hosts than other tools, but would still likely be caught by most modern anti-virus and EDR systems. We will use the same account as with psexec.py to access the host.
Using wmiexec.py
Code: bash
Note that this shell environment is not fully interactive, so each command issued will execute a new cmd.exe from WMI and execute your command. The downside of this is that if a vigilant defender checks event logs and looks at event ID 4688: A new process has been created, they will see a new process created to spawn cmd.exe and issue a command. This isn't always malicious activity since many organizations utilize WMI to administer computers, but it can be a tip-off in an investigation. In the image above, it's also apparent that the process is running under the context of user wley
on the host, not as SYSTEM. Impacket is an immensely valuable tool that has plenty of use cases. We will see many other tools in the Impacket toolkit throughout the remainder of this module. As a pentester working with Windows hosts, this tool should always be in our arsenal. Let's move on to the next tool, Windapsearch
.
Windapsearch
Windapsearch is another handy Python script we can use to enumerate users, groups, and computers from a Windows domain by utilizing LDAP queries. It is present in our attack host's /opt/windapsearch/ directory.
Windapsearch Help
Credentialed Enumeration - from Linux
We have several options with Windapsearch to perform standard enumeration (dumping users, computers, and groups) and more detailed enumeration. The --da
(enumerate domain admins group members ) option and the -PU
( find privileged users) options. The -PU
option is interesting because it will perform a recursive search for users with nested group membership.
Windapsearch - Domain Admins
Credentialed Enumeration - from Linux
From the results in the shell above, we can see that it enumerated 28 users from the Domain Admins group. Take note of a few users we have already seen before and may even have a hash or cleartext password like wley
, svc_qualys
, and lab_adm
.
To identify more potential users, we can run the tool with the -PU
flag and check for users with elevated privileges that may have gone unnoticed. This is a great check for reporting since it will most likely inform the customer of users with excess privileges from nested group membership.
Windapsearch - Privileged Users
Credentialed Enumeration - from Linux
You'll notice that it performed mutations against common elevated group names in different languages. This output gives an example of the dangers of nested group membership, and this will become more evident when we work with BloodHound graphics to visualize this.
Bloodhound.py
Once we have domain credentials, we can run the BloodHound.py BloodHound ingestor from our Linux attack host. BloodHound is one of, if not the most impactful tools ever released for auditing Active Directory security, and it is hugely beneficial for us as penetration testers. We can take large amounts of data that would be time-consuming to sift through and create graphical representations or "attack paths" of where access with a particular user may lead. We will often find nuanced flaws in an AD environment that would have been missed without the ability to run queries with the BloodHound GUI tool and visualize issues. The tool uses graph theory to visually represent relationships and uncover attack paths that would have been difficult, or even impossible to detect with other tools. The tool consists of two parts: the SharpHound collector written in C# for use on Windows systems, or for this section, the BloodHound.py collector (also referred to as an ingestor
) and the BloodHound GUI tool which allows us to upload collected data in the form of JSON files. Once uploaded, we can run various pre-built queries or write custom queries using Cypher language. The tool collects data from AD such as users, groups, computers, group membership, GPOs, ACLs, domain trusts, local admin access, user sessions, computer and user properties, RDP access, WinRM access, etc.
It was initially only released with a PowerShell collector, so it had to be run from a Windows host. Eventually, a Python port (which requires Impacket, ldap3
, and dnspython
) was released by a community member. This helped immensely during penetration tests when we have valid domain credentials, but do not have rights to access a domain-joined Windows host or do not have a Windows attack host to run the SharpHound collector from. This also helps us not have to run the collector from a domain host, which could potentially be blocked or set off alerts (though even running it from our attack host will most likely set off alarms in well-protected environments).
Running bloodhound-python -h
from our Linux attack host will show us the options available.
BloodHound.py Options
Credentialed Enumeration - from Linux
As we can see the tool accepts various collection methods with the -c
or --collectionmethod
flag. We can retrieve specific data such as user sessions, users and groups, object properties, ACLS, or select all
to gather as much data as possible. Let's run it this way.
Executing BloodHound.py
Credentialed Enumeration - from Linux
The command above executed Bloodhound.py with the user forend
. We specified our nameserver as the Domain Controller with the -ns
flag and the domain, INLANEFREIGHt.LOCAL with the -d
flag. The -c all
flag told the tool to run all checks. Once the script finishes, we will see the output files in the current working directory in the format of <date_object.json>.
Viewing the Results
Credentialed Enumeration - from Linux
Upload the Zip File into the BloodHound GUI
We could then type sudo neo4j start
to start the neo4j service, firing up the database we'll load the data into and also run Cypher queries against.
Next, we can type bloodhound
from our Linux attack host when logged in using freerdp
to start the BloodHound GUI application and upload the data. The credentials are pre-populated on the Linux attack host, but if for some reason a credential prompt is shown, use:
user == neo4j
/pass == HTB_@cademy_stdnt!
.
Once all of the above is done, we should have the BloodHound GUI tool loaded with a blank slate. Now we need to upload the data. We can either upload each JSON file one by one or zip them first with a command such as zip -r ilfreight_bh.zip *.json
and upload the Zip file. We do this by clicking the Upload Data
button on the right side of the window (green arrow). When the file browser window pops up to select a file, choose the zip file (or each JSON file) (red arrow) and hit Open
.
Uploading the Zip File
Now that the data is loaded, we can use the Analysis tab to run queries against the database. These queries can be custom and specific to what you decide using custom Cypher queries. There are many great cheat sheets to help us here. We will discuss custom Cypher queries more in a later section. As seen below, we can use the built-in Path Finding
queries on the Analysis tab
on the Left
side of the window.
Searching for Relationships
The query chosen to produce the map above was Find Shortest Paths To Domain Admins
. It will give us any logical paths it finds through users/groups/hosts/ACLs/GPOs, etc., relationships that will likely allow us to escalate to Domain Administrator privileges or equivalent. This will be extremely helpful when planning our next steps for lateral movement through the network. Take some time to experiment with the various features: look at the Database Info
tab after uploading data, search for a node such as Domain Users
and, scroll through all of the options under the Node Info
tab, check out the pre-built queries under the Analysis
tab, many which are powerful and can quickly find various ways to domain takeover. Finally, experiment with some custom Cypher queries by selecting some interesting ones from the Cypher cheatsheet linked above, pasting them into the Raw Query
box at the bottom, and hitting enter. You can also play with the Settings
menu by clicking the gear icon on the right side of the screen and adjusting how nodes and edges are displayed, enable query debug mode, and enable dark mode. Throughout the remainder of this module, we will use BloodHound in various ways, but for a dedicated study on the BloodHound tool, check out the Active Directory BloodHound module.
In the next section, we will cover running the SharpHound collector from a domain-joined Windows host and work through some examples of working with the data in the BloodHound GUI.
We experimented with several new tools for domain enumeration from a Linux host. The following section will cover several more tools we can use from a domain-joined Windows host. As a quick note, if you haven't checked out the WADComs project yet, you definitely should. It is an interactive cheat sheet for many of the tools we will cover (and more) in this module. It's hugely helpful when you can't remember exact command syntax or are trying out a tool for the first time. Worth bookmarking and even contributing to!
Last updated