mirror of
https://github.com/Astatin3/unshell.git
synced 2026-06-08 22:38:01 -06:00
Add base62 encoding
This commit is contained in:
Generated
+54
-2
@@ -13,6 +13,15 @@ dependencies = [
|
||||
"cpufeatures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
@@ -153,6 +162,12 @@ version = "0.2.177"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.103"
|
||||
@@ -177,6 +192,35 @@ version = "5.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.12.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.9"
|
||||
@@ -212,7 +256,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
|
||||
|
||||
[[package]]
|
||||
name = "unshell-obfuscate"
|
||||
name = "unshell-crypt"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"aes",
|
||||
@@ -221,10 +265,18 @@ dependencies = [
|
||||
"getrandom",
|
||||
"hex",
|
||||
"hex-literal",
|
||||
"regex",
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unshell-obfuscate"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"sha2",
|
||||
"syn",
|
||||
"unshell-crypt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
[package]
|
||||
name = "unshell-obfuscate"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[lib]
|
||||
@@ -11,13 +10,8 @@ proc-macro = true
|
||||
obfuscate = []
|
||||
|
||||
[dependencies]
|
||||
aes = "0.8.4"
|
||||
block-padding = "0.4.1"
|
||||
cbc = "0.1.2"
|
||||
getrandom = "0.3.4"
|
||||
hex = "0.4.3"
|
||||
hex-literal = "1.1.0"
|
||||
quote = "1.0.42"
|
||||
sha2 = "0.10.9"
|
||||
syn = {version = "2.0.109", features = ["full"]}
|
||||
proc-macro2 = "1.0.103"
|
||||
|
||||
unshell-crypt = {path = "../unshell-crypt"}
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
// --- Add these imports to the top of src/lib.rs ---
|
||||
use aes::{
|
||||
Aes256,
|
||||
cipher::{BlockEncryptMut, KeyIvInit},
|
||||
};
|
||||
use cbc::Encryptor;
|
||||
use cbc::cipher::block_padding::Pkcs7;
|
||||
use hex;
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
use crate::{BACKUP_ENV_KEY, ENV_KEY_NAME};
|
||||
|
||||
// type Aes256CbcEncryptor = ;
|
||||
|
||||
// A static, hardcoded IV. This is fine for obfuscation,
|
||||
// as we're not protecting against replay attacks, just static analysis.
|
||||
// This is the hex for "my_static_iv_012".
|
||||
const STATIC_IV: [u8; 16] = [
|
||||
0x6d, 0x79, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x69, 0x76, 0x5f, 0x30, 0x31, 0x32,
|
||||
];
|
||||
|
||||
fn pkcs7_padded_length(input_len: usize) -> usize {
|
||||
let block_size = 16;
|
||||
((input_len / block_size) + 1) * block_size
|
||||
}
|
||||
|
||||
pub fn get_obfuscated_symbol_name(input: &str) -> String {
|
||||
// 1. Get the key from the environment
|
||||
// let key_str =
|
||||
// std::env::var(ENV_KEY_NAME).expect(&format!("'{}' env var not set", ENV_KEY_NAME));
|
||||
|
||||
let key_str = std::env::var(ENV_KEY_NAME).unwrap_or(BACKUP_ENV_KEY.to_owned());
|
||||
|
||||
// 2. Hash the env key to get a 32-byte (256-bit) AES key
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(key_str.as_bytes());
|
||||
let key: [u8; 32] = hasher.finalize().into();
|
||||
|
||||
// 3. Encrypt the input string
|
||||
let cipher = Encryptor::<Aes256>::new(&key.into(), &STATIC_IV.into());
|
||||
let mut plaintext = input.to_string();
|
||||
let plaintext = unsafe { plaintext.as_bytes_mut() };
|
||||
|
||||
let buf_len = pkcs7_padded_length(plaintext.len());
|
||||
let mut buf: Vec<u8> = vec![0; buf_len];
|
||||
|
||||
buf[..plaintext.len()].copy_from_slice(plaintext);
|
||||
let ciphertext = cipher
|
||||
.encrypt_padded_mut::<Pkcs7>(&mut buf, plaintext.len())
|
||||
.expect("Could not encrypt");
|
||||
|
||||
// 4. Hex-encode the result
|
||||
let hex_encoded = hex::encode(ciphertext);
|
||||
|
||||
hex_encoded
|
||||
|
||||
// 5. Prepend a prefix
|
||||
// format!("obf_{}", hex_encoded)
|
||||
}
|
||||
@@ -3,10 +3,7 @@
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{Expr, ItemFn, LitStr, parse_macro_input};
|
||||
|
||||
#[cfg(feature = "obfuscate")]
|
||||
mod encrypt;
|
||||
use syn::{ItemFn, parse_macro_input};
|
||||
|
||||
mod format_helper;
|
||||
use format_helper::*;
|
||||
@@ -14,11 +11,12 @@ use format_helper::*;
|
||||
// Put all encrypt-related dependencies in a module, so they are easier to use with the feature flag
|
||||
#[cfg(feature = "obfuscate")]
|
||||
mod obs_deps {
|
||||
pub use crate::encrypt::get_obfuscated_symbol_name;
|
||||
pub use syn::LitStr;
|
||||
|
||||
pub const ENV_KEY_NAME: &str = "OBFUSCATION_KEY";
|
||||
pub const BACKUP_ENV_KEY: &str = "OBFUSCATION_KEY_DO_NOT_USE";
|
||||
pub use unshell_crypt::BACKUP_ENV_KEY;
|
||||
pub use unshell_crypt::ENV_KEY_NAME;
|
||||
pub use unshell_crypt::STATIC_IV;
|
||||
pub use unshell_crypt::aes::encrypt_aes_lines;
|
||||
pub use unshell_crypt::fill;
|
||||
}
|
||||
#[cfg(feature = "obfuscate")]
|
||||
use obs_deps::*;
|
||||
@@ -49,13 +47,18 @@ pub fn symbol(input: TokenStream) -> TokenStream {
|
||||
#[cfg(feature = "obfuscate")]
|
||||
pub fn obfuscated_symbol(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
// Parse the input function
|
||||
|
||||
use unshell_crypt::aes::encrypt_aes;
|
||||
let func = parse_macro_input!(item as ItemFn);
|
||||
|
||||
// Get the original function name
|
||||
let fn_name = func.sig.ident.to_string();
|
||||
|
||||
// get the encryption key
|
||||
let key_str = std::env::var(ENV_KEY_NAME).unwrap_or(BACKUP_ENV_KEY.to_owned());
|
||||
|
||||
// Generate the new, obfuscated name
|
||||
let obfuscated_name = get_obfuscated_symbol_name(&fn_name);
|
||||
let obfuscated_name = encrypt_aes_lines(&fn_name, &key_str, STATIC_IV);
|
||||
|
||||
// Create a new string literal for the name
|
||||
let new_name_lit = LitStr::new(&obfuscated_name, func.sig.ident.span());
|
||||
@@ -77,8 +80,11 @@ pub fn symbol(input: TokenStream) -> TokenStream {
|
||||
let lit_str = parse_macro_input!(input as LitStr);
|
||||
let original_name = lit_str.value();
|
||||
|
||||
// get the encryption key
|
||||
let key_str = std::env::var(ENV_KEY_NAME).unwrap_or(BACKUP_ENV_KEY.to_owned());
|
||||
|
||||
// Generate the exact same obfuscated name
|
||||
let obfuscated_name = get_obfuscated_symbol_name(&original_name);
|
||||
let obfuscated_name = encrypt_aes_lines(&original_name, &key_str, STATIC_IV);
|
||||
|
||||
// Expand to a static string literal
|
||||
TokenStream::from(quote! {
|
||||
@@ -106,7 +112,7 @@ pub fn obs(input: TokenStream) -> TokenStream {
|
||||
|
||||
// 1. Generate a unique, random key for this string
|
||||
let mut key = vec![0u8; len];
|
||||
getrandom::fill(&mut key).expect("Failed to get random bytes for XOR key");
|
||||
fill(&mut key).expect("Failed to get random bytes for XOR key");
|
||||
|
||||
// 2. XOR the string with the key
|
||||
let mut obfuscated = Vec::with_capacity(len);
|
||||
|
||||
Reference in New Issue
Block a user