Notice: Due to size constraints and loading performance considerations, scripts referenced in blog posts are not attached directly. To request access, please complete the following form: Script Request Form Note: A Google account is required to access the form.
Disclaimer: I do not accept responsibility for any issues arising from scripts being run without adequate understanding. It is the user's responsibility to review and assess any code before execution. More information

SMS Sign-In : Microsoft Entra ID - Report and Disablement.

Microsoft Entra ID is currently undergoing a significant transformation. By September 30, 2025, all organizations must migrate from legacy MFA and SSPR policies to the new unified Authentication Methods policy. However, this migration process has introduced a critical security concern that many administrators may not be aware of.

During the migration to the new Authentication Methods policy, SMS sign-in is enabled by default. This means users can now sign in using just their phone number and an SMS code - without needing to know their username or password.

This is then controlled by the Authentication method as defined in the Entra security:


If you then edit the SMS option you will see the option to "User for sign-in" is ticked as below:


If you do not want this feature then this tick needs to be removed from this option!

While this feature was designed to simplify authentication for frontline workers, it creates a significant security vulnerability for information workers and general enterprise users.

The Security Risk: Your Phone Number Is Your Password

Here's why SMS sign-in poses a serious security threat in enterprise environments:

1. Phone Numbers Are Public Information

Employee phone numbers are often discoverable through:

  • Exchange Online Global Address Lists
  • Company directories
  • Social media profiles
  • Public business listings
  • Previous data breaches

2. SMS Notifications Aren't Private by Default

Most smartphones display SMS messages on the lock screen by default. This means:

  • An attacker who knows someone's phone number can trigger an SMS login code
  • The code appears on the locked phone screen
  • No device access is required to view the message
  • The attack can be executed remotely

3. The Attack Scenario

  1. Attacker discovers employee phone number (via Exchange, social media, etc.)
  2. Attacker goes to Office 365 sign-in page
  3. Attacker enters the victim's phone number instead of email address
  4. System sends SMS code to victim's phone
  5. Code appears on victim's lock screen (if notification privacy not configured)
  6. Attacker gains access to the victim's account

4. Beyond Personal Phones

The risk extends to any scenario where SMS codes might be intercepted:

  • SIM swapping attacks
  • Shared or corporate devices
  • Phones left unattended on desks

When Did This Start?

The SMS sign-in default enablement began rolling out as part of Microsoft's Authentication Methods policy migration process, which organizations must complete by September 30, 2025. This migration was originally scheduled for 2024 but was extended to give organizations more time to prepare.

The issue specifically occurs because when migrating from legacy policies to the new Authentication Methods policy, the "Use for sign-in" option is enabled by default for SMS settings, automatically enabling SMS sign-in for users who have phone numbers registered for MFA.

Finding Available Users

To help identify which users in your organization have SMS sign-in available you can use this  PowerShell script that queries Microsoft Entra ID and exports the results, remember to update the connections in bold!

Script : sms-mobile-enabled.ps1

# App Registration Connection
$tenantId = "<tenant-id>"
$clientId = "<application-id>"
$clientSecret = "<secret>"

# Connect using app registration
$secureSecret = ConvertTo-SecureString $clientSecret -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($clientId, $secureSecret)
Connect-MgGraph -TenantId $tenantId -ClientSecretCredential $credential

Write-Host "Searching for users with SMS sign-in enabled..." -ForegroundColor Green

$results = @()
$allUsers = Get-MgUser -All -Property "id,displayName,userPrincipalName,userType" | Where-Object { $_.UserType -ne "Guest" }
$totalUsers = $allUsers.Count
$processedCount = 0

foreach ($user in $allUsers) {
    $processedCount++
    Write-Progress -Activity "Processing Users" -Status "Checking user $processedCount of $totalUsers" -PercentComplete (($processedCount / $totalUsers) * 100)
    
    try {
        $phoneAuth = Get-MgUserAuthenticationPhoneMethod -UserId $user.Id -ErrorAction SilentlyContinue
        if ($phoneAuth) {
            foreach ($phone in $phoneAuth) {
                if ($phone.SmsSignInState -eq "ready" -or $phone.SmsSignInState -eq "enabled") {
                    $results += [PSCustomObject]@{
                        DisplayName = $user.DisplayName
                        UserPrincipalName = $user.UserPrincipalName
                        PhoneNumber = $phone.PhoneNumber
                        PhoneType = $phone.PhoneType
                        SmsSignInState = $phone.SmsSignInState
                    }
                }
            }
        }
    }
    catch {
        continue
    }
}

# Clear progress bar
Write-Progress -Activity "Processing Users" -Completed

# Console output with count
Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "SMS SIGN-IN ENABLED USERS SUMMARY" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "Total users found with SMS sign-in enabled: $($results.Count)" -ForegroundColor Yellow
Write-Host "Total users processed: $totalUsers" -ForegroundColor Gray
Write-Host "`nUsers with SMS sign-in enabled:" -ForegroundColor Green

# Display results in console
$results | Format-Table -AutoSize

# Export to CSV
$csvPath = "SMS_Enabled_Users_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"
$results | Export-Csv -Path $csvPath -NoTypeInformation
Write-Host "`nResults exported to: $csvPath" -ForegroundColor Green
Write-Host "CSV file saved in current directory: $(Get-Location)" -ForegroundColor Gray

When executed it will scan though all the users (excluding guest and B2B as these accounts are not affect by this)


Interpreting the Results

When you run this script, you'll see output like this which will tell you all the user that are "Available" for SMS Login as below:

========================================
SMS SIGN-IN ENABLED USERS SUMMARY
========================================
Total users found with SMS sign-in enabled: 696
Total users processed: 18624

Users with SMS sign-in enabled:

DisplayName          UserPrincipalName              PhoneNumber      PhoneType SmsSignInState
-----------          -----------------              -----------      --------- --------------
John Smith           duck.dogders@croucher.cloud    +44123456789     mobile    enabled
Sarah Johnson        james.bond@croucher.cloud      +44987654321     mobile    enabled

Each user listed can potentially sign in using only their phone number and SMS code, bypassing traditional username/password authentication.

Finding Enabled Users

We now need to find all users that have this feature enabled, not ready, so for that we will use the CSV from earlier and look at all those users and look for the following attributes in bold as below:

Found 1 phone method(s):
  Phone Number: +44 7384751119
  Phone Type: mobile
  SMS Sign-In State: 'configured'
  SMS sign-in: Configured

We need to report on all users that have either of those attributes as that will mean they gone further than "being ready"

Script : locate-enabled-smslogins.ps1

# App Registration Connection
$tenantId = "<tenant_id>"
$clientId = "<application_id>"
$clientSecret = "<secret_key>"

# Connect using app registration
$secureSecret = ConvertTo-SecureString $clientSecret -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($clientId, $secureSecret)
Connect-MgGraph -TenantId $tenantId -ClientSecretCredential $credential

# Find the latest CSV file in current directory
$latestCSV = Get-ChildItem -Path "." -Filter "SMS_Enabled_Users_*.csv" | Sort-Object LastWriteTime -Descending | Select-Object -First 1

if (-not $latestCSV) {
    Write-Host "No SMS_Enabled_Users_*.csv file found in current directory!" -ForegroundColor Red
    exit
}

Write-Host "Processing latest CSV file: $($latestCSV.Name)" -ForegroundColor Green
$users = Import-Csv $latestCSV.FullName

Write-Host "Found $($users.Count) users to check detailed SMS sign-in status..." -ForegroundColor Yellow
Write-Host ""

$detailedResults = @()
$count = 0

foreach ($user in $users) {
    $count++
    Write-Progress -Activity "Checking Detailed SMS Status" -Status "User $count of $($users.Count): $($user.DisplayName)" -PercentComplete (($count / $users.Count) * 100)
    
    try {
        $phoneAuth = Get-MgUserAuthenticationPhoneMethod -UserId $user.UserPrincipalName -ErrorAction SilentlyContinue
        
        if ($phoneAuth) {
            foreach ($phone in $phoneAuth) {
                $detailedResults += [PSCustomObject]@{
                    DisplayName = $user.DisplayName
                    UserPrincipalName = $user.UserPrincipalName
                    PhoneNumber = $phone.PhoneNumber
                    PhoneType = $phone.PhoneType
                    OriginalSmsSignInState = $user.SmsSignInState
                    DetailedSmsSignInState = $phone.SmsSignInState
                    SMSSignInStatus = if ($phone.SmsSignInState -eq "ready") { "SMS SIGN-IN READY" } 
                                     elseif ($phone.SmsSignInState -eq "enabled") { "SMS SIGN-IN ENABLED" }
                                     elseif ($phone.SmsSignInState -eq "notConfigured") { "Not Configured" }
                                     else { $phone.SmsSignInState }
                }
            }
        } else {
            $detailedResults += [PSCustomObject]@{
                DisplayName = $user.DisplayName
                UserPrincipalName = $user.UserPrincipalName
                PhoneNumber = $user.PhoneNumber
                PhoneType = $user.PhoneType
                OriginalSmsSignInState = $user.SmsSignInState
                DetailedSmsSignInState = "No Phone Methods"
                SMSSignInStatus = "Account not Enabled"
            }
        }
    }
    catch {
        $detailedResults += [PSCustomObject]@{
            DisplayName = $user.DisplayName
            UserPrincipalName = $user.UserPrincipalName
            PhoneNumber = $user.PhoneNumber
            PhoneType = $user.PhoneType
            OriginalSmsSignInState = $user.SmsSignInState
            DetailedSmsSignInState = "Error"
            SMSSignInStatus = "Account not Enabled"
        }
    }
}

Write-Progress -Activity "Checking Detailed SMS Status" -Completed

# Display results
Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "DETAILED SMS SIGN-IN STATUS REPORT" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "Total users analyzed: $($detailedResults.Count)" -ForegroundColor Yellow

# Group by status
$statusSummary = $detailedResults | Group-Object SMSSignInStatus
Write-Host "`nStatus Summary:" -ForegroundColor Green
foreach ($status in $statusSummary) {
    Write-Host "  $($status.Name): $($status.Count) users" -ForegroundColor White
}

Write-Host "`nDetailed Results:" -ForegroundColor Green
$detailedResults | Format-Table -AutoSize

# Export detailed results
$detailedCSVPath = "SMS_Detailed_Status_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"
$detailedResults | Export-Csv -Path $detailedCSVPath -NoTypeInformation
Write-Host "`nDetailed results exported to: $detailedCSVPath" -ForegroundColor Green
Write-Host "CSV file saved in current directory: $(Get-Location)" -ForegroundColor Gray

The results will show that we have 7 notSupported users - which is triggered on an alternative number as this type of number is indeed not supported.


This is the entry in the CSV file for the "notSupported" people

"James Bond","james.bond:croucher.cloud","+44 7285412234","alternateMobile","ready","notSupported","notSupported"

This would therefore suggest that we have no users at the moment with this enabled, so it can be disabled without creating to much noise.

Notification Privacy

Ensure users configure notification privacy on their devices:

  • iPhone: Settings > Notifications > Show Previews > When Unlocked
  • Android: Settings > Apps > Notifications > On Lock Screen > Hide sensitive content

Conclusion

SMS sign-in in enterprise environments represents a significant downgrade in security posture, essentially reducing authentication to "something you have" (a phone) without the traditional "something you know" (password) component.

The PowerShell script provided gives you the tools to quickly identify affected users in your environment. Use this information to make informed decisions about your authentication policies and ensure your organization maintains strong security practices.

Previous Post Next Post

نموذج الاتصال