Detecting Windows Kerberos implementation elevation of privilege vulnerability attacks with Sentinel - part 2

Detecting Windows Kerberos implementation elevation of privilege vulnerability attacks with Sentinel - part 2

CVE-2014-6324 allows remote elevation of privilege in domains running Windows domain controllers. An attacker with the credentials of any domain user can elevate their privileges to that of any other account on the domain (including domain administrator accounts).

In part 1 I discussed how to to detect attempts to exploit this vulnerability on domain controllers (DCs) that had already been patched. In this post I'll show you how to detect successful attacks on unpatched DCs.

In their Security Research & Defense blog Microsoft describes what to look out for:

Windows Event Viewer - Event 4624


The key piece of information to note in this log entry is that the “Security ID” and “Account Name” fields do not match even though they should. In the screen shot above, the user account “nonadmin” used this exploit to elevate privileges to “TESTLAB\Administrator”.

On the "General" tab the Windows Event Viewer shows the Security ID (SID) as "TESTLAB\Administrator". The actual data in the event is a variable-length structure. This can be seen on the "Details" tab, where SIDs are shown in their standardized string notation ("S-R-I-S-S…"). This is also the value that gets send to Sentinel.  So Sentinel will need to resolve the SID to an account name, before it can compare the value to the account name noted in the event.

Sentinel provides the ability to use mapping to inject additional information into events. To apply this our current problem, we need

  1. a map with SIDs as keys and account names as associated values - let's call it SID_List.

  2. an event mapping for a custom field, so that the field's value is referenced from the map - we'll use field cv56.


Data to build the SID_List map can be gathered in various ways. On windows you can use dsquery or wmic:
dsquery * -s dc01.example.com -filter "&(objectClass=User)" -limit 0 -attr objectSID sAMAccountName

wmic useraccount get sid,name
On the Sentinel server you can use favorite scripting language to pull the data via LDAP. In all cases the output must be formatted to be a CSV file (SID_List.csv) with two columns: the SID in string notation ("S-R-I-S-S…") and the lowercase AccountName.

The current Microsoft Active Directory and Windows collectors puts the SID into the ExtendedInformation field - along with other data. Therefore this field cannot be used as key field for the event mapping. For the event mapping to work, the SID value must be in a field of its own. The Sentinel event schema reserves the TargetUserID (tuid) field for this kind of data. So we have to modify the collector to put the SID value into tuid. The parsing for event 4624 is contained in event_parser.js. Here is a unified diff of what needs to be changed:

diff -ubr Microsoft_Active-Directory-and-Windows_2011.1r5-201410080148-preview.clz/events_parser.js Microsoft_Active-Directory-and-Windows_2011.1r5-201410080148-preview-custom.clz/events_parser.js
--- Microsoft_Active-Directory-and-Windows_2011.1r5-201410080148-preview.clz/events_parser.js 2014-10-08 02:48:36.000000000 +0200
+++ Microsoft_Active-Directory-and-Windows_2011.1r5-201410080148-preview-custom.clz/events_parser.js 2014-11-24 13:30:36.120000000 +0100
@@ -4279,7 +4279,8 @@
}
this.logtype = this.spltIS[8];
this.sessType = instance.MAPS.logontypeMap.lookup(this.spltIS[8]);
-  this.ei_info(instance.MAPS.eiMap.lookup("Security ID"), this.spltIS[4], e);
+  //this.ei_info(instance.MAPS.eiMap.lookup("Security ID"), this.spltIS[4], e);
+  this.tuid = this.spltIS[4];
this.tun = this.spltIS[5];
this.tud = this.spltIS[6];
this.ei_info(instance.MAPS.eiMap.lookup("Logon ID"), this.spltIS[7], e);
@@ -4297,7 +4298,8 @@
this.logtype = messageArray[11].trim();
this.sessType = instance.MAPS.logontypeMap.lookup(this.logtype);
if (messageArray.length >= 57) {
-   this.ei_info(messageArray[15], messageArray[16], e);
+   //this.ei_info(messageArray[15], messageArray[16], e);
+   this.tuid = messageArray[16];
this.tun = messageArray[18];
this.tud = messageArray[20];
this.ei_info(messageArray[21], messageArray[22], e);
@@ -4310,7 +4312,8 @@
this.ei_info(messageArray[38], messageArray[39], e);
this.ei_info(messageArray[40], messageArray[41], e);
} else {
-   this.ei_info(messageArray[13], messageArray[14], e);
+   //this.ei_info(messageArray[13], messageArray[14], e);
+   this.tuid = messageArray[14];
this.tun = messageArray[16];
this.tud = messageArray[18];
this.ei_info(messageArray[19], messageArray[20], e);


Now we can create an event mapping to store the account name resolved from the SID within the event. cv56 is populated from the SID_List map (which has SID_List.csv as its map data source file). The specific value for cv56 is taken from the AccountName column from the SID_List map. The SID column is set as the key. When the TargetUserID field of the event matches one of the values in the SID column of the map, the row with the matching key is used to intersect the AccountName Column.

Finally, we can now write a correlation rule that compares the original account name to the resolved one:

filter(e.cv56 != e.dun)

To stop the rule from generating to much noise, we should check if cv56 actually has a value and group the output by account name:

filter(not(isnull(e.cv56)) AND e.cv56 != e.dun) flow trigger(1,59,discriminator(e.dun))

DISCLAIMER:

Some content on Community Tips & Information pages is not officially supported by Micro Focus. Please refer to our Terms of Use for more detail.
Comments
Thank you for this great explanation. Every bit of detail regarding that oh-so-difficult to monitor Windows platform is worthwhile.
Top Contributors
Version history
Revision #:
1 of 1
Last update:
‎2014-12-02 17:39
Updated by:
 
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.