What is a detection?
The term “detection” generally refers to a scheduled query against a database, and if that scheduled lookup gets any results, generally that would trigger an alert. The query then has parameters added to narrow down the search window of the query (what table, what timeframe, specific boleans that must be true simultaneously) to reduce risk of false positives or benign positives.
In a sense, it is an automated threat hunting – except the usecases of the queries tend to vary.
Why are detections made?
Detections are created to cover a wide area of threats, tactics, and procedures from the MITRE attack chain. The earlier an attack can be detected in the kill chain, the less impact it will have on the environment. As such, detections can be set for reconnaissance, initial access, and so on, and the number of detections within one specific MITRE tactic can give you an estimate of what type of coverage you have.
A detection query tends to be created either as a proactive initiative in response to new POCs, a lacking in a MITRE tactic, findings in pentests, or from CTI information about new threat actor tactics and methods that require urgent alerting.
Then, once the detection is made, you want to balance the signal to noise ratio to ensure the right balance between correct usecase coverage (to avoid being blindsided) while minimizing alert fatigue.
More on that below!
Design philosophy of automated detections
So – a query could be imagined as just the entire log database, which can be an oceanic quantity of data. We can trim that down to a specific table, like so:
DeviceNetworkEvents
//this query would get all the data for the DeviceNetworkEvents table within the timeframe
This data is then filtered down with parameter after parameter to get the exact, needle-thin specific usecase you want.
DeviceNetworkEvents //everything from the DeviceNetworkEvents table
| where DeviceName == “Device” //filter by only the network events for this device
| where RemoteURL == “URL” //further filter by only the traffic to this URL
By adding further parameters, you are thinning down your search query to only the specific requirements, which makes it less likely to trigger. Ideally, you’d run the query against the dataset you’re expecting to work against to see what noise might occur and filter accordingly. Best practice is to also run the query against a lab environment to check that the attack you’re trying to detect is being detected correctly.
Otherwise, you’re just kind of talking to a database for no reason (or threat hunting!) 😊
Examples
The absolute best-case scenario is to simply have a perfect query that never triggers unless it is a True Positive, but in the same way, it would be wonderful if all the tasty food in the world was also the healthiest. Alas!
Let’s look at an example:
A critical server is triggering alerts
You have a specific detection rule for detection LDAP enumerations within your environment. The scope of the detection includes a critical server that makes regular LDAP lookups akin to the you’re your detection flags as LDAP enumerations. The server is critical, but the number of alerts it is spawning is putting your SOC at risk of alert fatigue.
How do we solve this issue?
Option 1: Filter out the server
A quick and easy solution is to simply filter out the server. Add a bolean to your query that checks that the issuing server is not the noisy server. Done, no more alerts.
While this could be a very temporary solution, and it will stop the alert fatigue, you are also blinding yourself to a very real threat of LDAP enumerations from that specific server. Not a great choice.
Option 2: Let it be
Another solution is to simply leave it as is. If the SOC analysts are aware that this server is noisy, they can quickly check it and close the incident if nothing looks out of the ordinary.
The apparent issue here is alert fatigue. Alert fatigue can highly impact the efficacy and productivity of your SOC, and it is not something that can be simply ignored. It’s part of the human condition to find pattern in things, and if you’re specifically looking for that pattern, you may just find it even if it’s not there.
An abundance in alarms can also muddy important statistical data that can help understand where you can improve your security posture within the organization by checking what alarms are triggered and why.
Fringe Case vs Alert Fatigue
This leads us to a specific situation a detection engineer might face – assuming you don’t have the option to narrow the scope of your detection without blinding ourselves, is it better to risk alert fatigue or to risk missing a very fringe usecase?
Ideally, when you encounter this situation where an alert is generating many false or benign positives, you should consider if you can go more specific in how the attack is triggered. Is there something in a genuine attack that only would be generated in that specific attack? Run the attack in a lab environment and experiment against your data in hunting queries both in lab and non-lab environment to see if you can trim without blinding yourself to the very specific attack.
So in the examples below, the engineer is advised to try the LDAP attack in a lab environment, then see if they can be more specific in their query for detecting it – while not missing other types of attacks.
Trim, test, run against valid data to not miss attacks, and regular maintenance of your detection index makes for healthy detections. Penetration tests or purple team exercises can be a great way to test if your queries are up to par (or if you have MITRE usecases you’re missing), but until then, be kind to your SOC team – they are probably tired 😊