Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Detection - Azure Bastion Brute Force
// Detects brute force / credential-guessing against Azure Bastion by flagging a high
// number of FAILED session logins from the same source IP within a short window.
// Data source: MicrosoftAzureBastionAuditLogs (requires the "Bastion Audit Logs"
// diagnostic setting enabled and routed to Log Analytics).
// Tuning profiles (lookback / threshold):
// Aggressive: 5m / 5 | Balanced (recommended): 15m / 5 | Conservative: 1h / 10
let lookback = 15m;
let threshold = 5;
let AllowlistedSourceIPs = dynamic([]);
MicrosoftAzureBastionAuditLogs
| where TimeGenerated > ago(lookback)
| where Message == "Login Failed"
| extend UserName = tostring(UserName),
UserEmail = tostring(UserEmail),
SourceIP = tostring(ClientIpAddress),
TargetVM = tostring(TargetVMIPAddress),
TargetResourceId = tostring(TargetResourceId),
Protocol = tostring(Protocol)
| where isnotempty(SourceIP)
| where SourceIP !in (AllowlistedSourceIPs)
| summarize FailedAttempts = count(),
DistinctTargetVMs = dcount(TargetVM),
DistinctAccounts = dcount(UserName),
FirstSeen = min(TimeGenerated),
LastSeen = max(TimeGenerated),
TargetedAccounts = make_set(UserName, 25),
InitiatingUsers = make_set(UserEmail, 25),
TargetVMs = make_set(TargetVM, 25),
TargetResourceIds = make_set(TargetResourceId, 25),
Protocols = make_set(Protocol, 5)
by SourceIP
| where FailedAttempts >= threshold
| extend AttackWindowMinutes = datetime_diff('minute', LastSeen, FirstSeen)
| extend LikelyPasswordSpray = DistinctAccounts >= 5
| extend HighVolume = FailedAttempts >= threshold * 2
| order by FailedAttempts desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Detection - Bastion Brute Force

This query uses Azure Bastion audit logs (`MicrosoftAzureBastionAuditLogs`) to detect potential brute force activity by identifying multiple failed session logins (`Message == "Login Failed"`) from the same source IP against Bastion-fronted VMs within a short window. It groups failures by source IP, surfaces the targeted accounts and VMs, and raises a result when the count meets the configured threshold (default: 5 failures in 15 minutes). Adjust the `lookback` and `threshold` parameters to tune sensitivity for your environment.

## Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.

Loading