Tracking malicious sign-in attempts is not easy
Recently, we investigated suspicious behavior in an environment where Azure passwordless authentication was set up. Prompting the investigations was several users were hit with unexpected Authenticator app prompts. To their credit, none of the users fell for the ruse or let the attacker in.
This kind of event, known as MFA Fatigue, is routine and expected at organizations large and small. Attackers will leverage this social engineering technique to trick users into accepting push authentication prompts having been successful in recent attacks, including Uber).
The scenario proved to be uniquely difficult to investigate because of the log records associated with failed passwordless prompts.
Limitations in logging capabilities complicate investigations
Tracking malicious sign-in attempts is crucial for protecting cloud environments and only possible by monitoring available cloud logs . While Microsoft and other cloud providers publish log schemas and provide Service-Level Agreements (SLAs) for record delivery, there are still several issues that plague cloud logs:
- Record event types are often not well documented, and sometimes not documented at all.
- Some of the values and IDs logged are internal to the cloud provider and their meaning is unclear.
- New log record types are added, record types are retired, and record formats are changed without notice to consumers
All of this complicates incident monitoring and response, and leaves cloud consumers unsure about log record completeness and playing catch-up to unannounced changes – thus, it becomes difficult to investigate failed passwordless prompts from logged data.
A closer look at uncovering and Mitigating Passwordless sign-in failures in Azure
Passwordless authentication
For those who are unfamiliar, passwordless authentication is a robust option for mitigating the risk of users creating insecure passwords. There are several ways of enabling passwordless authentication in Azure. In the environment investigated, the Microsoft Authenticator App was used.
To enroll in passwordless authentication, end users would follow these detailed configuration steps. Once the user is enrolled in this method, they can enter their username in Azure sign-in prompt and then select "Use an app instead" option:
User is then given a number to enter in the mobile app to complete the process:
If the number matches, the user is authenticated. While being reasonably secure this method no longer requires users to deal with creating and remembering good passwords, which significantly improves usability.
Investigation
In the past we have monitored for different ways of setting up MFA in Azure, including using passwordless sign-in with Microsoft Authenticator as a second factor (i.e., when the user would be prompted in the app after they enter the correct password). Microsoft Authenticator as a second factor we observe one of the following two errors in the logs if Authenticator prompts are abandoned, or the code is incorrect:
- 50074 Strong Authentication is required.
- 500121 Authentication failed during strong authentication request.
As a result, our detection and hunting queries were set up to look for these error codes.
However, when the Microsoft Authenticator App is set up as a single factor as in the case with passwordless Authentication, we saw the following error when the prompt was abandoned
- {"errorCode":1003033,"failureReason":"The remote NGC session was denied."}
This error code was novel, something we had never seen before and searching the internet brings virtually no information on its origin. The error message was also cryptic, with no explanation of what "NGC" is. After some searching, we established that it corresponds to GUID D6886603-9D2F-4EB2-B667-1971041FA96B, which is documented as "PIN Credential Provider".
As we examined the log record, we saw some other inconsistencies (see screenshot below):
- Location and device details (in red) are not filled in.
- App and resource information (in blue) are missing.
- User information (in purple) is limited. UserPrincipalName and UserDisplayName are not filled with their expected values (user’s e-mail address and full name). Instead, UserId value is in all three fields.
The unusual error code and the missing data in the log records makes it hard to alert on such events and investigate them properly.
Mitigation
Given the difficulty we had investigating this incident we wanted to share the details we collected with the security community so that security practitioners could adjust their hunting queries to catch this condition. We at Vectra have already updated our products to cover this scenario.
The hunting query could be as simple as the following Kusto snippet that will find all failed passwordless login attempts in the last 30 days:
SigninLogs | where TimeGenerated > ago(30d) | where ResultType == 1003033
Some other error codes related to NGC may also be of interest:
Takeaways:
- As you introduce new ways to authenticate to your environment, assess the resulting logs from interactions with these new mechanisms. Look for new error codes and log record types which may need to be taken into consideration for monitoring and alerting.
- Organizations monitoring for passwordless sign-in failures, should consider adding code 1003033 to their hunting queries. Make note of limited information that is available with this record - you would not be able to use the UserPrincipalName or other information that is normally available in the sign-in log records.
- A call to cloud providers (including Microsoft): please start treating logs as a crucial security feature that a lot of actors depend on. Please document log records thoroughly, fill in information missing from them, and announce any changes you are making. This will help your customers and security vendors in their fight to keep everyone secure.
Author would like to thank Peter Schaub and Rey Valero for their help in researching this incident.