Processes and Threads


Windows handles processes in a different manner than UNIX-derived OSs do. A process itself doesn't run; it's simply a container for threads and essential process attributes that are required for the process to function. In its capacity as a container, the process provides the basic memory protection and access control boundaries expected from any multiuser OS. Although the kernel is fully capable of supporting the UNIX-style fork-exec approach, it's almost never done in practice.

In Windows, the basic unit of execution is the thread, although each thread is associated with a corresponding process. All threads belonging to a process share a single address space and security boundary, so each thread has effectively unrestricted access to any other thread running in the same process. The lack of security boundaries between threads becomes important in discussing security tokens and impersonation. For now, however, you should concentrate on some process-loading quirks that occur behind the scenes. This information helps you accurately assess the risk of being able to perform actions such as writing files to certain locations on the file system.

Note

Mark Russinovich and David Solomon are the authors of Microsoft Windows Internals 4th Edition (Microsoft Press, 2005; formerly the Inside Windows series). This book is an essential reference for anyone interested in the Windows architecture.

For a more applied introduction to Windows programming, Windows System Programming by Johnson M. Hart (Addison-Wesley, 2005) is recommended. It might not provide the breadth of Russinovich and Solomon's book, but it offers more practical depth and detailed code samples.


Process Loading

Programmers might never think about Windows process loading, but it can have a major impact on application security. The CreateProcess() function is the most common method of starting a process in Windows. It accepts ten arguments in total, but for the moment, you're concerned only with the first two parameters: the application name and the process command line. The application name parameter is rarely used in practice. Instead, the first argument is typically NULL, followed by the command-line argument containing the executable path and command-line parameters. A security issue may occur when the second argument includes an unquoted executable path containing spaces. This argument causes the CreateProcess() function to traverse the path at each space character until it can find an executable file, as shown in the following call:

CreateProcess(NULL,               "C:\\Program Files\\My Application\\my app.exe",                ...)


Because the spaces leave room for interpretation, the call attempts to find the first likely file and run it. For this example, the search proceeds in the following order:

  1. C:\Program.exe

  2. C:\Program Files\My.exe

  3. C:\Program Files\My Application\my.exe

  4. C:\Program Files\My Application\my app.exe

In Windows 2000 and earlier, this path traversal could be dangerous because any authenticated user could write a C:\Program.exe file that would run instead of the intended file. This error allowed a fairly trivial escalation technique for unquoted paths running in a higher context. The primary example is privilege escalation by exploiting an unquoted service image pathname. The correct way to make this call is as follows:

CreateProcess(NULL,               "\"C:\\Program Files\\My Application\\my app.exe\"",               ...)


Fortunately, Windows XP changed permissions on the root directory, which limits this attack to Power users, who already have the permissions required to overwrite the affected file. However, there has been no change to the actual handling of the filename. This means a privileged process might still be vulnerable to an injection attack if an unprivileged user can write to any directory in the executable path. When auditing, look for failures to quote any executable pathnames passed to CreateProcess().

ShellExecute and ShellExecuteEx

The ShellExecute() and ShellExecuteEx() functions can also be used to start processes and result in an indirect call to CreateProcess(). However, these functions might seem a little deceptive in their naming. Both functions actually use the Windows Explorer shell API for opening files, which you might be familiar with if you've right-clicked a file in Windows Explorer. These functions accept a verb for an operation, such as open, edit, print, explore, or search. The verb (or "open" if no verb is supplied) is then used to determine the appropriate handler for the file, based on the file extension. The easiest way to understand this is to right-click a file in Windows Explorer and see the list of actions displayed in bold type at the top of the shortcut menu; these actions correspond to the verbs.

From a security perspective, you're primarily concerned with the fact that these functions don't necessarily run the supplied file. They might run another application intended to handle this file type, so you need to be especially mindful of when these functions are called with any potentially untrusted input.

DLL Loading

Just like process loading, dynamically loaded libraries (DLLs) can have serious security repercussions. Vulnerabilities can occur because of how Windows searches for a DLL during the loading process. Historically, an ordered search for a DLL proceeds as follows:

  1. Application load directory

  2. Current directory

  3. System32 directory

  4. System directory

  5. Windows (or WINNT) directory

  6. PATH variable directories

Unfortunately, this load process creates a fairly easy way for attackers to replace a system DLL with their own DLL. All they need to do is cause the victim to run code in a directory where an attacker can write files. The attack proceeds as follows:

  1. Attacker writes a malicious DLL that has the same name as a system DLL.

  2. Attacker coaxes the victim to run a command in the attacker-controlled directory.

  3. The loader doesn't identify the DLL in the application directory.

  4. The loader identifies an attacker-controlled DLL with the appropriate name in the current directory.

  5. The application loads the malicious DLL, and code runs in the context of the victim.

Because of this simple attack vector, Windows XP added several features to reduce the threat of injecting a DLL via this method. The initial release of Windows XP included SafeDllSearchMode, which addresses this attack by changing the DLL load process to search the following locations in order:

  1. Application load directory

  2. System32 directory

  3. System directory

  4. Windows directory

  5. Current directory

  6. PATH variable directories

In addition, Windows XP introduced the SetDllDirectory() function, which changes the library load path without changing the current directory. It can be used to place tighter restrictions on a runtime-loaded DLL but doesn't affect a DLL loaded at process initialization. LoadLibraryEx() can also be used in all supported Windows versions for more specific control of how a DLL is loaded.

DLL Redirection

Windows 2000 and XP added the capability for DLL redirection, which was intended to address the common issues with DLL versioning, often referred to as DLL hell. However, it also provides additional security considerations. Specifically, the presence of a redirection file or directory causes Windows to load an alternate set of libraries, even when a qualified path is provided in the call to LoadLibrary() or LoadLibraryEx().

The redirection file is located in the same directory as the application, and the filename is the application filename plus a .local extension. The redirection file content is ignored, but the presence of the file causes DLLs in the current directory to be loaded in preference to any other locations. If the redirection file is actually a directory, the files in that directory are loaded first. DLL redirection is always superseded by an application manifest in Windows XP and later; Windows XP and later also prevent redirection of any DLLs listed in the registry key HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs.

Application Manifests

An application manifest is an XML file containing essential application information. It can affect the application-loading process by including a list of required libraries and modules along with specific version numbers. The required naming convention for the manifest is similar to the redirection file. The file is located in the same directory as the application, and the filename is the application filename plus a .manifest extension.

Potential Vulnerabilities

DLL-loading vulnerabilities occur when attackers can write a file in the library load path that takes precedence over the intended DLL. This vulnerability affected earlier versions of Windows when attackers could control the current directory. Later versions of Windows have added protection; however, they are still vulnerable to variations of this attack. Chapter 2 gave an example of an operational vulnerability that exploits this issue by leveraging a weakness in an inherited permission set.

When auditing for these issues, you must account for the OS version the application runs on and the complete path to the executable. Then step through the library search sequence (listed earlier) and identify whether attackers can write a DLL that takes precedence over the legitimate DLL file. This process involves auditing the file ACL, as discussed earlier in this chapter.

Services

A service is a background process that typically is started automatically at some point during system startup. Services can be configured to run under alternate accounts and are started by the Service Control Manager (SCM). Windows services are roughly equivalent to UNIX daemons, although they also address most of the functional requirements of setuid and setgid programs because Windows attaches no special context to a binary executable. Unlike UNIX, no special permission bits instruct Windows to run a program in a different context. Instead, Windows applications handle privileged operations by creating a service that exposes an IPC interface to lower privileged processes.

In Windows, services almost always run with some degree of elevated privilege and typically expose some form of attacker-facing interface. This is why most attacks on a Windows system focus on compromising a service. General classes of attacks are covered in other chapters, but considerations unique to services are addressed in the following sections and in Chapter 12.

Service Control Permissions

Services are started and stopped by issuing commands to the SCM. These control interfaces are protected by standard Windows access control, meaning the permission for controlling a service can be granted to individual users and groups. For example, the Network Dynamic Data Exchange (DDE) service is used to access a legacy IPC mechanism across the network. It's a popular target of the shatter privilege escalation vulnerability mentioned in Chapter 2. Part of why it makes such a good target is its capability to be started by users. This capability allows attackers to start the service if it's not already running and restart it if a failed attack causes it to crash.

The ability to start a vulnerable service provides a very simple example of a security issue with service control permissions. However, more complex attacks can exploit instabilities in the service startup process. During initialization, services are often more vulnerable to a variety of attacks, such as object squatting and time of check to time of use (TOCTOU, discussed in "TOCTTOU" later in this chapter). Being critical in scrutinizing any application that allows service control by nonadministrative users is essential.

When auditing service control permissions, you need to identify whether any control commands are allowed by nonadministrative users. You generally do this by using the sdshow command of the sc.exe command-line utility. This utility is a standard component in later versions of Windows and can be downloaded from Microsoft's Web site for earlier versions. The sdshow command displays security information in the condensed string format described in the "Security Descriptor Strings" section earlier in this chapter. You can review this section to familiarize yourself with the format, if necessary.

Service Image Path

The command line used to run a service is referred to as the service image path; this string is set when installing the service and contains the executable path followed by any command-line parameters. It might not seem like something to take note of, until you consider the earlier discussion of the CreateProcess() function. Like the majority of Windows processes, services are launched by calling CreateProcess() with a NULL first argument and a second argument containing the combined path and command-line parameters (provided by the image path string). This means an image path containing spaces might be open to hijacking by another executable, as described earlier. The problem is especially serious for services because they run in a more privileged context than a normal user. You can check the image path by using the qc command in the sc.exe command-line utility.




The Art of Software Security Assessment. Identifying and Preventing Software Vulnerabilities
The Art of Software Security Assessment: Identifying and Preventing Software Vulnerabilities
ISBN: 0321444426
EAN: 2147483647
Year: 2004
Pages: 194

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net