mirror of
https://github.com/s-b-repo/rustsploit
synced 2026-06-27 09:54:12 +00:00
Delete src/commands directory
This commit is contained in:
@@ -1,7 +0,0 @@
|
||||
use anyhow::Result;
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/creds_dispatch.rs"));
|
||||
|
||||
pub async fn run_cred_check(module_name: &str, target: &str) -> Result<()> {
|
||||
dispatch(module_name, target).await
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
use std::collections::HashSet;
|
||||
use std::env;
|
||||
use std::fs::{self, File};
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
fn main() {
|
||||
let out_dir = env::var("OUT_DIR").unwrap();
|
||||
// Keep dispatch file naming consistent with build.rs
|
||||
let dest_path = Path::new(&out_dir).join("creds_dispatch.rs");
|
||||
let mut file = File::create(&dest_path).unwrap();
|
||||
|
||||
let creds_root = Path::new("src/modules/creds");
|
||||
|
||||
let mut mappings: HashSet<(String, String)> = HashSet::new();
|
||||
|
||||
// Traverse all .rs files (excluding mod.rs)
|
||||
visit_all_rs(creds_root, "".to_string(), &mut mappings).unwrap();
|
||||
|
||||
// Generate dispatch function
|
||||
writeln!(
|
||||
file,
|
||||
"pub async fn dispatch(module_name: &str, target: &str) -> anyhow::Result<()> {{\n match module_name {{"
|
||||
).unwrap();
|
||||
|
||||
for (key, mod_path) in &mappings {
|
||||
let short_key = key.rsplit('/').next().unwrap_or(&key);
|
||||
let mod_code_path = mod_path.replace("/", "::");
|
||||
|
||||
writeln!(
|
||||
file,
|
||||
r#" "{short}" | "{full}" => {{ crate::modules::creds::{path}::run(target).await? }},"#,
|
||||
short = short_key,
|
||||
full = key,
|
||||
path = mod_code_path
|
||||
).unwrap();
|
||||
}
|
||||
|
||||
writeln!(
|
||||
file,
|
||||
r#" _ => anyhow::bail!("Cred module '{{}}' not found.", module_name),"#
|
||||
).unwrap();
|
||||
|
||||
writeln!(file, " }}\n Ok(())\n}}").unwrap();
|
||||
}
|
||||
|
||||
/// Recursively scan `src/modules/creds/` and find all `.rs` files (excluding `mod.rs`)
|
||||
fn visit_all_rs(dir: &Path, prefix: String, mappings: &mut HashSet<(String, String)>) -> std::io::Result<()> {
|
||||
if dir.is_dir() {
|
||||
for entry in fs::read_dir(dir)? {
|
||||
let entry = entry?;
|
||||
let path = entry.path();
|
||||
let file_name = entry.file_name().to_string_lossy().into_owned();
|
||||
|
||||
if path.is_dir() {
|
||||
let sub_prefix = if prefix.is_empty() {
|
||||
file_name.clone()
|
||||
} else {
|
||||
format!("{}/{}", prefix, file_name)
|
||||
};
|
||||
visit_all_rs(&path, sub_prefix, mappings)?;
|
||||
} else if path.extension().map_or(false, |e| e == "rs") {
|
||||
if file_name == "mod.rs" {
|
||||
continue;
|
||||
}
|
||||
|
||||
let file_stem = path.file_stem().unwrap().to_string_lossy();
|
||||
let mod_path = if prefix.is_empty() {
|
||||
file_stem.to_string()
|
||||
} else {
|
||||
format!("{}/{}", prefix, file_stem)
|
||||
};
|
||||
|
||||
if mappings.insert((mod_path.clone(), mod_path.clone())) {
|
||||
println!("✅ Found cred module: {}", mod_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
use anyhow::Result;
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/exploit_dispatch.rs"));
|
||||
|
||||
pub async fn run_exploit(module_name: &str, target: &str) -> Result<()> {
|
||||
dispatch(module_name, target).await
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
use std::collections::HashSet;
|
||||
use std::env;
|
||||
use std::fs::{self, File};
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
fn main() {
|
||||
let out_dir = env::var("OUT_DIR").unwrap();
|
||||
let dest_path = Path::new(&out_dir).join("exploit_dispatch.rs");
|
||||
let mut file = File::create(&dest_path).unwrap();
|
||||
|
||||
let exploits_root = Path::new("src/modules/exploits");
|
||||
|
||||
let mut mappings: HashSet<(String, String)> = HashSet::new();
|
||||
|
||||
// Traverse all .rs files (excluding mod.rs)
|
||||
visit_all_rs(exploits_root, "".to_string(), &mut mappings).unwrap();
|
||||
|
||||
// Start generating dispatch code
|
||||
writeln!(
|
||||
file,
|
||||
"pub async fn dispatch(module_name: &str, target: &str) -> anyhow::Result<()> {{\n match module_name {{"
|
||||
).unwrap();
|
||||
|
||||
for (key, mod_path) in &mappings {
|
||||
let short_key = key.rsplit('/').next().unwrap_or(&key);
|
||||
let mod_code_path = mod_path.replace("/", "::");
|
||||
|
||||
writeln!(
|
||||
file,
|
||||
r#" "{short}" | "{full}" => {{ crate::modules::exploits::{path}::run(target).await? }},"#,
|
||||
short = short_key,
|
||||
full = key,
|
||||
path = mod_code_path
|
||||
).unwrap();
|
||||
}
|
||||
|
||||
writeln!(
|
||||
file,
|
||||
r#" _ => anyhow::bail!("Exploit module '{{}}' not found.", module_name),"#
|
||||
).unwrap();
|
||||
|
||||
writeln!(file, " }}\n Ok(())\n}}").unwrap();
|
||||
}
|
||||
|
||||
/// Recursively walk through directories, find all .rs files excluding mod.rs
|
||||
fn visit_all_rs(dir: &Path, prefix: String, mappings: &mut HashSet<(String, String)>) -> std::io::Result<()> {
|
||||
if dir.is_dir() {
|
||||
for entry in fs::read_dir(dir)? {
|
||||
let entry = entry?;
|
||||
let path = entry.path();
|
||||
let file_name = entry.file_name().to_string_lossy().into_owned();
|
||||
|
||||
if path.is_dir() {
|
||||
let sub_prefix = if prefix.is_empty() {
|
||||
file_name.clone()
|
||||
} else {
|
||||
format!("{}/{}", prefix, file_name)
|
||||
};
|
||||
visit_all_rs(&path, sub_prefix, mappings)?;
|
||||
} else if path.extension().map_or(false, |e| e == "rs") {
|
||||
if file_name == "mod.rs" {
|
||||
continue;
|
||||
}
|
||||
|
||||
let file_stem = path.file_stem().unwrap().to_string_lossy();
|
||||
let mod_path = if prefix.is_empty() {
|
||||
file_stem.to_string()
|
||||
} else {
|
||||
format!("{}/{}", prefix, file_stem)
|
||||
};
|
||||
|
||||
// Add to mappings if not already added
|
||||
if mappings.insert((mod_path.clone(), mod_path.clone())) {
|
||||
println!("✅ Found exploit: {}", mod_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
pub mod exploit;
|
||||
pub mod scanner;
|
||||
pub mod creds;
|
||||
|
||||
use anyhow::Result;
|
||||
use crate::cli::Cli;
|
||||
use crate::config;
|
||||
use walkdir::WalkDir;
|
||||
use crate::utils::normalize_target;
|
||||
|
||||
/// CLI dispatcher: e.g. --command scanner --target "::1" --module scanners/port_scanner
|
||||
pub async fn handle_command(command: &str, cli_args: &Cli) -> Result<()> {
|
||||
// Use CLI target if provided, otherwise try global target
|
||||
let raw = if let Some(ref t) = cli_args.target {
|
||||
t.clone()
|
||||
} else if config::GLOBAL_CONFIG.has_target() {
|
||||
// Use single IP from global target (handles subnets intelligently)
|
||||
match config::GLOBAL_CONFIG.get_single_target_ip() {
|
||||
Ok(ip) => {
|
||||
println!("[*] Using global target: {}", config::GLOBAL_CONFIG.get_target().unwrap_or_default());
|
||||
ip
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(anyhow::anyhow!("No target specified and global target error: {}", e));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Err(anyhow::anyhow!("No target specified. Use --target <ip> or --set-target <ip/subnet>"));
|
||||
};
|
||||
|
||||
let target = normalize_target(&raw)?; // IPv6 wrap only, no port
|
||||
let module = cli_args.module.clone().unwrap_or_default();
|
||||
|
||||
match command {
|
||||
"exploit" => {
|
||||
let trimmed = module.trim_start_matches("exploits/");
|
||||
exploit::run_exploit(trimmed, &target).await?;
|
||||
},
|
||||
"scanner" => {
|
||||
let trimmed = module.trim_start_matches("scanners/");
|
||||
scanner::run_scan(trimmed, &target).await?;
|
||||
},
|
||||
"creds" => {
|
||||
let trimmed = module.trim_start_matches("creds/");
|
||||
creds::run_cred_check(trimmed, &target).await?;
|
||||
},
|
||||
_ => {
|
||||
eprintln!("Unknown command '{}'", command);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Interactive shell: handles `run` with raw target string
|
||||
/// If raw_target is empty, uses global target if available
|
||||
pub async fn run_module(module_path: &str, raw_target: &str) -> Result<()> {
|
||||
let available = discover_modules();
|
||||
|
||||
let full_match = available.iter().find(|m| m == &module_path);
|
||||
let short_match = available.iter().find(|m| {
|
||||
m.rsplit_once('/')
|
||||
.map(|(_, short)| short == module_path)
|
||||
.unwrap_or(false)
|
||||
});
|
||||
|
||||
let resolved = if let Some(m) = full_match {
|
||||
m
|
||||
} else if let Some(m) = short_match {
|
||||
m
|
||||
} else {
|
||||
eprintln!("❌ Unknown module '{}'. Available modules:", module_path);
|
||||
for m in available {
|
||||
println!(" {}", m);
|
||||
}
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
// Use provided target, or fall back to global target
|
||||
let target_str = if raw_target.is_empty() {
|
||||
if config::GLOBAL_CONFIG.has_target() {
|
||||
match config::GLOBAL_CONFIG.get_single_target_ip() {
|
||||
Ok(ip) => {
|
||||
println!("[*] Using global target: {}", config::GLOBAL_CONFIG.get_target().unwrap_or_default());
|
||||
ip
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(anyhow::anyhow!("No target specified and global target error: {}", e));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Err(anyhow::anyhow!("No target specified. Use 'set target <ip/subnet>' or provide target when running module"));
|
||||
}
|
||||
} else {
|
||||
raw_target.to_string()
|
||||
};
|
||||
|
||||
let target = normalize_target(&target_str)?;
|
||||
|
||||
let mut parts = resolved.splitn(2, '/');
|
||||
let category = parts.next().unwrap_or("");
|
||||
let module_name = parts.next().unwrap_or("");
|
||||
|
||||
match category {
|
||||
"exploits" => exploit::run_exploit(module_name, &target).await?,
|
||||
"scanners" => scanner::run_scan(module_name, &target).await?,
|
||||
"creds" => creds::run_cred_check(module_name, &target).await?,
|
||||
_ => eprintln!("❌ Category '{}' is not supported.", category),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Finds all .rs module paths inside `src/modules/**`, excluding mod.rs
|
||||
pub fn discover_modules() -> Vec<String> {
|
||||
let mut modules = Vec::new();
|
||||
let categories = ["exploits", "scanners", "creds"];
|
||||
|
||||
for category in &categories {
|
||||
let base = format!("src/modules/{}", category);
|
||||
for entry in WalkDir::new(&base).max_depth(6).into_iter().filter_map(|e| e.ok()) {
|
||||
let p = entry.path();
|
||||
if p.is_file()
|
||||
&& p.extension().map_or(false, |e| e == "rs")
|
||||
&& p.file_name().map_or(true, |n| n != "mod.rs")
|
||||
{
|
||||
if let Ok(rel) = p.strip_prefix("src/modules") {
|
||||
let module_path = rel
|
||||
.with_extension("")
|
||||
.to_string_lossy()
|
||||
.replace("\\", "/");
|
||||
modules.push(module_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
modules
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
use anyhow::Result;
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/scanner_dispatch.rs"));
|
||||
|
||||
pub async fn run_scan(module_name: &str, target: &str) -> Result<()> {
|
||||
dispatch(module_name, target).await
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
use std::collections::HashSet;
|
||||
use std::env;
|
||||
use std::fs::{self, File};
|
||||
use std::io::{Write};
|
||||
use std::path::Path;
|
||||
|
||||
fn main() {
|
||||
let out_dir = env::var("OUT_DIR").unwrap();
|
||||
let dest_path = Path::new(&out_dir).join("scanner_dispatch.rs");
|
||||
let mut file = File::create(&dest_path).unwrap();
|
||||
|
||||
let scanners_root = Path::new("src/modules/scanners");
|
||||
|
||||
let mut mappings: HashSet<(String, String)> = HashSet::new();
|
||||
|
||||
// Traverse all .rs files (excluding mod.rs)
|
||||
visit_all_rs(scanners_root, "".to_string(), &mut mappings).unwrap();
|
||||
|
||||
// Start generating dispatch code
|
||||
writeln!(
|
||||
file,
|
||||
"pub async fn dispatch(module_name: &str, target: &str) -> anyhow::Result<()> {{\n match module_name {{"
|
||||
).unwrap();
|
||||
|
||||
for (key, mod_path) in &mappings {
|
||||
let short_key = key.rsplit('/').next().unwrap_or(&key);
|
||||
let mod_code_path = mod_path.replace("/", "::");
|
||||
|
||||
writeln!(
|
||||
file,
|
||||
r#" "{short}" | "{full}" => {{ crate::modules::scanners::{path}::run(target).await? }},"#,
|
||||
short = short_key,
|
||||
full = key,
|
||||
path = mod_code_path
|
||||
).unwrap();
|
||||
}
|
||||
|
||||
writeln!(
|
||||
file,
|
||||
r#" _ => anyhow::bail!("Scanner module '{{}}' not found.", module_name),"#
|
||||
).unwrap();
|
||||
|
||||
writeln!(file, " }}\n Ok(())\n}}").unwrap();
|
||||
}
|
||||
|
||||
/// Recursively walk through directories, find all .rs files excluding mod.rs
|
||||
fn visit_all_rs(dir: &Path, prefix: String, mappings: &mut HashSet<(String, String)>) -> std::io::Result<()> {
|
||||
if dir.is_dir() {
|
||||
for entry in fs::read_dir(dir)? {
|
||||
let entry = entry?;
|
||||
let path = entry.path();
|
||||
let file_name = entry.file_name().to_string_lossy().into_owned();
|
||||
|
||||
if path.is_dir() {
|
||||
let sub_prefix = if prefix.is_empty() {
|
||||
file_name.clone()
|
||||
} else {
|
||||
format!("{}/{}", prefix, file_name)
|
||||
};
|
||||
visit_all_rs(&path, sub_prefix, mappings)?;
|
||||
} else if path.extension().map_or(false, |e| e == "rs") {
|
||||
if file_name == "mod.rs" {
|
||||
continue;
|
||||
}
|
||||
|
||||
let file_stem = path.file_stem().unwrap().to_string_lossy();
|
||||
let mod_path = if prefix.is_empty() {
|
||||
file_stem.to_string()
|
||||
} else {
|
||||
format!("{}/{}", prefix, file_stem)
|
||||
};
|
||||
|
||||
// Add to mappings if not already added
|
||||
if mappings.insert((mod_path.clone(), mod_path.clone())) {
|
||||
println!("✅ Found scanner: {}", mod_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user