root@thehacksparrow:~/writeups$ SYSTEM ONLINE
root@sparrow:~/writeups$ cat cereal.md
// writeups

Cereal

21 Nov 2020 · 21 min read · root access
Cereal - maquina de Hack The Box

Executive summary — Cereal is an end-to-end .NET exploitation chain: a forgotten .git repository in production leaks the full source code, and the version history itself still holds a secret that a later commit ("Security fixes") tried to scrub. That secret makes it possible to forge valid JWTs, because the backend only validates the signature, never the issuer or the user's role. Once inside the API, an insecure JSON.NET deserialization is guarded by a string blacklist and a localhost-only restriction — both get bypassed by combining a custom application gadget (outside the blacklist) with an XSS in the Markdown library that an admin bot executes from inside the box itself. The result is a webshell dropped into the webroot and, from there, a classic jump to SYSTEM via SeImpersonatePrivilege and GodPotato.

PlatformHack The Box
Operating systemWindows (IIS 10.0)
DifficultyHard
StatusRetired
Target IP10.129.75.23
Vhostscereal.htb (React SPA), source.cereal.htb (ASP.NET Core / source code)

Attack map

[443] source.cereal.htb — publicly exposed .git repository
   │  git-dumper -> full source code (ASP.NET Core + React)
   ▼
[GIT] commit history (the "Security fixes" commit redacted the key in HEAD)
   │  git grep across EVERY revision -> JWT signing secret in plaintext
   ▼
[JWT] Startup.cs only validates the SIGNATURE (no issuer/audience/role)
   │  forge a valid JWT for any "authenticated" user
   ▼
[443] POST /requests — JSON.NET TypeNameHandling.Auto + string blacklist
   │  CUSTOM gadget DownloadHelper (not covered by the blacklist)
   │  + XSS in react-marked-markdown (CVE-2020-26301) in another request
   ▼
[ADMIN BOT] browses /admin from localhost -> executes the XSS
   │  triggers GET /requests/{id} (passes RestrictIP: it IS localhost)
   │  deserializes -> DownloadHelper.Download() -> WebClient.DownloadFile()
   ▼
[RCE]  ASPX webshell written into C:\inetpub\source\uploads\
   ▼
[sonny]  (user.txt) — SeImpersonatePrivilege enabled
   ▼
[ROOT]  GodPotato (DCOM/RPC token coercion) -> SYSTEM

1. Reconnaissance

Transparency note: the source documents that the machine was reset mid-exercise, moving from 10.129.75.16 to 10.129.75.23. This write-up uses the final IP and that instance's flags; the attack chain is identical, only the numeric request ids change.

sudo nmap -p- --min-rate 5000 -T4 -Pn -n 10.129.75.23
sudo nmap -sCV -p22,80,443 -Pn -n 10.129.75.23
22/tcp  open  ssh      OpenSSH for_Windows_7.7 (protocol 2.0)
80/tcp  open  http     Microsoft IIS httpd 10.0   -> redirect to https
443/tcp open  ssl/http Microsoft IIS httpd 10.0
| ssl-cert: Subject: commonName=cereal.htb
| Subject Alternative Name: DNS:cereal.htb, DNS:source.cereal.htb

The TLS certificate's SAN field reveals two vhosts, so both are added to /etc/hosts:

echo "10.129.75.23 cereal.htb source.cereal.htb" | sudo tee -a /etc/hosts
  • https://cereal.htb/ → a React SPA ("Cereal"). Its JS reveals the API: POST /users/authenticate, GET/POST /requests, and an /admin route.
  • https://source.cereal.htb/ → ASP.NET (X-Powered-By: Sugar, X-AspNet-Version: 4.0.30319) serving a Compilation Error — a hint that this vhost exposes more than just the compiled app.
🔒 Clearance required

Root Access unlocks the content you can't see — everything else on the site is already open.

See Root Access plans

No account? Create one free then upgrade from your console.