Detection rules › Splunk

Gsuite Outbound Email With Attachment To External Domain

Status
production
Group by
dest_domain, phase, severity
Author
Teoderick Contreras, Stanislav Miskovic, Splunk
Source
github.com/splunk/security_content

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.

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.

MITRE ATT&CK coverage

Rule body

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

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

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
dest_domaineq"internal_test_email.com"excludes:dest_domain

Indicators

These rows show field, operator, and value matches.