Rule packCONSTRUCTED
Sigma network pack: four rules for DNS, proxy and firewall logs
Long DNS labels, scripting-engine user agents at the proxy, executables fetched from a bare IP address, and SMB leaving the network. Written for the log sources most estates already collect and rarely alert on.
version 1.0checked 2026-09-21network2 min read
T1071.004T1048.003T1071.001T1105T1187T1048
What this pack is for
Endpoint telemetry has gaps: unmanaged devices, appliances, hosts where the agent was the first thing the operator removed. The network sees all of them. These four rules run on logs most estates already keep for compliance and almost never alert on.
Field names, and why yours will differ
Sigma's network categories use conventional field names, and your logs will not match them until a processing pipeline maps them:
| Category | Fields these rules use | Typical sources |
|---|---|---|
dns | query | Zeek dns.log, Windows DNS analytical log, resolver query logs, Sysmon event 22 |
proxy | c-useragent, cs-host, c-uri | Squid, Zscaler, Blue Coat, any W3C-format proxy log |
firewall | dst_ip, dst_port, action | Any perimeter firewall that logs allowed connections |
The action values differ by vendor ("allow", "accept", "permit", "pass"). The
SMB rule lists the common three; add yours.
The aggregation the DNS rule cannot express
A single long label is a weak signal. The strong signal for DNS tunnelling is many distinct subdomains under one parent domain from one client in a short window, because every chunk of data needs its own unique name or the resolver answers from cache. A plain Sigma rule matches one event at a time, so write the aggregation in your SIEM beside it. In Splunk terms:
index=dns
| eval parent=replace(query, "^.*?([^.]+\.[^.]+)$", "\1")
| bin _time span=10m
| stats dc(query) AS unique_names, avg(len(query)) AS mean_length BY _time, src_ip, parent
| where unique_names > 200 AND mean_length > 40
The thresholds are starting points. The DNS tunnelling walkthrough shows how to derive them from a capture rather than guess.
How they were tested, and how they were not
All four parse under pySigma, convert with the Splunk backend and pass the core
validators, and sigma check reports no errors or issues. The regular expressions were checked against constructed values.
None has been run against production traffic, and network rules are noisier
than endpoint ones on first contact: antivirus reputation lookups, certificate
revocation checks and developer tooling will all appear. Run them silent for a
week and build the filters from what you see.
The files
DNS query with an unusually long label
T1071.004 and T1048.003. A per-query rule. Read the aggregation note below before relying on it alone.
title: DNS Query With An Unusually Long Label
id: 9a907a27-eb03-45e6-b3b4-68f3180c0080
status: experimental
description: |
Detects DNS queries containing a single label of fifty characters or more. Data carried over
DNS has to be packed into labels, and the practical limit of sixty-three characters per label
is where tunnelling tools sit. Legitimate names very rarely approach it. This is a per-query
rule; the stronger signal (many unique subdomains under one parent) needs an aggregation in
your SIEM and is described on the page this pack ships with.
references:
- https://attack.mitre.org/techniques/T1071/004/
- https://attack.mitre.org/techniques/T1048/003/
- https://www.rfc-editor.org/rfc/rfc1035
author: Security Artifacts
date: 2026-09-21
tags:
- attack.command-and-control
- attack.t1071.004
- attack.exfiltration
- attack.t1048.003
logsource:
category: dns
detection:
selection:
query|re: '(^|\.)[A-Za-z0-9_-]{50,}\.'
filter_optional_known:
query|endswith:
- '.in-addr.arpa'
- '.ip6.arpa'
- '.sophosxl.net'
- '.mcafee.com'
- '.e5.sk'
condition: selection and not 1 of filter_optional_*
falsepositives:
- Security products that carry reputation lookups in DNS labels (several antivirus vendors do). The filter list starts with the common ones; extend it from a week of your own resolver logs before alerting on this.
- DKIM and other long TXT lookups under _domainkey.
level: medium
Scripting engine user agent at the proxy
T1071.001 and T1105. Low severity by design: it is a hunting lead until you have baselined your own estate.
title: Scripting Engine User-Agent Seen At The Proxy
id: d5ff4ec6-2e67-4e3b-8ec1-9c0584c269b1
status: experimental
description: |
Detects outbound web requests whose user agent is the default of a scripting engine or a
living-off-the-land download tool rather than a browser. A workstation fetching from the
internet with the PowerShell, certutil or BITS default agent is a download cradle until shown
otherwise.
references:
- https://attack.mitre.org/techniques/T1071/001/
- https://attack.mitre.org/techniques/T1105/
author: Security Artifacts
date: 2026-09-21
tags:
- attack.command-and-control
- attack.t1071.001
- attack.t1105
logsource:
category: proxy
detection:
selection:
c-useragent|contains:
- 'WindowsPowerShell/'
- 'Microsoft BITS/'
- 'CertUtil URL Agent'
- 'Microsoft-CryptoAPI/'
- 'python-requests/'
- 'curl/'
- 'Wget/'
filter_main_microsoft:
cs-host|endswith:
- '.microsoft.com'
- '.windowsupdate.com'
- '.windows.com'
- '.digicert.com'
- '.msftconnecttest.com'
condition: selection and not 1 of filter_main_*
falsepositives:
- Certificate revocation checks use the CryptoAPI agent against many CAs, so expect to extend the host filter with the OCSP and CRL hosts your estate actually contacts.
- Developer workstations and build servers. Scope the rule to user subnets, or route those hosts to a lower severity.
level: low
Executable content downloaded from a bare IP address
T1105. The private-range filter is a string prefix, so add 172.16.0.0/12 by CIDR in your backend.
title: Executable Content Downloaded From A Bare IP Address
id: aa5a4f36-7f5b-4fc6-9a45-7222d72d30de
status: experimental
description: |
Detects a proxy request for an executable or script where the host is an IP address rather
than a name. Legitimate software distribution uses names and certificates; staging servers
stood up for a single intrusion frequently do not.
references:
- https://attack.mitre.org/techniques/T1105/
author: Security Artifacts
date: 2026-09-21
tags:
- attack.command-and-control
- attack.t1105
logsource:
category: proxy
detection:
selection_host:
cs-host|re: '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(:\d{1,5})?$'
selection_ext:
c-uri|endswith:
- '.exe'
- '.dll'
- '.ps1'
- '.hta'
- '.vbs'
- '.js'
- '.msi'
- '.bat'
- '.scr'
filter_main_private:
cs-host|startswith:
- '10.'
- '192.168.'
- '127.'
condition: all of selection_* and not 1 of filter_main_*
falsepositives:
- Internal deployment shares reached by address. The filter removes the common private ranges; add 172.16.0.0/12 by CIDR in your backend, which a string prefix cannot express safely.
- Appliance firmware fetched by IP from a vendor.
level: medium
Outbound SMB to a public address
T1187 and T1048. Uses the cidr modifier, which needs a backend that supports it.
title: Outbound SMB To A Public Address
id: 1ec97802-2511-40a1-bdf9-06116913caac
status: experimental
description: |
Detects an allowed connection on TCP 445 from inside the network to an address outside the
private ranges. There is almost no legitimate reason for SMB to cross the perimeter, and the
malicious reasons include forced authentication (a lure that makes the host send its NetNTLM
hash to the operator) and exfiltration.
references:
- https://attack.mitre.org/techniques/T1187/
- https://attack.mitre.org/techniques/T1048/
author: Security Artifacts
date: 2026-09-21
tags:
- attack.credential-access
- attack.t1187
- attack.exfiltration
- attack.t1048
logsource:
category: firewall
detection:
selection:
dst_port: 445
action:
- 'allow'
- 'accept'
- 'permit'
filter_main_private:
dst_ip|cidr:
- '10.0.0.0/8'
- '172.16.0.0/12'
- '192.168.0.0/16'
- '127.0.0.0/8'
- '169.254.0.0/16'
condition: selection and not 1 of filter_main_*
falsepositives:
- Azure Files and similar cloud file shares mounted over SMB 3. If you use one, exclude its published address ranges and keep the rule.
level: high