diff --git a/detections/application/pingid_new_mfa_method_after_credential_reset.yml b/detections/application/pingid_new_mfa_method_after_credential_reset.yml index 534ffc8cb2..7b0097d43c 100644 --- a/detections/application/pingid_new_mfa_method_after_credential_reset.yml +++ b/detections/application/pingid_new_mfa_method_after_credential_reset.yml @@ -1,17 +1,57 @@ name: PingID New MFA Method After Credential Reset id: 2fcbce12-cffa-4c84-b70c-192604d201d0 -version: 9 +version: 10 creation_date: '2023-12-20' -modification_date: '2026-05-13' +modification_date: '2026-09-29' author: Steven Dick status: production type: TTP -description: The following analytic identifies the provisioning of a new MFA device shortly after a password reset. It detects this activity by correlating Windows Event Log events for password changes (EventID 4723, 4724) with PingID logs indicating device pairing. This behavior is significant as it may indicate a social engineering attack where a threat actor impersonates a valid user to reset credentials and add a new MFA device. If confirmed malicious, this activity could allow an attacker to gain persistent access to the compromised account, bypassing traditional security measures. +description: |- + The following analytic identifies the provisioning of a new MFA device shortly after a password reset. It detects this activity by correlating Windows Event Log events for password changes + (EventID 4723, 4724) with PingID logs indicating device pairing. This behavior is significant as it may indicate a social engineering attack where a threat actor impersonates a valid user + to reset credentials and add a new MFA device. If confirmed malicious, this activity could allow an attacker to gain persistent access to the compromised account, bypassing traditional security measures. data_source: - PingID -search: "`pingid` \"result.message\" = \"*Device Paired*\" | rex field=result.message \"Device (Unp)?(P)?aired (?.+)\" | eval src = coalesce('resources{}.ipaddress','resources{}.devicemodel'), user = upper('actors{}.name'), reason = 'result.message' | eval object=CASE(ISNOTNULL('resources{}.devicemodel'),'resources{}.devicemodel',true(),device_extract) | eval action=CASE(match('result.message',\"Device Paired*\"),\"created\",match('result.message', \"Device Unpaired*\"),\"deleted\") | stats count min(_time) as firstTime, max(_time) as lastTime, values(reason) as reason by src,user,action,object | join type=outer user [| search `wineventlog_security` EventID IN(4723,4724) | eval PW_Change_Time = _time, user = upper(user) | fields user,src_user,EventID,PW_Change_Time] | eval timeDiffRaw = round(lastTime - PW_Change_Time) | eval timeDiff = replace(tostring(abs(timeDiffRaw) ,\"duration\"),\"(\\d*)\\+*(\\d+):(\\d+):(\\d+)\",\"\\2 hours \\3 minutes\") | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `security_content_ctime(PW_Change_Time)` | where timeDiffRaw > 0 AND timeDiffRaw < 3600 | `pingid_new_mfa_method_after_credential_reset_filter`" -how_to_implement: Target environment must ingest Windows Event Log and PingID(PingOne) data sources. Specifically from logs from Active Directory Domain Controllers and JSON logging from a PingID(PingOne) enterprise environment, either via Webhook or Push Subscription. -known_false_positives: False positives may be generated by normal provisioning workflows that generate a password reset followed by a device registration. +search: | + `pingid` + "result.message" = "*Device Paired*" + + | rex field=result.message "Device (Unp)?(P)?aired (?.+)" + | eval src = coalesce('resources{}.ipaddress','resources{}.devicemodel') + + | eval user = upper('actors{}.name') + | eval reason = 'result.message' + | eval object=CASE(ISNOTNULL('resources{}.devicemodel'),'resources{}.devicemodel',true(),device_extract) + | eval action=CASE(match('result.message',"Device Paired*"),"created",match('result.message', "Device Unpaired*"),"deleted") + + | stats count min(_time) as firstTime, max(_time) as lastTime, values(reason) as reason by src,user,action,object + + ```Standardizes user field by removing NetBIOS and email from reported user name``` + + | eval join_user = replace(user, "^[^\x5c]*\x5c|@.*$", "") + | join type=outer max=0 join_user [ + | search `wineventlog_security` EventID IN(4723,4724) + | eval PW_Change_Time = _time + ```Standardizes user field by removing NetBIOS and email from reported user name``` + | eval join_user = replace(upper(user), "^[^\x5c]*\x5c|@.*$", "") + | fields join_user,src_user,EventID,PW_Change_Time + ] + + | eval timeDiffRaw = round(lastTime - PW_Change_Time) + | eval timeDiff = replace(tostring(abs(timeDiffRaw) ,"duration"),"(\d*)\+*(\d+):(\d+):(\d+)","\2 hours \3 minutes") + | `security_content_ctime(firstTime)` + | `security_content_ctime(lastTime)` + | `security_content_ctime(PW_Change_Time)` + + | where timeDiffRaw > 0 AND timeDiffRaw < 3600 + | dedup src, user, action, object, lastTime sortby +timeDiffRaw + | fields - join_user + + | `pingid_new_mfa_method_after_credential_reset_filter` +how_to_implement: |- + Target environment must ingest Windows Event Log and PingID(PingOne) data sources. Specifically from logs from Active Directory Domain Controllers and JSON logging from a PingID(PingOne) enterprise environment, either via Webhook or Push Subscription. +known_false_positives: |- + False positives may be generated by normal provisioning workflows that generate a password reset followed by a device registration. references: - https://techcommunity.microsoft.com/t5/microsoft-entra-azure-ad-blog/defend-your-users-from-mfa-fatigue-attacks/ba-p/2365677 - https://www.bleepingcomputer.com/news/security/mfa-fatigue-hackers-new-favorite-tactic-in-high-profile-breaches/ @@ -28,11 +68,12 @@ drilldown_searches: earliest_offset: 7d latest_offset: "0" finding: - title: An MFA configuration change was detected for [$user$] within [$timeDiff$] of a password reset. The device [$object$] was $action$. + title: An MFA configuration change was detected for [$user$] within [$timeDiff$] of a password reset. The device [$object$] was [$action$]. entity: field: user type: user score: 50 +threat_objects: [] analytic_story: - Compromised User Account - Scattered Lapsus$ Hunters @@ -57,3 +98,12 @@ tests: source: PINGID sourcetype: _json test_type: unit + - name: True Positive Test - UPN usernames and multiple resets + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1621/pingid/windows_pw_reset_upn_multi_reset.log + source: XmlWinEventLog:Security + sourcetype: XmlWinEventLog + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1621/pingid/pingid_upn_multi_reset.log + source: PINGID + sourcetype: _json + test_type: unit