Detection rules › Splunk

Gsuite Drive Share In External Email

Status
experimental
Severity
low
Group by
"parameters.owner", ip_address, phase, severity
Author
Teoderick Contreras, Splunk
Source
github.com/splunk/security_content

The following analytic detects Google Drive or Google Docs files shared externally from an internal domain. It leverages GSuite Drive logs, extracting and comparing the source and destination email domains to identify external sharing. This activity is significant as it may indicate potential data exfiltration by an attacker or insider. If confirmed malicious, this could lead to unauthorized access to sensitive information, data leakage, and potential compliance violations. Monitoring this behavior helps in early detection and mitigation of data breaches.

Known false positives

  • network admin or normal user may share files to customer and external team.

MITRE ATT&CK coverage

Telemetry coverage

PlatformRecord / event type
Google Workspaceany: Drive (any event)

Rules detecting the same action

These rules filter on the same operation.

Rule body

name: Gsuite Drive Share In External Email
id: f6ee02d6-fea0-11eb-b2c2-acde48001122
version: 12
creation_date: '2021-08-16'
modification_date: '2026-05-13'
author: Teoderick Contreras, Splunk
status: experimental
type: Anomaly
description: The following analytic detects Google Drive or Google Docs files shared externally from an internal domain. It leverages GSuite Drive logs, extracting and comparing the source and destination email domains to identify external sharing. This activity is significant as it may indicate potential data exfiltration by an attacker or insider. If confirmed malicious, this could lead to unauthorized access to sensitive information, data leakage, and potential compliance violations. Monitoring this behavior helps in early detection and mitigation of data breaches.
data_source:
    - G Suite Drive
search: |
    `gsuite_drive` NOT (email IN("", "null"))
    | spath path=parameters.owner output=owner
    | rex field=owner "[^@]+@(?<src_domain>[^@]+)"
    | rex field=email "[^@]+@(?<dest_domain>[^@]+)"
    | where src_domain = "internal_test_email.com" and not dest_domain = "internal_test_email.com"
    | eval phase="plan"
    | eval severity="low"
    | stats values(parameters.doc_title) as doc_title,
      values(parameters.doc_type) as doc_types,
      values(email) as dst_email_list,
      values(parameters.visibility) as visibility,
      values(parameters.doc_id) as doc_id,
      count min(_time) as firstTime max(_time) as lastTime
      by parameters.owner ip_address phase severity
    | rename parameters.owner as user ip_address as src_ip
    | `security_content_ctime(firstTime)`
    | `security_content_ctime(lastTime)`
    | `gsuite_drive_share_in_external_email_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. In order for the search to work for your environment, please edit the query to use your company specific email domain instead of `internal_test_email.com`.
known_false_positives: network admin or normal user may share files to customer and external team.
references:
    - https://www.redhat.com/en/topics/devops/what-is-devsecops
intermediate_findings:
    entities:
        - field: dst_email_list
          type: user
          score: 20
          message: Suspicious share gdrive from $user$ to $dst_email_list$ namely as $doc_title$
        - field: user
          type: user
          score: 20
          message: Suspicious share gdrive from $user$ to $dst_email_list$ namely as $doc_title$
analytic_story:
    - Scattered Lapsus$ Hunters
    - Dev Sec Ops
    - Insider Threat
asset_type: GSuite
mitre_attack_id:
    - T1567.002
product:
    - Splunk Enterprise
    - Splunk Enterprise Security
    - Splunk Cloud
category: cloud
security_domain: endpoint

Stages and Predicates

Stage 1: search

`gsuite_drive` NOT (email IN("", "null"))

Stage 2: spath

| spath path=parameters.owner output=owner

Stage 3: rex

| rex field=owner "[^@]+@(?<src_domain>[^@]+)"

Stage 4: rex

| rex field=email "[^@]+@(?<dest_domain>[^@]+)"

Stage 5: where

| where src_domain = "internal_test_email.com" and not dest_domain = "internal_test_email.com"

Stage 6: eval

| eval phase="plan"

Stage 7: eval

| eval severity="low"

Stage 8: stats

| stats values(parameters.doc_title) as doc_title,
  values(parameters.doc_type) as doc_types,
  values(email) as dst_email_list,
  values(parameters.visibility) as visibility,
  values(parameters.doc_id) as doc_id,
  count min(_time) as firstTime max(_time) as lastTime
  by parameters.owner ip_address phase severity

Stage 9: rename

| rename parameters.owner as user ip_address as src_ip

Stage 10: search

| `security_content_ctime(firstTime)`

Stage 11: search

| `security_content_ctime(lastTime)`

Stage 12: search

| `gsuite_drive_share_in_external_email_filter`

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
emailin"", "null"excludes:email
dest_domaineq"internal_test_email.com"excludes:dest_domain

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
sourcetypeeq
  • gws:reports:drive
field:"sourcetype" kind:eq value:"gws:reports:drive"
src_domaineq
  • "internal_test_email.com"
field:"src_domain" kind:eq