clawscan 1.0.0

OpenClaw/Moltbot/Clawdbot vulnerability scanner for prompt injection, supply chain, and RAG poisoning attacks
Documentation
//! ClawScan CLI - High-Performance OpenClaw Vulnerability Scanner

use clap::Parser;
use clawscan::parse_target;
use colored::Colorize;

#[derive(Parser)]
#[command(name = "clawscan")]
#[command(about = "OpenClaw/Moltbot/Clawdbot Vulnerability Scanner", long_about = None)]
struct Cli {
    /// Target(s) to scan (domain, IP, or ws:// URL)
    targets: Vec<String>,

    /// Number of concurrent scans
    #[arg(short, long, default_value = "50")]
    concurrency: usize,

    /// Output JSON report to file
    #[arg(short, long)]
    json: Option<String>,

    /// Quiet mode - only show exploited vulnerabilities
    #[arg(short, long)]
    quiet: bool,
}

#[tokio::main]
async fn main() {
    let cli = Cli::parse();

    println!("{}", "🔍 ClawScan v1.0.0".bright_cyan().bold());
    println!();

    if cli.targets.is_empty() {
        eprintln!("{}", "Error: No targets specified".red());
        std::process::exit(1);
    }

    // Parse targets
    println!("📋 Parsing {} target(s)...", cli.targets.len());
    let mut parsed_targets = Vec::new();

    for target_input in &cli.targets {
        match parse_target(target_input) {
            Ok(target) => {
                println!("  {} {}", "".green(), target.url);
                parsed_targets.push(target);
            }
            Err(e) => {
                eprintln!("  {} {}: {}", "".red(), target_input, e);
            }
        }
    }

    if parsed_targets.is_empty() {
        eprintln!("{}", "Error: No valid targets to scan".red());
        std::process::exit(1);
    }

    println!();
    println!("🎯 Scanning {} target(s) with concurrency: {}",
        parsed_targets.len(), cli.concurrency);
    println!();

    // Show attack modules
    println!("{}", "Attack Modules (9/9 Complete):".bright_yellow());
    println!("  {} CVE-2026-25253: WebSocket CSWSH {}",
        "".bright_red(), "[CRITICAL]".red());
    println!("  {} CVE-2026-22708: Indirect Injection {}",
        "".bright_magenta(), "[HIGH]".yellow());
    println!("  {} CVE-2026-25157: Command Injection {}",
        "".bright_red(), "[CRITICAL]".red());
    println!("  {} Prompt Injection (24 techniques) {}",
        "".bright_magenta(), "[HIGH]".yellow());
    println!("  {} RAG/Memory Poisoning {}",
        "".bright_magenta(), "[HIGH]".yellow());
    println!("  {} Supply Chain (ClawHavoc) {}",
        "".bright_red(), "[CRITICAL]".red());
    println!("  {} MCP Tool Poisoning {}",
        "".bright_magenta(), "[HIGH]".yellow());
    println!("  {} Elevated Mode Bypass {}",
        "".bright_magenta(), "[HIGH]".yellow());
    println!("  {} Zero-Click RCE Chain {}",
        "".bright_red(), "[CRITICAL]".red());
    println!();

    // Execute scan
    use clawscan::{scan_targets, ScanConfig, generate_report, format_terminal_report, save_json_report};

    let config = ScanConfig {
        concurrency: cli.concurrency,
    };

    println!("{}", "⏳ Running vulnerability scan...".bright_cyan());

    match scan_targets(parsed_targets, config).await {
        Ok(results) => {
            // Generate report
            let report = generate_report(results);

            // Save JSON if requested
            if let Some(json_path) = &cli.json {
                match save_json_report(&report, json_path) {
                    Ok(_) => println!("{} Report saved to: {}", "".green(), json_path),
                    Err(e) => eprintln!("{} Failed to save JSON report: {}", "".red(), e),
                }
            }

            // Display report (unless quiet mode and no exploits)
            if !cli.quiet || report.summary.exploited > 0 {
                println!("{}", format_terminal_report(&report));
            }
        }
        Err(e) => {
            eprintln!("{} Scan failed: {}", "".red(), e);
            std::process::exit(1);
        }
    }
}