Merge pull request #1984 from Azure/shainw-huntFormatUpd

updating entity mappings and descriptions to fix some characters that…
This commit is contained in:
Shain 2021-03-23 20:47:20 -07:00 коммит произвёл GitHub
Родитель 227614b88f 605d3f044e
Коммит d43e0a60da
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
17 изменённых файлов: 135 добавлений и 34 удалений

Просмотреть файл

@ -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