Detection Playbook: Valid Accounts (T1078)

T1078 · 2026-07-07

Valid Accounts

Stealth
Containers ESXi IaaS Identity Provider
MITRE ATT&CK →
Technique Valid Accounts (T1078)
Tactic Stealth
Platforms Containers, ESXi, IaaS, Identity Provider, Linux, macOS, Network Devices, Office Suite, SaaS, Windows

Overview

Valid Accounts (T1078) describes adversaries using legitimate, existing credentials — stolen, purchased, phished, or brute-forced — to access systems and services rather than deploying malware. Because the access is technically authorized, attackers can achieve Initial Access, maintain Persistence, escalate Privileges, or evade defenses, all while blending into normal user activity across cloud, SaaS, on-premises, and network infrastructure.

This technique is one of the most commonly observed in real-world breaches precisely because it bypasses most endpoint and perimeter controls by design. Every security team needs behavioral detection for it because signature-based tools are largely useless here — the attacker looks like a legitimate user until context and pattern analysis expose the anomaly.

Attacker Perspective

Adversaries abuse valid accounts because it is the path of least resistance to durable, low-noise access across virtually every platform in an enterprise.

  • Credential stuffing against cloud/SaaS portals: Tools like Credmaster or Spray365 automate password spray attacks against Microsoft 365, Okta, or Google Workspace login endpoints, targeting accounts with weak or reused passwords to gain initial cloud access.
  • Dormant account abuse: Attackers enumerate disabled or inactive AD accounts using net user /domain or Get-ADUser -Filter {Enabled -eq $false}, then re-enable or exploit accounts belonging to former employees who will never notice anomalous login activity.
  • Service account lateral movement: After gaining a foothold, attackers extract service account credentials via Mimikatz sekurlsa::logonpasswords or Kerberoasting with Rubeus.exe kerberoast, then use those credentials to pivot to servers where those accounts have broad permissions.
  • Cloud IAM key abuse: Stolen AWS IAM access keys or Azure service principal secrets are used with aws sts get-caller-identity or az account get-access-token to enumerate cloud resources and escalate permissions without touching any endpoint.

This technique is uniquely attractive because it requires no custom malware, leaves minimal forensic artifacts on disk, and can persist for months undetected if behavioral baselines are not actively monitored.

Detection Strategy

Required Telemetry

  • Windows Authentication Events: Enable Audit Logon Events and Audit Account Logon Events via GPO (Computer Configuration → Windows Settings → Security Settings → Advanced Audit Policy Configuration). Key Event IDs: 4624 (successful logon), 4625 (failed logon), 4648 (explicit credential use), 4768/4769 (Kerberos TGT/service ticket requests), 4776 (NTLM credential validation), 4720 (account created), 4722 (account enabled), 4728/4732/4756 (member added to privileged group).
  • Windows Account Management: Enable Audit Account Management via GPO. Generates 4740 (account lockout), 4767 (account unlocked), 4723/4724 (password change/reset).
  • Active Directory Domain Controller Logs: Collect Security event logs from all DCs. Ensure Audit Directory Service Access is enabled to capture 4662 (AD object access, useful for DCSync detection).
  • Azure AD / Entra ID Sign-In Logs: Enable Azure AD Diagnostic Settings and stream SignInLogs and AuditLogs to your SIEM. Captures ResultType, RiskLevel, UserAgent, IPAddress, ConditionalAccessStatus, and MFA status for every authentication attempt.
  • Okta / Identity Provider Logs: Enable Okta System Log via API or Syslog integration. Key event types: user.session.start, user.authentication.auth_via_mfa, user.account.lock, user.session.impersonation.initiate, policy.evaluate_sign_on.
  • Linux PAM / Auditd: Deploy auditd with rules targeting authentication: -w /etc/passwd -p wa -k identity, -w /etc/sudoers -p wa -k sudoers. Collect /var/log/auth.log or /var/log/secure for SSH logon events (sshd: Accepted, sshd: Failed). Enable -a always,exit -F arch=b64 -S execve -k exec for process execution context.
  • VPN / Remote Access Logs: Collect authentication logs from your VPN gateway (Cisco ASA, Palo Alto GlobalProtect, Fortinet FortiGate). Capture user, source_ip, authentication_result, vpn_group, and session timestamps.
  • Cloud Provider Logs: AWS CloudTrail (all regions, all services, including ConsoleLogin events and AssumeRole calls). Azure Activity Log and Azure AD Sign-In Logs. GCP Cloud Audit Logs (cloudaudit.googleapis.com/activity). Enable all in the respective console and forward to SIEM.
  • SaaS Application Logs: Microsoft 365 Unified Audit Log (enable via Set-AdminAuditLogConfig -UnifiedAuditLogIngestionEnabled $true), capturing UserLoggedIn, FileAccessed, MailItemsAccessed operations. Collect Google Workspace Admin SDK Reports API logs similarly.
  • Network / Firewall Logs: Collect authentication-related flows for protocols like RDP (TCP/3389), SMB (TCP/445), WinRM (TCP/5985/5986), and SSH (TCP/22). Palo Alto, Fortinet, or Cisco ASA syslog should include src_ip, dst_ip, user, action.

Key Indicators

  • Off-hours authentication: In Windows Security logs, EventID = 4624 with LogonType = 10 (RemoteInteractive/RDP) or LogonType = 3 (Network) where TimeCreated falls outside established business hours for that user. In Azure AD SignInLogs, check createdDateTime against the user’s normal login window.
  • Impossible travel / geography anomaly: In Azure AD SignInLogs or Okta System Log, two user.session.start events from the same account within a short time window (timedelta < 60 minutes) where ipAddress geolocates to different countries. Field: location.countryOrRegion in Azure AD logs.
  • Password spray pattern: In Windows EventID 4625 logs, SubStatus = 0xC000006A (wrong password) across many distinct TargetUserName values from the same IpAddress within a short time window. In Azure AD, ResultType = 50126 (invalid credentials) across many users from one IP.
  • Dormant account activation: Windows EventID 4722 (account enabled) followed within minutes by EventID 4624 (successful logon) for an account with no prior logon events in 90+ days. Cross-reference TargetUserName against HR offboarding records.
  • Explicit credential use: Windows EventID 4648 where SubjectUserName differs from TargetUserName, particularly when the subject is not a known administrative account. This catches runas abuse and Pass-the-Hash pivoting.
  • Kerberoasting indicators: Windows EventID 4769 with TicketEncryptionType = 0x17 (RC4-HMAC, weak encryption) and ServiceName not ending in $ (not a machine account), especially when many such requests originate from one IpAddress in a short window.
  • New user agent or device for cloud account: In Azure AD SignInLogs, deviceDetail.browser or deviceDetail.operatingSystem values that have never been seen for this userPrincipalName before. In M365 Unified Audit Log, UserAgent field showing unusual client strings like python-requests or Go-http-client.
  • Cloud API key abuse: In AWS CloudTrail, eventName = ConsoleLogin where userIdentity.type = IAMUser combined with errorCode = AccessDenied across many eventName values — indicating reconnaissance using valid but low-privilege keys. Also watch for eventName = AssumeRole to unusual roleArn targets.
  • Service account interactive logon: Windows EventID 4624 where TargetUserName matches known service accounts (naming convention like svc_* or sa_*) and LogonType = 2 (interactive) or LogonType = 10 (RemoteInteractive) — service accounts should never log in interactively.

Detection Logic

Rule 1: High-volume failed logons followed by success (credential stuffing/spray)
IF EventID = 4625 AND SubStatus = 0xC000006A AND COUNT(DISTINCT TargetUserName) > 10 WITHIN 5 minutes BY IpAddress THEN alert("Possible Password Spray - Multiple Failed Logons")

This catches broad spray attacks across many accounts from one source IP. Expected volume: low in mature environments with MFA enforced, but may fire during legitimate lockout events — tune the threshold and whitelist known IT admin source IPs.

Rule 2: Successful logon after multiple failures for same account
IF EventID = 4625 AND COUNT(EventID = 4625) >= 5 WITHIN 10 minutes BY TargetUserName THEN EventID = 4624 BY same TargetUserName WITHIN 5 minutes THEN alert("Brute Force Success - Valid Account Compromised")

This higher-precision rule correlates repeated failures with eventual success on the same account — a strong indicator of credential brute-force. Expected volume: very low; most legitimate lockouts do not result in successful logon without a password reset.

Rule 3: Dormant account logon (inactive 90+ days)
IF EventID = 4624 AND TargetUserName NOT IN [last_logon_within_90_days_list] AND TargetUserName NOT IN [service_accounts, system_accounts] THEN alert("Dormant Account Logon Detected")

This requires enrichment: join logon events against an AD attribute table where lastLogonTimestamp is older than 90 days. Expected volume: low if your IAM hygiene is good; high if stale accounts are not regularly reviewed. Tune by excluding known service accounts and system identities.

Rule 4: Impossible travel — same account, two geolocations within 1 hour
IF user.session.start BY userPrincipalName WHERE geo_country(ipAddress) != geo_country(PREV(ipAddress)) AND timedelta(current_event, PREV(event)) < 60 minutes THEN alert("Impossible Travel Detected for Account")

Apply this to Azure AD SignInLogs, Okta System Log, or any IdP that provides ipAddress per session event. Expected volume: moderate — VPN users, travelers, and shared accounts generate false positives. Narrow with AND riskLevel != none in Azure AD or cross-reference with corporate VPN egress IPs to suppress legitimate cases.

Tuning Guidance

  • IT admin bulk operations: Helpdesk password resets or bulk account provisioning scripts can trigger spray-like patterns. Exclude IpAddress IN [helpdesk_admin_subnets] and SubjectUserName IN [tier1_admin_accounts] from failed-logon volume rules.
  • Corporate VPN egress IPs causing impossible travel false positives: Users connecting through split-tunnel VPNs or switching between VPN and direct internet appear in two countries. Maintain a list of corporate_vpn_egress_ips and exclude logins from these from the impossible travel rule, or suppress alerts where both logins originate from known corporate IP ranges.
  • Service accounts running scheduled tasks or batch jobs: These generate high-volume logon events (LogonType = 4 or LogonType = 5) that may match volume thresholds. Exclude LogonType IN [4, 5] from spray rules, and maintain a known-good service_accounts reference list scoped to expected source hosts.
  • Legitimate dormant accounts: Contractors, seasonal workers, or shared mailbox accounts may have long gaps between logins. Enrich your dormant account rule with an HR/identity lifecycle feed and exclude accounts tagged as account_type = contractor_seasonal or add a secondary check requiring the logon to originate from an unrecognized IP or device.
  • Developer and CI/CD service principals in cloud: AWS IAM roles and Azure service principals used by pipelines generate high volumes of API calls including AssumeRole and ConsoleLogin that can match cloud abuse patterns. Exclude userIdentity.arn IN [known_cicd_roles] and tag these identities explicitly in your SIEM lookup tables.

When the Alert Fires: Investigation Steps

  1. Verify the alert is real and pull the raw event. Navigate directly to the raw log in your SIEM — for Windows, confirm the EventID, TargetUserName, LogonType, IpAddress, and WorkstationName fields are populated as expected and the event was not generated by a test or synthetic log source.
  2. Identify the affected account and assess privilege level. Query Active Directory or your IdP for the account: check group memberships, last password change, lastLogonTimestamp, and whether it is a standard user, service account, or privileged admin. Flag immediately if the account has Domain Admin, Global Admin, or equivalent cloud IAM privileges — escalate to senior analyst or incident commander.
  3. Reconstruct the authentication timeline. Search for all logon events (EventID 4624, 4648, 4768, 4769) for this account across all systems in the past 72 hours. Use your SIEM to build a timeline of source IPs, workstations, logon types, and timestamps — look for the first anomalous entry as the likely point of initial access.
  4. Enumerate actions taken under the compromised account post-logon. For Windows, search process creation events (EventID 4688 or Sysmon EventID 1) filtered by SubjectUserName = affected_account. For cloud accounts, search CloudTrail, Azure Activity Log, or M365 Unified Audit Log for all API calls, file accesses, or mail reads performed after the suspicious logon — document every action taken.
  5. Check for network connections and data movement. For on-premises hosts, query firewall or proxy logs for connections from the source IP or workstation during the suspicious session — look for unusual outbound destinations, large data transfers, or connections to known-bad IPs. For cloud accounts, check for new S3 bucket policies, blob storage access, or email forwarding rules created during the session.
  6. Search for lateral movement originating from this account or host. Query for EventID 4624 with LogonType = 3 or LogonType = 10 where SubjectUserName or IpAddress matches the compromised account or its originating host. Check Sysmon network events (EventID 3) for RDP, SMB, WinRM, or SSH connections from the affected endpoint to other internal systems.
  7. Determine persistence and make the escalation decision. Search for new scheduled tasks (EventID 4698), new services (EventID 7045), new local admin accounts (EventID 4720), or new OAuth app grants in Azure AD/Okta. If any persistence mechanism, data exfiltration evidence, or lateral movement to additional systems is confirmed, escalate to a full incident response engagement — if the session was brief, from a known IP, with no anomalous actions and explainable by the user, document and close as a false positive.

Response Playbook

Containment

  • Isolate the affected endpoint while preserving forensics: If the suspicious logon involved a specific workstation or server, isolate it at the network switch level (disable port) or apply a host-based firewall block using EDR (CrowdStrike Network Containment, Defender for Endpoint Isolate Device). Do not power it off — memory artifacts and active connections are critical for investigation.
  • Disable the compromised account immediately: In Active Directory, run Disable-ADAccount -Identity <username> or use ADUC. In Azure AD, set accountEnabled = false via Entra ID portal or Update-MgUser -UserId <UPN> -AccountEnabled $false. In Okta, suspend the user via the Okta Admin Console or API: POST /api/v1/users/{userId}/lifecycle/suspend.
  • Revoke all active sessions and tokens: In Azure AD, use Revoke-MgUserSignInSession -UserId <UPN> to invalidate all refresh tokens. In Okta, clear all active sessions from the Admin Console under the user profile. For AWS, disable the access key immediately: aws iam update-access-key --access-key-id <key> --status Inactive.
  • Block identified source IPs at the perimeter: Submit the attacker’s source IP(s) to your firewall or SIEM-integrated blocking workflow. For Palo Alto, use Dynamic Address Groups via Panorama. For cloud environments, add deny rules to the relevant Security Group, Azure NSG, or GCP VPC Firewall. Also block at DNS if a domain is involved.
  • Terminate any active malicious sessions or processes: If the attacker is actively connected, terminate the RDP, WinRM, or SSH session from the server side (quser and logoff <sessionid> on Windows; pkill -u <username> on Linux). Use your EDR to kill any identified malicious processes by PID.

Eradication

  • Remove all identified persistence mechanisms: Check and remove unauthorized scheduled tasks (Get-ScheduledTask | Where {$_.TaskPath -notlike "\Microsoft*"}), registry run keys (HKCU\Software\Microsoft\Windows\CurrentVersion\Run), new local accounts, and installed services (Get-Service cross-referenced against baseline). On Linux, audit /etc/cron*, ~/.ssh/authorized_keys, and /etc/sudoers.d/.
  • Search for and remove dropped tools or payloads: Use your EDR to run a threat hunt for known attacker tools (Mimikatz, Rubeus, CrackMapExec binaries) across affected hosts. Hash-match against VirusTotal or your threat intel platform. Delete confirmed malicious files and document their paths and hashes as IOCs.
  • Force password reset for the compromised account and any accounts it accessed: Reset the compromised account’s password using a complex, unique value. Identify any accounts whose credentials may have been exposed (accounts logged into on the compromised host, or accessible via the compromised service account) and reset those as well. Enforce MFA enrollment before re-enabling any account.
  • Audit lateral movement targets for secondary compromise: For every system the compromised account authenticated to during the attack window, repeat the investigation steps — look for additional persistence, tool drops, or further lateral movement. Treat each as potentially compromised until cleared.
  • Rotate all secrets and API keys that were accessible during the compromise: For cloud environments, rotate any AWS access keys, Azure client secrets, or GCP service account keys that were in use or stored on the compromised system. Audit Secrets Manager, Key Vault, or similar services for unauthorized access during the attack window and rotate all exposed secrets.

Recovery

  • Verify the host is clean before restoring network connectivity: Confirm with your EDR and a manual review of persistence locations that no indicators remain. If confidence is low (e.g., the attacker had extended dwell time or admin access), re-image the endpoint from a known-good golden image rather than attempting to clean in place.
  • Re-enable the user account only after full validation: Before re-enabling the account, confirm: password has been reset, MFA is enrolled and verified, no persistence linked to the account remains on any system, and the user has been briefed on how their credentials were likely compromised (phishing, credential stuffing, etc.).
  • Implement enhanced monitoring for the affected account and host for 72 hours post-remediation: Create a temporary watchlist in your SIEM containing the username, host, and any identified attacker IPs. Alert on any logon, process creation, or network connection involving these entities at a lower threshold than normal for the 72-hour window.
  • Document the complete incident timeline and conduct a lessons-learned review: Record first evidence of compromise, attacker actions, systems affected, containment time, and eradication steps in your case management system (ServiceNow, Jira, TheHive). Identify what detection fired, what was missed, and what detection gaps allowed the attack to progress.
  • Update detection rules and threat intelligence with new IOCs: Add confirmed attacker IPs, user agents, cloud resource ARNs or role names, file hashes, and behavioral patterns to your SIEM detection rules and threat intel platform. Review whether the initial spray or logon anomaly could have been caught earlier and lower thresholds or add new rules accordingly.

Stay Ahead

Get daily threat intelligence and detection playbooks.

Free. No account. No email. Follow in Feedly, Inoreader, or any RSS reader.