The object manager can generate audit events as a result of an access check, and Win32 functions available to user applications can generate them directly. Kernel-mode code is always allowed to generate an audit event. Two privileges, SeSecurityPrivilege and SeAuditPrivilege, relate to auditing. A process must have the SeSecurityPrivilege privilege to manage the security Event Log and to view or set an object's SACL. Processes that call audit system services, however, must have the SeAuditPrivilege privilege to successfully generate an audit record.
The audit policy of the local system controls the decision to audit a particular type of security event. The audit policy, also called the local security policy, is one part of the security policy Lsass maintains on the local system. Lsass sends messages to the SRM to inform it of the auditing policy at system initialization time and when the policy changes. Lsass is responsible for receiving audit records generated based on the audit events from the SRM, editing the records, and sending them to the Event Logger. Lsass (instead of the SRM) sends these records because it adds pertinent details, such as the information needed to more completely identify the process that is being audited.
The SRM sends audit records via its LPC connection to Lsass. The Event Logger then writes the audit record to the security Event Log. In addition to audit records the SRM passes, both Lsass and the SAM generate audit records that Lsass sends directly to the Event Logger. Figure 8-6 depicts this overall flow.
Figure 8-6 Flow of security audit records
Audit records are put on a queue to be sent to the LSA as they are received—they are not submitted in batches. The audit records are moved from the SRM to the security subsystem in one of two ways. If the audit record is small (less than the maximum LPC message size), it is sent as an LPC message. The audit records are copied from the address space of the SRM to the address space of the Lsass process. If the audit record is large, the SRM uses shared memory to make the message available to Lsass and simply passes a pointer in an LPC message.
Figure 8-7 brings together the concepts covered so far in this chapter by illustrating the basic process and thread security structures. In the figure, notice that the process object and the thread objects have ACLs, as do the access-token objects themselves. Also in this figure, thread 2 and thread 3 each has an impersonation token, whereas thread 1 defaults to the process access token.
Figure 8-7 Process and thread security structures
Viewing Process and Thread Security Information
You can view process and thread security descriptors and access tokens with the Process Explode utility (Pview.exe). (This tool is part of the Windows NT 4 resource kits, but it isn't included with the Windows 2000 resource kit tools. You can, however, download it from www.reskit.com.) The numbering of the six buttons in the Security and Token sections of the Process Explode utility matches up with the process and thread security structures shown in Figure 8-7.
In this example, buttons 4 (ACL for thread token) and 6 (thread access token) are grayed out (disabled) because the currently selected thread (number 1700) has no thread-specific access token.
Try looking at the process ACL for a process in your interactive session—you should see your user ID and SYSTEM in the ACL with full control permissions.
To see process security in action, try the following:
- Create a local username named "test." To add a user, start Computer Management. (In Control Panel, open Administrative Tools and then click on Computer Management; or select Run from the Start menu and enter compmgmt.msc.) Expand Local Users And Groups (under System Tools), right-click on Users, and select New User. Enter the username test (no password), clear the User Must Change Password At Next Logon flag, and press Create. (Note: Your domain or local group policies might require that you enter a password.)
- Open a Windows 2000 Command Prompt window. (From the Start menu, select Programs/Accessories/Command Prompt.)
- Type runas /user:test cmd to create a command prompt running under the test username you just added. (Note: You might need to prefix test with the machine name or domain name, as in runas /user:machine\test cmd.)
- From this command prompt, run Pulist from the Windows 2000 resource kit. Notice that you can't see the security ID of the processes on the system other than the one running Cmd.exe and Pulist.exe under the security context of the test username. The reason you can't see this security ID is that the test username isn't in the ACL on the process access token on any of the other processes—therefore, you have no permission to see who these processes are.
- Now switch back to the command prompt started in step 2 (running under whatever account you were logged on to for this experiment), and run Pulist again. You should see the security IDs of all the processes in your interactive session (and the system processes if your account is a member of the local Administrators group). However, you shouldn't be able to see the security ID of the process running Cmd.exe under the test username (created in step 3) for the same reason that from the test username you can't see the processes not running under test.
- Now run Process Explode again, select a process in your interactive session (such as Explorer.exe), and change the ACL on the process and the process access token to allow the user test to have read access. Modify the process by pressing the Process button to bring up the Process Permissions dialog box. Press Add to add an entry to the process ACL. When the list of groups is displayed, press the Show Users button, scroll down the Names list, select the test username, press Add, and then press OK. You should now see the test username in the ACL. Press OK to make the change on the Explorer process. Follow the same steps again for the process access token, this time pressing the P.Token button instead of the Process button.
- Now go back to the process running Cmd as user test, and run Pulist again. This time, you should be able to see the security ID of the process Explorer.exe because you've granted read access to that process's access token.
The following steps don't work on Windows 2000 server systems that have Terminal Services installed. The reason they don't work in this context is explained after step 10.
- As a final test, start Task Manager, click on the Applications tab, right-click on "cmd (running as test)," and select Go To Process. This takes you to the Processes tab with the cmd.exe process highlighted. Click on this process, and then press the End Process button. (Press Yes in the warning message box that appears.) You should get an access denied error because you're not in the process ACL for that process.
- As an added exercise, rerun Pview.exe from the command prompt running under test and alter the process access for the Cmd.exe process running under test to grant full access to the username you're currently running under. (Press the Process button in PView, press Add, and then add your username to the ACL, remembering to select full control access.)
- Retry step 8—this time, you should be able to terminate the command prompt running under the test username because you granted yourself full access to that process.
The reason that steps 8 through 10 don't work on a system with Terminal Services installed is because the steps rely on the fact that, on systems without Terminal Services, Task Manager uses the TerminateProcess function to end processes. However, when you direct Task Manager to end a process on a system running in a Terminal Services environment, Task Manager calls on Termsrv.exe, the terminal services service, to perform the process termination. Because Termsrv.exe is a service process running in the System account, it has the debug privilege, which it uses to open a process it's terminating without regard to the process's token or process security settings.