Adversaries may attempt to exfiltrate secrets or credentials by querying sensitive tables, indicating potential unauthorized access or data theft. SOC teams should proactively hunt for this behavior in Azure Sentinel to identify and mitigate early-stage credential access tactics.
KQL Query
// Extend this list with items to search for
let keywords = dynamic(["password", "pwd", "creds", "credentials", "secret"]);
// To exclude key phrases or tables to exclude add to these lists
let table_exclusions = dynamic(["AuditLogs","SigninLogs", "LAQueryLogs", "SecurityEvent"]);
let keyword_exclusion = dynamic(["reset user password", "change user password"]);
LAQueryLogs
| where RequestClientApp != 'Sentinel-General'
| extend querytext_lower = tolower(QueryText)
| where querytext_lower has_any(keywords)
| project TimeGenerated, AADEmail, QueryText, RequestClientApp, RequestTarget, ResponseCode, ResponseRowCount, ResponseDurationMs, CorrelationId
| extend timestamp = TimeGenerated, AccountCustomEntity = AADEmail
| join kind=leftanti ( LAQueryLogs
| where RequestClientApp != 'Sentinel-General'
| extend querytext_lower = tolower(QueryText)
| where QueryText has_any(table_exclusions) or querytext_lower has_any(keyword_exclusion))
on CorrelationId
id: 2bf19f27-0466-4c16-a821-ce84e524476d
name: Query looking for secrets
description: |
'This hunting query looks for queries that appear to be looking for secrets or passwords in tables.'
requiredDataConnectors:
- connectorId: AzureMonitor(Query Audit)
dataTypes:
- LAQueryLogs
tactics:
- Collection
relevantTechniques:
- T1530
- T1213
query: |
// Extend this list with items to search for
let keywords = dynamic(["password", "pwd", "creds", "credentials", "secret"]);
// To exclude key phrases or tables to exclude add to these lists
let table_exclusions = dynamic(["AuditLogs","SigninLogs", "LAQueryLogs", "SecurityEvent"]);
let keyword_exclusion = dynamic(["reset user password", "change user password"]);
LAQueryLogs
| where RequestClientApp != 'Sentinel-General'
| extend querytext_lower = tolower(QueryText)
| where querytext_lower has_any(keywords)
| project TimeGenerated, AADEmail, QueryText, RequestClientApp, RequestTarget, ResponseCode, ResponseRowCount, ResponseDurationMs, CorrelationId
| extend timestamp = TimeGenerated, AccountCustomEntity = AADEmail
| join kind=leftanti ( LAQueryLogs
| where RequestClientApp != 'Sentinel-General'
| extend querytext_lower = tolower(QueryText)
| where QueryText has_any(table_exclusions) or querytext_lower has_any(keyword_exclusion))
on CorrelationId
version: 1.0.0
metadata:
source:
kind: Community
author:
name: Pete Bryan
support:
tier: Microsoft
categories:
domains: [ "Security - Threat Protection" ]
| Sentinel Table | Notes |
|---|---|
AuditLogs | Ensure this data connector is enabled |
SecurityEvent | Ensure this data connector is enabled |
SigninLogs | Ensure this data connector is enabled |
Scenario: Scheduled job for database backups using mysqldump
Filter/Exclusion: Exclude processes containing mysqldump or mysqlbackup in the command line.
Scenario: Admin task to rotate database credentials using sqlcmd or psql
Filter/Exclusion: Exclude processes with sqlcmd, psql, or pgpass in the command line.
Scenario: Log analysis using grep to search for sensitive patterns in logs
Filter/Exclusion: Exclude processes containing grep with patterns like password, secret, or token in the command line.
Scenario: Configuration management task using ansible to update secrets in config files
Filter/Exclusion: Exclude processes with ansible and --vault-password-file or --vault-id in the command line.
Scenario: Automated script to fetch API keys from a secure vault using vault CLI
Filter/Exclusion: Exclude processes containing vault and read or lookup commands in the command line.