From 8efa812baef344c1fb244eee896c654c6d05f56d Mon Sep 17 00:00:00 2001 From: AntwortEinesLebens Date: Sat, 19 Oct 2024 15:33:58 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20=E2=9C=A8=20Remove=20traces=20that=20ar?= =?UTF-8?q?e=20too=20specific?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/actions.rs | 21 +------ src/actions/ads.rs | 29 --------- src/actions/ads/create.rs | 85 -------------------------- src/actions/files.rs | 29 --------- src/actions/files/create.rs | 112 ---------------------------------- src/actions/mutexes.rs | 29 --------- src/actions/mutexes/create.rs | 57 ----------------- src/actions/pipes.rs | 29 --------- src/actions/pipes/create.rs | 69 --------------------- 9 files changed, 2 insertions(+), 458 deletions(-) delete mode 100644 src/actions/ads.rs delete mode 100644 src/actions/ads/create.rs delete mode 100644 src/actions/files.rs delete mode 100644 src/actions/files/create.rs delete mode 100644 src/actions/mutexes.rs delete mode 100644 src/actions/mutexes/create.rs delete mode 100644 src/actions/pipes.rs delete mode 100644 src/actions/pipes/create.rs diff --git a/src/actions.rs b/src/actions.rs index 0e7f704..0f613c2 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -2,18 +2,11 @@ // // SPDX-License-Identifier: GPL-3.0-or-later -use crate::actions::{ - ads::AlternateDataStreams, drivers::Drivers, files::Files, mutexes::Mutexes, pipes::Pipes, - processes::Processes, -}; +use crate::actions::{drivers::Drivers, processes::Processes}; use clap::{Args, Subcommand}; use std::error::Error; -pub mod ads; pub mod drivers; -pub mod files; -pub mod mutexes; -pub mod pipes; pub mod processes; #[derive(Debug, Args)] @@ -24,11 +17,7 @@ pub struct Actions { #[derive(Debug, Subcommand)] pub enum Commands { - AlternateDataStreams(AlternateDataStreams), Drivers(Drivers), - Files(Files), - Mutexes(Mutexes), - Pipes(Pipes), Processes(Processes), } @@ -39,13 +28,7 @@ pub trait Runnable { impl Runnable for Actions { fn run(&self) -> Result<(), Box> { match &self.command { - Commands::AlternateDataStreams(alternate_data_streams) => { - alternate_data_streams as &dyn Runnable - } - Commands::Drivers(drivers) => drivers, - Commands::Files(files) => files, - Commands::Mutexes(mutexes) => mutexes, - Commands::Pipes(pipes) => pipes, + Commands::Drivers(drivers) => drivers as &dyn Runnable, Commands::Processes(processes) => processes, } .run() diff --git a/src/actions/ads.rs b/src/actions/ads.rs deleted file mode 100644 index 57bd700..0000000 --- a/src/actions/ads.rs +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The WAG development team -// -// SPDX-License-Identifier: GPL-3.0-or-later - -use crate::actions::{ads::create::Create, Runnable}; -use clap::{Args, Subcommand}; -use std::error::Error; - -pub mod create; - -#[derive(Debug, Args)] -pub struct AlternateDataStreams { - #[clap(subcommand)] - pub command: Commands, -} - -#[derive(Debug, Subcommand)] -pub enum Commands { - Create(Create), -} - -impl Runnable for AlternateDataStreams { - fn run(&self) -> Result<(), Box> { - match &self.command { - Commands::Create(create) => create as &dyn Runnable, - } - .run() - } -} diff --git a/src/actions/ads/create.rs b/src/actions/ads/create.rs deleted file mode 100644 index 072ca1f..0000000 --- a/src/actions/ads/create.rs +++ /dev/null @@ -1,85 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The WAG development team -// -// SPDX-License-Identifier: GPL-3.0-or-later - -// Alternate Data Stream -// -// Last update 20240224 - -use crate::actions::Runnable; -use base64::engine::{general_purpose, Engine}; -use clap::Parser; -use regex_generate::{Generator, DEFAULT_MAX_REPEAT}; -use std::{error::Error, path::Path}; - -#[derive(Debug, Parser)] -pub struct Create { - #[clap( - short = 'f', - long, - required = true, - help = "Full path filename (regex)" - )] - filename: String, - #[clap(short = 'a', long, required = true, help = "ADS to use")] - ads: String, - #[clap( - short = 'd', - long, - required = false, - default_value = "V2VsY29tZSB0byB0aGUgV0FH", - help = "Data to write in base64" - )] - data: String, -} - -fn create_ads(fullpath: String, adsname: String, hex_data: Vec) -> bool { - let file_base: &Path = Path::new(&fullpath); - if !file_base.exists() { - println!("Missing base file for ADS, try to create it"); - let folder: &Path = file_base.parent().unwrap(); - - let ret_folder: Result<(), std::io::Error> = std::fs::create_dir_all(folder); - match ret_folder { - Ok(_) => println!("The folder is valid"), - Err(_) => return false, - } - let ret_file: Result<(), std::io::Error> = std::fs::write( - file_base, - vec![ - 87, 105, 110, 100, 111, 119, 115, 32, 65, 114, 116, 101, 102, 97, 99, 116, 32, 71, - 101, 110, 101, 114, 97, 116, 111, 114, - ], - ); - match ret_file { - Ok(_) => println!("The base file is created"), - Err(_) => return false, - } - } - let full_ads_name: String = format!("{}:{}", fullpath, adsname); - let file_ads: &Path = Path::new(&full_ads_name); - let ret_file: Result<(), std::io::Error> = std::fs::write(file_ads, hex_data); - ret_file.is_ok() -} - -impl Runnable for Create { - /* Version 20230908 */ - fn run(&self) -> Result<(), Box> { - println!("Alternate Data Stream"); - - if !self.filename.is_empty() { - let mut generator: Generator = - Generator::new(&self.filename, rand::thread_rng(), DEFAULT_MAX_REPEAT)?; - let mut buffer: Vec = vec![]; - generator.generate(&mut buffer).unwrap(); - let fullname: String = String::from_utf8(buffer)?; - let barrow_ads: String = self.ads.to_string(); - let payload: Vec = general_purpose::STANDARD.decode(self.data.as_str())?; - let ret_ads: bool = create_ads(fullname, barrow_ads, payload); - - return Ok(()); - } - - Ok(()) - } -} diff --git a/src/actions/files.rs b/src/actions/files.rs deleted file mode 100644 index b908c7a..0000000 --- a/src/actions/files.rs +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The WAG development team -// -// SPDX-License-Identifier: GPL-3.0-or-later - -use crate::actions::{files::create::Create, Runnable}; -use clap::{Args, Subcommand}; -use std::error::Error; - -pub mod create; - -#[derive(Debug, Args)] -pub struct Files { - #[clap(subcommand)] - pub command: Commands, -} - -#[derive(Debug, Subcommand)] -pub enum Commands { - Create(Create), -} - -impl Runnable for Files { - fn run(&self) -> Result<(), Box> { - match &self.command { - Commands::Create(create) => create as &dyn Runnable, - } - .run() - } -} diff --git a/src/actions/files/create.rs b/src/actions/files/create.rs deleted file mode 100644 index bc1f903..0000000 --- a/src/actions/files/create.rs +++ /dev/null @@ -1,112 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The WAG development team -// -// SPDX-License-Identifier: GPL-3.0-or-later - -/* - File creation Artefact - -the magic bytes and NTFS ADS are store a string HEX value. -like 504B0304 or 4D5A. - -Path are regex in json so need `\\.` to get a `.`. - -if fullpath is empty , it build the path from -env variable and the cmd_path. -"SystemRoot" "Temp\\debug\\.bin" will give "c:\Windows\Temp\debug.bin" - -You can use `SET | more` or `Get-ChildItem Env:` to get the list - -*/ - -use crate::{actions::Runnable, windows::users::is_administrator}; -use base64::engine::{general_purpose, Engine}; -use clap::Parser; -use regex_generate::{Generator, DEFAULT_MAX_REPEAT}; -use std::{ - error::Error, - io::Result as IOResult, - path::Path, - thread, - time::{self, Duration}, -}; - -#[derive(Debug, Parser)] -pub struct Create { - #[clap( - short = 'f', - long, - required = true, - help = "Full path filename (regex)" - )] - filename: String, - #[clap( - short = 'm', - long, - required = false, - default_value = "V2VsY29tZSB0byB0aGUgV0FH", - help = "MagicBytes name to use with module manual in base64" - )] - magicbyte: String, - #[clap( - short = 'a', - long, - required = false, - default_value_t = false, - help = "Need to be admin" - )] - admin: bool, -} - -fn create_file(fullpath: String, hex_data: Vec) -> bool { - println!("Try to create : {}", fullpath); - let file_path: &Path = Path::new(&fullpath); - if !file_path.exists() { - let folder: &Path = file_path.parent().unwrap(); - - let ret_folder: IOResult<()> = std::fs::create_dir_all(folder); - match ret_folder { - Ok(_) => println!("The folder is valid"), - Err(_) => return false, - } - - let ret_file: IOResult<()> = std::fs::write(file_path, hex_data); - match ret_file { - Ok(_) => println!("The file is created"), - Err(_) => return false, - } - - let sleep_duration: Duration = time::Duration::from_millis(2000); - thread::sleep(sleep_duration); - - let ret_remove: IOResult<()> = std::fs::remove_file(file_path); - match ret_remove { - Ok(_) => println!("The file is removed"), - Err(_) => return false, - } - - return true; - } - false -} - -impl Runnable for Create { - fn run(&self) -> Result<(), Box> { - if self.admin && !is_administrator()? { - println!("Need to have Administrator right to create the file"); - return Ok(()); - } - - let mut generator: Generator = - Generator::new(&self.filename, rand::thread_rng(), DEFAULT_MAX_REPEAT)?; - let mut buffer: Vec = vec![]; - generator.generate(&mut buffer).unwrap(); - let fullname: String = String::from_utf8(buffer)?; - - println!("Create a file on disk"); - - let payload: Vec = general_purpose::STANDARD.decode(self.magicbyte.as_str())?; - let ret: bool = create_file(fullname, payload); - - Ok(()) - } -} diff --git a/src/actions/mutexes.rs b/src/actions/mutexes.rs deleted file mode 100644 index e51e2ba..0000000 --- a/src/actions/mutexes.rs +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The WAG development team -// -// SPDX-License-Identifier: GPL-3.0-or-later - -use crate::actions::{mutexes::create::Create, Runnable}; -use clap::{Args, Subcommand}; -use std::error::Error; - -pub mod create; - -#[derive(Debug, Args)] -pub struct Mutexes { - #[clap(subcommand)] - pub command: Commands, -} - -#[derive(Debug, Subcommand)] -pub enum Commands { - Create(Create), -} - -impl Runnable for Mutexes { - fn run(&self) -> Result<(), Box> { - match &self.command { - Commands::Create(create) => create as &dyn Runnable, - } - .run() - } -} diff --git a/src/actions/mutexes/create.rs b/src/actions/mutexes/create.rs deleted file mode 100644 index 986b1af..0000000 --- a/src/actions/mutexes/create.rs +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The WAG development team -// -// SPDX-License-Identifier: GPL-3.0-or-later - -// Mutex -// -// Last update 20240224 - -use crate::actions::Runnable; -use clap::Parser; -use regex_generate::{Generator, DEFAULT_MAX_REPEAT}; -use std::{error::Error, thread, time}; -use windows::{ - core::{Result as WindowsResult, PCSTR}, - Win32::{ - Foundation::{CloseHandle, HANDLE}, - System::Threading::CreateMutexA, - }, -}; - -#[derive(Debug, Parser)] -pub struct Create { - #[clap( - short = 'n', - long, - required = true, - help = "Regex of the Mutex to Create" - )] - name: String, -} - -fn create_mutex(name: &String, wait: u64) { - let full_malware_mutex: String = format!("{}\0", name); - let mutex_name: PCSTR = PCSTR::from_raw(full_malware_mutex.as_ptr()); - let mutex_handle: WindowsResult = unsafe { CreateMutexA(None, true, mutex_name) }; - let sleep_duration: time::Duration = time::Duration::from_millis(wait); - thread::sleep(sleep_duration); - let _res_server_pipe: WindowsResult<()> = unsafe { CloseHandle(mutex_handle.unwrap()) }; -} - -impl Runnable for Create { - fn run(&self) -> Result<(), Box> { - println!("Create Mutex"); - - let mut generator: Generator = - Generator::new(&self.name, rand::thread_rng(), DEFAULT_MAX_REPEAT)?; - let mut buffer: Vec = vec![]; - generator.generate(&mut buffer).unwrap(); - let payload: String = String::from_utf8(buffer)?; - - println!("Create the Mutex : {}", payload); - - create_mutex(&payload, 2000); - - Ok(()) - } -} diff --git a/src/actions/pipes.rs b/src/actions/pipes.rs deleted file mode 100644 index 061b810..0000000 --- a/src/actions/pipes.rs +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The WAG development team -// -// SPDX-License-Identifier: GPL-3.0-or-later - -use crate::actions::{pipes::create::Create, Runnable}; -use clap::{Args, Subcommand}; -use std::error::Error; - -pub mod create; - -#[derive(Debug, Args)] -pub struct Pipes { - #[clap(subcommand)] - pub command: Commands, -} - -#[derive(Debug, Subcommand)] -pub enum Commands { - Create(Create), -} - -impl Runnable for Pipes { - fn run(&self) -> Result<(), Box> { - match &self.command { - Commands::Create(create) => create as &dyn Runnable, - } - .run() - } -} diff --git a/src/actions/pipes/create.rs b/src/actions/pipes/create.rs deleted file mode 100644 index e42ab4c..0000000 --- a/src/actions/pipes/create.rs +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The WAG development team -// -// SPDX-License-Identifier: GPL-3.0-or-later - -// Name Pipe -// -// Last update 20240224 - -use crate::actions::Runnable; -use clap::Parser; -use regex_generate::{Generator, DEFAULT_MAX_REPEAT}; -use std::{error::Error, thread, time}; -use windows::{ - core::{Result as WindowsResult, PCSTR}, - Win32::{ - Foundation::{CloseHandle, HANDLE}, - Storage::FileSystem::PIPE_ACCESS_DUPLEX, - System::Pipes::{CreateNamedPipeA, PIPE_TYPE_MESSAGE}, - }, -}; - -#[derive(Debug, Parser)] -pub struct Create { - #[clap( - short = 'n', - long, - required = true, - help = "Regex of the PipeName to Create" - )] - name: String, -} - -fn create_name_pipe(name: &String, wait: u64) { - let full_malware_pipe: String = format!("\\\\.\\pipe\\{}\0", name); - let pipe_name: PCSTR = PCSTR::from_raw(full_malware_pipe.as_ptr()); - let server_pipe: WindowsResult = unsafe { - CreateNamedPipeA( - pipe_name, - PIPE_ACCESS_DUPLEX, - PIPE_TYPE_MESSAGE, - 1, - 2048, - 2048, - 0, - None, - ) - }; - let sleep_duration: time::Duration = time::Duration::from_millis(wait); - thread::sleep(sleep_duration); - let _res_server_pipe: WindowsResult<()> = unsafe { CloseHandle(server_pipe.unwrap()) }; -} - -impl Runnable for Create { - fn run(&self) -> Result<(), Box> { - println!("Create NamePipe"); - - let mut generator: Generator = - Generator::new(&self.name, rand::thread_rng(), DEFAULT_MAX_REPEAT)?; - let mut buffer: Vec = vec![]; - generator.generate(&mut buffer).unwrap(); - let payload: String = String::from_utf8(buffer)?; - - println!("Create the namepipe : {}", payload); - - create_name_pipe(&payload, 2000); - - Ok(()) - } -}