Detection rules › Kusto
SlackAudit - Public link created for file which can contain sensitive information.
'Detects public links created for files that may contain sensitive data such as passwords, authentication tokens, secret keys, or private configuration files. Tune exclusions using the SlackAuditSensitiveFile_Allowlist_File and SlackAuditSensitiveFile_Allowlist_Account watchlists when known benign files or accounts generate expected public-link activity.'
MITRE ATT&CK coverage
Rule body
id: 279316e8-8965-47d2-9788-b94dc352c853
name: SlackAudit - Public link created for file which can contain sensitive information.
description: |
'Detects public links created for files that may contain sensitive data such as passwords, authentication tokens,
secret keys, or private configuration files. Tune exclusions using the SlackAuditSensitiveFile_Allowlist_File and SlackAuditSensitiveFile_Allowlist_Account
watchlists when known benign files or accounts generate expected public-link activity.'
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: SlackAuditAPI
dataTypes:
- SlackAudit_CL
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
- Exfiltration
relevantTechniques:
- T1048
- T1567.002
query: |
let AllowedFiles = toscalar(_GetWatchlist('SlackAuditSensitiveFile_Allowlist_File') | summarize make_set(tostring(SearchKey)));
let AllowedUsers = toscalar(_GetWatchlist('SlackAuditSensitiveFile_Allowlist_Account') | summarize make_set(tostring(SearchKey)));
SlackAudit
| where Action =~ 'file_public_link_created'
| extend FileNameLower = tolower(EntityFileName), UserLower = tolower(SrcUserName)
| where EntityFileName in~ ('id_rsa')
or FileNameLower has_any ('password', 'secret', 'token', 'credential', 'private key', 'api key')
or FileNameLower has_any ('.ssh', '.npmrc', '.muttrc', '.gitconfig', '.netrc', 'package.json', 'Gemfile', 'bower.json', 'config.gypi', 'travis.yml', 'config.json')
| where isempty(AllowedFiles) or EntityFileName !in~ (AllowedFiles)
| where isempty(AllowedUsers) or UserLower !in~ (AllowedUsers)
| extend AccountCustomEntity = SrcUserName
| extend IPCustomEntity = SrcIpAddr
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: AccountCustomEntity
- entityType: IP
fieldMappings:
- identifier: Address
columnName: IPCustomEntity
alertDetailsOverride:
alertDisplayNameFormat: Slack public link created for sensitive file {{EntityFileName}} by {{SrcUserName}}
alertDescriptionFormat: Public link created for {{EntityFileName}} by {{SrcUserName}} from {{SrcIpAddr}}
customDetails:
FileName: EntityFileName
Action: Action
SourceUser: SrcUserName
SourceIP: SrcIpAddr
ActorEntity: AccountCustomEntity
IpEntity: IPCustomEntity
version: 1.0.1
kind: Scheduled
Stages and Predicates
Let binding: AllowedFiles
let AllowedFiles = toscalar(_GetWatchlist('SlackAuditSensitiveFile_Allowlist_File') | summarize make_set(tostring(SearchKey)));
Let binding: AllowedUsers
let AllowedUsers = toscalar(_GetWatchlist('SlackAuditSensitiveFile_Allowlist_Account') | summarize make_set(tostring(SearchKey)));
Stage 1: source
SlackAudit
Stage 2: where
| where Action =~ 'file_public_link_created'
Stage 3: extend
| extend FileNameLower = tolower(EntityFileName), UserLower = tolower(SrcUserName)
Stage 4: where
| where EntityFileName in~ ('id_rsa')
or FileNameLower has_any ('password', 'secret', 'token', 'credential', 'private key', 'api key')
or FileNameLower has_any ('.ssh', '.npmrc', '.muttrc', '.gitconfig', '.netrc', 'package.json', 'Gemfile', 'bower.json', 'config.gypi', 'travis.yml', 'config.json')
Stage 5: where
| where isempty(AllowedFiles) or EntityFileName !in~ (AllowedFiles)
Stage 6: where
| where isempty(AllowedUsers) or UserLower !in~ (AllowedUsers)
Stage 7: extend
| extend AccountCustomEntity = SrcUserName
Stage 8: extend
| extend IPCustomEntity = SrcIpAddr
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
Action | eq |
| field:"Action" kind:eq value:"file_public_link_created" |
AllowedFiles | is_null | field:"AllowedFiles" kind:is_null | |
AllowedUsers | is_null | field:"AllowedUsers" kind:is_null | |
EntityFileName | in |
| field:"EntityFileName" kind:in value:"id_rsa" |
FileNameLower | match |
| field:"FileNameLower" kind:match |
Output fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
FileNameLower | extend |
UserLower | extend |
AccountCustomEntity | extend |
IPCustomEntity | extend |