Even MOAR Powershell, looking Entra logins - the good, the bad and password sprays
One thing that folks never seem to do after "going to the CLOOOOUUUUD" is to look at their logs, logs that they would have checked daily when things were on premise.
One log that really bears looking at is the log of successful and failed logins. the call for that is:
$f = Get-MgAuditLogSignIn
Let's look at one object in the log:

This is an interactive login to Outlook, which failed on a conditional access check
What is that under location though - that's likely why this failed. How do we get the "where" from that? And why does the status got a similar string in it instead of an actual status?
The command below shows us pulling only failed logins ("status/errorCode ne 0"), extracting the geo location info, and also the failure reason
Get-MgAuditLogSignIn -Filter "status/errorCode ne 0" -All | Select-Object `
CreatedDateTime,
UserPrincipalName,
IPAddress,
@{Name="City"; Expression={$_.Location.City}},
@{Name="State"; Expression={$_.Location.State}},
@{Name="Country"; Expression={$_.Location.CountryOrRegion}},
@{Name="FailureReason"; Expression={$_.Status.FailureReason}}
Aha! Now we have that otherwise hidden information! It's this sort of list where you'll see password sprays show up. The list below shows part of such an attack, note that the last two lines show the account is locked. The "IP address with malicious activity" alert generally means that this is a rotating proxy service, and the IP's in it have been fully or partially enumerated as "bad".

Or, looking for successful logins from unexpected countries, the command below. Let's also remove the State / City info, normally it's just the country that matters, at least on the first pass through the data.
# set the array of "expected" Countries
$ExpectedCountries = @("CA", "US" )
#Get all successful logins
$f = Get-MgAuditLogSignIn -Filter "status/errorCode eq 0" -All | Select-Object `
CreatedDateTime,
UserPrincipalName,
UserDisplayName,
AppDisplayName,
ResourceDisplayName,
IsInteractive,
IPAddress,
@{Name="Country"; Expression={$_.Location.CountryOrRegion}},
@{Name="FailureReason"; Expression={$_.Status.FailureReason}}
# remove expected countries, and what is left is unexpected
# Just as Sherlock Holmes (or Occam) would say
$f | Where { $_.Country -notin $ExpectedCountries } | out-gridview

It's interesting to see a few IPv6 addresses in the list.
In writing this diary, I found multiple password spray attacks. This helped the client tighten up their conditional access policies, which was one of our goals going in.
Take a run at your Entra logs using the methods above. Let us know in the comments if you found any unexpected (or expected) events or attacks, or if you were able to use your logs to effect a change in your configuration (in conditional access polices for instance)
===============
Rob VandenBrink
[email protected]

Comments