CHAPTER 01 30 MIN READ BEGINNER

Windows Architecture & the Process Model

Every EDR alert you will ever triage and every Sysmon event you will ever read is, underneath the vendor branding, a story about processes, threads, and the relationships between them. An alert says a process was created, a handle was opened, a thread was injected into another process, or a child spawned from a parent that should never have spawned it. None of that means anything until you know precisely what a process is, what a thread does inside it, and how Windows tracks the objects they touch. This chapter builds that vocabulary from the ground up, deliberately and without shortcuts, because guessing at these terms is how analysts misread perfectly good telemetry.

processes integrity levels sessions
New to security? This module assumes you already know core security vocabulary from the CIA triad and basic client-server networking concepts. If any of that is unfamiliar, start with the Fundamentals module and the Networking module first.

Processes and Threads

What a Process Actually Is

A process is not code running. It is a container: an isolated virtual address space, a unique process ID (PID), a security context, and a table of handles to the kernel objects it has opened.

When you double-click an executable, the operating system does not simply "start the program." It asks the kernel to allocate a new address space, map the executable image and its dependent DLLs into that space, set up an initial environment block, and create the bookkeeping structures the kernel needs to manage the process for the rest of its life. That container is what shows up in Process Explorer, in Task Manager, and in every EDR process-creation event with a PID attached to it.

Threads Do the Actual Work

A process by itself does nothing; it cannot execute a single instruction. Execution belongs to threads. A thread is the actual unit of scheduling and execution within a process: it has its own stack, its own set of CPU register values, and its own execution context, but it shares the parent process's address space, handle table, and loaded modules with every other thread in that process.

When you see a process "doing" something, what is actually happening is one or more of its threads running on a CPU core, and the operating system's scheduler decides which thread runs on which core at which moment. A single process can have one thread or thousands; a typical service process idles with a handful and spins up more under load.

Why the Distinction Matters for Detection

This distinction matters immediately for detection work. Process injection techniques do not create a new process at all. They create a new thread inside an existing, already-running process, using functions like CreateRemoteThread or its many API-calling and syscall variants.

The process the injected code runs under does not change: the PID stays the same, and the parent-child chain looks identical to before. What changes is that a foreign thread, executing code that was never part of the original image, is now running inside a process's address space. Recognizing that a process and the threads inside it are two different things you can independently manipulate is the first mental model shift that makes injection techniques legible instead of magical.

User Mode vs Kernel Mode

Underneath both processes and threads sits the split between kernel mode and user mode. User mode is where ordinary application code, including malware, runs with restricted CPU privileges: it cannot directly touch hardware or arbitrary physical memory, and every request that needs that kind of access, like reading a file or opening a network socket, has to be handed off.

Kernel mode is where the operating system's core, ntoskrnl.exe, and its loaded drivers run with essentially unrestricted access to the machine. A user-mode process crosses into kernel mode through a system call, a controlled transition point where the CPU switches privilege levels, the kernel validates the request, performs the privileged work, and returns control to user mode.

Almost every meaningful action a process takes, opening a handle, writing to disk, allocating memory, ultimately routes through this boundary. That is exactly why EDR products hook or monitor system calls to see what a process is really doing, rather than trusting what it appears to do at the user-mode API layer.

Put together, a running Windows machine at any given moment is a set of process containers, each holding one or more threads that are actually executing, with the kernel arbitrating access to hardware and enforcing this boundary underneath all of it. Every later concept in this chapter, handles, sessions, integrity levels, process trees, is really just describing different facets of this same basic structure: what a process is allowed to touch, where it runs, and who its ancestors were.

Handles and the Object Manager

Quick glossary, keep these straight:
  • Kernel object: the internal representation of a resource, files, registry keys, mutexes, events, threads, and even other processes are all kernel objects.
  • Handle: a small integer value in a process's private handle table that points to a kernel object the process has been granted some access to.
  • Object Manager: the kernel component that creates, tracks, access-checks, and tears down every kernel object.
  • DuplicateHandle: the API that lets one process share its existing access to an object with a different process.

A Handle Is a Reference, Not the Resource

A handle is not the resource itself. It points to a kernel object the process has been granted some level of access to, typically obtained by calling an API like CreateFile or OpenProcess.

The handle value itself is meaningless outside the process that owns it. Process A's handle number 0x84 and process B's handle number 0x84 can point to two completely unrelated objects, because each process has its own private handle table.

What the Object Manager Does

When a process asks to open a handle to an object, the Object Manager checks the requesting process's security token against the object's access control list. It decides what level of access to grant, read-only, full control, or something in between, and returns a handle scoped to exactly that access level.

The Object Manager also maintains a reference count on every object. As long as at least one process holds an open handle to an object, the kernel keeps that object alive in memory, which is why a locked file or an in-use registry key cannot be deleted until every handle referencing it is closed.

Handle Duplication: Legitimate and Abused

A process that already holds a handle to another object can, under the right permissions, share that access with a completely different process using DuplicateHandle. This is legitimate machinery, used constantly for things like passing a file handle to a child process.

It is also one of the most reliable ways attackers gain access to a protected process without ever calling OpenProcess directly against it. If direct access to a sensitive process like lsass.exe is blocked or heavily monitored, an attacker who can get another process that already legitimately holds a powerful handle to lsass.exe to duplicate that handle into their own process obtains equivalent access, sidestepping the access check and, in some tooling, the alerting that a direct OpenProcess call would trigger.

Why EDR Watches Handle Activity Around lsass.exe

A direct process-access event against lsass.exe from an unusual parent is a fairly obvious signal. A handle duplicated from a trusted process that already had legitimate access is quieter, and requires correlating which process originally held the handle, which process received the duplicate, and what access rights transferred.

Understanding handles as first-class, trackable objects, not just an implementation detail, is what lets an analyst reason about that chain instead of only seeing the final suspicious action.

Sessions and Window Stations

What a Session Groups Together

A session in Windows is a logical container that groups together the processes, window stations, and desktops belonging to one logon. Every time a user logs on interactively, a service starts, or a Remote Desktop connection is established, that activity happens inside a session, identified by a session ID visible in Task Manager, Process Explorer, and most EDR telemetry.

Sessions matter for security work because Windows deliberately isolates certain sessions from others, and that isolation is a real security boundary, not just an organizational convenience.

Before Session 0 Isolation: Shatter Attacks

The specific isolation that matters most is Session 0 isolation, introduced starting with Windows Vista and Windows Server 2008. Before that change, services ran in the same session as the first interactive user logon, Session 0, which meant a service process and a logged-on user's desktop applications shared the same session and, critically, the same window station.

That created a real attack surface: a service running with SYSTEM privileges could have its window station and desktop objects manipulated by a lower-privileged interactive process sitting in the same session. This class of attack is broadly known as a shatter attack, where malicious window messages sent to a privileged process's UI could be used to execute code with that process's privileges.

The fix, two isolated categories:
  • Session 0. Every service runs here permanently, with no interactive desktop in any normal configuration. A service that tries to pop up a UI dialog either fails silently or, on older pre-fix systems, could not be seen by the logged-on user.
  • Session 1 and up. Every interactive logon, at the console or over RDP, gets its own numbered session with its own window station and desktop, fully isolated from Session 0 and from each other.

Why This Isolation Matters for Detection

Because Session 0 runs services, many of them with SYSTEM privileges and no interactive desktop, escalation techniques that target services specifically care about crossing that session boundary. A technique that can get code to execute as a Session 0 service, or that abuses a service's SYSTEM-level token to spawn a process into a different, interactive session, is meaningfully more dangerous than one confined to a single user's own session.

Session IDs in your telemetry are also a useful pivot on their own. A process spawned into Session 0 that is not a recognized service binary, or a service-hosted process suddenly interacting with a session it should have no business touching, is worth a second look.

Integrity Levels and the UAC Boundary

A Different Question From a Permission Check

Integrity levels are a security mechanism, introduced with Windows Vista's Mandatory Integrity Control, that sits alongside and independently of standard discretionary permissions like NTFS ACLs and group membership. Where a permission check asks "does this account have rights to this object," an integrity level check asks a different question: "is this process trustworthy enough to write to this object at all," regardless of what the account nominally has access to.

Every process and every securable object carries an integrity level. The general rule, sometimes called the no-write-up policy, is that a process cannot write to, inject into, or otherwise modify an object with a higher integrity level than its own, even if the underlying discretionary permissions would technically allow it.

The Four Levels

LevelWho Runs Here
LowThe most sandboxed, least trusted processes, historically Internet Explorer's Protected Mode or a browser's sandboxed renderer. Can write only to specifically designated low-integrity locations, regardless of the logged-on user's actual permissions.
MediumThe default for an ordinary standard user process and for a standard interactive session even under an administrator account. Almost everything you run day to day starts here.
HighProcesses that have successfully elevated: an admin-approval prompt accepted, or a process launched with Run as Administrator.
SystemReserved for SYSTEM-level services and core OS processes, sitting above even High.

How UAC Actually Uses This

When an administrator logs on, Windows does not simply hand out a full-privilege token by default. It issues two tokens: a filtered, Medium-integrity token used for everything the user does normally, and a full, High-integrity administrator token that stays dormant until something requests elevation.

The UAC consent prompt you see is Windows asking permission to hand over that dormant High-integrity token to a specific process. This is precisely why an administrator account still runs day-to-day applications, and is still just as exploitable by a Medium-integrity malicious process, as a standard user account. Admin group membership alone does not grant High-integrity execution, the UAC prompt does, and that prompt is the actual security boundary, not the account's group memberships.

Why Integrity Level Beats the Account Name for Analysis

For malware and living-off-the-land analysis, integrity level is often more informative than the user account a process is running under. A process running under an administrator's account but at Medium integrity cannot silently reach into a High-integrity process's memory or tamper with protected registry keys and system files, because the integrity check blocks it regardless of the account's nominal admin rights.

This is exactly why so many privilege escalation and UAC bypass techniques exist: they exist specifically to get code from Medium integrity to High integrity without triggering the visible consent prompt, by abusing auto-elevating binaries, DLL hijacking inside a trusted auto-elevate process, or COM elevation moniker abuse. An EDR or Sysmon event that shows a process integrity level jumping from Medium to High with no corresponding consent.exe interaction in between is a legitimate red flag worth investigating on its own.

Process Trees and Parent-Child Relationships

Every Process Records Its Parent

Every process on a Windows system, with the narrow exception of a handful of processes created directly by the kernel at boot like System and Idle, is created by another process calling CreateProcess or an equivalent API. The creating process is the parent; the newly created process is the child, and it records its parent's PID as part of its own metadata.

Follow that chain far enough back on any running process and you eventually land on a small number of root ancestors: services.exe for service-spawned processes, winlogon.exe or userinit.exe descendants for the interactive logon shell, and ultimately System for the earliest kernel-created processes. The result across a whole machine is not a flat list of processes but a tree, and that tree shape is one of the single most valuable pieces of context in all of endpoint telemetry.

Why the Pattern Is Detectable

Legitimate software has predictable, boring parent-child patterns, and those patterns are stable enough to build reliable detection logic on. explorer.exe launching a user's applications, svchost.exe instances hosting services under services.exe, a browser spawning its own renderer and GPU helper processes: these are the overwhelming majority of process creation events on any endpoint, and they follow the same shapes day after day.

Sysmon Event ID 1 and equivalent EDR process-creation telemetry record exactly this: the new process, its command line, and critically its parent process and parent command line. A detection engineer's job is very often not spotting an inherently malicious binary, but spotting a parent-child pairing that breaks the expected pattern.

The Canonical Example

Each binary in this chain, winword.exe, cmd.exe, powershell.exe, is completely legitimate and signed by Microsoft. It is the parentage, an Office application directly spawning a shell, that is the anomaly worth alerting on.

  1. A user opens a macro-enabled document. Microsoft Word, under completely normal use, has no legitimate reason to launch a command interpreter; Word's job is to open and render documents, not shell out to cmd.exe.
  2. The macro's VBA code calls Shell() or an equivalent function. This drops winword.exe into launching cmd.exe, a command interpreter it has no documented reason to invoke.
  3. cmd.exe launches powershell.exe. PowerShell gives an attacker a full scripting environment, in-memory execution capability, and easy access to .NET, making it the preferred next step to download or execute a second-stage payload.

Beyond Office Macros

This generalizes well beyond Office macros. Any office application, PDF reader, or browser directly spawning a shell interpreter, a scripting engine it has no documented reason to invoke, or a LOLBAS binary known for proxy execution, is worth the same scrutiny.

Process tree analysis is also why command lines matter as much as the binary name: powershell.exe launched with -enc and a base64 blob, or with -WindowStyle Hidden, tells a very different story from powershell.exe opened by a user typing into a terminal, even though the binary and its immediate parent, cmd.exe, look identical in a shallow log. Reading the full chain, not just the single new process, is what turns a list of process-creation events into an actual narrative of what happened on a host.

Parent ProcessChild ProcessWhy It Is Suspicious
winword.exe / excel.execmd.exe or powershell.exeOffice apps have no legitimate need to launch a shell; strongly indicates a macro payload
outlook.execmd.exe, wscript.exe, or mshta.exeEmail client spawning a script host suggests a malicious attachment executed
svchost.execmd.exe with an unusual command lineLegitimate for some services, but worth checking which service and whether the command line fits it
powershell.exerundll32.exe or regsvr32.exe with a remote pathClassic pattern for staging a second-stage payload via a LOLBAS proxy execution technique

What This Module Covers

Eight chapters build a working mental model of Windows internals for detection and hunting work, starting from this foundation and moving toward the specific mechanisms attackers abuse.

  • Chapter 2, Active Directory Fundamentals. Domains, forests, trusts, organizational units, and the objects that make up a directory service most enterprise environments depend on.
  • Chapter 3, Authentication with NTLM and Kerberos. The two protocols underneath nearly every logon event you will investigate, including why Kerberos ticket structure is the basis for attacks like Kerberoasting and Golden Ticket.
  • Chapter 4, Tokens, Privileges & Access Control. How a security token actually represents a user's identity and rights, and how privilege abuse turns a low-level foothold into SYSTEM.
  • Chapter 5, The Registry. Both as a configuration database and as one of the most heavily abused persistence and defense-evasion surfaces on the platform.
  • Chapter 6, Windows Event Logging and Sysmon. Which event IDs matter and why, building directly on the process-creation concepts introduced in this chapter.
  • Chapter 7, Common Windows Attack Techniques. Credential dumping, process injection, and living-off-the-land binary abuse, tying together the handle, integrity level, and process tree concepts from this chapter into real attacker tradecraft.
  • Chapter 8, Active Directory Attacks and Detection. Closes the module, covering the kill chain from initial domain foothold through to domain dominance and how to catch it at each stage.
Tip: If you already understand processes and threads from another OS or from development work, do not skip integrity levels and process trees. Those two sections carry the most direct weight for reading EDR and Sysmon output, and the rest of this module assumes you can reason about both fluently.

Key Takeaways

  • A process is a container: an address space, a PID, and a handle table. A thread is the actual unit of execution inside it, and a process can hold many threads.
  • A handle is a reference to a kernel object, tracked and access-checked by the Object Manager. Handle duplication lets one process share its access to an object with another process, which attackers abuse to reach protected processes like lsass.exe indirectly.
  • Session 0 isolation, since Windows Vista, keeps services in their own non-interactive session, separate from every interactive user session, closing off an older class of shatter attacks.
  • Integrity levels (Low, Medium, High, System) are a security boundary separate from account permissions. UAC works by holding a dormant High-integrity token until a consent prompt releases it.
  • Process trees record every parent-child relationship on a host. Detection logic leans heavily on recognizing when a normally boring parent, like winword.exe, spawns a child it has no legitimate reason to spawn, like cmd.exe.
  • These five concepts, processes, handles, sessions, integrity levels, and process trees, are the vocabulary underneath essentially every EDR alert and Sysmon event you will read for the rest of this module.

Knowledge Check

Click an answer to reveal the explanation.

An EDR alert shows no new process was created, but a foreign thread began executing inside an already-running, legitimate process. What does this best describe?

Process injection does not create a new process at all; it creates a new thread inside an existing process's address space, using an API like CreateRemoteThread or a syscall equivalent. The PID and parent-child chain stay unchanged, which is exactly why this technique evades detection logic that only watches process-creation events instead of thread activity within existing processes.

A logged-on administrator runs a script that attempts to modify a High-integrity system file. The script's process is running under the administrator's account but at Medium integrity, with no UAC prompt shown. What happens?

Integrity levels are a no-write-up boundary enforced independently of discretionary permissions. An administrator's day-to-day processes run at Medium integrity by default; only after a UAC prompt releases the dormant High-integrity token does a process gain the right to write to High-integrity objects. Group membership alone never grants that access.

Sysmon Event ID 1 shows outlook.exe as the parent of wscript.exe, which then launches powershell.exe with a base64-encoded command. What makes this chain worth escalating?

Each binary in this chain is legitimate and signed by Microsoft on its own. The anomaly is the parentage: Outlook's job is to render email and attachments, not to launch a script host, so outlook.exe spawning wscript.exe strongly suggests a malicious attachment executed. The encoded PowerShell command that follows fits the common pattern of obfuscating a second-stage download or execution step, reinforcing the same conclusion.