Skip to content

CVE-2025-20281 Cisco ISE API Unauthenticated Remote Code Exe... #1188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -123,5 +123,6 @@ The rule triggers on any write attempt to `*/release_agent` from a process insid

* [Unit 42 – CVE-2022-0492: container escape via cgroups](https://unit42.paloaltonetworks.com/cve-2022-0492-cgroups/) – detailed analysis and mitigation script.
* [Sysdig Falco rule & detection guide](https://sysdig.com/blog/detecting-mitigating-cve-2022-0492-sysdig/)
* [Cisco ISE privileged container escape via cgroup user-mode helpers (CVE-2025-20281)](https://www.thezdi.com/blog/2025/7/24/cve-2025-20281-cisco-ise-api-unauthenticated-remote-code-execution-vulnerability)

{{#include ../../../../banners/hacktricks-training.md}}
39 changes: 39 additions & 0 deletions src/pentesting-web/command-injection.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,47 @@ powershell C:**2\n??e*d.*? # notepad
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/command_injection.txt
{{#endref}}

### Java Runtime.exec Tokenization & ${IFS} Bypass

When the vulnerable code ultimately calls `java.lang.Runtime.exec(String cmd)` **with a single string argument**, the JRE **tokenises** that string before it is passed to `/bin/sh`. The tokeniser (`StringTokenizer` in Java 8) simply splits on whitespace characters (`\t`, `\n`, `\r`, `\f`, and the regular space). Unlike a POSIX shell, **quotes (" or ') and back-ticks are *ignored*** by the tokeniser, so an attacker cannot rely on them to keep a payload together.

As a consequence, classic payloads such as:

```java
"x; touch /flag"
```

become the following argument array once Java finishes splitting:

```
[x;, touch, /flag]
```

Only the very first element ( `x;` ) reaches the invoked script, breaking the injection attempt.

#### Bypass – replace the spaces with ${IFS}

When the attacker controls a **bash** context (either directly or through a helper script), the trick is to replace every space with the shell’s *Internal Field Separator* variable `IFS`:

```bash
id${IFS}-a
```

* `Runtime.exec` sees no literal spaces → **no tokenisation takes place**, so the whole string is forwarded as **one single argument**.
* Inside the `/bin/sh` that finally interprets the parameter, `${IFS}` expands back to a regular space, giving **`id -a`**.

This technique was successfully used against Cisco ISE’s `enableStrongSwanTunnel` API (CVE-2025-20281) to achieve unauthenticated RCE even though the vulnerable Java code passed user input to a root shell script via `sudo`.

> Tip: When your final payload cannot contain `${IFS}` literally (e.g. it will later be copied into `release_agent` or another restricted context) you can **base64-encode** the whole command and decode it on the fly:
>
> ```bash
> echo${IFS}BASE64_PAYLOAD${IFS}|${IFS}base64${IFS}-d${IFS}|${IFS}bash
> ```
## References
- [CVE-2025-20281 – Cisco ISE `enableStrongSwanTunnel` unauthenticated RCE (ZDI blog)](https://www.thezdi.com/blog/2025/7/24/cve-2025-20281-cisco-ise-api-unauthenticated-remote-code-execution-vulnerability)
- [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Command%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Command%20Injection)
- [https://portswigger.net/web-security/os-command-injection](https://portswigger.net/web-security/os-command-injection)
Expand Down