Windows NT Event Logging
Windows NT Event Logging
Windows NT Event Logging
By James D. Murray 1st Edition September 1998 1-56592-514-9, Order Number: 5149 316 pages, $34.95 Includes CD-ROM
be disallowed access, and only a single, uniform API will be used by all processes needing to access the event logs and their information.
Figure 2-1. Interaction of a Win32 program with the event logging service
When Windows NT boots, it starts the SCM, which in turn starts all of the services configured for automatic start-up. One of these services is the Event Logging service (EVENTLOG.EXE). When a user-mode process needs to
access the event logs, it must make a request to the event logging service to perform the desired operation (read, write, back up, query, or clear). The request is made by calling one or more of the functions defined by the event logging API. The API is made available to Win32 processes in the %SystemRoot%\SYSTEM32\ADVAPI32.DLL Dynamic Link Library (DLL). (This is the same DLL that contains several other APIs, including those of the Service Control Manager, NT security, and the registry.) The event logging API is therefore the gateway to the information stored in the event logs and the only mechanism available to report events to NT's event logging service. (The event logging API is described in Chapter 4, Windows NT Security Auditing, and Chapter 5, The Event Logging API.) When the operating system, device driver, or application reports an event, it is actually sending the report to the event logging service. The service then stores the information associated with each event as a record in one of the three event log files located on the local system disk. The registry also plays a very important part in event logging. All event sources must be registered to be properly recognized. The event logging service uses each source's registration information to find the localized strings for each event message and for other information. The registry is also where the event logging service's parameters are stored (you'll find out more about this in the following sections). When a user-mode process needs to write an event report to an event log, it requests the handle of an event log using the name of a registered event source. The event logging service searches the registry to determine which log is used by the event source, and passes a handle to the log back to the process. The log handle is then used to send the information on each event reported to the event logging service. When a user-mode process needs to retrieve event information from an event log file, it uses the event logging API to request a handle to the log, and then uses additional API calls to specify which records are read from the log file. The event logging service reads the event record data from the log file and passes it back to the process. The process must then read the registry to find the message files of each event source whose records were read, read the
localized strings from the message file, and use the strings to format the event descriptions. The event logging API may be called only by user-mode applications.[1] Programs that run exclusively in kernel mode, such as most Win32 device drivers, cannot directly call the event logging API. Instead, they must report events using functions provided by the NT I/O Manager specifically for reporting events indirectly to the event logging service. Kernelmode programs may only report events; they may not read, back up, query, or clear the event logs. See Appendix E, Kernel-Mode Event Logging, for more information on implementing event reporting in Win32 kernel-mode programs.
If we were to look at this event using Event Viewer's Event Detail window, we would see the record information displayed as in Figure 2-3. Figure 2-3. Event detail of the security event log containing one event
Comparing the contents of Figures See and See , we can correlate all of the data in the event log record with the information displayed in the Event Detail dialog box. But you can see in the Description box several strings that are not present in the event log record ("The audit log was cleared", "Primary User Name: ", etc.). Where does Event Viewer find these strings? Read on . . .
and, as a result, most Win32 applications report events using only English descriptions. As I mentioned in Chapter 1, all language-dependent information is referred to as localized information. Localized strings used by an application will change based on the primary language and sublanguage used by a Windows NT installation.[2] For example, "initializing," "initialising," and "inicializando" are all localized strings of the same word. The format used to display time, date, and currency information is also locale-dependent. The localized information in an event report includes the name of the event category, the format of the time and date stamp, some types of parameter data, and the event description itself. Nonlocalized information includes all strings and data which remain the same regardless of the system locale, such as file names, common and standard acronyms, process and logon identifiers, and most parameter data. The localized strings in event reports are not stored in the event log files themselves. If they were, then event logs would quickly fill with records containing many redundant, localized event descriptions, most of which would never be seen in Event Viewer. Instead, the localized strings for each event report are (or should be) stored outside of the event logs in message table resources attached to the reporting process's executable file or to an event message file. When the event logging service reads, at the request of a process, a record from an event log file, it must also read from the registry to determine where the localized event strings for the record are kept. The event source named in the event record is matched to a list of registered event sources in the registry. If a match is found, the location of the message resource file is determined from the source's registry values; the strings matching the language of the local system are read from the indicated message resource files(s); the description strings are merged with any nonlocalized data stored in the event log record; and the complete record is returned by the event logging service. If an event source match is not found, then an error will be returned and Event Viewer will display its very helpful "The system cannot find the file specified" message. In the previous section describing the event log files, I noted that some of the strings in the event description displayed in the Event Detail window were not present in the event record data. These strings are localized data stored inside the message file(s) used by the event source
reporting the event. Event Viewer located the specific message files and read the strings using information in the event log record and the registry (see the next section). Event message files are a very good way to isolate localized information from both applications and the event log files. If any description strings need to be changed, added, or removed, only the DLL (dynamic link library) needs to be recompiled, not the entire application. If this isn't a major advantage to your design, then you can do away with the event message file altogether and store the localized description strings in the application's executable file itself. There is one major drawback that is inherited from the use of message files. If the wrong version or an out-of-date event message file is referenced by the event logging service, the description strings may not be found, or the wrong description may be read. This is especially a problem when viewing event logs on a remote system. Event Viewer will read the event record data from the remote log files, but will search the registry of the local system for the corresponding event message files. If the correct version of the event message file is not installed on the local system, an incorrect string may be displayed, or a message indicating that the string associated with the event ID could not be found will result.
The EventLog key contains the configuration parameters for the event logging service. These values are used by the Service Control Manger when loading the event logging service:
HKEY_LOCAL_MACHINE SYSTEM CurrentControlSet Services EventLog ErrorControl 0x00000001 Group "EventLog" ImagePath "%SystemRoot%\system32\services.exe" ObjectName "LocalSystem" PlugPlayServiceType 0x00000003 Start 0x00000002 Type 0x00000020
Under normal circumstances, you should never need to add any values or modify any of the data stored directly under the EventLog key. One notable exception is when an event log file become corrupt and must be manually deleted.[3] The event log files can't be deleted because they are always kept open by the event logging service; the service can't be stopped using the Services applet in Control Panel because so many other services depend on it. The registry editor must therefore be used to change the EventLog\Start value from 0x02 to 0x04, and the system must be restarted. This will prevent the event logging service from being started by the Service Control Manager and will allow the corrupt file to be removed.
MaxSize 0x00010000 Retention 0x00000000 Sources 57 69 6e 6c 6f 67 6f 6e 00 57 69 6e 64 6f 77 Security File "%SystemRoot%\System32\config\SecEvent.Evt" MaxSize 0xffff0000 PrimaryModule "Security" Retention 0xffffffff Sources 53 70 6f 6f 6c 65 72 00 53 65 63 75 72 69 74 System File "%SystemRoot%\System32\config\SysEvent.Evt" MaxSize 0x00080000 RestrictGuestAccess 1 Retention 0x00093a80 Sources 53 70 6f 6f 6c 65 72 00 53 65 63 75 72 69 74
Table 2-1 lists the names and values stored under each event log subkey. Table 2-1: Event Source Values Name Type Description The name and location of the file used to store records for the REG_EXPAND_S event log. This value must be Z changed to relocate the event log files to a different folder or partition. The maximum physical size the log file may grow to. This value must be specified in 64Kb (0x00010000) increments. Nonconforming values are rounded upward to the next 64Kb boundary by the event logging service. The default is 512Kb (0x00080000).
File
MaxSize
REG_DWORD
PrimaryModule
The name of the primary REG_EXPAND_S module (event source) using Z the event log. This key is used only by the security log. Guests and null accounts have read access to the system and application event logs by default. Setting this key to 1 will disallow these accounts access to the event logs. The security log is always protected from access by guest and null accounts.
Retention
REG_DWORD
The possible values for this key are 0x00000000 (overwrite events as needed) and 0xffffffff (do not overwrite events). Any other value is interpreted as "overwrite events older than N days." The value of "N days" is expressed in seconds (0x00015180 for one day and 0x01e13380 for 365 days). This value must be in increments of 86400 seconds. Nonconforming values will be adjusted to the nearest day by Event Viewer. The default Retention key value is 0x00093a80 (7 days).
A listing of all event sources registered with the event log. The name of each registered source is delimited by a NULL character, and the entire list is terminated by two consecutive Sources REG_BINARY NULLs. The last name in the list is that of the event log. This value is automatically updated by the event logging service each time a new event source is added to an event log subkey. Again, you should never need to add any names or directly modify any of the values stored under the event log subkeys, although there are two exceptions. If you want to change the location of the event log files themselves, you'll have to modify the File value manually using the Registry Editor.[4] You'll also need to modify the Sources value directly when removing an event source from the registry. The Sources value is stored in the registry as binary data, and it's difficult to see how the event source names are stored. The following dump shows the Sources value under the Security event log key on my NT system:
0000 0008 0010 0018 0020 0028 0030 53 53 20 20 00 67 4e 70 6f 6f 6c 65 72 00 Spooler. 65 63 75 72 69 74 79 Security 41 63 63 6f 75 6e 74 Account 4d 61 6e 61 67 65 72 Manager 53 43 20 4d 61 6e 61 .SC Mana 65 72 00 50 72 6f 67 ger.Prog 61 6d 65 53 65 63 00 NameSec.
When an event source key (explained in the next section) is added to the registry, the name of the event source is automatically added to the Sources value of the corresponding event log subkey by the event logging service. The Sources value is not actually updated until the new event source registry key is closed. If the new event source registry key fails to close properly, then the event source may be misregistered and may not be usable by Event Viewer. If this happens, you should delete and recreate the event source key. An event source is simply removed by deleting its key from the registry. However, the event logging service does not immediately remove the event source name from the corresponding event log subkey's Sources value. Instead, the Sources value is rebuilt each time the event logging service is started (usually only when the system boots). An application removing an event source may also manually update the Sources value, but it really isn't necessary.
(Application, Security, and System), and one event source subkey (ntbackup, Security, and eventlog) under each event log subkey:
HKEY_LOCAL_MACHINE SYSTEM CurrentControlSet Services EventLog Application ntbackup EventMessageFile %SystemRoot %\System32\ntbackup.exe TypesSupported 0x00000007 Security Security CategoryCount 0x00000007 CategoryMessageFile %SystemRoot %\System32\MsAuditE.dll EventMessageFile %SystemRoot%\System32\MsAuditE.dll ParameterMessageFile %SystemRoot%\System32\MsObjs.dll TypesSupported 0x0000001c System eventlog EventMessageFile %SystemRoot%\System32\netevent.dll TypesSupported 0x00000007
Table 2-2 lists the names and values that may be stored under each event source subkey. Table 2-2: Event Source Key Values Key Type Description The number of event categories that are supported. This name and value is present only if the event source uses event categories.
CategoryCount
REG_DWORD
The location of the category message file(s). Multiple file names are delimited by CategoryMessageFil REG_EXPAND_S semicolons. This name and e Z value is present only if the event source uses event categories. The location of the event message file(s). Multiple file names are delimited by REG_EXPAND_S semicolons. This name and Z value must appear, as every event source must have at least one event message file.
EventMessageFile
The location of the parameter message file(s). Multiple file names are delimited by ParameterMessage REG_EXPAND_S semicolons. This name and File Z value is present only if the event source uses a parameter message file. This mandatory value contains a bitmask of the supported event types. This value is created by ORing one or more of the following values: EVENTLOG_ERROR_TYPE 0x0001 TypesSupported REG_DWORD EVENTLOG_WARNING_TYPE 0x0002 EVENTLOG_INFORMATION_TYP E 0x0004 EVENTLOG_AUDIT_SUCCESS 0x0008 EVENTLOG_AUDIT_FAILURE 0x0010
Print Spooler
The HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ Print\Providers\EventLog key is used to control the reporting of print spooler events. Under Windows NT 3.x, this key value is used to enable (1) or disable (0) the reporting of all print spooler events to the system event log. Under Windows NT 4.0, this key value is a bitfield used to indicate which print spooler events are reported by event types:
Event Type
Bitfiel d
Error events 0x01 Warning events 0x02 Information 0x04 events See the section for information on how to change this registry value using the Printer applet in Control Panel. More information on this registry key is found in the Microsoft Knowledge Base.[5]
CrashOnAuditFail
One last, and very significant, event logging registry key is HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ Lsa\CrashOnAuditFail. Setting this key's value to 1 causes the local system to halt with a STOP message and a blue screen when the security log is filled. This is to prevent the situation in which the system is unable to log any auditable events that may occur on the system because the security log is filled to its capacity. CrashOnAuditFail does not cause the system to be stopped if the application or system logs are filled. Just before the system is halted, the operating system changes the key's value to 2, indicating that when the system is restarted, only an account belonging to the Administrators group may initially log on.[6] Changing the key's value back to 1 enables normal logon sessions. The system must be restarted each time the CrashOnAuditFail value is changed. And this key must be deleted from the registry to disable this feature. The CrashOnAuditFail feature should not be used in most deployments of Windows NT. It exists only to satisfy the operational requirements used by some classified military systems. It is not required in most commercial and private deployments of Windows NT.
housekeeping chores are the responsibility of the NT system administrators. Under Windows NT 4.0, most administrative tasks are performed using the applications found in the Start Administrative Tools (Common) menu, or in the Administrative Tools group box under NT 3.x. And as I mentioned in the previous section, the primary tool used to perform event log maintenance is Event Viewer. If you are not a system administrator, or if you only use your NT system as a stand-alone workstation, then you probably haven't experimented much with NT's system and user administration. If you plan on seriously using event logging for system security and troubleshooting, you need to realize that there is some maintenance involved.
type of tacitly written logging file (error, debugging, auditing, etc.) has the potential of being the source of a mysterious disappearance of available disk space. One solution to this problem is found in the design of many embedded systems that retain logs but have no local disks. They record significant events in a fixed block of nonvolatile memory (EEPROM) allocated as log storage. When the log memory is full, the newest event overwrites the record of the oldest event. This design is called a wrap around or a roll over log. This design is the default record retention policy of the Windows NT event logs, and it is part of the responsibility of the event logging service to follow this policy. The event log record retention policy is used by the system administrators to specify the maximum possible physical size the three event log files may reach, and how to handle an event log that has filled to its capacity. In such a case, the default is for the oldest events in the log to be overwritten by the newest recorded events. You can overwrite this default by saying that you want to overwrite only events older than a specific number of days (1 to 365 days, with 7 days being the default), or that you do not want to overwrite any existing recorded events and instead drop all newly-reported events until the log is cleared. Each event log file may range from 64Kb to (theoretically) 4Gb in size. The maximum possible log file size is really the size of the disk partition where the log file is stored. The practical maximum size is, of course, much smaller. The default size of each event log file is 512Kb, and a "cleared" event log file is always 64K in size. The retention policy for each event log file is set using Event Viewer, and is explained in Chapter 3, Event Viewer.
I have mentioned that event logging is an extremely important part of system troubleshooting and security. Event logging must therefore be protected from both accidental and deliberate corruption. The bottom line is this: the event logs are no more secure than the system itself. Windows NT contains a considerable amount of security that is enabled by default. But unless you have taken deliberate steps to prevent users from successfully tampering with your system, you run a very good chance of leaving security holes open that may be exploited by an intruder. Securing computer systems running the Windows NT operating system is a topic beyond the scope of this book. But we will take a brief look at the possible security problems and question of reliability of the Windows NT event logging facility itself. (See Chapter 4 for more information on Windows NT security.)
Missing Events
One question of reliability is raised by incomplete event pairs. An event pair consists of two event reports that indicate an object has been opened/closed, started/stopped, allocated/deallocated, and so forth. For every "open" event reported, you would expect to see the associated "close" event also reported, right? Well, sifting through even a modestly sized security event log using an automated search and report generation tool (see Appendix A) will reveal many unmatched pairs. An attempt to match up event pairs may indicate that objects have been opened (560), processes have been created (592), and users have been logged on (528), but never closed (562), terminated (593), or logged off (538). One could blame this inconsistency on buggy software, but these events are reported by Windows NT itself! Initially, the problem of open event pairs lies with the auditing policy itself. For example, if you are only tracking failures, but not successes (probably to conserve log space), then any object that was successfully opened, but failed to properly close, will result in an open event pair. This won't be the case with closing events that can't fail. For example, the logoff event (538) can only be logged as successful. To NT there is no such thing as a bad logoff. Sometimes the fault with missing event reports lies with the reporting applications themselves. Perhaps a call made to an event logging API function returned an error, and the
calling application did not handle it properly, or the application simply gave up and didn't attempt to retry reporting the event. Flaws in the application's logic may create circumstances under which an event is not reported, although it should be. And the abnormal termination of a process or thread may cause a failure of objects to properly close. Another source of open pairs is when the system is shut down. The event logging service is just another process running under NT that must be shut down with all the rest. If event logging is stopped before all the other objects are terminated, their closing will not be recorded in the audit log, and open pairs will result. The primary example of this occurrence is from the event logging service itself. When loaded, the event logging service reports in the system log "The event log service has started," but it never reports "The event log service has stopped" when the system is shutting down. (Actually, if the event logging service were able to log this event after it had actually stopped, then NT would truly be a spooky operating system.) If shutting down the system resulted in a significant number of open event pairs, it would seem that we could consider the System Shutdown event (513) to be the closing event for all open pairs. There is a problem, though: this could be true, but without explicit log entries there is no way to know if each open event closed successfully or not. This concept also fails because the Windows NT shutdown event is never recorded in the security log. System Startup (512) and System Shutdown (513) are themselves always an open event pair!
All services started by the SCM run within the context of the Local System account[10] and inherit the security context of the SCM. The event logging service does not appear as a separate process under Task Manager, but can be listed with all other services using the SCList utility included with the Windows NT Resource Kit.
secured with the proper file system and registry permissions. Unfortunately, on systems that allow the users to install software applications, the EventLog registry key must be writeable to allow installation programs to register (create) new event sources. Registry keys are therefore vulnerable to attack. The message files used by such applications are also vulnerable to attack due to the inability of a typical user account to place the installed files under Administrator-only control. It is also possible that a deliberate attack may be directed towards the event log files themselves. A common attack involves the attempt to clear or delete the security log file where incriminating evidence is usually stored. But an attacker would need to log on to the system using an Administrator-level account to succeed. If this type of brute-force attack were successful, it would immediately tip off an alert system administrator that something abnormal had occurred on the system, but there would be no logged evidence to indicate what exactly had taken place. The proper policy would be to immediately restrict all access to the system until it could be determined how, when, why, and by whom the security log was cleared. An intruder with a quest to obtain permanent, ill-gotten access would not want this to happen. A more sophisticated attack would involve simply editing the security log and removing all records that indicated illegal activity. But there is no native NT utility for editing the event log files on a per-record basis, so such a utility would need to be transferred to the system and removed when finished. But the event log files are not shared for writing by the event logging service. The event log files are opened when the event logging service is started, and are not closed until the service is shut down. A sharing violation will result if a process other than SERVICES.EXE attempts to write directly to any of the log files or to read from the security event log. This is true even for processes running under an Administrator-level user account. The log files aren't even easy to directly copy. When the SCM opens each event log file it changes several bit values in each file's header to indicate that the file is open. The event logging service interprets these byte values as an indication that the log file is corrupt. Applications such as Event Viewer are able to successfully read the event log
files because they obtain the handles of the open log files from the event logging API rather than attempting to open the log files directly. To successfully copy an event log you must use the Log Save As menu command in Event Viewer, or use the BackupEventLog function in the event logging API. Unfortunately, the event log files are completely vulnerable to attack if the system is shut down and restarted under MS-DOS--even if the logs are stored on an NTFS partition. [13]
processor mode that allows access to system memory and hardware. Most low-level device drivers and the system executive run in kernel-mode. User-mode is a nonprivileged processor mode in which all user applications, high-level drivers, and protected subsystems (Windows On Windows, POSIX, etc.) execute. User-mode applications cannot access system memory and hardware except by calling kernel-mode system services and drivers. 2. Refer to WINNT.H for a listing of primary languages and sublanguages supported by NT. 3. See Microsoft Knowledge Base, "How to Delete Corrupt Event Viewer Log Files," article Q172156. 4. See Microsoft Knowledge Base, "Moving Security and System Logs to Another Location," article Q111534. The event logs are typically relocated to a volume that contains greater security and/or a greater amount of storage space, or simply in an attempt to reduce the fragmentation of the %SystemRoot% volume. 5. See Microsoft Knowledge Base "EventLog Registry Value Does Not Enable Print Event Logging," article Q143132, "Unable to Disable Print Event Logging in Windows NT 3.5," article Q124549, and "Turning Off Print Job Logging in the System Log," article Q115841. 6. See Microsoft Knowledge Base "How To Prevent Auditable Activities When Security Log Is Full," article Q140058, and "Only Admins May Log in After Applying C2 Security from Reskit," article Q155076. 7. See Microsoft Knowledge Base "Access Denied When Saving Event Log," article Q164430. 8. The appearance of this message box is not reliable, nor is it guaranteed. Experimentation has shown that it may not appear until many failed attempts to write to the filled log file have occurred; after the log is cleared and filled again, it may not reappear at all. 9. Several pieces of Microsoft documentation, including the Event Viewer help file itself, claim that the event logging service may be paused and/or stopped. This is only true under Windows NT 3.x and not under NT 4.0. Too many other services depend on the event logging service to allow it to be paused or stopped. 10. Local System (or, simply, the "System" account) is a predefined account under NT that is used to start all services and local system processes. It is not a user account and has no associated credentials (i.e., domain, username, and password).
11. See Microsoft Knowledge Base "Event Logging Frozen While Doing Heavy Logging," article Q164938. 12. An excellent argument for including the event description message table resource inside the application's executable file. See the discussion of message files in Chapter 6, Message Files. 13. Utilities that can read and write NTFS partitions from MS-DOS and Windows 95 include NTDOSUtils, available at http://www.sysinternals.com.