
Tecnica di persistenza su Windows tramite COM
ispirato da CVE-2026-21509
Un'implementazione di esempio di un gestore del menu contestuale di Windows utilizzando C++ e COM, che dimostra una tecnica di persistenza furtiva. Registrando un oggetto COM personalizzato, il tuo codice viene eseguito ogni volta che un utente fa clic con il tasto destro su obiettivi specifici (file, cartelle o sfondi) in Windows Explorer.
Disclaimer: Questo progetto è destinato esclusivamente a scopi educativi e di ricerca. Le tecniche qui dimostrate possono essere utilizzate per scopi dannosi. L'autore non approva l'uso di questo codice per attività illegali. Sii responsabile e usa questa conoscenza in modo etico.

DllMain.cpp
+-----------------------+
| DLL Template Project |
+-------+-------+-------+
____/ | \_____
| | |
v v v
+------------+ +----------------+ +--------------+
| Define | | MyClassFactory | | Define |
clsid_defined.h | CLSID | +----------------+ | Export | Source.def
+------------+ ClassFactory | Functions |
class +--------------+
|
|
v
+--------------+
| MyMenuHandler|
+--------------+
MyMenuHandler
class
DllMain.cppContiene le funzioni standard richieste da un oggetto COM per registrare e deregistrare la DLL.
DllRegisterServer(): Scrive i percorsi del registro corrispondenti alle estensioni/sfondi dei file di destinazione. Eseguita quando la DLL viene registrata.STDAPI DllRegisterServer() {
std::wstring clsidString = MyStringFromCLSID(CLSID_DecrypShellExtensionx64);
std::wstring dllPath = MyGetModuleFilename();
// 1. Register the COM Class (CLSID)
std::wstring clsidBaseKey = L"SOFTWARE\\Classes\\CLSID\\" + clsidString;
SetRegistryKey(HKEY_LOCAL_MACHINE, clsidBaseKey, L"", L"MyMenuHandler Object");
// 2. Register the DLL Path and Threading Model
std::wstring inprocKey = clsidBaseKey + L"\\InprocServer32";
SetRegistryKey(HKEY_LOCAL_MACHINE, inprocKey, L"", dllPath);
SetRegistryKey(HKEY_LOCAL_MACHINE, inprocKey, L"ThreadingModel", L"Apartment");
// 3. Register for all Shell Contexts
// Array of paths to cover Files, Folders, Backgrounds, and Desktop
std::wstring handlerPaths[] = {
L"SOFTWARE\\Classes\\*\\shellex\\ContextMenuHandlers\\",
L"SOFTWARE\\Classes\\Directory\\shellex\\ContextMenuHandlers\\",
L"SOFTWARE\\Classes\\Directory\\Background\\shellex\\ContextMenuHandlers\\",
L"SOFTWARE\\Classes\\DesktopBackground\\shellex\\ContextMenuHandlers\\"
};
for (const auto& path : handlerPaths) {
std::wstring fullPath = path + L"MyMenuHandler"; // Replace with your handler's name
SetRegistryKey(HKEY_LOCAL_MACHINE, fullPath, L"", clsidString);
}
// 4. Register in the Approved list (Required for many Windows versions)
std::wstring approvedKey = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved";
SetRegistryKey(HKEY_LOCAL_MACHINE, approvedKey, clsidString, L"MyMenuHandler");
// 5. Notify the Shell that things have changed
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
return S_OK;
}
DllUnregisterServer(): Pulisce il registro. Chiamata quando la DLL viene deregistrata.MyClassFactoryNecessario per istanziare l'oggetto COM. Maggiori informazioni sulle class factory.
Clsid_defined.hContiene il GUID con cui l'applicazione verrà registrata in Explorer. Puoi generare un nuovo GUID usando guidgen.exe di Visual Studio o un Generatore GUID online.
// {CEF1AA1B-42F7-4A54-AF46-BCEE5B3FE6BF}
DEFINE_GUID(CLSID_DecrypShellExtensionx64, 0xcef1aa1b, 0x42f7, 0x4a54, 0xaf, 0x46, 0xbc, 0xee, 0x5b, 0x3f, 0xe6, 0xbf);
Source.defIl file di definizione del modulo. Questo determina quali funzioni la DLL esporta. Maggiori informazioni sui file .DEF.
EXPORTS
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
MyMenuHandler.cppLa classe principale che implementa IShellExtInit e IContextMenu. Qui definisci le tue azioni personalizzate.
MyContextMenuHandler::Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject* pdtobj, HKEY hkeyProgId)
Chiamato ogni volta che si fa clic con il tasto destro sul target registrato. Utilizzato per analizzare quale file o cartella è stato cliccato.HRESULT MyContextMenuHandler::Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject* pdtobj, HKEY hkeyProgId)
{
MessageBoxA(NULL, "Initialize Called!", "Debug", MB_OK);
// 1. Check if we clicked on a FILE/FOLDER
if (pdtobj)
{
STGMEDIUM medium;
FORMATETC fe = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
if (SUCCEEDED(pdtobj->GetData(&fe, &medium)))
{
DragQueryFileA((HDROP)medium.hGlobal, 0, m_szFile, MAX_PATH);
ReleaseStgMedium(&medium);
return S_OK; // Success!
}
}
// 2. Check if we clicked the BACKGROUND (pidlFolder)
if (pidlFolder)
{
if (SHGetPathFromIDListA(pidlFolder, m_szFile))
{
return S_OK; // Success!
}
}
// 3. Fallback: If we got neither, still return S_OK to show the menu.
// You just won't have a path populated in m_szFile.
return S_OK;
}
MyContextMenuHandler::InvokeCommand(LPCMINVOKECOMMANDINFO picp)
Chiamato quando l'utente fa clic sull'opzione personalizzata specifica dal menu contestuale. Qui viene eseguito il tuo payload di persistenza o azione personalizzata.Sulla macchina virtuale di destinazione, copia la DLL compilata ed esegui i seguenti comandi:
Registra la DLL utilizzando i binari standard di Windows.
regsvr32.exe RightHandPersistence.dll
Riavvia il processo explorer.exe per assicurarsi che carichi la nuova estensione shell in memoria.
taskkill /f /im explorer.exe & start explorer.exe
Per rimuovere il gestore del menu contestuale e pulire il registro, usa il flag /u con regsvr32.exe. Questo richiama la tua funzione DllUnregisterServer.
regsvr32.exe /u RightHandPersistence.dll
Windows classifica lo "spazio vuoto" in modo diverso dai file. Per colpire lo sfondo, mappa le tue chiavi di registro in queste posizioni specifiche.
Maggiori dettagli su come mappare le estensioni si trovano nella documentazione Microsoft sui menu contestuali della shell.
Puoi specificare un testo personalizzato per il menu (ad esempio "Copia personalizzata" o "Esegui diagnostica") implementando il metodo IContextMenu::QueryContextMenu. Cliccando su questo testo personalizzato si attiva la tua logica all'interno di IContextMenu::InvokeCommand.
| Bersaglio del clic destro | Percorso chiave di registro |
|---|
| File (Tutti) | HKEY_CLASSES_ROOT\*\shellex\ContextMenuHandlers |
| Cartelle (l'icona) | HKEY_CLASSES_ROOT\Directory\shellex\ContextMenuHandlers |
| Sfondo cartella | HKEY_CLASSES_ROOT\Directory\Background\shellex\ContextMenuHandlers |
| Sfondo desktop | HKEY_CLASSES_ROOT\DesktopBackground\shellex\ContextMenuHandlers |