Detection rules › Splunk
Excessive Usage of NSLOOKUP App
The following analytic detects excessive usage of the nslookup application, which may indicate potential DNS exfiltration attempts. It leverages Sysmon EventCode 1 to monitor process executions, specifically focusing on nslookup.exe. The detection identifies outliers by comparing the frequency of nslookup executions against a calculated threshold. This activity is significant as it can reveal attempts by malware or APT groups to exfiltrate data via DNS queries. If confirmed malicious, this behavior could allow attackers to stealthily transfer sensitive information out of the network, bypassing traditional data exfiltration defenses.
Known false positives
- No false positives have been identified at this time.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Exfiltration |
Telemetry coverage
| Provider | Record / event type |
|---|---|
| Sysmon | Event ID 1: Process creation |
| Security-Auditing | Event ID 4688: A new process has been created. |
Rule body
name: Excessive Usage of NSLOOKUP App
id: 0a69fdaa-a2b8-11eb-b16d-acde48001122
version: 12
creation_date: '2021-04-22'
modification_date: '2026-05-13'
author: Teoderick Contreras, Stanislav Miskovic, Splunk
status: production
type: Anomaly
description: The following analytic detects excessive usage of the nslookup application, which may indicate potential DNS exfiltration attempts. It leverages Sysmon EventCode 1 to monitor process executions, specifically focusing on nslookup.exe. The detection identifies outliers by comparing the frequency of nslookup executions against a calculated threshold. This activity is significant as it can reveal attempts by malware or APT groups to exfiltrate data via DNS queries. If confirmed malicious, this behavior could allow attackers to stealthily transfer sensitive information out of the network, bypassing traditional data exfiltration defenses.
data_source:
- Sysmon EventID 1
- Windows Event Log Security 4688
- CrowdStrike ProcessRollup2
search: |-
| tstats `security_content_summariesonly` count as numNsLookup min(_time) as firstTime max(_time) as lastTime values(Processes.action) as action values(Processes.original_file_name) as original_file_name values(Processes.parent_process_exec) as parent_process_exec values(Processes.parent_process_guid) as parent_process_guid values(Processes.parent_process_name) as parent_process_name values(Processes.parent_process_path) as parent_process_path values(Processes.process) as process values(Processes.process_exec) as process_exec values(Processes.process_guid) as process_guid values(Processes.process_hash) as process_hash values(Processes.process_id) as process_id values(Processes.process_integrity_level) as process_integrity_level values(Processes.process_path) as process_path values(Processes.user_id) as user_id values(Processes.vendor_product) as vendor_product values(Processes.parent_process) as parent_process values(Processes.process_name) as process_name values(Processes.parent_process_id) as parent_process_id values(Processes.user) as user FROM datamodel=Endpoint.Processes
WHERE Processes.process_name = "nslookup.exe"
BY Processes.dest _time span=1m
| `drop_dm_object_name(Processes)`
| eventstats avg(numNsLookup) as avgNsLookup, stdev(numNsLookup) as stdNsLookup, count as numSlots
BY dest
| eval upperThreshold=(avgNsLookup + stdNsLookup *3)
| eval isOutlier=if(numNsLookup > 20 and numNsLookup >= upperThreshold, 1, 0)
| search isOutlier=1
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `excessive_usage_of_nslookup_app_filter`
how_to_implement: To successfully implement this search, you need to be ingesting logs with the process name, parent process, and command-line executions from your endpoints. If you are using Sysmon, you must have at least version 6.0.4 of the Sysmon TA. Tune and filter known instances of nslookup.exe may be used.
known_false_positives: No false positives have been identified at this time.
references:
- https://www.mandiant.com/resources/fin7-spear-phishing-campaign-targets-personnel-involved-sec-filings
- https://www.varonis.com/blog/dns-tunneling
- https://www.microsoft.com/security/blog/2021/01/20/deep-dive-into-the-solorigate-second-stage-activation-from-sunburst-to-teardrop-and-raindrop/
intermediate_findings:
entities:
- field: dest
type: system
score: 20
message: Excessive usage of nslookup.exe has been detected on $dest$. This detection is triggered as as it violates the dynamic threshold
analytic_story:
- Suspicious DNS Traffic
- Dynamic DNS
- Data Exfiltration
- Command And Control
asset_type: Endpoint
mitre_attack_id:
- T1048
product:
- Splunk Enterprise
- Splunk Enterprise Security
- Splunk Cloud
category: endpoint
security_domain: endpoint
Stages and Predicates
Stage 1: tstats
| tstats `security_content_summariesonly` count as numNsLookup min(_time) as firstTime max(_time) as lastTime values(Processes.action) as action values(Processes.original_file_name) as original_file_name values(Processes.parent_process_exec) as parent_process_exec values(Processes.parent_process_guid) as parent_process_guid values(Processes.parent_process_name) as parent_process_name values(Processes.parent_process_path) as parent_process_path values(Processes.process) as process values(Processes.process_exec) as process_exec values(Processes.process_guid) as process_guid values(Processes.process_hash) as process_hash values(Processes.process_id) as process_id values(Processes.process_integrity_level) as process_integrity_level values(Processes.process_path) as process_path values(Processes.user_id) as user_id values(Processes.vendor_product) as vendor_product values(Processes.parent_process) as parent_process values(Processes.process_name) as process_name values(Processes.parent_process_id) as parent_process_id values(Processes.user) as user FROM datamodel=Endpoint.Processes
WHERE Processes.process_name = "nslookup.exe"
BY Processes.dest _time span=1m
Stage 2: search
| `drop_dm_object_name(Processes)`
Stage 3: eventstats
| eventstats avg(numNsLookup) as avgNsLookup, stdev(numNsLookup) as stdNsLookup, count as numSlots
BY dest
Stage 4: eval
| eval upperThreshold=(avgNsLookup + stdNsLookup *3)
Stage 5: eval
| eval isOutlier=if(numNsLookup > 20 and numNsLookup >= upperThreshold, 1, 0)
isOutlier =if
numNsLookup > 20 AND numNsLookup >= upperThreshold1else
0Stage 6: search
| search isOutlier=1
Stage 7: search
| `security_content_ctime(firstTime)`
Stage 8: search
| `security_content_ctime(lastTime)`
Stage 9: search
| `excessive_usage_of_nslookup_app_filter`
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
Processes.process_name | eq |
| field:"process_name" kind:eq |
isOutlier | eq |
| field:"isOutlier" kind:eq value:"1" |