ServiceNow tradecraft, Claude bitten by a snake, and SAML identities in the wrong database.
Detailed write-ups covering a full ServiceNow engagement are still relatively scarce. MDSec shares a lot here: privilege escalation, persistence, credential extraction, access to internal MID servers and the detection gaps encountered along the way. There are scripts, table names and explanations of how the different features fit together.
One example starts with catalog_admin, which allows scripts in catalog access criteria. Those scripts cannot directly grant admin, but they can grant action_designer, which provides system-context scripting. A useful reminder to follow what a role lets you become, as well as what it lets you do.
The persistence details are worth reading too. Business rules recreate deleted backdoor accounts, while administrative sessions retain their privileges after the corresponding role is removed. Both matter when trying to contain a compromise.
I particularly like their approach of recreating a compromised user’s roles in a developer instance to investigate escalation paths. This gives readers a way to approach an unfamiliar platform and build on the research themselves. When it Snows it Pours - Anatomy of a ServiceNow Red Team - MDSec.
This is a clever combination of agent behaviour and an old Python trick. A website returns an error to the fetch tool, prompting Claude to try curl. It retrieves an archive containing encoded records and a binary decoder. Claude refuses to execute the binary and writes its own decoder instead.
Unfortunately, it runs that code inside the extracted directory. Importing base64 indirectly imports struct, and the archive contains an attacker-controlled struct.py. The malicious module executes its payload while preserving the functionality needed to decode the records.
The attacker anticipates the model’s caution: Claude avoids the supplied executable, but its replacement still loads attacker-controlled code.
What I particularly liked is what happens afterwards. In some runs, Claude inspects struct.py, recognises the compromise and tries to terminate the malicious process. Auto Mode then blocks the cleanup command. The agent identifies the problem and attempts to recover, but the control that allowed the compromise prevents that recovery.
This is worth including in agent evaluations: can the agent recognise a compromise, accurately report what ran, and contain it? Detecting the attack is useful, even after execution, provided the agent still has a way to act on that information. Breaking Claude Code Opus 5 Auto Mode.
A nice chain starting with SAML signature wrapping. Cleo verifies the signature over one assertion but reads the identity from another, unsigned assertion. Structural validation exceptions are swallowed, and the application simply consumes the first assertion in the response.
The part I found most interesting comes afterwards. Cleo issues ordinary users refresh tokens marked `UNI_ADMIN`. When processing one of these tokens, it looks up the username in its administrator database, even though the token was issued for a user in a different database. If the names match, it treats the caller as that administrator. The SAML wrapping bug lets the attacker choose an identity that matches an administrator account. Once administrator, command execution is available through a built-in feature.
A classic testing detail worth remembering: keeping the SSO cookie causes the refresh endpoint to return the existing token. Removing it, while retaining the Bearer token, reaches the vulnerable token issuance path. Compromising Cleo Harmony: A SAML Bypass Chain to Arbitrary Code Execution.
Get these curated picks delivered to your inbox every week:
Want to build these skills hands-on?
PentesterLab has 700+ real-world labs on web hacking, code review, and vulnerability analysis. Start with a free account.