Detection rules › Splunk

Detect Spike in blocked Outbound Traffic from your AWS

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

The following analytic identifies spikes in blocked outbound network connections originating from within your AWS environment. It leverages VPC Flow Logs data from CloudWatch, focusing on blocked actions from internal IP ranges to external destinations. This detection is significant as it can indicate potential exfiltration attempts or misconfigurations leading to data leakage. If confirmed malicious, such activity could allow attackers to bypass network defenses, leading to unauthorized data transfer or communication with malicious external entities.

Rule body splunk

name: Detect Spike in blocked Outbound Traffic from your AWS
id: d3fffa37-492f-487b-a35d-c60fcb2acf01
version: 8
creation_date: '2020-04-29'
modification_date: '2026-05-13'
author: Bhavin Patel, Splunk
status: experimental
type: Anomaly
description: The following analytic identifies spikes in blocked outbound network connections originating from within your AWS environment. It leverages VPC Flow Logs data from CloudWatch, focusing on blocked actions from internal IP ranges to external destinations. This detection is significant as it can indicate potential exfiltration attempts or misconfigurations leading to data leakage. If confirmed malicious, such activity could allow attackers to bypass network defenses, leading to unauthorized data transfer or communication with malicious external entities.
data_source: []
search: |-
    `cloudwatchlogs_vpcflow` action=blocked (src_ip=10.0.0.0/8 OR src_ip=172.16.0.0/12 OR src_ip=192.168.0.0/16) ( dest_ip!=10.0.0.0/8 AND dest_ip!=172.16.0.0/12 AND dest_ip!=192.168.0.0/16)  [search  `cloudwatchlogs_vpcflow` action=blocked (src_ip=10.0.0.0/8 OR src_ip=172.16.0.0/12 OR src_ip=192.168.0.0/16) ( dest_ip!=10.0.0.0/8 AND dest_ip!=172.16.0.0/12 AND dest_ip!=192.168.0.0/16)
      | stats count as numberOfBlockedConnections
        BY src_ip
      | inputlookup baseline_blocked_outbound_connections append=t
      | fields - latestCount
      | stats values(*) as *
        BY src_ip
      | rename numberOfBlockedConnections as latestCount
      | eval newAvgBlockedConnections=avgBlockedConnections + (latestCount-avgBlockedConnections)/720
      | eval newStdevBlockedConnections=sqrt(((pow(stdevBlockedConnections, 2)*719 + (latestCount-newAvgBlockedConnections)*(latestCount-avgBlockedConnections))/720))
      | eval avgBlockedConnections=coalesce(newAvgBlockedConnections, avgBlockedConnections), stdevBlockedConnections=coalesce(newStdevBlockedConnections, stdevBlockedConnections), numDataPoints=if(isnull(latestCount), numDataPoints, numDataPoints+1)
      | table src_ip, latestCount, numDataPoints, avgBlockedConnections, stdevBlockedConnections
      | outputlookup baseline_blocked_outbound_connections
      | eval dataPointThreshold = 5, deviationThreshold = 3
      | eval isSpike=if((latestCount > avgBlockedConnections+deviationThreshold*stdevBlockedConnections) AND numDataPoints > dataPointThreshold, 1, 0)
      | where isSpike=1
      | table src_ip]
      | stats values(dest_ip) as dest_ip, values(interface_id) as "resourceId" count as numberOfBlockedConnections, dc(dest_ip) as uniqueDestConnections
        BY src_ip
      | `detect_spike_in_blocked_outbound_traffic_from_your_aws_filter`
how_to_implement: You must install the AWS App for Splunk (version 5.1.0 or later) and Splunk Add-on for AWS (version 4.4.0 or later), then configure your VPC Flow logs. You can modify `dataPointThreshold` and `deviationThreshold` to better fit your environment. The `dataPointThreshold` variable is the number of data points required to meet the definition of "spike." The `deviationThreshold` variable is the number of standard deviations away from the mean that the value must be to be considered a spike. This search works best when you run the "Baseline of Blocked Outbound Connection" support search once to create a history of previously seen blocked outbound connections.
known_false_positives: The false-positive rate may vary based on the values of`dataPointThreshold` and `deviationThreshold`. Additionally, false positives may result when AWS administrators roll out policies enforcing network blocks, causing sudden increases in the number of blocked outbound connections.
references: []
intermediate_findings:
    entities:
        - field: src_ip
          type: system
          score: 20
          message: Blocked $numberOfBlockedConnections$ outbound connections from your AWS VPC $src_ip$
analytic_story:
    - AWS Network ACL Activity
    - Suspicious AWS Traffic
    - Command And Control
asset_type: AWS Instance
mitre_attack_id: []
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: cloud
security_domain: network
baselines:
    - Baseline of blocked outbound traffic from AWS

Stages and Predicates

Stage 1: search

`cloudwatchlogs_vpcflow` action=blocked (src_ip=10.0.0.0/8 OR src_ip=172.16.0.0/12 OR src_ip=192.168.0.0/16) ( dest_ip!=10.0.0.0/8 AND dest_ip!=172.16.0.0/12 AND dest_ip!=192.168.0.0/16)  [search  `cloudwatchlogs_vpcflow` action=blocked (src_ip=10.0.0.0/8 OR src_ip=172.16.0.0/12 OR src_ip=192.168.0.0/16) ( dest_ip!=10.0.0.0/8 AND dest_ip!=172.16.0.0/12 AND dest_ip!=192.168.0.0/16)
  | stats count as numberOfBlockedConnections
    BY src_ip
  | inputlookup baseline_blocked_outbound_connections append=t
  | fields - latestCount
  | stats values(*) as *
    BY src_ip
  | rename numberOfBlockedConnections as latestCount
  | eval newAvgBlockedConnections=avgBlockedConnections + (latestCount-avgBlockedConnections)/720
  | eval newStdevBlockedConnections=sqrt(((pow(stdevBlockedConnections, 2)*719 + (latestCount-newAvgBlockedConnections)*(latestCount-avgBlockedConnections))/720))
  | eval avgBlockedConnections=coalesce(newAvgBlockedConnections, avgBlockedConnections), stdevBlockedConnections=coalesce(newStdevBlockedConnections, stdevBlockedConnections), numDataPoints=if(isnull(latestCount), numDataPoints, numDataPoints+1)
  | table src_ip, latestCount, numDataPoints, avgBlockedConnections, stdevBlockedConnections
  | outputlookup baseline_blocked_outbound_connections
  | eval dataPointThreshold = 5, deviationThreshold = 3
  | eval isSpike=if((latestCount > avgBlockedConnections+deviationThreshold*stdevBlockedConnections) AND numDataPoints > dataPointThreshold, 1, 0)
  | where isSpike=1
  | table src_ip]

Stage 2: stats

| stats values(dest_ip) as dest_ip, values(interface_id) as "resourceId" count as numberOfBlockedConnections, dc(dest_ip) as uniqueDestConnections
    BY src_ip

Stage 3: search

| `detect_spike_in_blocked_outbound_traffic_from_your_aws_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
actioneq
  • blocked
dest_ipne
  • 10.0.0.0/8
  • 172.16.0.0/12
  • 192.168.0.0/16
sourcetypeeq
  • aws:cloudwatchlogs:vpcflow
src_ipeq
  • 10.0.0.0/8
  • 172.16.0.0/12
  • 192.168.0.0/16