简体中文 | English
JavaShellRadar is a standalone JVM runtime scanner for Java memory shells, malicious request-path hooks, and high-risk web entry points. It attaches to a running JVM, correlates loaded classes with live container registrations, inspects selected bytecode, verifies CodeSource consistency, and writes evidence-rich reports for incident response.
JavaShellRadar is scan-only. It does not unload classes, remove components, or modify container state.
- Attach to a running JVM and inspect already loaded classes.
- Read Filter, Servlet, Listener, Valve, WebSocket, Spring MVC/WebFlux, Jetty, Undertow, WebLogic, Netty, and Reactor Netty registrations where runtime structures can be accessed safely.
- Combine class shape, annotations, class loaders, CodeSource, runtime registration, bytecode behavior, payload constants, and protected request-path integrity instead of relying on a single indicator.
- Compare captured memory bytecode with the corresponding disk artifact, separating memory threats from disk-backed application risk.
- Use a fast
standardmode for routine production scans and an opt-indeepmode for broader candidate analysis. - Guard Attach and scanning with timeouts, a single-scan lock, batched retransformation, cancellation checks, and terminal status files.
- Produce Markdown, text, and JSON reports together with captured class files, decompiled source, runtime inventories, and diagnostics.
A class moves through the following stages before it appears in a report:
- Attach and scan isolation — the CLI creates a separate output directory for the scan and loads the agent.
- Runtime discovery — JavaShellRadar enumerates loaded JVM classes, determines which supported containers or frameworks are present, and starts the relevant runtime scan stages.
- Initial class assessment — every eligible class is checked using low-cost signals such as hierarchy, interfaces, annotations, class and package names, class loader, CodeSource, and runtime role.
- Candidate planning —
standardmode selects bytecode candidates from the initial assessment.deepmode also considers entry points, important framework classes, missing or changed CodeSource artifacts, and unusual application class loaders. - Controlled bytecode capture — candidates are retransformed in bounded batches.
- Bytecode and payload analysis — captured code is checked for dangerous invocation chains, command or script execution, dynamic class definition, reflection, request access, proxy and tunnel behavior, deserialization, embedded class payloads, encryption and encoding stages, and modifications to protected request paths.
- CodeSource verification and evidence correlation — when a class has a usable disk origin, its in-memory representation is compared with the corresponding artifact, then combined with runtime registration, bytecode behavior, payload evidence, and disk consistency.
- Classification and reporting — results include a behavior score, memory-risk assessment, finding category, and a profile when the evidence is sufficiently stable.
- Completion and cleanup
No individual interface, annotation, class name, or CodeSource result is intended to prove maliciousness on its own. Reporting is based on correlated evidence.
Runtime registration recovery currently covers:
| Environment | Runtime entries and relationships |
|---|---|
| Apache Tomcat | Filter, Servlet, Listener, Valve, JSR 356 WebSocket endpoint, HTTP UpgradeProtocol |
| TongWeb | Tomcat-compatible Filter, Servlet, Listener, Valve and WebSocket paths under supported TongWeb package structures, plus application contexts and mappings |
| Eclipse Jetty | Filter, Servlet, Listener, JSR 356 WebSocket endpoint, HttpConfiguration.Customizer |
| Undertow | Filter, Servlet and Listener |
| WebLogic | Filter, Servlet and Listener |
| Spring MVC | HandlerInterceptor, Controller/handler method, handler map, request handler, and Spring WebSocket |
| Spring WebFlux | WebFilter, WebHandler, controller/handler method, handler map, and servlet-adapter chains |
| Netty / Reactor Netty | Handler and Reactor Netty PipelineConfigurer |
JavaShellRadar currently recognizes or prioritizes the following classes of entry points and malicious behavior:
javax.servletandjakarta.servletFilter, Servlet, FilterChain, request/context Listener, and JSP-generated classes.- Tomcat and TongWeb Valve implementations and proxy-wrapped container components.
- Spring MVC Controller, REST mapping, HandlerInterceptor, HandlerAdapter, HttpRequestHandler, handler mappings, and Spring WebSocket handlers.
- Spring WebFlux WebFilter, WebHandler, HandlerFunction, annotated handler methods, and Reactor Netty forwarding chains.
- JSR 356
Endpoint,@ServerEndpoint, message handlers, and registered WebSocket endpoints. - Netty ChannelHandler, inbound/outbound handler, pipeline hook, and Reactor Netty pipeline configurer.
- Jetty Handler and
HttpConfiguration.Customizer; Undertow HttpHandler. - Struts2 Action and convention annotations.
- Apache Dubbo and Alibaba Dubbo Filter, service annotation, and exporter-listener entry points.
- Resin request-path hook targets and WebSocket listeners, plus Grizzly filter-chain entries at class/bytecode level.
- Command shells, encrypted dynamic-loader shells, embedded Java class payloads, agent-based hooks and injectors, generic dynamic class loaders, deserialization paths, script execution, and socket/proxy tunnels.
- Behavioral profiles for Godzilla-like, Behinder-like, AntSword-like, NeoreGeorg-like, suo5-style servlet/WebFlux/WebSocket tunnels, WebSocket command shells, JSP payload injectors, and related loader helpers when sufficient evidence is present.
This list describes detection coverage, not a claim that every version of every product exposes identical runtime metadata.
JavaShellRadar is built with Maven and targets Java 6 bytecode for broad incident-response compatibility. Building with JDK 8 is recommended.
cd JavaShellRadar
mvn packageIn an offline development environment with dependencies already cached:
mvn -o packageThe runnable jar is generated at:
JavaShellRadar/cli/target/javashellradar.jar
Scan a target JVM by PID:
java -jar JavaShellRadar/cli/target/javashellradar.jar -p <pid>Useful options:
-p, --pid <pid> target JVM process id
-c, --class <regex> only scan classes matching the regex
--threshold <score> minimum score to report, default 30
--bytecode-threshold <score> minimum outlook score to run bytecode detectors, default 10
--class-budget-ms <ms> soft scan budget per class, default 50
--payload-sweep <priority|all> payload constant sweep mode, default priority
--bytecode-batch-size <count> classes per bytecode capture batch, default 64
--attach-timeout-sec <seconds> attach handshake timeout, default 300, 0 disables timeout
--scan-timeout-sec <seconds> end-to-end scan timeout, default 300, 0 disables timeout
--scan-mode <standard|deep> bytecode candidate strategy, default standard
--deep shorthand for --scan-mode deep
--deep-confirm-threshold <n> ask before deep mode captures more than n classes, default 512
--deep-force skip the deep candidate-count confirmation
--json <true|false> write result.json, default true
--incremental experimental local-cache status marking
standard is the default for routine production scans. It uses the initial class and runtime assessment to keep bytecode capture focused and predictable.
deep broadens candidate analysis for protected framework hooks, high-value runtime components, missing or changed CodeSource artifacts, unexpected application class loaders, and risky disk bytecode. Large Controller or Servlet sets are first inspected from disk where possible, limiting unnecessary retransformation of ordinary business classes.
If the planned deep capture count exceeds --deep-confirm-threshold, an interactive CLI asks whether to continue. Non-interactive execution rejects the oversized scan safely unless --deep-force is supplied or the threshold is explicitly raised. The threshold is a confirmation boundary, not a truncation limit.
Each scan is written to a separate directory:
.javashellradar/runs/<timestamp>_pid<pid>_<class-filter>_<random>/
Common artifacts include:
result.md,result.txt, andresult.jsonfindings.- Captured
.classfiles and decompiled Java source. - Runtime component and transformer inventories.
- Bytecode capture and CodeSource diagnostics.
scan-status.properties, which recordscompleted,failed,timed_out,cancelled,busy, or the temporaryconfirmation_requiredstate.cache.json, the scan fingerprint cache; cross-run incremental status marking remains experimental.
The Markdown report separates memory threats and active runtime hooks from disk-backed application risks. Behavior severity and memory-risk confidence are shown independently so a dangerous but legitimate disk-backed business function is not presented as equivalent to a fileless memory shell.
- JavaShellRadar inspects classes already loaded in the target JVM; it does not replace filesystem webshell scanning. A JSP that has never been requested or compiled may not yet exist as a loaded class and therefore will not appear in the results.
- Runtime registration recovery is best-effort and can vary with container versions, vendor patches, module access, and application topology.
- If an attacker modifies an already loaded class with a retransformation-capable Transformer and removes that Transformer before scanning, the retransformation used by JavaShellRadar to capture bytecode may expose only the pre-modification baseline and restore the target method body to that baseline. This can lose the modification evidence and change the current runtime state; the behavior was reproduced on JDK 8, 11, 17, and 25.
- JavaShellRadar reports evidence and artifacts; containment, removal, and application repair remain operator actions.
JavaShellRadar builds on ideas and code paths from Arthas and copagent, together with practical experience from RASP-style runtime analysis. It uses ASM for bytecode inspection and CFR for decompilation.