DarkZeroReturns
01Why the full writeup is held back
DarkZeroReturns is a live Season 11 machine, so in line with Hack The Box's guidance on active machines I am not publishing a step-by-step reproduction, commands or payloads. (HTB flags are per-user and dynamic, so there is nothing to redact there — the method is simply held back while the box is live.) The full chain goes up here once the season closes.
02The interesting bits (no spoilers)
An SSTI that fought back
The injection point was obvious, but the exploit was not. The classic Handlebars prototype-walk gadgets were dead: prototype-access control was enabled and the old CVE was patched. Getting there meant a long, documented dead-end investigation before a newer bug emerged: an AST type-confusion in Handlebars (CVE-2026-33940), where handing the compiler an object shaped like an already-parsed template skips the string parser and smuggles code into the generated function. The realistic lesson is that patched hardening does not mean immune.
A Linux box that was really an AD box
The entry host was domain-joined through SSSD, so standard name-service lookups resolved real Active Directory accounts with no credentials at all. A Linux server joined to a domain is part of the AD attack surface, and enumerating it that way mapped out the internal network and the domain controller.
Two domains by design
The environment ran two separate domains and two domain controllers. A credential and a hash that failed against the first only made sense once it was clear a second, differently-named domain existed behind the first host's gateway. Reading the environment, rather than forcing a hash where it "should" work, was the whole game.
Kerberos as a privilege boundary
The final local root did not need a Unix password. Domain-admin rights were used to create a Kerberos principal that the host was pre-configured to trust as local root, then that ticket was exchanged for a root shell. When a host trusts a realm, AD identity is local identity — a powerful reminder for anyone hardening domain-joined Linux.
03Takeaways
- A patch narrows a technique, it doesn't always remove it. A hardened classic SSTI path still fell to a newer template-engine bug.
- Domain-joined Linux is AD attack surface. SSSD/NSS, Kerberos and keytabs all matter; unauthenticated account enumeration should be monitored.
- Segment trust between domains and hosts. Domain Admin on one domain should not chain to local root on a host and a flag on a different domain.
- Watch AD writes. Anomalous LDAP writes (new principals and OUs, password sets), Kerberos principal creation, and CI-runner abuse are all detectable, and are exactly what this chain relied on.
04If this were your environment
The part that matters for my day job: every link in this chain is a separate, fixable control failure. Treating it like a real engagement, here is how I would remediate it.
- Fix the RCE at the root. Patch the template engine, and never compile user-controlled input as a template — render it as data. Enforce the field type at the boundary and run the render path sandboxed, with no access to process internals.
- Remove the Kerberos-to-root mapping. No arbitrary domain principal should map to local root. Restrict who can create accounts and write principal/password/UAC attributes in AD, and pin any Kerberos-to-local mapping to an explicit named list.
- Tier the identities. Eliminate password reuse across app, OS and domain, and keep Domain Admin accounts off low-tier, internet-facing hosts (Tier 0 model, Protected Users, authentication policy silos).
- Harden the domain-joined Linux host. Restrict the SSSD login policy to an explicit allow-list and disable unauthenticated directory enumeration, so a web host can't resolve the whole directory.
- Contain the pivot. Segment the two domains and deploy LAPS so a reused local Administrator password can't chain across hosts. Protect the CI pipeline so a workflow change can't run as a privileged service account.
- Detections: anomalous LDAP writes, Kerberos-to-root events, a Domain Admin authenticating from a low-tier host, and out-of-band commands injected into the CI runner.
Closure isn't the single Handlebars patch — it's re-running the whole chain and confirming it fails at several independent points.