Detection rules › Kusto
Azure DevOps PAT used with Browser
'Personal Access Tokens (PATs) are used as an alternate password to authenticate into Azure DevOps. PATs are intended for programmatic access use in code or applications. This can be prone to attacker theft if not adequately secured. This query looks for the use of a PAT in authentication but from a User Agent indicating a browser. This should not be normal activity and could be an indicator of an attacker using a stolen PAT.'
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Credential Access |
Rule body
id: 5f0d80db-3415-4265-9d52-8466b7372e3a
name: Azure DevOps PAT used with Browser
description: |
'Personal Access Tokens (PATs) are used as an alternate password to authenticate into Azure DevOps. PATs are intended for programmatic access use in code or applications.
This can be prone to attacker theft if not adequately secured. This query looks for the use of a PAT in authentication but from a User Agent indicating a browser.
This should not be normal activity and could be an indicator of an attacker using a stolen PAT.'
severity: Medium
status: Available
requiredDataConnectors: []
queryFrequency: 1d
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
- CredentialAccess
relevantTechniques:
- T1528
query: |
ADOAuditLogs
| where AuthenticationMechanism startswith "PAT"
// Look for useragents that include a redenring engine
| where UserAgent has_any ("Gecko", "WebKit", "Presto", "Trident", "EdgeHTML", "Blink")
| extend AccountName = tostring(split(ActorUPN, "@")[0]), AccountUPNSuffix = tostring(split(ActorUPN, "@")[1])
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: ActorUPN
- identifier: Name
columnName: AccountName
- identifier: UPNSuffix
columnName: AccountUPNSuffix
- entityType: IP
fieldMappings:
- identifier: Address
columnName: IpAddress
version: 1.0.6
kind: Scheduled
Stages and Predicates
Stage 1: source
ADOAuditLogs
Stage 2: where
| where AuthenticationMechanism startswith "PAT"
Stage 3: where
| where UserAgent has_any ("Gecko", "WebKit", "Presto", "Trident", "EdgeHTML", "Blink")
Stage 4: extend
| extend AccountName = tostring(split(ActorUPN, "@")[0]), AccountUPNSuffix = tostring(split(ActorUPN, "@")[1])
Indicators
These rows show field, operator, and value matches.
| Field | Kind | Values | Search |
|---|---|---|---|
AuthenticationMechanism | starts_with |
| field:"AuthenticationMechanism" kind:starts_with value:"PAT" |
UserAgent | match |
| field:"aws::userAgent" kind:match |
Output fields
These fields are emitted when the rule matches.
| Field | Source |
|---|---|
AccountName | extend |
AccountUPNSuffix | extend |