SSPR/MFA
What Is SSPR
Attack
If you have control of an MFA method that is available to a user, you can reset their password without knowing their password.
Detect
Hunt for known bad MFA devices
Below scripts lists all MFA methods by every user and lists their properties.
param ($Path, $UserList)
if ( ($Path -eq $null) -or ($Path -eq "") -or ($Path -eq " "))
{
Write-Host "-Path not valid, please provide a filepath to export CSV to."
Write-Host "-UserList, to optionally add a list of users to save time. By default grabs a list of every user in the tenant."
}
else
{
#Connect MgGraph
Connect-MgGraph -Scopes 'UserAuthenticationMethod.Read.All' -NoWelcome
if ($UserList -eq $null)
{
# Display the custom objects
#Get all Azure users
$users = get-mguser -All
}
else
{
#Provide list of users
$users = ForEach ($mguser in $(get-content -Path $UserList)) {
get-mguser -userid $mguser
}
}
$results=@();
Write-Host "`nRetreived $($users.Count) users";
#loop through each user account
foreach ($user in $users) {
$MFAData=Get-MgUserAuthenticationMethod -UserId $user.UserPrincipalName #-ErrorAction SilentlyContinue
#check authentication methods for each user
ForEach ($method in $MFAData) {
$myObject = [PSCustomObject]@{
user = "-"
Id = "-"
MFAstatus = "-"
email = "-"
fido2 = "-"
app = "-"
password = "-"
phone = "-"
softwareoath = "-"
tempaccess = "-"
hellobusiness = "-"
DeviceName = "-"
PhoneAppVersion = "-"
DeviceTag = "-"
}
$myobject.user = $user.UserPrincipalName;
Switch ($method.AdditionalProperties["@odata.type"]) {
"#microsoft.graph.emailAuthenticationMethod" {
$myObject.Id = $method.Id
$myObject.email = $true
$myObject.MFAstatus = "Enabled"
}
"#microsoft.graph.fido2AuthenticationMethod" {
$myObject.fido2 = $true
$myObject.MFAstatus = "Enabled"
}
"#microsoft.graph.passwordAuthenticationMethod" {
$myObject.password = $true
# When only the password is set, then MFA is disabled.
if($myObject.MFAstatus -ne "Enabled")
{
$myObject.MFAstatus = "Disabled"
}
}
"#microsoft.graph.phoneAuthenticationMethod" {
$myObject.phone = $true
$myObject.MFAstatus = "Enabled"
}
"#microsoft.graph.microsoftAuthenticatorAuthenticationMethod" {
$myObject.Id = $method.Id
$myObject.DeviceName = $method.AdditionalProperties.displayName
$myObject.PhoneAppVersion = $method.AdditionalProperties.phoneAppVersion
$myObject.deviceTag = $method.AdditionalProperties.deviceTag
$myObject.MFAstatus = "Enabled"
}
"#microsoft.graph.softwareOathAuthenticationMethod" {
$myObject.Id = $method.Id
$myObject.softwareoath = "Oath OTP Enabled"
$myObject.MFAstatus = "Enabled"
}
"#microsoft.graph.temporaryAccessPassAuthenticationMethod" {
$myObject.tempaccess = $true
$myObject.MFAstatus = "Enabled"
}
"#microsoft.graph.windowsHelloForBusinessAuthenticationMethod" {
$myObject.hellobusiness = $true
$myObject.MFAstatus = "Enabled"
}
}
$results+= $myObject;
}
}
# Display the custom objects
$results | export-csv -path $Path
}


What logs are available?
Audit Logs:
Password is not required for SSPR, only an alternate authentication method.
SSPR activity flow:
User submitted their user ID
User was presented with verification options
User started the mobile app code verification option
User completed the mobile app code verification option
User completed all verification steps required to reset their password
User submitted a new password
Reset user password
Update StsRefreshTokenValidFrom Timestamp
Successfully completed reset.
First MFA:
OLD VALUE:
{"DeviceName":"SM-S911U","DeviceToken":"fdP4zadhT9mVkYYo_yQqEz:APA91bF61gVUucY6QWx2eWDi5IaSxCbSAM6LWsNGMmiiNXLgzCughKpLH5Nm2BetAEkl0axD2_ySPOJ24TEc0Wh-wwDeQBH-VP5c7rEme-xPTPioBPs-KsO5ftitRu4YG218wxXmII1Z",
"DeviceTag":"SoftwareTokenActivated",
"PhoneAppVersion":"6.2309.6329",
"OathTokenTimeDrift":0,
"DeviceId":"00000000-0000-0000-0000-000000000000",
"Id":"8cb20903-8109-4518-8269-a82dab749591","TimeInterval":0,
"AuthenticationType":3,
"NotificationType":4,
"LastAuthenticatedTimestamp":"2023-10-25T06:38:08.344692Z",
"AuthenticatorFlavor":null,
"HashFunction":null,
"TenantDeviceId":null,
"SecuredPartitionId":0,
"SecuredKeyId":0}
NEW VALUE:
{"DeviceName":"SM-S911U",
"DeviceToken":"fdP4zadhT9mVkYYo_yQqEz:APA91bF61gVUucY6QWx2eWDi5IaSxCbSAM6LWsNGMmiiNXLgzCughKpLH5Nm2BetAEkl0axD2_ySPOJ24TEc0Wh-wwDeQBH-VP5c7rEme-xPTPioBPs-KsO5ftitRu4YG218wxXmII1Z",
"DeviceTag":"SoftwareTokenActivated",
"PhoneAppVersion":"6.2309.6329",
"OathTokenTimeDrift":0,
"DeviceId":"00000000-0000-0000-0000-000000000000",
"Id":"8cb20903-8109-4518-8269-a82dab749591",
"TimeInterval":0,
"AuthenticationType":3,
"NotificationType":4,
"LastAuthenticatedTimestamp":"2024-12-12T12:38:08.344692Z",
"AuthenticatorFlavor":"Authenticator",
"HashFunction":"hmacsha256",
"TenantDeviceId":null,
"SecuredPartitionId":0,"SecuredKeyId":0}]
AuthenticationFlavor is updated from null, to authenticator (not sure why):
"AuthenticatorFlavor":null,
"AuthenticatorFlavor":"Authenticator",
LastAuthenticatedTimestamp is sometimes updated (note sure when):
"LastAuthenticatedTimestamp":"2023-10-25T06:38:08.344692Z",
"LastAuthenticatedTimestamp":"2024-12-12T12:38:08.344692Z",
Get audit log details, OData queries not support for filtering. Will have to get through graph explorer and copy paste to .txt file.
Sign-In Logs:
Mitigate
Last updated