Pull-based C2 framework with ten native transports, concurrent multi-profile handlers, ECDSA-signed tasking, and a multi-operator team server with RBAC and Qt/CLI consoles.
A pull-based C2 with ten native transports, concurrent multi-profile handlers, and an honest threat model. The agent is a single Go binary with every behavioural property baked in at build time — no runtime config file, no environment variable, no command-line arguments. Tasks and results are ECDSA-signed end to end. The transports are HTTPS, QUIC/HTTP/3, WebSocket, DNS TXT, DNS-over-HTTPS, ICMP, WireGuard, SMB-pivot, TCP-bind, and TCP-reverse.
Use this software only on systems you own or on systems where you hold explicit written authorization. You are solely responsible for compliance with applicable laws and organizational policies. The authors and contributors accept no liability for misuse, data loss, or legal consequences arising from the use of this project.
TornadoC2 is a pull-based C2. The agent does not hold a live socket; it wakes on its own schedule, checks in with the server, retrieves queued work, executes it, and goes back to sleep. The operator queues commands; the beacon picks them up on its next check-in.
This design trades immediacy for resilience. A live shell dies when the network flaps; a beacon reconnects on its next wake-up and resumes. A live shell leaves a persistent footprint on the wire; a beacon's traffic pattern is bounded by its sleep interval. The framework is built for long-haul engagements where the implant has to survive reboots, retry on failure, and self-destruct on a schedule.
The implant is a single Go binary, cross-compiled from the operator machine. There is no runtime configuration file, no environment variable, no registry key. The callback URL, sleep interval, kill date, C2 profile, and evasion set are all baked in at build time. A captured binary contains everything it needs to run, and nothing the operator did not put there.
The framework is compiled for Linux and Windows today, on amd64 and arm64. macOS support is on the near-term list, along with additional native commands and additional evasion primitives. The Capability summary below lists what is available in the current version.
The PySide6 operator console. Beacon table on top, log and
chat on the bottom, one command bar for both. The terminal REPL
is the reference implementation; the GUI is a presentation layer
over the same Client methods.
I used Sliver for a year. It is a good tool — that needs saying before anything else, because what follows is not a criticism of it. The problem was that I could not change the agent's shape. A Sliver beacon looks like a Sliver beacon: one fingerprint, one polling schedule, one protocol family, one runtime configuration that sits on disk. I could point it at a different URL. I could not make it something else. That is the right trade for engagements where a generalist shape is fine. It was the wrong trade for the networks I was working on.
I tried Mythic. The modularity is genuine and the community work behind it is impressive. I could not work in it. Every interaction went through a browser tab. I spend eight hours a day in a console, and the tool was not in the console. I stopped after a week.
I looked at Cobalt Strike and Brute Ratel. Both are excellent and both are priced for teams and institutions. I am one person. I do not have a team budget.
The tools that existed were good at things I did not need. The features they had were not the features I was looking for, and the ones I was looking for were not in any of them. I needed an agent that could be a specific shape for a specific target, a console that stayed close to my hands, and a handler where rotating a profile mid-engagement did not kill every live session. I also wanted the operator side to be treated as a real part of the framework — not an agent-first tool with a coordination layer added later, but a team server that a group of operators could actually run an engagement on, with the roles, the audit trail, and the shared state that professional work requires.