Detection rules › Splunk
Gsuite Outbound Email With Attachment To External Domain
The following analytic detects outbound emails with attachments sent from an internal email domain to an external domain. It leverages Gsuite Gmail logs, parsing the source and destination email domains, and flags emails with fewer than 20 outbound instances. This activity is significant as it may indicate potential data exfiltration or insider threats. If confirmed malicious, an attacker could use this method to exfiltrate sensitive information, leading to data breaches and compliance violations.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Exfiltration | T1048.003 Exfiltration Over Alternative Protocol: Exfiltration Over Unencrypted Non-C2 Protocol |
Rule body splunk
name: Gsuite Outbound Email With Attachment To External Domain
id: dc4dc3a8-ff54-11eb-8bf7-acde48001122
version: 9
creation_date: '2021-08-17'
modification_date: '2026-05-13'
author: Teoderick Contreras, Stanislav Miskovic, Splunk
status: production
type: Hunting
description: The following analytic detects outbound emails with attachments sent from an internal email domain to an external domain. It leverages Gsuite Gmail logs, parsing the source and destination email domains, and flags emails with fewer than 20 outbound instances. This activity is significant as it may indicate potential data exfiltration or insider threats. If confirmed malicious, an attacker could use this method to exfiltrate sensitive information, leading to data breaches and compliance violations.
data_source:
- G Suite Gmail
search: |-
`gsuite_gmail` num_message_attachments > 0
| rex field=source.from_header_address "[^@]+@(?<source_domain>[^@]+)"
| rex field=destination{}.address "[^@]+@(?<dest_domain>[^@]+)"
| where source_domain="internal_test_email.com" and not dest_domain="internal_test_email.com"
| eval phase="plan"
| eval severity="low"
| stats values(subject) as subject, values(source.from_header_address) as src_domain_list, count as numEvents, dc(source.from_header_address) as numSrcAddresses, min(_time) as firstTime max(_time) as lastTime
BY dest_domain phase severity
| where numSrcAddresses < 20
| sort - numSrcAddresses
| `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)`
| `gsuite_outbound_email_with_attachment_to_external_domain_filter`
how_to_implement: To successfully implement this search, you need to be ingesting logs related to gsuite having the file attachment metadata like file type, file extension, source email, destination email, num of attachment and etc.
known_false_positives: network admin and normal user may send this file attachment as part of their day to day work. having a good protocol in attaching this file type to an e-mail may reduce the risk of having a spear phishing attack.
references:
- https://www.redhat.com/en/topics/devops/what-is-devsecops
analytic_story:
- Dev Sec Ops
- Insider Threat
asset_type: GSuite
mitre_attack_id:
- T1048.003
product:
- Splunk Enterprise
- Splunk Enterprise Security
- Splunk Cloud
category: cloud
security_domain: endpoint
tests:
- name: True Positive Test
attack_data:
- data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1566.001/gsuite_outbound_email_to_external/gsuite_external_domain.log
source: http:gsuite
sourcetype: gsuite:gmail:bigquery
test_type: unit
Stages and Predicates
Stage 1: search
`gsuite_gmail` num_message_attachments > 0
Stage 2: rex
| rex field=source.from_header_address "[^@]+@(?<source_domain>[^@]+)"
Stage 3: rex
| rex field=destination{}.address "[^@]+@(?<dest_domain>[^@]+)"
Stage 4: where
| where source_domain="internal_test_email.com" and not dest_domain="internal_test_email.com"
Stage 5: eval
| eval phase="plan"
Stage 6: eval
| eval severity="low"
Stage 7: stats
| stats values(subject) as subject, values(source.from_header_address) as src_domain_list, count as numEvents, dc(source.from_header_address) as numSrcAddresses, min(_time) as firstTime max(_time) as lastTime
BY dest_domain phase severity
Stage 8: where
| where numSrcAddresses < 20
Stage 9: sort
| sort - numSrcAddresses
Stage 10: search
| `security_content_ctime(firstTime)`
Stage 11: search
| `security_content_ctime(lastTime)`
Stage 12: search
| `gsuite_outbound_email_with_attachment_to_external_domain_filter`
Exclusions
Top-level NOT(...) conjuncts: predicates this rule actively suppresses.
| Field | Kind | Excluded values |
|---|---|---|
dest_domain | eq | "internal_test_email.com" |
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.
| Field | Kind | Values |
|---|---|---|
numSrcAddresses | lt |
|
num_message_attachments | gt |
|
source_domain | eq |
|
sourcetype | eq |
|