The descriptions of several of the Sysinternals
utilities—including Process Explorer, Process Monitor, PsExec,
AdInsight, Desktops, and LogonSessions—refer to terminal services
sessions, session IDs, the “console session,” and “session 0”;
interactive and noninteractive window stations; and other programs
running on the “same desktop.” These concepts, although not widely
understood, can be critical to problem solving on the Windows platform.
Let’s start with an overview of the hierarchy, an example of which is depicted in Figure 1,
and then define the terms. At the outermost layer are terminal services
(TS) sessions. Each session contains one or more window stations, which
contain desktops. Each of these securable objects has resources
allocated for its sole use. There is also a loose relationship between
these and logon sessions created by the LSA. Although Windows
documentation doesn’t always make a clear distinction between LSA logon
sessions and TS sessions, they are completely separate entities.
1. Terminal Services Sessions
Terminal
services support multiple interactive user sessions on a single
computer. Introduced in Windows NT 4.0 Terminal Server Edition, they
were not incorporated into the Windows client operating system family
until Windows XP. Features they support include Fast User Switching,
Remote Desktop, Remote Assistance, Remote Applications Integrated
Locally (RAIL, a.k.a. RemoteApps), and virtual machine integration
features. An important limitation of Windows clients (Windows XP,
Windows Vista, and Windows 7) is that only one interactive session can
be active at a time. That is, while processes can continue to run in
multiple disconnected sessions simultaneously, only one session can
update a display device and receive keyboard and mouse input. A further
limitation is that a domain-joined
Windows XP computer supports at most only one interactive session. For
example, if a user is logged on at the console, you can log on to the
computer via Remote Desktop using the same account and continue that
session, but you cannot log on with a different user account unless the
first user is logged off.
Terminal
services sessions are identified by an incrementing numeric session ID,
starting with session 0. Windows defines a global namespace in the
Object Manager and a session-private “local” namespace for each session
numbered 1 and higher to provide isolation between sessions. The global
namespace serves as the local namespace for processes in session 0.
System processes and
Windows services always run in terminal services session 0. In Windows
XP and Windows Server 2003, the first interactive user to log on to a
computer also uses terminal services session 0 and, consequently, uses
the same local namespace as services. Windows XP and Windows Server 2003
create sessions 1 and higher only when needed; if the first user logs
off before a second one logs on, the second user uses session 0 as well.
Consequently, on a domain-joined Windows XP, session 0 is always the
only session.
In Windows Vista and
newer, services run in session 0, but for security reasons all
interactive user sessions run in sessions 1 and higher. This increased
separation between end-user processes and system processes is called session 0 isolation.
Note:
The term console session is sometimes mistaken as a synonym for session 0.
The console session is the terminal services session associated with
the locally attached keyboard, video, and mouse. If all active sessions
on a computer are remote desktop sessions, the console session remains
connected and displays a logon screen. It might or might not happen to
be session 0 on Windows XP/Windows 2003, but it is never session 0 on
Windows Vista or newer.
2. Window Stations
Each terminal services session contains one or more named window stations.
A window station is a securable object that contains a clipboard, an
atom table, and one or more desktops. Every process is associated with
one window station. Within a TS session, only the window station named WinSta0
can display a user interface or receive user input. In TS sessions 1
and higher, Windows creates only a WinSta0 window station. (See Figure 2.)
In session 0, in addition to WinSta0, Windows creates a separate window
station for every LSA logon session associated with a service, with the
locally unique identifier (LUID) of the logon session incorporated into
the window station name. For example, service processes that run as
System run in the Service-0x0-3e7$ window station, while those that run as Network Service run in the Service-0x0-3e4$ window station. These window stations cannot display UI.
PsExec -s cmd.exe runs a command prompt in the Service-0x0-3e7$ window station and redirects its console I/O to PsExec. PsExec’s -i
option lets you specify the terminal services session and runs the
target process in its WinSta0 window station.
A service configured to run as
System can also be configured to Allow Service To Interact With Desktop.
When so configured, the service runs in session 0’s WinSta0 instead of Service-0x0-3e7$.
When the interactive user was also in session 0, this allowed the
service to display UI directly to the end user. In hindsight, this
wasn’t a good idea as I’ll describe shortly, and Microsoft has
recommended against using this technique—and with session 0 isolation,
this no longer works. (The Interactive Services Detection service,
UI0Detect, offers partial mitigation.)
3. Desktops
Each window station
contains one or more desktops. A desktop is a securable object with a
logical display surface on which applications can render UI in the form
of windows.
Note:
The desktops described here are unrelated to the Desktop abstraction at the top of the Windows Explorer shell namespace.
Multiple desktops can
contain UI, but only one can be displayed at a time. There are typically
three desktops in the interactive window station: Default,
Screen-saver, and Winlogon. The Default desktop is where user
applications run by default. (The Sysinternals Desktops utility creates
up to three additional desktops on which to run applications.)
The Screen-saver desktop is where Windows runs the screen saver if
password protection is enabled. The Winlogon desktop, also known as the secure desktop,
is where Windows transfers control when you press Ctrl+Alt+Del and the
default place to display UAC elevation dialog boxes. Permissions on the
Winlogon desktop restrict access only to programs running as System, which protects secure operations involving password entry.
As a process is associated
with a window station, each of its threads is associated with a desktop
within the window station. Although individual threads of a process can
be associated with different desktops, they are usually associated with a
single desktop.
Several Sysinternals utilities, including Process Explore and Process Monitor,
identify the TS session ID to which a process belongs. Although none of
the utilities reliably identify the window station or desktops that a
process is associated with, Process Explorer’s Handle View can offer
hints in the form of open handles to window stations or desktop objects.
For example, in Figure 3,
Process Explorer shows a process running as System in session 0 with
open handles to the \Default desktop and the
\Windows\WindowStations\Service-0x0-3e7$ window station.
4. Window Messages
Unlike console applications,
Windows-based applications are event driven. Each thread that creates
window objects has a queue to which messages are sent. These GUI threads
wait for and then process window messages as they arrive. These
messages tell the window what to do or what occurred. For example,
messages can tell the window “Redraw yourself,” “Move to screen
coordinates (x,y),” “Close yourself,” “The Enter key was pressed,” “The
right mouse button was clicked at coordinates (x,y),” or “The user is
logging off.”
Window messaging is mediated by the window manager. Messages can be sent to any window from any thread running on the same desktop—the window manager does not allow a program to send a window message to a window on a different desktop. Process Monitor’s /Terminate and /WaitForIdle
commands must be invoked from the same desktop on which the target
Procmon instance is running, because they use window messaging to tell
the existing instance to shut itself down and to determine that the
target instance is ready to process commands in the form of window
messages.
Window messages can be
used to simulate mouse or keyboard activity. RegJump and the Jump To
feature in Process Monitor and Autoruns do exactly this to navigate to a
key in Regedit. Because of the levels of abstraction between a physical
keypress and the resulting window messages received by a GUI program,
it is effectively impossible for the target program to know with
absolute certainty whether a key was pressed on a keyboard or another
program simulated a keypress by sending it window messages. (This is
true of all windowing systems, not just Windows.)
Except for the
introduction of multithreading support in 32-bit versions of Windows,
this window messaging architecture dates back to Windows 1.0, and it
brings forward a lot of legacy. In particular, window objects do not
have security descriptors or access control lists. This is why allowing
services to display windows on the user’s desktop was a bad idea—user
programs could send malformed or specially crafted messages to windows
owned by processes running as System and, if successfully exploited,
control those processes. (This is commonly called a shatter attack.)
If the user was not already an administrator, elevation of privilege
became trivially easy. This is the main reason that interactive users no
longer log on to session 0.
With “standard user,”
which is the default mode in Windows Vista and newer—and with UAC
elevation popularizing the ability of applications to run with
administrator rights in the same desktop with nonadministrative
processes—some additional protection was needed to reduce the risk of
shatter attacks against windows owned by elevated processes. The result
is User Interface Privilege Isolation (UIPI).
Prior to Windows Vista, any
process running as a particular user could take complete control over
any other process running as the same user. With Mandatory Integrity
Control (MIC), processes are assigned and run at an integrity level
(IL), a numeric value that indicates the relative trustworthiness of
the process. Elevated apps run at High, normal user apps run at Medium,
and low-rights processes such as Protected Mode Internet Explorer run at
Low.
With
UIPI, when the window manager mediates a window message that can change
the target’s state (such as a button click message), the window manager
compares the IL of the process sending the message to the IL of the
process that owns the window receiving the message. If the sender’s IL
is lower than that of the receiver’s, the message is blocked. This is
the reason that RegJump and similar Jump To features must execute at an
IL at least as high as that of Regedit.
For more information about MIC and UIPI, see the Windows Vista Integrity Mechanism Technical Reference at http://msdn.microsoft.com/en-us/library/bb625964.aspx.