Model or dataset
cha0upup/LeoAI avatar
cha0upup/LeoAI

LeoAI gives one web workbench two Puppet runtimes and an AI that delegates down to the node

AI 驱动的后渗透综合管理平台,深度集成 LLM Agent,开箱即用。

311 stars31 forksJavaGPL-3.0

At a glance

What is it?
LeoAI is a Java platform for authorised red team work that combines a host asset catalogue, a Puppet operation console, a platform-level AI, and a node-level AI copilot. Its architectural bet is that Java and PHP are equal Puppet runtimes behind one service provider interface, so nothing above them knows which one it is talking to. The deployment defaults are where the operational risk sits.
Who is it for?
LeoAI fits a red team that has heterogeneous estate, where some agents will only run PHP on a locked-down host and others have a JVM, since the capability contract is what makes one console work across both. It does not fit a deployment where published default credentials and encryption keys are acceptable, because the compose file ships both.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Two Puppet runtimes, one SPI, and services that never name a runtime

The central design claim is that Java and PHP are equal Puppet runtimes, and the module layout shows how that is enforced.

The shared module defines only protocol, session, and capability contracts. The concrete implementations live in `javacore` and `phpcore`, and the `web` module does the final assembly. Alongside them sit `service` and `ai` for shared business logic and orchestration, `core` for the runtime SPI, capability, RPC, and session layer, and `jmg` for the Java shell and memory shell builders.

The capability table is where the abstraction is visible, and most rows are identical. File capabilities are the same on both sides: browse, edit, chunked transfer, compression, and hashing. Network capabilities are the same: HTTP, scanning, SOCKS5 and HTTP proxying, and forward and reverse tunnels.

The rows that differ are mechanical. The entry form is a Java core with a container or script generator on one side and a single-file HTTP entry point requiring PHP 5.6 or newer on the other. Components load as independent Java bytecode on demand versus independent PHP components lazily loaded by digest. Commands run through `ProcessBuilder` with PTY or pipe sessions versus `proc_open` with a Python PTY and command backend. And a database connection description is converted to JDBC parameters on one side and to a PDO DSN on the other.

Capability discovery is dynamic on both sides through a Runtime Profile, which is what lets the web console show only the tools a given node can actually run.

PHP capability depends on which extensions the target host has

The documentation is specific about what a PHP node can and cannot do, and it comes down to the host rather than the platform.

Database access needs the corresponding PDO driver. Compression needs `ZipArchive`. And a persistent proxy or tunnel worker needs at least one of `shell_exec`, `exec`, or `popen`.

That list is short and it is the whole contract. It also explains why the PHP entry point is a single file with an HTTP RPC surface rather than a full runtime: the goal is to land on a host where you have limited extension availability and still expose a usable capability set.

The consequence for the operator is that two PHP nodes with different PHP builds can report different Runtime Profiles, and the console will show different tools for them. Nothing is misconfigured in that case; the platform is reporting what it found.

Component stability is handled on both sides as well, and the v1.0.0 notes describe what was added: bounded tasks, time-to-live, resource deregistration, cache caps, and lifecycle cleanup, so a component that stops responding releases its resources instead of holding a slot.

The AI layer delegates from the platform down to the node session

There are two AIs and the relationship between them is the product's main idea.

The platform AI does unified analysis and task distribution, and it can choose a target Puppet, hand it a task, watch subtask status and execution progress in the platform session, and receive the final deliverable. The Puppet AI then works inside the target session, calling tools in the current context, streaming execution progress back, and accumulating reconnaissance results.

Underneath is LangChain4j, with multi-turn tool calls and parallel execution, automatic planning and execution of post-exploitation steps, and more than 100 atomic AI tools spanning command execution, files, network, credentials, scanning, HTTP packet sending, database, scripts, and plugins.

Model support covers OpenAI, Tongyi Qianwen, DeepSeek, and Claude, with runtime hot switching, and both AIs share a unified input area where you can switch model and reasoning strength and attach text or code files, with the change announced in the session rather than applied silently.

The context handling is the part with numbers in it. The window adapts dynamically to the model's context, up to 1M, and history is compressed automatically to preserve the important parts, while reconnaissance summaries accumulate and compress on their own so the context grows as the operation does rather than being discarded at the end of each step.

The console carries memory shell builders for two dozen middleware products

The web runtime module is the largest single feature area, and it is built around a generator rather than a fixed set of handlers.

Supported memory shell types include Filter, Servlet, Listener, Valve, Interceptor, Controller, WebSocket, an HTTP upgrade protocol, WebFlux filters and handler functions, a Netty handler, and a Dubbo service. Supported middleware is listed as 24 products, from Tomcat through Jetty, JBoss variants, Wildfly, Undertow, Resin, GlassFish, Payara, WebLogic, WebSphere, Apusic, BES, InforSuite, TongWeb, Struts2, Spring Web MVC, Spring WebFlux, XXL-JOB, and Dubbo.

The version handling is where the real work is. TongWeb valves are matched to a runtime contract by major version, with 6 mapping to one package, 7 to another, and 8 to a third, and the interface and API both require you to choose the server version. XXL-JOB is split the same way: versions 2.2 through 2.5 use one request body and 2.0 through 2.1 use a Hessian-based one, with the capability catalog validating the packer against the declared server version.

Mounting is per container type rather than per process, covering the filter chain and context valve on the Tomcat, JBoss, GlassFish, Payara, InforSuite, and TongWeb families, the handler on Jetty, the servlet handler on Undertow, the filter chain on Resin, the servlet context on WebLogic, the filter manager on WebSphere, the framework servlet on Spring MVC, and single classes for Apusic and BES.

Alongside that sits a packer list of expression and template languages used to fill the payload, and an artifact mode that emits a base64 jar carrying `premain` and `agentmain` manifests so it can be loaded with a java agent flag or through the Attach API.

The compose file ships a default encryption key in plaintext

The deployment example is a single service built from the repository, and two of its environment defaults deserve attention before anyone copies it.

yaml
      SPRING_DATASOURCE_URL: jdbc:sqlite:/app/data/data.db
      VFSPATH: /app/data/root

The first is unremarkable: a SQLite file under the data volume, and a virtual filesystem path alongside it.

The second is not. The plugin encryption key is set with a default value that is a literal word repeated, and the database master key defaults to an empty string. Both are overridable through the environment, which is exactly why the compose file is a starting point rather than a deployment.

Everything stateful lives in one named volume mounted at the data directory, and the port mapping is 8082 by default with an override variable. The container is configured with a runtime image argument defaulting to a Temurin 17 JRE base, and it downloads the application jar from a URL passed as a build argument rather than building the Maven project inside the image.

That last detail has a consequence. The image you run is whatever that URL points to at build time, not what your repository checkout contains.

The compose jar URL is newer than the newest release tag

The compose file and the repository's release history do not line up, and it is the kind of mismatch worth catching before you deploy.

The build argument points at a download URL for version 2.2.0 of the application jar. The release history in the repository shows v2.0.2, then v2.0.0, then v1.0.1, and the last push to the main branch is later than all of them.

So a compose deployment resolves an artifact version ahead of the newest tag visible in the repository metadata, and the release notes in the readme describe the 1.0.0 line.

Two readings are possible. Either the project publishes releases from a workflow the repository metadata does not show, or the compose file was updated ahead of a tag. Nothing published settles it, which is the point: if the provenance of the jar matters to you, check that the URL resolves to a release you can identify and read its notes.

The Dockerfile has the same behaviour by design, since it installs curl, fetches the jar, and then purges curl again in the same layer, which is a small detail that shows the image was written to be self-contained rather than cache-friendly.

This line ships as a fresh install, not as an upgrade

The installation baseline note is unusually blunt, and it removes a class of support problem.

The release is published as a fresh install. Deploying the production version means using a new data directory, and data files, component caches, and generated artifacts from older test versions are explicitly not accepted as upgrade input.

The reason is visible in what changed underneath. The database baseline is created directly by a schema file and a data file that establish the final structure for that version, and the first start creates the SQLite database, the base configuration, and the administrator account. A previous schema would not match those files, so rather than write a migration they chose to require a clean directory.

Two related policies sit alongside it. First login forces a change of the initial password, so the shipped credential is a one-time value rather than a standing one. And the release version is unified across the Maven modules, the frontend, the Docker build, and the artifacts, so the official jar name matches the version everywhere.

For an operator that means upgrade planning is a data migration you do yourself, not something the platform performs.

Editorial conclusion

LeoAI fits a red team that has heterogeneous estate, where some agents will only run PHP on a locked-down host and others have a JVM, since the capability contract is what makes one console work across both. It does not fit a deployment where published default credentials and encryption keys are acceptable, because the compose file ships both. Before deploying, change `LEO_PLUGIN_ENCRYPT_KEY` and `LEO_DATABASE_MASTER_KEY`, note that the compose file pulls a jar URL newer than the newest release tag, and follow the project's own baseline note that this line ships as a fresh install rather than an upgrade.

Frequently asked questions

What does LeoAI do?

It is an AI-driven post-exploitation and host collaboration platform for authorised red teams and security research. It puts host assets, a Puppet operation console, platform-level AI, node-level AI copilot, and team governance in one web workbench, with team boundaries, host sharing, operation audit, and AI audit.

What is the difference between the Java and PHP Puppet runtimes?

They are equal runtimes behind one PuppetRuntimeModule SPI, capability contract, and RPC response protocol. They differ mechanically: Java uses a core plus container or script generation with ProcessBuilder and JDBC, while PHP uses a single-file HTTP entry point with proc_open and a PDO DSN, and each reports its own Runtime Profile.

Which AI models can LeoAI use?

OpenAI, Tongyi Qianwen, DeepSeek, and Claude, switchable at runtime. Both AIs share an input area with model switching, reasoning strength switching, and text or code file input, and the context window adapts to the model up to 1M with automatic compression of history.

How do I deploy LeoAI with Docker?

The compose file builds the image from the repository with a runtime image argument and a jar download URL, maps port 8082, keeps state in a named volume at the data directory, and runs as an unprivileged system user. Override the plugin encryption key and the database master key, because the compose defaults are published values.

What AI tools and skills does LeoAI ship?

More than 100 atomic tools covering command execution, files, network, credentials, scanning, HTTP packet sending, database, scripts, and plugins, plus built-in skills for two scenarios, node-level and platform, covering reconnaissance, credential collection, privilege escalation, persistence, lateral movement, disguise, fingerprint, and vulnerability suggestions, managed through a visual Skill manager that needs no restart.

Official sources

  1. cha0upup/LeoAI on GitHub
  2. Issues
  3. License: GPL-3.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/cha0upup-leoai.svg)](https://hysenlabs.com/projects/cha0upup-leoai)