Signs of beaconing activity
You want to monitor your network to see whether any hosts are beaconing—or checking in with—malicious command and control infrastructure.
Required data
Procedure
This sample search uses Stream DNS data. You can replace this source with any other DNS data used in your organization.
Run the following search. You can optimize it by specifying an index and adjusting the time range.
eventtype="stream_dns" message_type="Query" | fields _time, query | streamstats current=f last(_time) AS last_time BY query | eval gap=last_time - _time | stats count avg(gap) AS AverageBeaconTime var(gap) AS VarianceBeaconTime BY query | eval AverageBeaconTime=round(AverageBeaconTime,3), VarianceBeaconTime=round(VarianceBeaconTime,3) | sort -count | where VarianceBeaconTime < 60 AND count > 2 AND AverageBeaconTime>1.000 | table query VarianceBeaconTime count AverageBeaconTime
Search explanation
The table provides an explanation of what each part of this search achieves. You can adjust this query based on the specifics of your environment.
Splunk Search | Explanation |
---|---|
|
Search only Stream DNS events. |
|
Search for queries. |
|
Keep only the time and the query field to speed up the search. |
|
Stream the last time each query was seen for all preceding events (excluding the current event) and output as |
|
Calculate the gap between the |
|
Calculate count for each query. For each query, also calculate the average gap and display it in an |
|
Round the |
|
Sort the results with the query with the highest occurrence appearing first. |
|
Filter results to display only results with a low variance relative to the other parameters. You can adjust these numbers according to baselines for your organization. |
|
Display the results in a table with columns in the order shown. |
Next steps
Low time variance in time in queries may indicate that hosts are contacting command and control infrastructure on a predetermined time slot. You might want to investigate activity on those hosts more closely. You can also add the src field to the | fields line of this search:
| fields _time, src, query
and a distinct count to the | stats line
| stats count dc(src) AS NumHosts avg(gap) AS AverageBeaconTime var(gap) AS VarianceBeaconTime BY query
to see the number of distinct hosts engaging in the same beaconing behavior.
Finally, you might be interested in other processes associated with this use case: