Detection rules › Splunk

Email servers sending high volume traffic to hosts

Status
experimental
Severity
low
Group by
_time, dest_ip
Author
Bhavin Patel, Splunk
Source
github.com/splunk/security_content

The following analytic identifies a significant increase in data transfers from your email server to client hosts. It leverages the Network_Traffic data model to monitor outbound traffic from email servers, using statistical analysis to detect anomalies based on average and standard deviation metrics. This activity is significant as it may indicate a malicious actor exfiltrating data via your email server. If confirmed malicious, this could lead to unauthorized data access and potential data breaches, compromising sensitive information and impacting organizational security.

MITRE ATT&CK coverage

Rule body splunk

name: Email servers sending high volume traffic to hosts
id: 7f5fb3e1-4209-4914-90db-0ec21b556378
version: 10
creation_date: '2020-04-29'
modification_date: '2026-05-13'
author: Bhavin Patel, Splunk
status: experimental
type: Anomaly
description: The following analytic identifies a significant increase in data transfers from your email server to client hosts. It leverages the Network_Traffic data model to monitor outbound traffic from email servers, using statistical analysis to detect anomalies based on average and standard deviation metrics. This activity is significant as it may indicate a malicious actor exfiltrating data via your email server. If confirmed malicious, this could lead to unauthorized data access and potential data breaches, compromising sensitive information and impacting organizational security.
data_source: []
search: |-
    | tstats `security_content_summariesonly` sum(All_Traffic.bytes_out) as bytes_out FROM datamodel=Network_Traffic
      WHERE All_Traffic.src_category=email_server
      BY All_Traffic.dest_ip _time span=1d
    | `drop_dm_object_name("All_Traffic")`
    | eventstats avg(bytes_out) as avg_bytes_out stdev(bytes_out) as stdev_bytes_out
    | eventstats count as num_data_samples avg(eval(if(_time < relative_time(now(), "@d"), bytes_out, null))) as per_source_avg_bytes_out stdev(eval(if(_time < relative_time(now(), "@d"), bytes_out, null))) as per_source_stdev_bytes_out
      BY dest_ip
    | eval minimum_data_samples = 4, deviation_threshold = 3
    | where num_data_samples >= minimum_data_samples AND bytes_out > (avg_bytes_out + (deviation_threshold * stdev_bytes_out)) AND bytes_out > (per_source_avg_bytes_out + (deviation_threshold * per_source_stdev_bytes_out)) AND _time >= relative_time(now(), "@d")
    | eval num_standard_deviations_away_from_server_average = round(abs(bytes_out - avg_bytes_out) / stdev_bytes_out, 2), num_standard_deviations_away_from_client_average = round(abs(bytes_out - per_source_avg_bytes_out) / per_source_stdev_bytes_out, 2)
    | table dest_ip, _time, bytes_out, avg_bytes_out, per_source_avg_bytes_out, num_standard_deviations_away_from_server_average, num_standard_deviations_away_from_client_average
    | `email_servers_sending_high_volume_traffic_to_hosts_filter`
how_to_implement: This search requires you to be ingesting your network traffic and populating the Network_Traffic data model.  Your email servers must be categorized as "email_server" for the search to work, as well. You may need to adjust the deviation_threshold and minimum_data_samples values based on the network traffic in your environment. The "deviation_threshold" field is a multiplying factor to control how much variation you're willing to tolerate. The "minimum_data_samples" field is the minimum number of connections of data samples required for the statistic to be valid.
known_false_positives: The false-positive rate will vary based on how you set the deviation_threshold and data_samples values. Our recommendation is to adjust these values based on your network traffic to and from your email servers.
references: []
intermediate_findings:
    entities:
        - field: dest
          type: system
          score: 20
          message: High volume of network traffic from $dest$
analytic_story:
    - Collection and Staging
    - HAFNIUM Group
asset_type: Endpoint
mitre_attack_id:
    - T1114.002
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: application
security_domain: network

Stages and Predicates

Stage 1: tstats

| tstats `security_content_summariesonly` sum(All_Traffic.bytes_out) as bytes_out FROM datamodel=Network_Traffic
  WHERE All_Traffic.src_category=email_server
  BY All_Traffic.dest_ip _time span=1d

Stage 2: search

| `drop_dm_object_name("All_Traffic")`

Stage 3: eventstats

| eventstats avg(bytes_out) as avg_bytes_out stdev(bytes_out) as stdev_bytes_out

Stage 4: eventstats

| eventstats count as num_data_samples avg(eval(if(_time < relative_time(now(), "@d"), bytes_out, null))) as per_source_avg_bytes_out stdev(eval(if(_time < relative_time(now(), "@d"), bytes_out, null))) as per_source_stdev_bytes_out
  BY dest_ip

Stage 5: eval

| eval minimum_data_samples = 4, deviation_threshold = 3

Stage 6: where

| where num_data_samples >= minimum_data_samples AND bytes_out > (avg_bytes_out + (deviation_threshold * stdev_bytes_out)) AND bytes_out > (per_source_avg_bytes_out + (deviation_threshold * per_source_stdev_bytes_out)) AND _time >= relative_time(now(), "@d")

Stage 7: eval

| eval num_standard_deviations_away_from_server_average = round(abs(bytes_out - avg_bytes_out) / stdev_bytes_out, 2), num_standard_deviations_away_from_client_average = round(abs(bytes_out - per_source_avg_bytes_out) / per_source_stdev_bytes_out, 2)

Stage 8: table

| table dest_ip, _time, bytes_out, avg_bytes_out, per_source_avg_bytes_out, num_standard_deviations_away_from_server_average, num_standard_deviations_away_from_client_average

Stage 9: search

| `email_servers_sending_high_volume_traffic_to_hosts_filter`

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
All_Traffic.src_categoryeq
  • email_server