Detection rules › Elastic
DNS Request to Dynamic DNS via Suspicious Executable
This rule detects DNS queries to dynamic DNS services via living-off-the-land executables or executables in world/user-writable directories. Malware authors may use these requests to communicate with command and control infrastructure or to exfiltrate data from the target system.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Command & Control |
Rule body
[rule]
description = """
This rule detects DNS queries to dynamic DNS services via living-off-the-land executables or executables in
world/user-writable directories. Malware authors may use these requests to communicate with command and control
infrastructure or to exfiltrate data from the target system.
"""
id = "b85d016e-3a28-43bd-8fbf-cbb19b09dc46"
license = "Elastic License v2"
name = "DNS Request to Dynamic DNS via Suspicious Executable"
os_list = ["linux"]
reference = ["https://www.rapid7.com/blog/post/tr-new-whitepaper-stealthy-bpfdoor-variants/"]
version = "1.0.5"
query = '''
sequence by process.entity_id with maxspan=10s
[process where event.type == "start" and event.action == "exec" and (
process.name in ("curl", "wget", "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox", "timeout", "env") or
process.name like (".*", "python*", "perl*", "php*", "ruby*", "lua*", "node", "deno") or
process.executable like (
"./*", "/tmp/*", "/var/tmp/*", "/dev/shm/*", "/run/*", "/var/run/*", "/boot/*", "/sys/*",
"/lost+found/*", "/proc/*", "/var/mail/*", "/var/www/*", "/home/*/*", "/root/*"
)
) and
not (
(
process.parent.name in ("bash", "node") and
(
process.working_directory in ("/usr/local/meshcentral", "/opt/meshcentral/meshcentral", "/usr/local/mesh_services/meshagent") or
process.parent.args in ("/usr/local/meshcentral/node_modules/meshcentral", "/home/periodic/dyndns-noip.sh")
)
) or
(
process.command_line == "python3 -m app.run_scheduled_update" and
process.parent.args == "./workflow_unified.sh"
) or
process.executable == "/usr/bin/qbittorrent-nox" or
process.executable like "/snap/firefox/*/usr/lib/firefox/firefox" or
(process.executable like "/usr/bin/php*" and process.args == "/var/tools/koalaping/bin/ping.php")
)]
[dns where event.action == "lookup_result" and dns.question.name like~ (
"*.no-ip.com", "*.no-ip.org", "*.no-ip.biz", "*.no-ip.info", "*.noip.com", "*.afraid.org", "*.changeip.com",
"*.ddns.net", "*.dyndns.org", "*.hopto.org", "*.zapto.org", "*.servehttp.com", "*.sytes.net", "*.myftp.biz",
"*.myftp.org", "*.ddnsfree.com", "*.duckdns.org", "*.000webhostapp.com", "*.myddns.me", "*.dlinkddns.com",
"*.chickenkiller.com", "*.thddns.net", "*.linkpc.net", "*.gotdns.ch", "*.dynv6.net", "*.dns.army",
"*.dns.navy", "*.v6.army", "*.v6.navy", "*.v6.rocks", "*.dyndns-office.com", "*.myvnc.com", "*.is-certified.com",
"*.instanthq.com", "*.ddnsgeek.com", "*.ygto.com", "*.casacam.com"
)]
'''
min_endpoint_version = "9.3.0"
optional_actions = []
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.entity_id"
state = 1
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 0
[[actions]]
action = "kill_process"
field = "process.parent.entity_id"
state = 1
[[threat]]
framework = "MITRE ATT&CK"
[[threat.technique]]
id = "T1071"
name = "Application Layer Protocol"
reference = "https://attack.mitre.org/techniques/T1071/"
[[threat.technique.subtechnique]]
id = "T1071.004"
name = "DNS"
reference = "https://attack.mitre.org/techniques/T1071/004/"
[[threat.technique]]
id = "T1102"
name = "Web Service"
reference = "https://attack.mitre.org/techniques/T1102/"
[threat.tactic]
id = "TA0011"
name = "Command and Control"
reference = "https://attack.mitre.org/tactics/TA0011/"
[internal]
min_endpoint_version = "9.3.0"
Stages and Predicates
Ordered sequence: each step below must occur in order within 10s, correlated by process.entity_id.
Stage 1: process
[process where event.type == "start" and event.action == "exec" and (
process.name in ("curl", "wget", "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox", "timeout", "env") or
process.name like (".*", "python*", "perl*", "php*", "ruby*", "lua*", "node", "deno") or
process.executable like (
"./*", "/tmp/*", "/var/tmp/*", "/dev/shm/*", "/run/*", "/var/run/*", "/boot/*", "/sys/*",
"/lost+found/*", "/proc/*", "/var/mail/*", "/var/www/*", "/home/*/*", "/root/*"
)
) and
not (
(
process.parent.name in ("bash", "node") and
(
process.working_directory in ("/usr/local/meshcentral", "/opt/meshcentral/meshcentral", "/usr/local/mesh_services/meshagent") or
process.parent.args in ("/usr/local/meshcentral/node_modules/meshcentral", "/home/periodic/dyndns-noip.sh")
)
) or
(
process.command_line == "python3 -m app.run_scheduled_update" and
process.parent.args == "./workflow_unified.sh"
) or
process.executable == "/usr/bin/qbittorrent-nox" or
process.executable like "/snap/firefox/*/usr/lib/firefox/firefox" or
(process.executable like "/usr/bin/php*" and process.args == "/var/tools/koalaping/bin/ping.php")
)]
Stage 2: dns
[dns where event.action == "lookup_result" and dns.question.name like~ (
"*.no-ip.com", "*.no-ip.org", "*.no-ip.biz", "*.no-ip.info", "*.noip.com", "*.afraid.org", "*.changeip.com",
"*.ddns.net", "*.dyndns.org", "*.hopto.org", "*.zapto.org", "*.servehttp.com", "*.sytes.net", "*.myftp.biz",
"*.myftp.org", "*.ddnsfree.com", "*.duckdns.org", "*.000webhostapp.com", "*.myddns.me", "*.dlinkddns.com",
"*.chickenkiller.com", "*.thddns.net", "*.linkpc.net", "*.gotdns.ch", "*.dynv6.net", "*.dns.army",
"*.dns.navy", "*.v6.army", "*.v6.navy", "*.v6.rocks", "*.dyndns-office.com", "*.myvnc.com", "*.is-certified.com",
"*.instanthq.com", "*.ddnsgeek.com", "*.ygto.com", "*.casacam.com"
)]
Exclusions
The rule actively suppresses these predicates.
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
dns.question.name | wildcard |
| field:"QueryName" kind:wildcard |
event.action | eq |
| field:"EventType" kind:eq |
event.type | eq |
| field:"event.type" kind:eq value:"start" |
process.executable | wildcard |
| field:"Image" kind:wildcard |
process.name | in |
| field:"process_name" kind:in |
process.name | wildcard |
| field:"process_name" kind:wildcard |