You are browsing the archive for threat hunting.

Event, Event on the wall, who’s the fairest of them all?

March 29, 2019 in threat hunting

Update

After I posted it, Brian (thx!) pointed me to a very neat research by John Hubbard who takes similar concept to a completely new level. It turns out PowerShell gives us a programmatic access to Windows Event templates and we can use it to access all the info – here is the tweet demonstrating it.

We can write it all down to a file:

$provider = get-winevent -ListProvider Microsoft-Windows-Security-Auditing

$provider.events | Out-File -FilePath "eventdump.txt"

We can then do same exercise as I did before and get this nice list (Windows 7):

  • 4611 LogonProcessName
  • 4615 ProcessName
  • 4616 ProcessName
  • 4616 ProcessName
  • 4624 LogonProcessName
  • 4624 ProcessName
  • 4625 LogonProcessName
  • 4625 ProcessName
  • 4648 ProcessName
  • 4649 LogonProcessName
  • 4649 ProcessName
  • 4656 ProcessName
  • 4656 ProcessName
  • 4657 ProcessName
  • 4658 ProcessName
  • 4660 ProcessName
  • 4661 ProcessName
  • 4661 ProcessName
  • 4663 ProcessName
  • 4670 ProcessName
  • 4673 ProcessName
  • 4674 ProcessName
  • 4688 NewProcessName
  • 4688 NewProcessName
  • 4689 ProcessName
  • 4696 TargetProcessName
  • 4696 ProcessName
  • 4904 ProcessName
  • 4905 ProcessName
  • 4907 ProcessName
  • 4985 ProcessName
  • 5039 ProcessName
  • 5050 CallerProcessName
  • 5051 ProcessName
  • 5712 ProcessName

And Windows 10 gives us this:

  • 4611 LogonProcessName
  • 4615 ProcessName
  • 4616 ProcessName
  • 4616 ProcessName
  • 4624 LogonProcessName
  • 4624 ProcessName
  • 4624 LogonProcessName
  • 4624 ProcessName
  • 4624 LogonProcessName
  • 4624 ProcessName
  • 4625 LogonProcessName
  • 4625 ProcessName
  • 4648 ProcessName
  • 4649 LogonProcessName
  • 4649 ProcessName
  • 4656 ProcessName
  • 4656 ProcessName
  • 4657 ProcessName
  • 4658 ProcessName
  • 4660 ProcessName
  • 4661 ProcessName
  • 4661 ProcessName
  • 4663 ProcessName
  • 4663 ProcessName
  • 4670 ProcessName
  • 4673 ProcessName
  • 4674 ProcessName
  • 4688 NewProcessName
  • 4688 NewProcessName
  • 4688 NewProcessName
  • 4688 ParentProcessName
  • 4689 ProcessName
  • 4696 TargetProcessName
  • 4696 ProcessName
  • 4703 ProcessName
  • 4798 CallerProcessName
  • 4799 CallerProcessName
  • 4818 ProcessName
  • 4904 ProcessName
  • 4905 ProcessName
  • 4907 ProcessName
  • 4911 ProcessName
  • 4913 ProcessName
  • 4985 ProcessName
  • 5039 ProcessName
  • 5050 CallerProcessName
  • 5051 ProcessName
  • 5712 ProcessName
  • 6417 ProcessName
  • 6418 ProcessName

Old Post

This post started with a bold idea inspired by the song ‘I want it all’ by Queen. Not really, I made it up, but the mood is similar.

No one, at least to my knowledge, has ever enabled all the possible event logs for testing purposes. We are obviously very used to the known Event IDs e.g. 4688 (A new process has been created), 4689 (A process has exited), but perhaps there is more… For example, how many of us enabled 6410 (Code integrity determined that a file does not meet the security requirements to load into a process)?

Obviously, I was wondering what would happen if we enabled them all, but also, which of them would have a practical meaning to our defensive efforts.

In my attempt to answer the question I went in two different directions. I was not aware there was a even better direction – one that I mentioned at the top of this post and which relies on research of John Hubbard. Since John’s approach is better, you can ignore my ‘manual’ data extraction process described below, and just use powershell to extract all the info you need. TL;DR; you don’t need to read the stuff below 🙂

First, a bit of a background. I don’t know if you know, but the Microsoft web site provides an awesome feature that helps reading their docs. It allows you to download pages and sections of their documentation as a PDF. It is contextual. Wherever you are, you can just download what’s there + everything lower in the documentation hierarchy in one go. Seriously, this is one of the coolest features ever and if you have not used it before, you gonna love it…

Say you find the description of the Event ID 4688. If you look at the left corner of your browser, there is a ‘Download PDF’ button.

Yup. You can download this specific page as a PDF. Now go to the parent node, and climb up the hierarchy. Now you can download the whole section that page belongs to. With that, I downloaded the whole Security Auditing section.

Secondly, the documentation for Windows Events is pretty good. One thing that I remembered seeing before was that it contained a systematic description of actual fields related to specific events. The nice folks at Microsoft define these fields using a standard syntax:

FieldName [Type = FieldType]: description

For example:

Now I got the whole PDF full of descriptions of all events featured in that aforementioned Security Auditing section and… I know I can parse it.

I converted the PDF to text, and wrote a simple perl script that produced this nice log. There are duplicates there, plus some data is truncated (you will see below), but:

  • such data set is instantly available (took me 5 minutes)
  • can immediately support threat hunting and may lead us to uncharted territories (this is where we want to go, right?)

Let’s have a look at an example.

We can load this data set into Excel, and then filter by a keyword Process Name – I hope you will agree that any field with such a name is interesting to us from a detection perspective:

This produces a nice list of Events that refer to process names one way or another:

  • 4799(S): A security-enabled local group membership Process Name
  • 4798(S): A user’s local group membership was Process Name
  • 4688(S): A new process has been created. New Process Name
  • 4688(S): A new process has been created. Creator Process Name [Version 2]
  • 4696(S): A primary token was assigned to process. Process Name
  • 4696(S): A primary token was assigned to process. Target Process Name
  • 4689(S): A process has exited. Process Name
  • 4937(S): A lingering object was removed from a Process Name
  • 4932(S): Synchronization of a replica of an Active Caller Process Name
  • 4624(S): An account was successfully Process Name
  • 4624(S): An account was successfully Caller Process Name
  • 4648(S): A logon was attempted using explicit Process Name
  • 5144(S): A network share object was deleted. Process Name
  • 4658(S): The handle to an object was closed. Process Name
  • 4660(S): An object was deleted. Process Name
  • 4663(S): An attempt was made to access an object. Process Name
  • 4985(S): The state of a transaction has changed. Process Name
  • 4670(S): Permissions on an object were changed. Process Name
  • 4690(S): An attempt was made to duplicate a handle Process Name
  • 4663(S): An attempt was made to access an Process Name
  • 4657(S): A registry value was modified. Process Name
  • 4818(S): Proposed Central Access Policy does not Process Name
  • 4907(S): Auditing settings on object were changed. Process Name
  • 4904(S): An attempt was made to register a security Process Name
  • 4905(S): An attempt was made to unregister a Process Name
  • 4703(S): A user right was adjusted. Process Name
  • 4911(S): Resource attributes of the object were Process Name
  • 4913(S): Central Access Policy on the object was Process Name
  • 6144(S): Security policy in the group policy objects Process Name
  • 4611(S): A trusted logon process has been registered Logon Process Name

We can apply other filters e.g. file, path, object, etc. and come up with additional events that may be worth exploring!

In other words, we don’t need to enable all audit policies to cherry-pick some interesting events, and then can simply just focus on targeted analysis!

Time for the take two.

If you ever wondered where the Event Logs come from, and I don’t mean all these magic unicorns that write them, or aggregate them, but the templates that are used to ensure their ‘look and feel’ is always the same – read below. (a note here: to be accurate, the layout of templates changes across OS versions — 4688 is a great example of it with its additional fields added in Windows 10/2016).

So, where do these templates come from?

Searching Windows 10 binaries one can quickly find files that refer to these event log templates — they are stored inside the Security Audit Schema DLL and its associated MUI file:

  • \Windows\System32\adtschema.dll
  • \Windows\System32\en-US\adtschema.dll.mui

If you open any of them inside the Resource Hacker you will immediately spot this very Message Table:

The table is organized in a neat way and it’s easy to extract all the Event templates from the file as IDs refer to specific Event IDs.

Once you do it, there are a few interesting research avenues to pursue here:

  • If you use a localized version of OS, you can extract templates for languages other than English; this may sound silly, but many ‘native’ fields in Event Logs are unfortunately localized 🙁 it’s a very expensive mistake that localization teams did at Microsoft long time ago and stuck to it. It makes writing queries e.g. in Splunk harder, because you need to coalesce a number of localized field names if you are dealing with Events coming to you in multiple languages, and if some of them happen to use the localized template.
  • Secondly, we can try to duplicate the analysis I did for the PDF and extract interesting event IDs that might have escaped the attention of security community till now
  • Thirdly, we can extract templates from various OS versions and compare them, building a superset schema for all OS versions and Event versions (may come handy with generic parsing)
  • Finally, if we are quick and look at the latest version of OS there is always a possibility we may come across new event ID or templates that have not been documented yet

If you are curious about the second bullet point, here’s a result for a Process Name filter:

  • 4611 A trusted logon process has been registered with the Local Security Authority
  • 4624 An account was successfully logged on
  • 4625 An account failed to log on
  • 4648 A logon was attempted using explicit credentials
  • 4649 A replay attack was detected
  • 4656 A handle to an object was requested
  • 4657 A registry value was modified
  • 4658 The handle to an object was closed
  • 4660 An object was deleted
  • 4661 A handle to an object was requested
  • 4663 An attempt was made to access an object
  • 4670 Permissions on an object were changed
  • 4673 A privileged service was called
  • 4674 An operation was attempted on a privileged object
  • 4688 A new process has been created
  • 4689 A process has exited
  • 4696 A primary token was assigned to process
  • 4703 A token right was adjusted
  • 4798 A user’s local group membership was enumerated
  • 4799 A security-enabled local group membership was enumerated
  • 4818 Proposed Central Access Policy does not grant the same access permissions as the current Central Access Policy
  • 4904 An attempt was made to register a security event source
  • 4905 An attempt was made to unregister a security event source
  • 4907 Auditing settings on object were changed
  • 4911 Resource attributes of the object were changed
  • 4913 Central Access Policy on the object was changed
  • 4985 The state of a transaction has changed
  • 5039 A registry key was virtualized
  • 5050 An attempt to programmatically disable Windows Firewall using a call to INetFwProfile
  • 5051 A file was virtualized
  • 6417 The FIPS mode crypto selftests succeeded
  • 6418 The FIPS mode crypto selftests failed

I hope some of you will find it interesting and will explore some of these new Event IDs. This requires a bit of a patience & time, because in some cases re-creating conditions in which these events trigger may be non-trivial.

The story of an underTAG that tried to wear a mitre…

March 10, 2019 in Mitre Att&ck, Preaching, Random ideas, Sysmon, threat hunting

Today we tag everything with Mitre Techniques. I like it, but I would also want a bit more flexibility. So, I like to mix the ‘proper’ Mitre tags with my own tags (not only subtechnique tags, but also my own specific tags).

Why?

Say… you detect that System.Management.Automation.dll or System.Management.Automation.ni.dll is loaded into a process. Does it mean it is T1086: PowerShell? Or does it mean, that the process is using a DLL that offers automation capabilities? And may not even do anything dodgy? I suspect (s/suspect/know/) that calling it T1086: PowerShell w/o providing that extra info loses a lot of context.

Why not calling it what it is? <some magic prefix>: Powershell Automation DLL?

Is loading WinSCard.dll always an instance of T1098: Account Manipulation, or T1003: Credential Dumping? Or is it just a DLL that _may_ be used for nefarious purposes, but most of the time it is not (lots of legitimate processes use it; sysmon logs analysis is a nice eye opener here).

Why not calling it <some magic prefix>: Smart Card API DLL?

As usual, at the end of this tagged event, or events’ cluster, there is a poor soul, and the underdog of this story that is tasked with analysing it. If our tagging is as conservative as the mindset of politicians who studied at Eton… then so will be the quality of analysis, statistics, and actual response.

And it is easy to imagine confusion of analysts seeing events tagged with a vague name. For example, net.exe command that accesses user/account data, and the loading of WinSCard.dll may make them assume that there is a cluster of ‘account manipulation’ events indicating an attack. A triage of such vague cluster of events is a time wasted… There is a response cost, and there is an opportunity cost at play here. The example is over-simplistic of course, but the devil is in the details. Especially for the analysts.

I’d say… given the way most of events are logged today, often w/o much correlation and data enrichment at source, the event collection process should make any attempt possible to contextualize every single event as much as possible.

We can argue that combining data at its destination, in aggregation systems, SIEMs, collectors, or even ticketing systems, or on a way to them, is possible and actually, desirable… today’s reality is that we need that single event to provide as many answers as possible…

This is because we know that Data Enrichment at the destination is a serious pain in the neck and relies heavily on a lot of dependencies (up to date asset inventories, list of employees, DHCP mapping, then there is a lack or poor support of nested queries, poor performance of nested queries, and this forces us to use a lot of lookup tables that need to be up to date and require a lot maintenance). And if we need to go back to the system that generated event to fetch additional artifacts, or enrich data manually, then we are probably still stuck in a triage process A.D. 2010…

So… if we must tag stuff, let’s make it work for us, our analysts, and make it act as a true data enrichment tool that it was meant to be… If the event, their cluster, or detection based on them is not actionable, then it’s… noise.