We’ve recently released a capability called Advanced Hunting in Windows Defender ATP that allows you to get unfiltered access to the raw data inside your Windows Defender ATP tenant and proactively h...
I will take the chance to add some inspiration to the hunting :)
Example:
An event (let's call it Event A) occour but is by itself not classed as malicious. However if Event B accours after a certain amout of time we have an incident. But Event B is by itself not malicious
Solution:
This example is to hunt for a USB Rubber Ducky which is configured to execute powershell and run some commands
First we will Query for the device connection where device description is "HID Keyboard Device" but this event is, by itself not malicious
let MalPnPDevices =
MiscEvents
| where ActionType == "PnpDeviceConnected"
| extend parsed=parse_json(AdditionalFields)
| sort by EventTime desc nulls last
| where parsed.DeviceDescription == "HID Keyboard Device"
| project PluginTime=EventTime, ComputerName,parsed.ClassName, parsed.DeviceId, parsed.DeviceDescription;
After this event we want to see if we have a cmd or powershell execution to determain if this is a USB Rubber Ducky/Bad USB.
To achieve this we use the EventTime to compare with the eventtime of the process start
ProcessCreationEvents
| where ProcessCommandLine contains "powershell" or
ProcessCommandLine startswith "cmd"
| project ProcessCommandLine, ComputerName, EventTime, ReportId, MachineId
| join kind=inner MalPnPDevices on ComputerName
| where (EventTime-PluginTime) between (0min..10s)
We join the first result with the new statement and look for the event time and make sure that the events were recorded within 10 seconds.
(The reson is that the attacker can configure the ducky to delay for x amount of seconds which you normaly do to have time for driver to load, but from attacker perspective you would normaly want the payload to execute as soon as possible) of course you can change the "between seconds" to whatever you want and this is just an example).
Output:
To use this example you may have to tweak it a bit to avoid FPs but this post is more to inspire to extend the queries.
// Hunting for malicious HID Keyboard devices
// PNP Event and Powershell or CMD within 10 seconds after driver load
let MalPnPDevices =
MiscEvents
| where ActionType == "PnpDeviceConnected"
| extend parsed=parse_json(AdditionalFields)
| sort by EventTime desc nulls last
| where parsed.DeviceDescription == "HID Keyboard Device"
| project PluginTime=EventTime, ComputerName,parsed.ClassName, parsed.DeviceId, parsed.DeviceDescription, AdditionalFields;
ProcessCreationEvents
| where ProcessCommandLine contains "powershell" or
ProcessCommandLine startswith "cmd"
| project ProcessCommandLine, ComputerName, EventTime, ReportId, MachineId
| join kind=inner MalPnPDevices on ComputerName
| where (EventTime-PluginTime) between (0min..10s)
Other example scenarios
Event A and then look for a outbound Connection, inbound Connection and then a process start..