You are browsing the archive for Sysmon.

Code Execution via surgical callback overwrites (e.g. DNS memory functions)

June 12, 2019 in Code Injection, Sysmon

Today I looked at Sysmon v10 and its support for logging DNS queries. It’s a pretty cool feature that intercepts all the DNS requests on a monitored host, and if possible, maps them to the process name making that request. It is a nice addition to Sysmon’s already awesome logging capabilities.

Just for fun, I created a simple POC that used DnsQuery_A API to send a multiline DNS query, because I wanted to see how Sysmon will react to it. It was obviously a non-sensical exercise, but it’s fun to see we can modify the layout of Event Logs by introducing some unexpected, redundant data:

Anyway…

I decided to look at the DnsQuery_A function in IDA as well. I was curious if/what characters it accepts & if there is any limit to the buffer it can process. This was a quick & dirty attempt to see if I could send a query that Sysmon would truncate in a similar fashion as I described in this post.

While digging into the code I noticed an interesting way dnsapi.dll is allocating memory. Instead of a fixed (inline) function it relies on a couple of callbacks. One of them is a memory allocation routine. When the library needs memory, it calls the function, and if it is not set, it relies on its own internal routines.

This immediately caught my attention. If we can find the address of this callback inside a remote process we can use it to execute code next time DNS library asks for memory.

This is the memory allocation function used by DnsQuery_* functions (32-bit):

Under normal circumstances finding callback pointers in a remote process memory is quite hard and noisy (lots of ReadProcessMemory calls, possible disassembling). Unless of course there is an interface we can use to surgically target some specific callback (e.g. using documented windows messages, or SetProp function). As far as I can tell there is no such interface in our case.

I found a surrogate solution that we can try to exploit though.

When I looked at references to the callback function (which I named fnMemAlloc on the listing above) I discovered a exported function called DnsApiHeapReset. It takes 3 arguments and each of them is … a callback replacement:

I quickly analyzed each callback’s role and they just are 3 basic/core memory allocation/reallocation/release primitives.

So…

If we can locate the address of dnsapi.dll in a remote process (easy), find the address of exported DnsApiHeapReset function (easy), then with a basic parsing of its code we can discover the address of each callback (also easy). Then, with a single, surgical WriteProcessMemory call we can modify any of them.

This is not a new code injection trick. It’s just one way to execute code without engaging remote threads, APCs, windows hooks, side-loading, process hollowing, patching API code (e.g. NtClose), etc..

There are of course tons of other callbacks like this, but finding their exact location without any point of reference is hard. Or… not really. Just think of all the Windows Procedures – all of them are callbacks.

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.