mirror of
https://github.com/s-b-repo/rustsploit
synced 2026-06-27 09:54:12 +00:00
fb9ae7f3c2
migrated away from free rdp lots of improvements there and created native libs feel free to use native libs but contribute if you improve please add more wider api support and cli and shell payload mutator for api endpoint going to do that for payloads gens and other stuff later and im also planning some more bug changes and improvement check the api template
170 lines
5.5 KiB
Markdown
170 lines
5.5 KiB
Markdown
# Module Development
|
|
|
|
Reference for maintainers and contributors writing new Rustsploit modules.
|
|
|
|
---
|
|
|
|
## How Modules Are Discovered
|
|
|
|
Rustsploit uses a build-time code-generation approach — no manual registry:
|
|
|
|
1. **`build.rs` scan** — Before compilation, `build.rs` recursively walks `src/modules/` looking for `.rs` files that are not `mod.rs`.
|
|
2. **Signature detection** — A file that exposes `pub async fn run(` is treated as a callable module.
|
|
3. **Name generation** — Both a *short name* (`ssh_bruteforce`) and a *qualified path* (`creds/generic/ssh_bruteforce`) are registered.
|
|
4. **Dispatcher emission** — Three files are generated:
|
|
- `src/commands/exploit_gen.rs`
|
|
- `src/commands/scanner_gen.rs`
|
|
- `src/commands/creds_gen.rs`
|
|
|
|
Each contains an exhaustive `match` mapping names → `use crate::modules::...::run`.
|
|
5. **Shell + CLI resolution** — `use exploits/foo` or `--module foo` both resolve through the dispatcher.
|
|
|
|
Because it's generated at build time, there is **no manual registry drift** as long as modules live in the correct folder and export `run`.
|
|
|
|
---
|
|
|
|
## Project Code Layout
|
|
|
|
```text
|
|
rustsploit/
|
|
├── Cargo.toml
|
|
├── build.rs # Generates dispatcher by scanning src/modules
|
|
├── src/
|
|
│ ├── main.rs # Entry point — CLI or shell mode, input validation
|
|
│ ├── cli.rs # Clap-based CLI parser and dispatcher
|
|
│ ├── shell.rs # Interactive shell loop + UX helpers
|
|
│ ├── api.rs # REST API server — auth, rate limiting, hardening
|
|
│ ├── config.rs # Global config and target validation
|
|
│ ├── commands/
|
|
│ │ ├── mod.rs
|
|
│ │ ├── exploit.rs
|
|
│ │ ├── exploit_gen.rs # build.rs output
|
|
│ │ ├── scanner.rs
|
|
│ │ ├── scanner_gen.rs # build.rs output
|
|
│ │ ├── creds.rs
|
|
│ │ └── creds_gen.rs # build.rs output
|
|
│ ├── modules/
|
|
│ │ ├── exploits/ # Exploit modules
|
|
│ │ ├── scanners/ # Scanner modules
|
|
│ │ └── creds/ # Credential modules
|
|
│ └── utils.rs # Shared helpers — normalization, prompts, validation
|
|
├── docs/ # This wiki
|
|
├── lists/ # Wordlists and data files
|
|
└── README.md # Product overview
|
|
```
|
|
|
|
---
|
|
|
|
## Required Module Signature
|
|
|
|
Every module **must** export:
|
|
|
|
```rust
|
|
use anyhow::Result;
|
|
|
|
pub async fn run(target: &str) -> Result<()> {
|
|
// ...
|
|
Ok(())
|
|
}
|
|
```
|
|
|
|
Optional: also expose `pub async fn run_interactive(target: &str) -> Result<()>` for modules with multiple code paths.
|
|
|
|
---
|
|
|
|
## Adding a New Module — Checklist
|
|
|
|
1. **Choose a location** under `src/modules/{exploits,scanners,creds}`.
|
|
Use subfolders for vendor families (e.g., `exploits/cisco/`).
|
|
2. **Create the `.rs` file** with the required `pub async fn run` signature.
|
|
3. **Register in `mod.rs`** — add `pub mod your_module;` to the sibling `mod.rs`.
|
|
Without this, `build.rs` ignores the file.
|
|
4. **Run `cargo check`** — the dispatcher is regenerated automatically.
|
|
|
|
---
|
|
|
|
## Module Skeleton
|
|
|
|
```rust
|
|
use anyhow::{Context, Result};
|
|
use colored::Colorize;
|
|
use crate::utils::normalize_target;
|
|
|
|
pub async fn run(target: &str) -> Result<()> {
|
|
let target = normalize_target(target)?;
|
|
println!("{} Checking {}", "[*]".cyan(), target);
|
|
|
|
let url = format!("http://{}/status", target);
|
|
let body = reqwest::get(&url)
|
|
.await
|
|
.with_context(|| format!("Failed to reach {}", url))?
|
|
.text()
|
|
.await
|
|
.context("Failed to read response body")?;
|
|
|
|
if body.contains("vulnerable") {
|
|
println!("{} {} appears vulnerable", "[+]".green(), target);
|
|
} else {
|
|
println!("{} {} not vulnerable", "[-]".red(), target);
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Output Conventions
|
|
|
|
| Prefix | Color | Meaning |
|
|
|--------|-------|---------|
|
|
| `[+]` | Green | Success / found |
|
|
| `[-]` | Red | Not found / not vulnerable |
|
|
| `[!]` | Yellow | Warning |
|
|
| `[*]` | Cyan | Info / progress |
|
|
|
|
Use `.green()`, `.red()`, `.yellow()`, `.cyan()` from the `colored` crate. Keep messages short and actionable.
|
|
|
|
---
|
|
|
|
## Async I/O Guidelines
|
|
|
|
- Prefer `reqwest`, `tokio::net`, `tokio::process` for async work.
|
|
- Wrap synchronous blocking calls with `tokio::task::spawn_blocking` (see the SSH module for reference).
|
|
- For concurrency:
|
|
- `tokio::sync::Semaphore` (wrapped in `Arc`) for async modules.
|
|
- `threadpool` + `crossbeam-channel` for synchronous protocols (Telnet, POP3).
|
|
|
|
---
|
|
|
|
## Error Handling
|
|
|
|
Bubble up errors using `anyhow::Context` so the shell/CLI surface meaningful messages:
|
|
|
|
```rust
|
|
.with_context(|| format!("Failed to connect to {}", target))?
|
|
```
|
|
|
|
Avoid `unwrap()` and `unwrap_or_default()` in critical paths.
|
|
|
|
---
|
|
|
|
## Wordlists & Resources
|
|
|
|
Store under `lists/` and document them in `lists/readme.md`. Reference paths relative to the working directory.
|
|
|
|
---
|
|
|
|
## 0.0.0.0/0 Internet-Wide Scanning
|
|
|
|
Modules supporting mass-scan accept `0.0.0.0`, `0.0.0.0/0`, or `random` as targets. When detected, the module enters an infinite loop generating random public IPs using:
|
|
|
|
```rust
|
|
fn generate_random_public_ip() -> Ipv4Addr { ... }
|
|
fn is_excluded_ip(ip: Ipv4Addr) -> bool { ... }
|
|
```
|
|
|
|
The `EXCLUDED_RANGES` constant covers bogons, private, reserved, documentation CIDRs, and public DNS servers. Copy this pattern from an existing mass-scan module (e.g., `telnet_hose` or `hikvision_rce`).
|
|
|
|
Honeypot detection is disabled in mass-scan mode to avoid interactive prompts.
|