By now, you've probably had the opportunity to use the LogParser command-line tool to track and analyze important events in your Windows Security logs, as I showed you how to do in "Targeting Failed Logons," September 2004, InstantDoc ID 43450, and "LogParser," July 2004, InstantDoc ID 42174. I've given you a basic understanding of how this tool works and an example of how to use its Strings field and EXTRACT_TOKEN function to distill data in your domain controllers' (DCs') Security logs. You can use LogParser to write queries that will zero in on just about any Security-log information: Simply look at a sample event for the type of occurrence you want to track, determine which Strings elements you want LogParser to return and how you want to refer to them, and which elements you want to use to filter your data—then use the sample queries in this and my other LogParser articles to format your own queries.

In "Targeting Failed Logons," I wrote about tracking authentication failures caused by bad passwords. Let's examine several other types of events—such as failed authentications caused by problems other than bad passwords, the addition of a member to a group, and certain user-account changes (e.g., password resets)—that the savvy IT pro will want to keep an eye on.

Authentication Failures
Let's begin with a query that tracks authentication failures. Such failures can be a red flag that someone is threatening your network. (You might want to review my earlier LogParser articles to refresh your memory about how the tool's queries work—e.g., the index begins with 0. Also, be aware that you need to type all LogParser commands on one line, even though they are printed on multiple lines here because of space considerations. You can directly download all the listings in this article at, InstantDoc ID 43827.)

When you enable logging for the Windows Audit account logon event category on your DCs, you can track every authentication event that involves Active Directory (AD) user accounts. Windows 2000 uses event ID 676 to report all Kerberos authentication failures other than those caused by a bad password or a skewed clock. Windows Server 2003 uses event ID 672 for both successful and failed Kerberos authentications, so you also need to filter for Event Type 16 (Failure Audit Event). Web Figure 1 (, InstantDoc ID 43827) shows an example of this type of event.

You can use LogParser to filter and report these events. Furthermore, if you're gathering data from Windows 2003 DCs, you can use LogParser's EXTRACT_VALUE and REPLACE_IF_NULL functions to include an explanation of each error code (Windows 2003 uses several). EXTRACT_VALUE is similar to EXTRACT_TOKEN; whereas EXTRACT_TOKEN parses a delimited list of strings and returns the string at position x, EXTRACT_VALUE parses a delimited list of valuename=value pairs and returns the value for the specified value name.

The command that Listing 1 shows supplies an EXTRACT_VALUE list of FailureCode=FailureDescription pairs. When the command runs, LogParser searches the list of delimited strings for the failure code, then returns the appropriate description. Note that I populated the EXTRACT_VALUE list with only the most common codes. If LogParser encounters a FailureCode value name that doesn't appear in the supplied list, EXTRACT_VALUE returns null. Now, I've wrapped the EXTRACT_VALUE expression inside a REPLACE_IF_NULL expression, so if the first argument supplied to REPLACE_IF_NULL is null, the function returns the second value—in this case, a message that directs the reader to Internet Engineering Task Force (IETF) Request for Comments (RFC) 1510, which supplies a complete list of Kerberos error codes. (Be aware that RFC 1510 lists the codes in decimal format even though Windows displays them in hexadecimal format. Web Table 1 lists both formats.) To get the same type of report for NT LAN Manager (NTLM) failed authentication attempts, you can use the command that Listing 2 shows. These queries return a report similar to the one that Figure 1 shows.

If you want to roll up identical records into a summary, which is often more valuable for analysis purposes, you can use the SQL aggregate COUNT(*) function. For example, the command that Listing 3 shows produces one record per user, showing the day and total bad-password authentication failures for that user and day, as Figure 2, page 14, shows.

Group Changes
You can also use LogParser to track Account Management category events. You'll end up with clean reports that show you all group membership additions, which change the group's rights and permissions. Just code a LogParser command that searches for event IDs 636, 632, and 660, which indicate the Security Enabled Group Member Added event for local, global, and universal groups, respectively.

Strings tokens 4 and 1 in these events list the group's and new member's SIDs, respectively. To determine who added the new member, use the event's SID field (as I explain in "LogParser"). For readability purposes, you might want to use the RESOLVE_SID() function to translate the SIDs in the user and group names. However, that function doesn't understand the
format of Strings tokens 4 and 1, which include the percent symbol (%) and brackets (\{\}). Fortunately, LogParser's REPLACE_CHR() function can take care of that problem. Listing 4, page 14, uses the RESOLVE_SID() and REPLACE_CHR() functions to produce the report that Figure 3, page 14, shows. This report lists all new member additions to all local, global, and universal groups and uses the ORDER BY expression to sort the data first by the NewMember column, then by the Group column.

Account Activity
Another great way to use LogParser is to track security-related changes to user accounts. Such changes include password resets, the reinstatement of disabled accounts, or the setting of account controls such as Password never expires.

Windows 2003 and Win2K both log event ID 627 when a user changes his or her password and log event ID 628 when someone else (e.g., an administrator, a Help desk staffer) resets a user's password. You can use the command that Listing 5 shows to track such password resets. This command produces the report that Figure 4 shows.

To identify disabled user accounts that have been re-enabled in Windows 2003, look for event ID 626, as the command in Listing 6 does. In Win2K, you'll need to search for event ID 642 in which the first Strings element includes the value Account Enabled (Web Figure 2 shows a sample event). This query is a little more complicated than in Windows 2003 because the element can hold multiple values. The values are delimited by carriage returns, so you'll need to use the INDEX_OF function (I explain the use of this function in "LogParser"), as the command in Listing 7 shows. This function will return NULL if it doesn't locate the specified value. The queries in Listing 6 and Listing 7 will return a report such as the one that Figure 5 shows.

Privilege Use
The Privilege Use category tracks user rights such as Change system time and Manage auditing and security log. The use of these rights can indicate an intruder exercising a privileged right for such mischief as clearing the Security log. (These rights are defined in Group Policy Objects—GPOs—under \Computer Configuration\Windows Settings\Security Settings\Local Policies\User Rights Assignments.) Enabling the Privilege Use category causes Windows to generate events frequently because of certain rights that computers within the domain constantly exercise, but you can use LogParser to filter out such events and extract key information.

Windows uses event ID 577 or event ID 578 to indicate an instance of the Privilege Use category. (Event ID 576 is used for Privilege Use rights that are granted to a user at logon—e.g., the Backup files and directories right.) Web Figure 3 shows an example of event ID 577, which indicates a system time change. Notice that this event reports both a Primary User Name and a Client User Name. Some rights are exercised by a system service on behalf of the user. In such cases, the Primary User Name will be "NT Authority," "SYSTEM," or a similar name and the Client User Name will show the name of the user. Therefore, I recommend including requests for both primary and client user names and domains in your queries.

To discover which right was exercised, look for the Privileges field, which is token 8 in event ID 577 or token 9 in event ID 578. Windows uses the short, system name instead of the longer, more familiar descriptions found in Group Policy. SeSystemtimePrivilege corresponds to the Change system time right, SeSecurityPrivilege corresponds to the Manage auditing and security log right, and SeIncreaseBasePriorityPrivilege corresponds to the Increase scheduling priority right. (If in doubt as to which right the short name means, simply run an Internet keyword search on the name.)

The query that Listing 8, page 16, shows searches for both event ID 577 and event ID 578. Because the Strings tokens I wanted to search for occupy different places in these two events, I need to add some logic so that LogParser will increment the Strings indices by 1 when dealing with event ID 578. To create that logic, I use the ADD() and SUB() functions. After extracting the domain name (tokens 6 and 3), the command uses STRCAT() to concatenate a backslash (\), then concatenates the client and primary (tokens 5 and 2) respectively. Similar logic extracts the privilege name from its relative positions in both events. To ignore the abundant and typically harmless rights exercised by computers (as I mentioned earlier), the command uses the WHERE clause and the INDEX_OF function to filter out instances in which the Primary User Name includes the dollar sign ($). Figure 6, page 16, shows the resulting output of the command.

Easy Information
With a bit of imagination, you can use LogParser to get the information you need from your network's Security logs. But the Security log is only one source of information that you can use LogParser to analyze. Once you're comfortable with this amazing tool, you can use it to monitor other Windows logs. And remember, after it extracts the information you want, LogParser offers a variety of output options, including .csv, .evt, and .txt files as well as SQL tables. Just run logparser /? from the command line for details about the tool's many options. Happy logging!