Merge pull request #1984 from Azure/shainw-huntFormatUpd
updating entity mappings and descriptions to fix some characters that…
This commit is contained in:
Коммит
d43e0a60da
|
@ -30,6 +30,11 @@ query: |
|
|||
// Chart the 3 most interesting lines
|
||||
// A 0-value slope corresponds to an account being completely stable over time for a given Azure Active Directory application
|
||||
| top 3 by Slope desc
|
||||
| extend AccountCustomEntity = UserPrincipalName
|
||||
| extend timestamp = TimeGenerated, AccountCustomEntity = UserPrincipalName
|
||||
| render timechart
|
||||
|
||||
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountCustomEntity
|
|
@ -43,4 +43,9 @@ query: |
|
|||
| project timerange, AppDisplayName , UserPrincipalName, threeDayWindowLocationCount, locationList
|
||||
| order by AppDisplayName, UserPrincipalName, timerange asc
|
||||
| extend timestamp = timerange, AccountCustomEntity = UserPrincipalName
|
||||
|
||||
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountCustomEntity
|
|
@ -20,4 +20,9 @@ query: |
|
|||
| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), count() by AppDisplayName, UserPrincipalName
|
||||
| extend timestamp = StartTimeUtc, AccountCustomEntity = UserPrincipalName
|
||||
| order by count_ desc
|
||||
|
||||
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountCustomEntity
|
|
@ -17,9 +17,14 @@ query: |
|
|||
| where TimeGenerated >= ago(timeRange)
|
||||
| where ResultType == "50057"
|
||||
| where ResultDescription == "User account is disabled. The account has been disabled by an administrator."
|
||||
| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), numberAccountsTargeted = dcount(UserPrincipalName),
|
||||
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), numberAccountsTargeted = dcount(UserPrincipalName),
|
||||
numberApplicationsTargeted = dcount(AppDisplayName), accountSet = makeset(UserPrincipalName), applicationSet=makeset(AppDisplayName),
|
||||
numberLoginAttempts = count() by IPAddress
|
||||
| extend timestamp = StartTimeUtc, IPCustomEntity = IPAddress
|
||||
| extend timestamp = StartTime, IPCustomEntity = IPAddress
|
||||
| order by numberLoginAttempts desc
|
||||
|
||||
|
||||
entityMappings:
|
||||
- entityType: IP
|
||||
fieldMappings:
|
||||
- identifier: Address
|
||||
columnName: IPCustomEntity
|
|
@ -2,7 +2,7 @@ id: 847c2652-547d-4d5f-9b71-d2f8d81eac62
|
|||
name: Inactive or new account signins
|
||||
description: |
|
||||
'Query for accounts seen signing in for the first time - these could be associated
|
||||
with stale/inactive accounts that ought to have been deleted but weren't - and have
|
||||
with stale/inactive accounts that ought to have been deleted but were not - and have
|
||||
subseuqently been compromised.
|
||||
Results for user accounts created in the last 7 days are filtered out'
|
||||
requiredDataConnectors:
|
||||
|
@ -23,7 +23,7 @@ query: |
|
|||
| where TimeGenerated >= ago(endtime)
|
||||
// successful sign-in
|
||||
| where ResultType == 0
|
||||
| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), loginCountToday=count() by UserPrincipalName, Identity
|
||||
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), loginCountToday=count() by UserPrincipalName, Identity
|
||||
| join kind=leftanti (
|
||||
SigninLogs
|
||||
// historical successful sign-in
|
||||
|
@ -40,5 +40,10 @@ query: |
|
|||
// Normalize to lower case in order to match against equivalent UPN in Signin logs
|
||||
| extend NewUserPrincipalName = tolower(extractjson("$.userPrincipalName", tostring(TargetResources[0]), typeof(string)))
|
||||
) on $left.UserPrincipalName == $right.NewUserPrincipalName
|
||||
| extend timestamp = StartTimeUtc, AccountCustomEntity = UserPrincipalName
|
||||
|
||||
| extend timestamp = StartTime, AccountCustomEntity = UserPrincipalName
|
||||
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountCustomEntity
|
|
@ -41,8 +41,17 @@ query: |
|
|||
| extend OS = DeviceDetail.operatingSystem, Browser = DeviceDetail.browser
|
||||
| extend LocationString= strcat(tostring(LocationDetails["countryOrRegion"]), "/",
|
||||
tostring(LocationDetails["state"]), "/", tostring(LocationDetails["city"]))
|
||||
| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), AttemptCount = count()
|
||||
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), AttemptCount = count()
|
||||
by UserPrincipalName, ClientAppUsed, AppDisplayName, IPAddress, isLegacyAuth, tostring(OS), tostring(Browser), LocationString
|
||||
| sort by AttemptCount desc nulls last
|
||||
| extend timestamp = StartTimeUtc, AccountCustomEntity = UserPrincipalName, IPCustomEntity = IPAddress
|
||||
|
||||
| extend timestamp = StartTime, AccountCustomEntity = UserPrincipalName, IPCustomEntity = IPAddress
|
||||
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountCustomEntity
|
||||
- entityType: IP
|
||||
fieldMappings:
|
||||
- identifier: Address
|
||||
columnName: IPCustomEntity
|
|
@ -59,3 +59,4 @@ query: |
|
|||
//Thresholds, 15% account authentication failure rate at a 50% increase in accounts attempting to authenticate by default
|
||||
//Comment out line below to see all anomalous results
|
||||
| where FailureRate >= failureThreshold and PercentageChange >= percentageChangeThreshold
|
||||
| extend timestamp = TimeGenerated
|
||||
|
|
|
@ -42,4 +42,14 @@ query: |
|
|||
| extend TimeGenerated = todatetime(tostring(TimeGenerated)), IPAddress = tostring(IPAddresses), Status = tostring(Status)
|
||||
| project-away IPAddresses
|
||||
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated) by UserPrincipalName, UserId, UserDisplayName, Status, IPAddress, IPAddressCount, AppDisplayName, Browser, OS, FullLocation
|
||||
| extend timestamp = StartTime, AccountCustomEntity = UserPrincipalName, IPCustomEntity = IPAddress
|
||||
| extend timestamp = StartTime, AccountCustomEntity = UserPrincipalName, IPCustomEntity = IPAddress
|
||||
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountCustomEntity
|
||||
- entityType: IP
|
||||
fieldMappings:
|
||||
- identifier: Address
|
||||
columnName: IPCustomEntity
|
|
@ -25,4 +25,13 @@ query: |
|
|||
Location, State, City
|
||||
| extend timestamp = Date, AccountCustomEntity = UserPrincipalName, IPCustomEntity = IPAddress
|
||||
| sort by Date
|
||||
|
||||
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountCustomEntity
|
||||
- entityType: IP
|
||||
fieldMappings:
|
||||
- identifier: Address
|
||||
columnName: IPCustomEntity
|
|
@ -19,6 +19,7 @@ query: |
|
|||
let IP_Data = (externaldata(network:string)
|
||||
[@"https://raw.githubusercontent.com/Azure/Azure-Sentinel/master/Sample%20Data/Feeds/VPS_Networks.csv"] with (format="csv"));
|
||||
SigninLogs
|
||||
| where TimeGenerated >= ago(1d)
|
||||
| where ResultType == 0
|
||||
| extend additionalDetails = tostring(Status.additionalDetails)
|
||||
| evaluate ipv4_lookup(IP_Data, IPAddress, network, return_unmatched = false)
|
||||
|
|
|
@ -48,4 +48,13 @@ query: |
|
|||
) on SuccessAppDisplayName, ResultType
|
||||
| project UserPrincipalName, SuccessLogonTime, IPAddress, SuccessAppDisplayName, FailedLogonTime, FailedAppDisplayName, ResultType, ResultDescription
|
||||
| extend timestamp = SuccessLogonTime, AccountCustomEntity = UserPrincipalName, IPCustomEntity = IPAddress
|
||||
|
||||
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountCustomEntity
|
||||
- entityType: IP
|
||||
fieldMappings:
|
||||
- identifier: Address
|
||||
columnName: IPCustomEntity
|
|
@ -1,8 +1,9 @@
|
|||
name: Sign-ins from IPs that attempt sign-ins to disabled accounts
|
||||
description: |
|
||||
'Identifies IPs with failed attempts to sign in to one or more disabled accounts signed in successfully to another account.
|
||||
This analytic will additionally identify the successful signed in accounts as the mapped account entities for investigation.
|
||||
References: https://docs.microsoft.com/azure/active-directory/reports-monitoring/reference-sign-ins-error-codes
|
||||
50057 - User account is disabled. The account has been disabled by an administrator.' This analytic will additionally identify the successful signed in accounts as the mapped account entities for investigation in Sentinel.
|
||||
50057 - User account is disabled. The account has been disabled by an administrator.'
|
||||
severity: Medium
|
||||
requiredDataConnectors:
|
||||
- connectorId: AzureActiveDirectory
|
||||
|
@ -34,17 +35,27 @@ query: |
|
|||
SigninLogs
|
||||
| where TimeGenerated >= ago(lookBack)
|
||||
| where ResultType == 0
|
||||
| summarize successfulAccountSigninCount = dcount(UserPrincipalName), successfulAccountSigninSet = makeset(UserPrincipalName, 15) by IPAddress
|
||||
| summarize successSigninStart = min(TimeGenerated), successSigninEnd = max(TimeGenerated), successfulAccountSigninCount = dcount(UserPrincipalName), successfulAccountSigninSet = makeset(UserPrincipalName, 15) by IPAddress
|
||||
// Assume IPs associated with sign-ins from 100+ distinct user accounts are safe
|
||||
| where successfulAccountSigninCount < threshold
|
||||
) on IPAddress
|
||||
// IPs from which attempts to authenticate as disabled user accounts originated, and had a non-zero success rate for some other account
|
||||
| where successfulAccountSigninCount != 0
|
||||
// Successful Account Signins occur within the same lookback period as the failed
|
||||
| extend SuccessBeforeFailure = iff(TimeGenerated < StartTime, true, false)
|
||||
| extend SuccessBeforeFailure = iff(successSigninStart >= StartTime and successSigninEnd <= EndTime, true, false)
|
||||
| project StartTime, EndTime, IPAddress, disabledAccountLoginAttempts, disabledAccountsTargeted, disabledAccountSet, applicationSet,
|
||||
successfulAccountSigninCount, successfulAccountSigninSet
|
||||
| order by disabledAccountLoginAttempts
|
||||
// Break up the string of Succesfully signed into accounts into individual events
|
||||
| mvexpand successfulAccountSigninSet
|
||||
| extend AccountCustomEntity = tostring(successfulAccountSigninSet), timestamp = StartTime, IPCustomEntity = IPAddress
|
||||
| extend timestamp = StartTime, IPCustomEntity = IPAddress
|
||||
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountCustomEntity
|
||||
- entityType: IP
|
||||
fieldMappings:
|
||||
- identifier: Address
|
||||
columnName: IPCustomEntity
|
|
@ -1,7 +1,7 @@
|
|||
id: cf83633e-5dfd-4887-993b-c910452439da
|
||||
name: Failed attempt to access Azure Portal
|
||||
description: |
|
||||
'Access attempts to Azure Portal from an unauthorized user. Either invalid password or the user account does not exist.'
|
||||
'Access attempts to Azure Portal from an unauthorized user. Either invalid password or the user account does not exist.'
|
||||
requiredDataConnectors:
|
||||
- connectorId: AzureActiveDirectory
|
||||
dataTypes:
|
||||
|
@ -22,9 +22,14 @@ query: |
|
|||
| extend OS = DeviceDetail.operatingSystem, Browser = DeviceDetail.browser
|
||||
| extend StatusCode = tostring(Status.errorCode), StatusDetails = tostring(Status.additionalDetails)
|
||||
| extend State = tostring(LocationDetails.state), City = tostring(LocationDetails.city)
|
||||
| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), IPAddresses = makeset(IPAddress), DistinctIPCount = dcount(IPAddress),
|
||||
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), IPAddresses = makeset(IPAddress), DistinctIPCount = dcount(IPAddress),
|
||||
makeset(OS), makeset(Browser), makeset(City), AttemptCount = count()
|
||||
by UserDisplayName, UserPrincipalName, AppDisplayName, ResultType, ResultDescription, StatusCode, StatusDetails, Location, State
|
||||
| extend timestamp = StartTimeUtc, AccountCustomEntity = UserPrincipalName
|
||||
| extend timestamp = StartTime, AccountCustomEntity = UserPrincipalName
|
||||
| sort by AttemptCount
|
||||
|
||||
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountCustomEntity
|
|
@ -3,7 +3,7 @@ name: User Login IP Address Teleportation
|
|||
description: |
|
||||
'This query over SiginLogs will identify user accounts that have logged in from two different countries
|
||||
within a specified time window, by default this is a 10 minute window either side of the previous login.
|
||||
This query will detect users roaming onto VPN's, it's possible to exclude known VPN IP address ranges.'
|
||||
This query will detect users roaming onto VPNs, it is possible to exclude known VPN IP address ranges.'
|
||||
requiredDataConnectors:
|
||||
- connectorId: AzureActiveDirectory
|
||||
dataTypes:
|
||||
|
@ -64,3 +64,14 @@ query: |
|
|||
| where TimeGenerated between (WindowStart .. WindowEnd)
|
||||
| project Account=UserPrincipalName, AnomalousIP=IPAddress, AnomalousLoginTime=TimeGenerated, AnomalousCountry=country, OtherLoginIP=IPAddress1, OtherLoginCountry=country1, OtherLoginWindowStart=WindowStart, OtherLoginWindowEnd=WindowEnd
|
||||
| where AnomalousIP !in(excludeKnownVPN) and OtherLoginIP !in(excludeKnownVPN)
|
||||
| extend timestamp = AnomalousLoginTime, AccountCustomEntity = Account, IPCustomEntity = AnomalousIP
|
||||
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountCustomEntity
|
||||
- entityType: IP
|
||||
fieldMappings:
|
||||
- identifier: Address
|
||||
columnName: IPCustomEntity
|
|
@ -40,4 +40,9 @@ query: |
|
|||
tostring(LocationDetails["city"]), ";" , tostring(LocationDetails["geoCoordinates"])), UserPrincipalName
|
||||
| extend timestamp = TimeGenerated, AccountCustomEntity = UserPrincipalName
|
||||
| order by AppDisplayName, TimeGenerated desc
|
||||
|
||||
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountCustomEntity
|
|
@ -1,9 +1,9 @@
|
|||
id: 41fa6e2d-afe9-4398-9356-cec3a927e44e
|
||||
name: Azure Active Directory signins from new locations
|
||||
description: |
|
||||
'New Azure Active Directory signin locations today versus historical Azure Active Directory signin data
|
||||
'New Azure Active Directory signin locations today versus historical Azure Active Directory signin data.
|
||||
In the case of password spraying or brute force attacks one might see authentication attempts for many
|
||||
accounts from a new location'
|
||||
accounts from a new location.'
|
||||
requiredDataConnectors:
|
||||
- connectorId: AzureActiveDirectory
|
||||
dataTypes:
|
||||
|
@ -22,7 +22,7 @@ query: |
|
|||
| summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), perIdentityAuthCount = count()
|
||||
by Identity, locationString = strcat(tostring(LocationDetails["countryOrRegion"]), "/", tostring(LocationDetails["state"]), "/",
|
||||
tostring(LocationDetails["city"]), ";" , tostring(LocationDetails["geoCoordinates"]))
|
||||
| summarize StartTimeUtc = min(StartTimeUtc), EndTimeUtc = max(EndTimeUtc), distinctAccountCount = count(), identityList=makeset(Identity) by locationString
|
||||
| summarize StartTime = min(StartTimeUtc), EndTime = max(EndTimeUtc), distinctAccountCount = count(), identityList=makeset(Identity) by locationString
|
||||
| extend identityList = iff(distinctAccountCount<10, identityList, "multiple (>10)")
|
||||
| join kind= anti (
|
||||
SigninLogs
|
||||
|
@ -34,5 +34,5 @@ query: |
|
|||
on locationString
|
||||
// select threshold above which #new accounts from a new location is deemed suspicious
|
||||
| where distinctAccountCount > countThreshold
|
||||
| extend timestamp = StartTimeUtc
|
||||
| extend timestamp = StartTime
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
id: 745a22ec-fed8-49b9-9f62-4570b7709da4
|
||||
name: Azure Active Directory sign-in burst from multiple locations
|
||||
description: |
|
||||
'This query over Azure Active Directory sign-in activity highlights accounts associated
|
||||
with multiple authentications from different geographical locations in a short space of time.'
|
||||
'Highlights accounts associated with multiple authentications from different geographical locations in a short period of time.'
|
||||
requiredDataConnectors:
|
||||
- connectorId: AzureActiveDirectory
|
||||
dataTypes:
|
||||
|
@ -22,6 +21,7 @@ query: |
|
|||
// filter out signins associated with top 100 signin locations
|
||||
| join kind=anti (
|
||||
SigninLogs
|
||||
| where TimeGenerated >= timeRange
|
||||
| extend locationString= strcat(tostring(LocationDetails["countryOrRegion"]), "/",
|
||||
tostring(LocationDetails["state"]), "/", tostring(LocationDetails["city"]))
|
||||
| where locationString != "//"
|
||||
|
@ -48,4 +48,9 @@ query: |
|
|||
| summarize by timeSpan, Identity, locationString, EndLocationString, Start, End, UserPrincipalName
|
||||
| extend timestamp = Start, AccountCustomEntity = UserPrincipalName
|
||||
| order by Identity
|
||||
|
||||
|
||||
entityMappings:
|
||||
- entityType: Account
|
||||
fieldMappings:
|
||||
- identifier: FullName
|
||||
columnName: AccountCustomEntity
|
Загрузка…
Ссылка в новой задаче