> Windows Syscalls
ntoskrnl.exeT1134T1106

NtCreateLowBoxToken

Leitet ein LowBox- (AppContainer-)Token aus einem bestehenden Token ab — setzt die Package-SID und Capability-Liste, die den Broker-IPC-Zugriff steuern.

Prototyp

NTSTATUS NtCreateLowBoxToken(
  PHANDLE              TokenHandle,
  HANDLE               ExistingTokenHandle,
  ACCESS_MASK          DesiredAccess,
  POBJECT_ATTRIBUTES   ObjectAttributes,
  PSID                 PackageSid,
  ULONG                CapabilityCount,
  PSID_AND_ATTRIBUTES  Capabilities,
  ULONG                HandleCount,
  PHANDLE              Handles
);

Argumente

NameTypeDirDescription
TokenHandlePHANDLEoutEmpfängt das Handle des neuen LowBox-Tokens.
ExistingTokenHandleHANDLEinQuell-Token. Erfordert TOKEN_DUPLICATE. Das LowBox wird aus seinem User/Groups abgeleitet.
DesiredAccessACCESS_MASKinAuf das neue Token angefragte Zugriffsmaske. TOKEN_ALL_ACCESS ist üblich, wenn der Aufrufer es danach zuweist.
ObjectAttributesPOBJECT_ATTRIBUTESinObjekt-Attribute. SecurityQualityOfService steuert den Impersonation-Level bei entsprechender Nutzung.
PackageSidPSIDinAppContainer-Package-SID — kodiert die eindeutige Identität der sandboxed App, scoped Objektnamen unter \Sessions\...\AppContainerNamedObjects.
CapabilityCountULONGinAnzahl der Einträge in Capabilities. Darf 0 sein.
CapabilitiesPSID_AND_ATTRIBUTESinArray von Capability-SIDs (internetClient, picturesLibrary usw.), die dem LowBox gewährt werden.
HandleCountULONGinAnzahl der Handles in Handles. Üblicherweise 0.
HandlesPHANDLEinOptionales Array von Objekt-Handles, die dem LowBox angehängt werden, damit es darauf zugreifen kann trotz normaler AC-Restriktionen.

Syscall-IDs pro Windows-Version

Windows-VersionSyscall-IDBuild
Win10 15070xA5win10-1507
Win10 16070xA7win10-1607
Win10 17030xAAwin10-1703
Win10 17090xABwin10-1709
Win10 18030xACwin10-1803
Win10 18090xACwin10-1809
Win10 19030xADwin10-1903
Win10 19090xADwin10-1909
Win10 20040xB1win10-2004
Win10 20H20xB1win10-20h2
Win10 21H10xB1win10-21h1
Win10 21H20xB2win10-21h2
Win10 22H20xB2win10-22h2
Win11 21H20xB5win11-21h2
Win11 22H20xB6win11-22h2
Win11 23H20xB6win11-23h2
Win11 24H20xB8win11-24h2
Server 20160xA7winserver-2016
Server 20190xACwinserver-2019
Server 20220xB4winserver-2022
Server 20250xB8winserver-2025

Kernel-Modul

ntoskrnl.exeNtCreateLowBoxToken

Verwandte APIs

CreateAppContainerTokenCreateProcessAsUserNtAssignProcessTokenNtCreateUserProcessDeriveCapabilitySidsFromNameDeriveAppContainerSidFromAppContainerName

Syscall-Stub

4C 8B D1            mov r10, rcx
B8 B8 00 00 00      mov eax, 0xB8
F6 04 25 08 03 FE 7F 01   test byte ptr [0x7FFE0308], 1
75 03               jne short +3
0F 05               syscall
C3                  ret
CD 2E               int 2Eh
C3                  ret

Undokumentierte Hinweise

Trägt die in Windows 8 eingeführte AppContainer-Sandbox, die jede Windows-Runtime-App, Edges Content-Prozesse, Chromes Renderer-Sandbox (im AppContainer-Modus), die WSA-Android-Runtime und der moderne WebView2-Host nutzen. Die Kernel-Routine SepCreateLowBoxToken nimmt das Quell-Token, kopiert User/Groups/Privileges und legt darüber die LowBox-Attribute: die Package-SID (gespeichert in `LowBoxNumberEntry` / `Package` des Tokens) und das Capability-Array (als spezielle Gruppe mit Attributen nahe SE_GROUP_INTEGRITY). Sobald das resultierende Token einem Prozess via NtAssignProcessToken zugewiesen oder mit NtCreateUserProcess genutzt wird, fügt der Kernel AppContainer-Access-Checks ein: Objektnamen werden in den per-AC-Namespace `\Sessions\<n>\AppContainerNamedObjects\<PackageSid>` umgeleitet; Netzwerkzugriff wird durch `internetClient` / `privateNetworkClientServer` reguliert; Broker-IPC-Kanäle (für AppContainer reservierte RPC-Interfaces) werden erreichbar.

Häufige Malware-Nutzung

Überwiegend legitim; echte bösartige Nutzung existiert, ist aber selten. Muster: Ein Prozess, der sonst an einer Broker-RPC-Schnittstelle scheitern würde (manche WinRT-Broker-Endpoints prüfen die Aufrufer-PackageSid und akzeptieren nur AppContainer-Principals), ruft NtCreateLowBoxToken mit der *erwarteten* PackageSid einer legitimen AC-App auf, weist das Token einem Helper-Child zu und pivotet durch den Broker, als wäre er diese App. Das ist der Kern mehrerer veröffentlichter Sandbox-Escape-PoCs von Project Zero, Google-Bughuntern und einigen CTF-Writeups (insbesondere Escapes aus Edges Content-Prozess und dem WSA-RuntimeBroker). Vereinzelt auch in Red-Team-Tooling, um *freiwillig* in einen AppContainer einzutreten — praktisch, wenn der Operator möchte, dass sein Tradecraft für ein defensives Tool, das AC-Prozesse whitelistet, wie ein normales Edge-Kind aussieht.

Erkennungs­möglichkeiten

Microsoft-Windows-Threat-Intelligence emittiert kein dediziertes Event für NtCreateLowBoxToken; Detection muss sich auf Seiteneffekte stützen. Hochwertiger Pivot: *Erzeugung eines AppContainer-Tokens durch einen nicht-AC-bewussten Prozess*. Alles außerhalb einer kleinen Whitelist (svchost.exe als AC-Infra-Host, MicrosoftEdgeUpdate.exe, RuntimeBroker.exe, BackgroundTaskHost.exe, smsvchost.exe), das diesen Syscall aufruft, ist anomal. Sysmon-Event 25 (Process Tampering) feuert manchmal beim folgenden NtAssignProcessToken, wenn das neue Token den Manifest-Deklarationen des Prozesses widerspricht. Der ETW-Provider Microsoft-Windows-Win32k-Power kann das Namespace-Remapping zeigen, sobald das LowBox-Child auf `\Sessions\...\AppContainerNamedObjects\<unerwartetes-package>` zugreift. PackageSid-Fälschung (Mismatch zwischen PackageSid und signierter Identität der Executable) ist der stärkste verhaltensbasierte Indikator.

Direkte Syscall-Beispiele

cVoluntarily enter a LowBox (red-team blend pattern)

// Build a LowBox token tagged with an arbitrary PackageSid, then assign it
// to a helper process so it executes as if it were that AppContainer app.
typedef NTSTATUS(NTAPI* fnNtCreateLowBoxToken)(
    PHANDLE, HANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
    PSID, ULONG, PSID_AND_ATTRIBUTES, ULONG, PHANDLE);

HANDLE BuildLowBox(HANDLE hSourceToken, PSID packageSid) {
    HMODULE n = GetModuleHandleA("ntdll.dll");
    fnNtCreateLowBoxToken p = (fnNtCreateLowBoxToken)
        GetProcAddress(n, "NtCreateLowBoxToken");
    OBJECT_ATTRIBUTES oa = { sizeof(oa) };
    HANDLE hLowBox = NULL;
    NTSTATUS s = p(&hLowBox, hSourceToken, TOKEN_ALL_ACCESS, &oa,
                   packageSid, 0, NULL, 0, NULL);
    return (s == 0) ? hLowBox : NULL;
}

asmx64 direct stub (Win11 24H2 SSN)

; SSN 0xB8 on win11-24h2 / winserver-2025. 9 args — most spill to the stack.
NtCreateLowBoxToken PROC
    mov  r10, rcx
    mov  eax, 0B8h
    syscall
    ret
NtCreateLowBoxToken ENDP

rustAdd internetClient capability to a LowBox

// Capability SIDs are derived from cap names via DeriveCapabilitySidsFromName.
// Here we hard-code S-1-15-3-1 (internetClient) for brevity.
use windows_sys::Win32::Security::PSID;
use windows_sys::Win32::System::LibraryLoader::{GetModuleHandleA, GetProcAddress};

#[repr(C)]
struct SidAndAttributes { sid: PSID, attributes: u32 }

type NtCreateLowBoxToken = unsafe extern "system" fn(
    out: *mut isize, src: isize, access: u32, oa: *mut u8,
    package: PSID, cap_count: u32, caps: *mut SidAndAttributes,
    handle_count: u32, handles: *mut isize,
) -> i32;

pub unsafe fn lowbox_with_internet(
    src: isize, package: PSID, internet_client: PSID,
) -> Option<isize> {
    let n = GetModuleHandleA(b"ntdll.dll\0".as_ptr());
    let addr = GetProcAddress(n, b"NtCreateLowBoxToken\0".as_ptr())?;
    let f: NtCreateLowBoxToken = std::mem::transmute(addr);
    let mut cap = SidAndAttributes { sid: internet_client, attributes: 0x04 /* SE_GROUP_ENABLED */ };
    let mut oa = [0u8; 48];
    let mut out: isize = 0;
    if f(&mut out, src, 0xF01FF, oa.as_mut_ptr(), package, 1, &mut cap, 0, core::ptr::null_mut()) == 0 {
        Some(out)
    } else { None }
}

MITRE ATT&CK-Mappings

Last verified: 2026-05-20