Skip to content

[New Rule] Microsoft Entra ID Exccessive Account Lockouts Detected #4781

Closed
@terrancedejesus

Description

@terrancedejesus

Description

From recent VOID BLIZZARD research, password spraying and brute-force were a key observation for initial access to accounts in Entra ID. As such we have rules to detect this behavior, but not excessive lockouts if the method used were credential stuffing or password guessing. This error is often returned when authentication is attempted for an account that is locked. A high volume of these would be a decent signal.

Target Ruleset

azure

Target Rule Type

ES|QL

Tested ECS Version

No response

Query

FROM logs-azure.signinlogs*

| EVAL
    time_window = DATE_TRUNC(15 minutes, @timestamp),
    user_id = TO_LOWER(azure.signinlogs.properties.user_principal_name),
    ip = source.ip,
    login_error = azure.signinlogs.result_description,
    error_code = azure.signinlogs.properties.status.error_code,
    request_type = TO_LOWER(azure.signinlogs.properties.incoming_token_type),
    app_name = TO_LOWER(azure.signinlogs.properties.app_display_name),
    asn_org = source.`as`.organization.name,
    country = source.geo.country_name,
    user_agent = user_agent.original,
    event_time = @timestamp

| WHERE event.dataset == "azure.signinlogs"
    AND event.category == "authentication"
    AND azure.signinlogs.category IN ("NonInteractiveUserSignInLogs", "SignInLogs")
    //AND event.outcome == "failure"
    AND azure.signinlogs.properties.authentication_requirement == "singleFactorAuthentication"
    AND error_code == 50053
    AND user_id IS NOT NULL AND user_id != ""
    AND user_agent != "Mozilla/5.0 (compatible; MSAL 1.0) PKeyAuth/1.0"
    AND asn_org != "MICROSOFT-CORP-MSN-AS-BLOCK"

| STATS
    authentication_requirement = VALUES(azure.signinlogs.properties.authentication_requirement),
    client_app_id = VALUES(azure.signinlogs.properties.app_id),
    client_app_display_name = VALUES(azure.signinlogs.properties.app_display_name),
    target_resource_id = VALUES(azure.signinlogs.properties.resource_id),
    target_resource_display_name = VALUES(azure.signinlogs.properties.resource_display_name),
    conditional_access_status = VALUES(azure.signinlogs.properties.conditional_access_status),
    device_detail_browser = VALUES(azure.signinlogs.properties.device_detail.browser),
    device_detail_device_id = VALUES(azure.signinlogs.properties.device_detail.device_id),
    device_detail_operating_system = VALUES(azure.signinlogs.properties.device_detail.operating_system),
    incoming_token_type = VALUES(azure.signinlogs.properties.incoming_token_type),
    risk_state = VALUES(azure.signinlogs.properties.risk_state),
    session_id = VALUES(azure.signinlogs.properties.session_id),
    user_id = VALUES(azure.signinlogs.properties.user_id),
    user_principal_name = VALUES(azure.signinlogs.properties.user_principal_name),
    result_description = VALUES(azure.signinlogs.result_description),
    result_signature = VALUES(azure.signinlogs.result_signature),
    result_type = VALUES(azure.signinlogs.result_type),

    unique_users = COUNT_DISTINCT(user_id),
    user_id_list = VALUES(user_id),
    login_errors = VALUES(login_error),
    unique_login_errors = COUNT_DISTINCT(login_error),
    error_codes = VALUES(error_code),
    unique_error_codes = COUNT_DISTINCT(error_code),
    request_types = VALUES(request_type),
    app_names = VALUES(app_name),
    ip_list = VALUES(ip),
    unique_ips = COUNT_DISTINCT(ip),
    source_orgs = VALUES(asn_org),
    countries = VALUES(country),
    unique_country_count = COUNT_DISTINCT(country),
    unique_asn_orgs = COUNT_DISTINCT(asn_org),
    first_seen = MIN(event_time),
    last_seen = MAX(event_time),
    total_attempts = COUNT()
BY time_window
| WHERE unique_users >= 15 AND (total_attempts >= unique_users)
| KEEP
    time_window, total_attempts, first_seen, last_seen,
    unique_users, user_id_list, login_errors, unique_login_errors,
    unique_error_codes, error_codes, request_types, app_names,
    ip_list, unique_ips, source_orgs, countries,
    unique_country_count, unique_asn_orgs,
    authentication_requirement, client_app_id, client_app_display_name,
    target_resource_id, target_resource_display_name, conditional_access_status,
    device_detail_browser, device_detail_device_id, device_detail_operating_system,
    incoming_token_type, risk_state, session_id, user_id,
    user_principal_name, result_description, result_signature, result_type

New fields required in ECS/data sources for this rule?

No response

Related issues or PRs

No response

References

Redacted Example Data

No response

Metadata

Metadata

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions