Introduction
Việc gán cứng key giải mã ở trong mã nguồn là không nên do nó dễ bị trích xuất. Thay vào đó, ta nên mã hóa nó bằng một key khác và thực hiện brute-force để giải mã khi malware được chạy.
Để thực hiện việc brute-force, ta cần có hint byte, là một byte mà ta sẽ thêm vào plaintext key. Quá trình brute-force sẽ kết thúc khi ta dùng một key nào đó (được chọn ngẫu nhiên) mà giải mã ra được hint byte.
Hint byte có thể được thêm vào đầu plaintext key:
Trong hình trên, ta sẽ giải mã chuỗi byte của encrypted key đến khi nào byte đầu của nó là BA
.
Note
Tất nhiên, ta sẽ lưu hint byte ở đâu đó.
Key Encryption Process
Trước tiên, sinh ra một key ngẫu nhiên dùng cho việc mã hóa plaintext key:
// Genereting a seed
srand(time(NULL));
// 'b' is used as the key of the key encryption algorithm
BYTE b = rand() % 0xFF;
Cấp phát các buffer chứa các key:
// 'pKey' is where the original key will be generated to
PBYTE pKey = (PBYTE)malloc(sKey);
// 'pProtectedKey' is the encrypted version of 'pKey' using 'b'
PBYTE pProtectedKey = (PBYTE)malloc(sKey);
Tạo plaintext key gốc dùng cho việc mã hóa payload:
// Genereting another seed
srand(time(NULL) * 2);
// The key starts with the hint byte
pKey[0] = HintByte;
// generating the rest of the key
for (int i = 1; i < sKey; i++){
pKey[i] = (BYTE)rand() % 0xFF;
}
Có thể thấy, byte đầu tiên của plaintext key chính là hint byte.
Mã hóa plaintext key bằng cách dùng key b
:
// Encrypting the key using a xor encryption algorithm
// Using 'b' as the key
for (int i = 0; i < sKey; i++){
pProtectedKey[i] = (BYTE)((pKey[i] + i) ^ b);
}
// Saving the encrypted key by pointer
*ppProtectedKey = pProtectedKey;
Key Decryption Process
Do ta không lưu key b
ở bất kỳ chỗ nào, malware sẽ phải thực hiện việc brute-force để tìm ra giá trị này dựa trên hint byte.
Cụ thể hơn, khi decrypt, ta sẽ thực hiện việc XOR byte đầu tiên của encrypted key với một giá trị b
được sinh ngẫu nhiên đến khi nào kết quả của phép XOR là hint byte. Khi đó, giá trị b
chính là key mà ta cần tìm.
BYTE b = 0;
while (1){
// using the hint byte, if this is equal, then we found the 'b' value needed to decrypt the key
if (((pProtectedKey[0] ^ b) - 0) == HintByte)
break;
// else, increment 'b' and try again
else
b++;
}
Sau khi tìm được key dùng để giải mã encrypted key thông qua vòng lặp while
như trên, ta sẽ dùng nó để giải mã:
PBYTE pRealKey = (PBYTE)malloc(sKey);
// The reverse algorithm of the xor encryption, since 'b' now is known
for (int i = 0; i < sKey; i++){
pRealKey[i] = (BYTE)((pProtectedKey[i] ^ b) - i);
}