Challenge link: https://cyberdefenders.org/blueteam-ctf-challenges/azurespray
Master the detection, investigation, and remediation of password spray attacks in Azure AD by analyzing sign-in logs with KQL queries, identifying attack patterns and compromised accounts, implementing Microsoft Sentinel analytics rules for automated detection, and applying security controls including Smart Lockout, Conditional Access policies, and incident response playbooks to protect against credential-based attacks.
Q1: What is the most common Result Type associated with password spray attacks in Azure AD sign-in logs?
To find the answer, I started looking into the data. What a better place to start than see all the distinct ResultTypes and their Descriptions. Note that in this lab, the SigninLogs is called SigninLogs_CL.
SigninLogs_CL| distinct ResultType, ResultDescription--------------------------------------------------50126 Invalid username or password or Invalid on-premise username or password.
We can confirm this further by counting the event types in the data:
SigninLogs_CL| summarize count() by ResultType| order by count_ desc--------------------------------------------------ResultType count_50126 54350053 10500011 450074 250072 20 2
Q2: Which IP address had the highest number of failed login attempts during the attack window?
Similiar concept to Q1, some statistics are needed.
SigninLogs_CL| summarize count() by IPAddress| order by count_ desc| take 1--------------------------------------------------IPAddress count_3.123.15.9 6
It is interesting to see many IP addresses yielding results in the range of 1-4 login events. Maybe this indicates the adversary was avoiding spray detection by constant rotating?
Q3: What is the user agent string identified in the attack?
Once again, some data analysis with simple query.
SigninLogs_CL| summarize count() by UserAgent| order by count_ desc--------------------------------------------------Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36 557
Clearly the user agent above is yielding most results in the data.
Q4: What is the specific sign-in error code that indicates an account has been locked out by Azure AD Smart Lockout?
I just used the data from Q1 for this:
50053 Account is locked because user tried to sign in too many times with an incorrect user ID or password.
Q5: What time (UTC) in CreatedDateTime did the password spray attack begin based on the first failed authentication attempt?
This one requires a bit of filtering. First, considering data from Q1 query, the correct event to look for is 50126. Secondly, we have to order data based on CreatedDateTime attribute. Third, we do not need all 90-ish fields to be printed for our convinience.
SigninLogs_CL| where ResultType == 50126| order by CreatedDateTime asc| project CreatedDateTime, UserPrincipalName, ResultType, ResultDescription| take 5--------------------------------------------------CreatedDateTime UserPrincipalName ResultType ResultDescription2025-06-29T18:35:06.2578049Z lucile.siverd@compliantsecure.store 50126 Invalid username or password or Invalid on-premise username or password.
Q6: How many unique user accounts in the Compliant Secure company were targeted in this password spray attack?
For this one, we want to filter out all the events that are not related to either account lockout or invalid passowrd (or usernames). Thus we only want to have event types 50126 and 50053. Furthermore, we do not want any non-company accounts to be included in the results, thus we filter for UserPrincipalNames ending with “compliantsecure.store“.
SigninLogs_CL| where ResultType == 50126 or ResultType == 50053| where UserPrincipalName endswith "compliantsecure.store"| distinct UserPrincipalName| count--------------------------------------------------Count89
Q7: The attack originated from a single country. What is the name of the region where the attack originated?
This was simple.
SigninLogs_CL| summarize count() by Location--------------------------------------------------Location count_DE 561<empty> 2
Q8: What is the name of the analytics rule that identifies evidence of failures from multiple accounts against Microsoft Entra ID applications?
I’ll just post the answer here:
Password spray attack against Microsoft Entra ID application
Q9: Based on the attack patterns observed in this incident, what is the maximum value you should set for authenticationThreshold to ensure the rule would have detected this specific attack?
As was discussed in Q2, there were many IP addresses with 1-4 login events. Range 1-2 is quite low, and can indicate normal login events. 3-4 range is more likely to represent either an user mispelling their password, or an attacker trying to stay undetected while password spraying. Thus, we should set the treshold to 3.
Q10: What is the value (in minutes) set for the authenticationWindow parameter?
It is at the beginning of the code in a variable.
Q11: Review the entities section, which shows all IP addresses involved in this attack. List all attacker IP addresses identified in the incident.
Wait a few minutes for the rule to process. After that, we can retrieve the list easily from the incident.
3.123.1x.x, 3.123.x.x, 3.70.x.x
Q12: What is the minimum number of failed attempts from a single IP before Smart Lockout triggers for an unfamiliar location (based on default settings)?
Answer is at https://learn.microsoft.com/en-us/entra/identity/authentication/howto-password-smart-lockout
Q13: What is the user principal name of the account that was successfully breached?
ResultType 0 represents a successful login.
SigninLogs_CL| where ResultType == 0| project UserPrincipalName--------------------------------------------------UserPrincipalNamelouisa.hartis@compliantsecure.store
Q14-Q18
Won’t be writing down answers to these, as the answers can be literally found from MS articles or other sources in 5 minutes.