# Hunting Falcon

<details>

<summary>Renamed Command Line Programs</summary>

```
event_platform=win event_simpleName=ProcessRollup2 ImageSubsystem_decimal=3
```

\\

</details>

<details>

<summary>PE Language ID Prevalence in PeVersionInfo</summary>

```
event_simpleName=PeVersionInfo event_platform=win NOT LanguageId_decimal IN (1033, 0)
| rex field=FilePath "(\\\\Device\\\\HarddiskVolume\d+)?(?<trimmedFilePath>.*)"
| search "Users"
| regex trimmedFilePath!=".*\\\(Google|boot\\efi)\\\.*"
| regex FileName!=".*\.LocalizedResources\..*"
| stats count(aid) as uniqueEndpoints, values(FileName) as fileNames, values(OriginalFilename) as originalFileNames, values(trimmedFilePath) as filePaths by SHA256HashData, LanguageId_decimal
| sort -occurrences 
| lookup local=true LanguageId.csv LanguageId_decimal OUTPUT lcid_lang, lcid_string
| table SHA256HashData, fileNames, originalFileNames, filePaths, uniqueEndpoints, LanguageId_decimal, lcid_lang, lcid_string
| rename SHA256HashData as SHA256, fileNames as "File Names", originalFileNames as "Original FileNames", filePaths as "File Paths", uniqueEndpoints as "Endpoints", LanguageId_decimal as "Language ID", lcid_lang as "LCID Code", lcid_string as "LCID String"
```

![](https://1771079106-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MQbAc68qKpvpcr7cwG8%2Fuploads%2F1YSeQvmDONlquqWqTNE4%2Fimage.png?alt=media\&token=50cca57a-4b24-46a1-947b-b8a702f2a321)

<mark style="color:red;">**Explanation**</mark><mark style="color:red;">:</mark>\
&#x20;\ <mark style="color:red;">🔸</mark>When a Portable Executable (PE) file is written to disk or loaded, the sensor will generate the `PeVersionInfo` event. There is quite a bit of useful information contained within: `FileVersion`, `OriginalFileName`, etc. The field that is usually overlooked, that we’ll zoom-in on today, is `LanguageId_decimal`.\ <mark style="color:red;">🔸</mark>The field `LanguageId_decimal` is mapped to the Windows Language Code Identifier (LCID) value as [specified](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/70feba9f-294e-491e-b6eb-56532684c37f?source=recommendations) by Microsoft. The Microsoft article requires the download of a PDF or DOCX file to view it, but you can see an extrapolated table at [this](https://www.science.co.il/language/Locale-codes.php#definitions) website.\ <mark style="color:red;">🔸</mark>So the general hypothesis is: if I see a low prevalence PE file being written or loaded that has an unexpected LCID value for my environment, that might be a point of interest to start a hunt and/or investigation.

</details>

<details>

<summary>Windows Dump Files</summary>

```
(event_simpleName=ProcessRollup2 OR event_simpleName=SyntheticProcessRollup2) AND FileName=WerFault.exe AND ParentBaseFileName=prunsrv-amd64.exe
| rename TargetProcessId_decimal AS ContextProcessId_decimal, FileName as crashProcessor, ParentBaseFileName as crashingProgram, RawProcessId_decimal as osPID
| join aid, ContextProcessId_decimal 
    [search event_simpleName=DmpFileWritten]
| table timestamp aid ComputerName UserName crashProcessor crashingProgram TargetFileName ContextProcessId_decimal, osPID
| sort + timestamp
| eval timestamp=timestamp/1000
| convert ctime(timestamp)
| rename ComputerName as endpointName, UserName as userName, TargetFileName as dmpFile, ContextTimeStamp_decimal, as crashTime, ContextProcessId_decimal as falconPID
```

<mark style="color:red;">**Explanation:**</mark>\
\
Problematic programs. Software wonkiness. LSASS pilfering. Dump files on Windows are rarely good news. This week, we're going to do some statistical analysis on problematic programs that are creating a large numbers of dump files, locate those dump files, and upload them to the Falcon cloud for triage.\
What we are absolutely NOT going to do is make jokes about dump files, log purges, flushing the cache, etc. That is in no way appropriate and we would never think of using cheap toilet humor like that for a laugh.

**Step 1 - The Event**

When a Windows process crashes, for any reason, it typically goes through a standard two step process. In the first step, the crashing program spawns `werfault.exe`. In the second step, `werfault.exe` writes a dump file (usually with a `.dmp` extension, but not always) to disk.

In the first part of our journey, since we're concerned about things spawning `werfault.exe`, we'll use the `ProcessRollup2` event. You can view all those events (there are a lot of them!) with the following query: \
\&#xNAN;*<mark style="color:orange;">event\_platform=win (event\_simpleName=ProcessRollup2 OR event\_simpleName=SyntheticProcessRollup2)</mark>*\
**NOTE**: Falcon emits an event called `SyntheticProcessRollup2` when a process on a system starts before the sensor is there. Example: Let's say you install Falcon for the first time, right this very second, on the computer you're currently using. Unlike some other endpoint solutions (you know who you are!), you do not need to restart the system in order for prevention to work and for EDR data to be collected and correlated. But Falcon just arrived on your system, and your system is running, so there are some programs that are *in flight* already. Falcon takes a good, hard look at the system and emits `SyntheticProcessRollup2` events for these processes so lineage can be properly recorded, the Falcon Situational Model can be built on the endpoint, and preventions enforced.

**Step 2 - FileName and ParentBaseFileName Pivot**

What we need to do now is to refine our query a bit as, at present, we're just looking at every Windows process execution. We'll want to key in on two things: (1) when is `WerFault.exe` running (2) what is invoking it. For this we can use the fields `FileName` and `ParentBaseFileName`. Let's get all the `WerFault.exe` executions first. To do that, we'll just add one argument to our query:\ <mark style="color:orange;">event\_platform=win (event\_simpleName=ProcessRollup2 OR event\_simpleName=SyntheticProcessRollup2) AND FileName=werfault.exe</mark>\
Now we should be looking at all executions of `WerFault.exe`.

Fun fact: the "wer" in the program name stands for "Windows Error Reporting."

**Step 3 - Statistical Analysis of What's Crashing**

What we want to do now is either: (1) figure out what programs seems to be crashing a lot (operational use case) or (2) figure out what programs aren't really crashing that much and what are the dump files (hunting use case).

With the query above we have all the data we need, it just needs to be organized using `stats`. Here we go...\ <mark style="color:orange;">event\_platform=win (event\_simpleName=ProcessRollup2 OR event\_simpleName=SyntheticProcessRollup2) AND FileName=werfault.exe</mark> \ <mark style="color:orange;">| stats dc(aid) as endpointCount count(aid) as crashCount by ParentBaseFileName</mark> \ <mark style="color:orange;">| sort - crashCount</mark> \ <mark style="color:orange;">| rename ParentBaseFileName as crashingProgram</mark>\
\
**Here's what we're doing:**

* `by ParentBaseFileName`: if the `ParentBaseFileName` (this is the thing invoking WerFault) is the same, treat the events as a dataset and perform the following `stats` commands.
* `| stats dc(aid) as endpointCount count(aid) as crashCount`: perform a distinct count on the field `aid` and name the output `endpointCount`. Perform a raw count on the field `aid` and name the output `crashCount`.
* `| sort - crashCount`: sort the values in the column `crashCount` from highest to lowest.
* `| rename ParentBaseFileName as crashingProgram`: unnecessarily rename `ParentBaseFileName` to `crashingProgram` so it matches the rest of the output and Andrew-CS's eye doesn't start twitching.

A few quick notes...

You can change the sort if you would like to see the field `crashCount` organized lowest to highest. Just change the `-` to a `+` like this (or click on that column in the UI):\ <mark style="color:orange;">| sort + crashCount</mark>\\

I personally like using `stats`, but you can *cheat* and use `common` and `rare` when evaluating things like we are.

Examples:\ <mark style="color:orange;">event\_platform=win (event\_simpleName=ProcessRollup2 OR event\_simpleName=SyntheticProcessRollup2) AND FileName=werfault.exe</mark>\
Or...\ <mark style="color:orange;">event\_platform=win (event\_simpleName=ProcessRollup2 OR event\_simpleName=SyntheticProcessRollup2) AND FileName=werfault.exe | common ParentBaseFileName limit=25</mark>\
You can change the `limit` value to whatever you desire (5, 10, 500, etc.).

Okay, back to our original query using stats. As a sanity check, it should look something like this: <https://imgur.com/a/2Spsqup>

**Step 4 - Isolate a Dump File**

In my example, I see `prunsrv-amd64.exe` crashing one time on a single system. So what we're going to do, in my example, is: isolate that process, locate it's dump file, and upload it to Falcon via Real-Time Response (RTR).

What we need to do now is link two events together, the process execution event for WerFault and the dump file event for whatever it created (`DmpFileWritten`).

This is the query:\ <mark style="color:orange;">(event\_simpleName=ProcessRollup2 OR event\_simpleName=SyntheticProcessRollup2) AND FileName=WerFault.exe AND ParentBaseFileName=prunsrv-amd64.exe</mark> \ <mark style="color:orange;">| rename TargetProcessId\_decimal AS ContextProcessId\_decimal, FileName as crashProcessor, ParentBaseFileName as crashingProgram, RawProcessId\_decimal as osPID</mark> \ <mark style="color:orange;">| join aid, ContextProcessId\_decimal \[search event\_simpleName=DmpFileWritten]</mark>\
As you can see, we've added `AND ParentBaseFileName=prunsrv-amd64.exe` to the first line of the query to isolate that program. Here's what the rest is doing:

* `| rename TargetProcessId_decimal AS ContextProcessId_decimal, FileName as crashProcessor, ParentBaseFileName as crashingProgram, RawProcessId_decimal as osPID`: this is a bunch of field renaming. The very important one, is renaming `TargetProcessId_decimal` to `ContextProcessId_decimal` since the event `DmpFileWritten` is a context event. This is how we'll be linking these two together.
* `| join aid, ContextProcessId_decimal`: here is the `join` statement. We're saying, "take the values of `aid` and `ContextProcessId_decimal`, then search for the matching corresponding values in the event below and combine them.
* `[search event_simpleName=DmpFileWritten]`: this is the sub-search and the event we're looking to combine with our process execution event. Note sub-searches always have to be in braces.

We'll add some quick formatting so the output is prettier:\ <mark style="color:orange;">(event\_simpleName=ProcessRollup2 OR event\_simpleName=SyntheticProcessRollup2) AND FileName=WerFault.exe AND ParentBaseFileName=prunsrv-amd64.exe</mark> \ <mark style="color:orange;">| rename TargetProcessId\_decimal AS ContextProcessId\_decimal, FileName as crashProcessor, ParentBaseFileName as crashingProgram, RawProcessId\_decimal as osPID</mark> \ <mark style="color:orange;">| join aid, ContextProcessId\_decimal \[search event\_simpleName=DmpFileWritten]</mark> \ <mark style="color:orange;">| table timestamp aid ComputerName UserName crashProcessor crashingProgram TargetFileName ContextProcessId\_decimal, osPID</mark> \ <mark style="color:orange;">| sort + timestamp | eval timestamp=timestamp/1000 | convert ctime(timestamp)</mark> \ <mark style="color:orange;">| rename ComputerName as endpointName, UserName as userName, TargetFileName as dmpFile, ContextTimeStamp\_decimal, as crashTime, ContextProcessId\_decimal as falconPID</mark>\
Don't forget to substitute out `prunsrv-amd64.exe` in the first line to whatever you want to isolate.

Just as a sanity check, you should have some output that looks like this: <https://imgur.com/a/r4fneBo>

**Step 5 - Dump File Acquisition**

If you look in the above screen shot, you'll see we have the complete file path of the .dmp file. Now, we can use RTR to grab that file for offline examination. Just initiate an RTR with the system in question (or use PSFalcon!) and run:\ <mark style="color:orange;">get C:\Windows\System32\config\systemprofile\AppData\Local\CrashDumps\prunsrv-amd64.exe.1820.dmp</mark>\
\
**Application In The Wild**

This week's use-case is operational with some hunting adjacencies. You can quickly see (using steps 1-3) which programs in your environment are crashing most frequently or least frequently and, if desired, acquire the dump files (using steps 4-5). You can (obviously) hunt more broadly over the `DmpFileWritten` event and look for unexpected dumps. \
**Bonus**: when a system blue screens for any reason (the dreaded BSOD!) Falcon emits an event called `CrashNotification`... if you want to go hunting for those as well!

\\

\\

\\

</details>

<details>

<summary>Suspicious Network Connections from Processes</summary>

```
event_simpleName="NetworkConnectIP4"
| rename ContextProcessId_decimal as TargetProcessId_decimal
| join TargetProcessId_decimal 
    [ search event_simpleName=ProcessRollup2 ]
| table RemoteIP RemotePort_decimal ImageFileName UserName UserSid_readabl
```

</details>

<details>

<summary>Suspicious PowerShell Process, Spawned from Explorer, with Network Connections</summary>

```
event_simpleName="DnsRequest"
| rename ContextProcessId as TargetProcessId
| join TargetProcessId 
    [ search (event_simpleName="ProcessRollup2" OR event_simpleName="SyntheticProcessRollup2") AND FileName="explorer.exe" 
    | rename TargetProcessId_decimal as ParentProcessId_decimal 
    | join ParentProcessId_decimal 
        [ search event_simpleName="ProcessRollup2" FileName="powershell.exe" ]] 
| table ComputerName timestamp ImageFileName DomainName CommandLine
```

</details>
