# ShiroAttack2: a Java GUI and CLI tool for Shiro-550 rememberMe exploitation

> ShiroAttack2 targets the Shiro-550 (CVE-2016-4437) rememberMe deserialization flaw with a shared JavaFX and command-line attack engine. It is built for authorised penetration testing, and its licence file and package manifest disagree.

**SummerSec/ShiroAttack2** — shiro反序列化漏洞综合利用（仅限授权测试使用）

- Repository: https://github.com/SummerSec/ShiroAttack2
- Stars: 2,629 · Forks: 292
- Language: Java
- License: MIT
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/summersec-shiroattack2

## What Shiro-550 is, and the three reasons ShiroAttack2 still has a target

ShiroAttack2 is a Java tool for exploiting the Apache Shiro rememberMe deserialization vulnerability, tracked as Shiro-550 and CVE-2016-4437. The README is blunt about why a 2016 bug still matters: Shiro 1.2.4 and earlier hard-coded an AES key in CookieRememberMeManager, the value kPH+bIxk5D2deZiIxcaaaA==, and tutorials and scaffolding code have copied that value for years. The second reason is operational. rememberMe requires the client and the server to hold the same key, so once a key is written into a config file, a Docker image or a source repository, replacing it means changing every node at once. The third is cost: the README notes that a GUI takes a few clicks to reach a shell, and the CLI can be embedded directly into scripts.

The audience is therefore narrow and explicit. This is a tool for authorised penetration testing and academic research, per the disclaimer in the README. It is not a scanner you point at a fleet to produce a report, and it is not a patch. If you are on the defensive side looking for a way to detect exposed Shiro instances, this is the wrong shape of tool: it is an exploitation client, and running it against systems you do not have written authorisation for is, in the project's own words, illegal under the cited Chinese statutes.

## The attack chain: probe, crack, gadget, command execution, memory shell

The README lays out a five-stage flow, and the stages map onto distinct code paths rather than one monolithic request.

Detection works by sending rememberMe=yes and watching for Set-Cookie: rememberMe=deleteMe. The README states that Shiro 1.x always returns deleteMe when it receives an invalid cookie, which makes the absence of that header the signal.

Cracking serialises a SimplePrincipalCollection and encrypts it with each candidate key from the dictionary. No deleteMe in the response means the key is correct. The tool walks both AES modes automatically: CBC for Shiro 1.2.4 and earlier, GCM for Shiro 1.2.5 and later, and locks onto whichever one hits. The CLI exposes these as --cbc and --gcm.

Gadget selection is where the version differences bite. The tool tries the String, AttrCompare and ObjectToStringComparator variants first because they do not need commons-collections, then falls back to the CommonsBeanutils variant that depends on ComparableComparator. The release bundle ships the CommonsBeanutils JARs under lib/ for this reason.

Command execution carries the gadget payload in the rememberMe cookie, with the command placed in the Authorization header. Echo output is handled by one of several types: TomcatEcho, SpringEcho, DFS-AllEcho, ReverseEcho or NoEcho. Memory-shell injection reuses the same gadget chain to plant a Filter, Servlet, Interceptor, HandlerMethod or TomcatValve, after which the tool no longer depends on rememberMe at all. Key replacement then rewrites Shiro's AES key through the memory shell, with six injection paths and automatic verification of the old and new keys.

The design decision worth noting is that the 5.x CLI does not fork the attack logic. The README states that AttackService, described as over 1000 lines, was not changed for CLI mode. Instead the CLI subclasses TextArea to intercept log output and injects a fake MainController through the ControllersFactory registry, so GUI and CLI share one implementation. A JFXPanel initialises the JavaFX thread at startup without opening a window. That is a pragmatic hack, and it means a JavaFX dependency remains in the CLI path even though no window appears.

## Installing ShiroAttack2 and running a first detect and crack

There are two routes. The release page offers shiro_attack-<version>-<jdk>.jar as a single executable file and shiro_attack-<version>-<jdk>-bundle.zip as a complete archive containing data/ and lib/. The README shows the expected working directory, with the key dictionary at data/shiro_keys.txt holding one Base64 key per line and the CommonsBeanutils JARs in lib/.

If you build from source instead, two local JARs must be installed into the Maven repository first, exactly as the README gives them:

```bash
mvn install:install-file -Dfile=libs/jEG-Core-1.0.0.jar -DgroupId=jeg -DartifactId=jeg-core -Dversion=1.0.0 -Dpackaging=jar
mvn install:install-file -Dfile=libs/jmg-sdk-1.0.9.jar -DgroupId=jmg -DartifactId=jmg-sdk -Dversion=1.0.9 -Dpackaging=jar
mvn clean package -DskipTests
```

The README states the build targets Java 8 and produces target/shiro_attack-5.1.1-all.jar. The jEG and jMG artifacts are the third-party echo generator and memory-shell generator integrations; the README says the tool falls back to a Legacy path when they fail.

CLI mode starts through the main class, with the command as the first argument:

```bash
java -cp shiro_attack-<version>.jar com.summersec.attack.CLI.MainCLI <command> [options]
```

The README lists six commands: detect, crack, exec, memshell, changekey and gui. A first session against an authorised target would be detect, then crack against the same URL using the shipped dictionary. In --json mode the output is split across two channels: lines beginning with { are structured logs that a script or an agent can parse line by line, and lines that do not begin with { are raw command output, so tail -1 returns the result. The README points to @skills/shiro-attack-cli/SKILL.md for the full parameter list and troubleshooting rules, and to docs/USAGE.md for the complete usage guide.

## Where ShiroAttack2 fails or is the wrong choice

The most obvious failure mode is the key dictionary. Cracking depends on the target using a key that appears in data/shiro_keys.txt. A deployment that rotated to a random key outside that list will not crack, and the README offers no brute-force-over-arbitrary-keyspace mode beyond the dictionary file. The tool's own framing supports this: the reason Shiro-550 persists is that people keep the default key, not that the tool can find any key.

Gadget availability is the second constraint. The tool prefers variants that avoid commons-collections, but the fallback needs ComparableComparator and therefore the matching CommonsBeanutils JAR on the classpath. The repository has a docs/NoGadget.md document, which tells you the maintainers consider the no-gadget case a separate scenario that needs its own explanation rather than something the default path handles.

Then there is the CLI's JavaFX dependency. Because the CLI reuses the GUI logging path and starts a JFXPanel, the CLI is not a lightweight headless client in the way a pure Java command-line tool would be. It avoids opening a window, but it still initialises the JavaFX toolkit.

Finally, scope. This is an exploitation tool with memory-shell injection and key replacement built in. If your goal is inventory or compliance reporting, none of those capabilities help, and the risk of running it outside a written authorisation is entirely on you, which the disclaimer states plainly.

## How ShiroAttack2 differs from ysoserial and manual rememberMe crafting

The natural alternative for the same vulnerability class is ysoserial plus a hand-written client: generate a CommonsBeanutils or CommonsCollections payload, AES-encrypt it with a candidate key, Base64-encode it, and set the rememberMe cookie yourself. The difference is in what each one owns.

ysoserial owns payload generation and nothing else. It does not probe whether a target is Shiro, does not test candidate keys, does not switch between CBC and GCM, does not pick an echo type, and does not inject a memory shell. Every one of those steps is your code. That is an advantage when you need a payload the tool does not generate, and a disadvantage when you are repeating the same five steps across a scope of hosts.

ShiroAttack2 owns the whole chain. Detection, key cracking against a dictionary, automatic AES mode selection, gadget variant fallback, echo selection, memory-shell injection and key replacement all live behind one command set. The trade-off is that you inherit its opinions: its key dictionary, its gadget list, its echo types, and its Java 8 build. If a target needs a gadget chain outside that list, you are back to ysoserial for the payload and ShiroAttack2 for nothing.

The other difference is the interface. ShiroAttack2 ships a JavaFX GUI and a CLI over the same engine, which suits testers who alternate between exploratory clicking and scripted runs. A ysoserial-based workflow is scripted by default and has no GUI to fall back on.

## Maintenance, releases and the licence discrepancy

The last push to the repository was on 2026-06-04, and the most recent releases are v5.1.1 on 2026-05-27, v5.1.0 on 2026-05-15 and 5.0.2 on 2026-05-06. The repository is not archived. The README states that releases are built by GitHub Actions when a tag matching v* or X.Y.Z is pushed, with optional per-version notes under docs/releases/<tag>.md. That is a conventional setup, and it means the upgrade cost for a user is mostly re-downloading the bundle and keeping data/shiro_keys.txt current, since the key dictionary is a plain text file you can edit yourself.

On licensing, the repository contradicts itself and neither value should be treated as settled. The repository states an MIT license, and the LICENSE file is present at the top level. The package.json in the same repository declares "license": "Apache-2.0". These are different licences with different obligations, and nothing in the repository explains the discrepancy. This is not legal advice: if you plan to redistribute the JAR, embed it in a product or ship it to a client, ask the maintainer which licence governs the artifact rather than picking the one you prefer. The bundled libs/jEG-Core-1.0.0.jar and libs/jmg-sdk-1.0.9.jar are third-party components with their own terms, which the MIT or Apache-2.0 declaration on the main project does not cover.

## Conclusion

Adopt ShiroAttack2 if you are a penetration tester or red teamer with written authorisation for the targets, and you want one Java 8 artifact that covers detection, key cracking, gadget selection, echo and memory-shell injection from both a GUI and a scriptable CLI. Do not adopt it as a defensive scanner or as anything you can run without an explicit scope document; the project's own disclaimer forbids unauthorised use. Before you rely on it, verify the licence question first: the repository ships an MIT LICENSE file while package.json declares Apache-2.0, and only the maintainer can resolve which applies to the artifact you redistribute.

## FAQ

### What is ShiroAttack2 used for?

It is a Java tool for exploiting the Shiro-550 rememberMe deserialization vulnerability, CVE-2016-4437. The README describes detection, AES key cracking, command execution, memory-shell injection and Shiro key replacement, and states it is only for authorised security testing and academic research.

### Does ShiroAttack2 have a command-line mode, or is it GUI only?

It has both. The README states that CLI mode was added after version 5.0 and that the GUI and CLI share the same AttackService attack logic, with the CLI injecting a fake MainController through the ControllersFactory registry. Commands include detect, crack, exec, memshell, changekey and gui.

### Which Java version does ShiroAttack2 need to build?

The README's build section states the fat JAR packaging targets Java 8, and the build produces target/shiro_attack-5.1.1-all.jar. Two local JARs, jEG-Core-1.0.0.jar and jmg-sdk-1.0.9.jar, must be installed into the local Maven repository before packaging.

### What licence is ShiroAttack2 released under?

The repository states MIT and includes a LICENSE file, but package.json in the same repository declares Apache-2.0. The repository does not explain the difference, so confirm with the maintainer before redistributing the artifact.

## Sources

- [Issues](https://github.com/SummerSec/ShiroAttack2/issues)
- [License: MIT](https://github.com/SummerSec/ShiroAttack2/blob/master/LICENSE)
- [README](https://github.com/SummerSec/ShiroAttack2/blob/master/README.md)
- [Releases](https://github.com/SummerSec/ShiroAttack2/releases)
- [SummerSec/ShiroAttack2 on GitHub](https://github.com/SummerSec/ShiroAttack2)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/summersec-shiroattack2
