NtTerminateJobObject
Beendet atomar jeden Prozess, der einem Job-Objekt aktuell zugewiesen ist.
Prototyp
NTSTATUS NtTerminateJobObject( HANDLE JobHandle, NTSTATUS ExitStatus );
Argumente
| Name | Type | Dir | Description |
|---|---|---|---|
| JobHandle | HANDLE | in | Handle auf das Job-Objekt mit JOB_OBJECT_TERMINATE-Zugriff. Alle Prozesse im Job — und in verschachtelten Child-Jobs — werden beendet. |
| ExitStatus | NTSTATUS | in | Exit-Code, der für jeden beendeten Prozess über GetExitCodeProcess gemeldet wird. |
Syscall-IDs pro Windows-Version
| Windows-Version | Syscall-ID | Build |
|---|---|---|
| Win10 1507 | 0x1A2 | win10-1507 |
| Win10 1607 | 0x1AB | win10-1607 |
| Win10 1703 | 0x1B1 | win10-1703 |
| Win10 1709 | 0x1B5 | win10-1709 |
| Win10 1803 | 0x1B7 | win10-1803 |
| Win10 1809 | 0x1B8 | win10-1809 |
| Win10 1903 | 0x1B9 | win10-1903 |
| Win10 1909 | 0x1B9 | win10-1909 |
| Win10 2004 | 0x1BF | win10-2004 |
| Win10 20H2 | 0x1BF | win10-20h2 |
| Win10 21H1 | 0x1BF | win10-21h1 |
| Win10 21H2 | 0x1C1 | win10-21h2 |
| Win10 22H2 | 0x1C1 | win10-22h2 |
| Win11 21H2 | 0x1CB | win11-21h2 |
| Win11 22H2 | 0x1CF | win11-22h2 |
| Win11 23H2 | 0x1CF | win11-23h2 |
| Win11 24H2 | 0x1D2 | win11-24h2 |
| Server 2016 | 0x1AB | winserver-2016 |
| Server 2019 | 0x1B8 | winserver-2019 |
| Server 2022 | 0x1C7 | winserver-2022 |
| Server 2025 | 0x1D2 | winserver-2025 |
Kernel-Modul
Verwandte APIs
Syscall-Stub
4C 8B D1 mov r10, rcx B8 D2 01 00 00 mov eax, 0x1D2 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
NtTerminateJobObject ist die Kernelseite von `TerminateJobObject`. Der Kernel läuft die Prozessliste des Jobs durch (unter PspJobLock) und ruft `PspTerminateProcess` für jeden auf, daher ist der Kill aus Sicht eines einzelnen Prozesses effektiv atomar — kein Race-Fenster, in dem ein Kind sich aus dem Job herausforken könnte. Die SSN ändert sich bei jedem Major-Release (`0x1B9` Win10 1903, `0x1BF` 2004, `0x1D2` Win11 24H2 / Server 2025), dynamische Auflösung ist also für Cross-Build-Payloads Pflicht. Der prominenteste legitime Aufrufer ist der Chromium-Browser-Hauptprozess, der seine Renderer-/GPU-/Utility-Jobs recycelt, und `cmd /c taskkill /T /F` auf eine Prozessbaum-Wurzel, die in einem Job lebt.
Häufige Malware-Nutzung
Vergleichsweise selten in Offensiv-Tooling — die meisten Angreifer bevorzugen `NtTerminateProcess` gegen einzeln benannte EDR-Prozesse (Conti, LockBit, BlackCat machen das). Wo NtTerminateJobObject *auftaucht*: (1) Anti-Analyse-Ransomware, die — sobald sie ihren Cuckoo-/Joe-Sandbox-Container-Job erkannt und ein Handle erlangt hat — die gesamte Sandbox-Kohorte killt, um die Artefakt-Sammlung zu stören; (2) Custom-Backdoors, die User-Mode-Opfer-Helper in einen Job einwickeln, gerade um sie bei der Deinstallation per Syscall abzureißen; (3) Red-Team-Tooling, das nach Missbrauch von PROCESS_SET_QUOTA / JOB_OBJECT_ASSIGN_PROCESS einen EDR-Sensor in einen kontrollierten Job zwingt und dann den ganzen Job killt, um den Per-Prozess-Selbstschutz zu umgehen. Die Technik ist laut, leicht erkennbar und in Commodity-Loadern kaum zu sehen.
Erkennungsmöglichkeiten
ETW `Microsoft-Windows-Kernel-Process/ProcessStop` feuert einmal pro getötetem Prozess mit einem gemeinsamen, sehr eng beieinander liegenden Timestamp-Cluster — der Smoking Gun für eine job-weite Terminierung gegenüber einer sequenziellen `taskkill`-Schleife. PsSetCreateProcessNotifyRoutineEx-Callbacks sehen dasselbe Muster. Sysmon Event ID 5 (`ProcessTerminate`) hat kein Terminator-PID-Feld, der Zeit-Burst bleibt aber charakteristisch. Hochpräzise Regel: 5+ Prozesse desselben Jobs enden innerhalb von 50 ms, beendet von einem Prozess außerhalb ihrer Eltern-Kette. EDR-Selbstschutz (PPL auf `MsMpEng.exe`, Defender-Protected-Process-Flag auf `MsSense.exe`) verhindert, dass NtTerminateJobObject Defender / MDE auch von SYSTEM aus killt — diese Technik ist gegen moderne Protected-Process-EDRs eine bekannte Sackgasse.
Direkte Syscall-Beispiele
asmx64 stub (Win11 24H2 SSN 0x1D2)
; Direct syscall stub for NtTerminateJobObject
NtTerminateJobObject PROC
mov r10, rcx ; syscall convention
mov eax, 1D2h ; SSN (Win11 24H2 / Server 2025)
syscall
ret
NtTerminateJobObject ENDPcBrowser-style sandbox recycle
// Recycle a renderer cohort: open the named job we own and terminate it.
#include <windows.h>
DWORD RecycleSandbox(const wchar_t *job_name) {
HANDLE h = OpenJobObjectW(JOB_OBJECT_TERMINATE, FALSE, job_name);
if (!h) return GetLastError();
DWORD err = 0;
if (!TerminateJobObject(h, 0xDEAD0001)) // STATUS-style exit
err = GetLastError();
CloseHandle(h);
return err;
}cAnti-sandbox: tear down Cuckoo monitor cohort
// Hostile (defensive PoC): if we detect we're inside a sandbox job and
// can open a handle to it with TERMINATE rights, kill every sibling.
// In practice the monitor strips JOB_OBJECT_TERMINATE from descendants —
// this rarely works, hence why ransomware prefers per-process killing.
#include <windows.h>
typedef NTSTATUS (NTAPI *pNtTerminateJobObject)(HANDLE, NTSTATUS);
BOOL NukeContainingJob(void) {
// Acquire a handle via OpenProcess + duplicating the job from a sibling
// is a non-trivial dance; abbreviated here.
HANDLE h_job = /* ... */ NULL;
if (!h_job) return FALSE;
pNtTerminateJobObject NtTerminateJobObject = (pNtTerminateJobObject)GetProcAddress(
GetModuleHandleA("ntdll.dll"), "NtTerminateJobObject");
return NtTerminateJobObject(h_job, 0) == 0;
}MITRE ATT&CK-Mappings
Last verified: 2026-05-20