Every Solution You Can Imagine – and More
What cybersecurity solution do you need? From Zero Trust to ADR, IAM, risk/privacy, data protection, AppSec and threat, securing digital transformation, to resiliency and remediation, we can build the right program to help solve your challenges.
A Single Partner for Everything You Need
Optiv works with more than 400 world-class security technology partners. By putting you at the center of our unmatched ecosystem of people, products, partners and programs, we accelerate business progress like no other company can.
We Are Optiv
Greatness is every team working toward a common goal. Winning in spite of cyber threats and overcoming challenges in spite of them. It’s building for a future that only you can create or simply coming home in time for dinner.
However you define greatness, Optiv is in your corner. We manage cyber risk so you can secure your full potential.
Microsoft 365 OAuth Device Code Flow and Phishing
During a recent red team engagement, we found that the target organization used a well-known identity access management (IAM) product for their multi-factor authentication (MFA) solution. Most of their Internet-facing login portals, such as Office365 and Citrix portals, were behind this IAM platform; however, their users were allowed to enable multiple MFA options, including Email OTP (one-time passcode). Given these situations, we thought a phishing campaign abusing Microsoft 365 OAuth device code flow would be a great attack vector for potentially bypassing their MFA and gaining access to the applications from the Internet.
According to Microsoft, it uses OAuth device authorization grant to allow users to sign in to input-constrained devices such as smart TVs, IoT devices or printers. To enable this authorization flow, the device will have the user visit a webpage from another device’s browser to sign in. Once the user signs in, the device can request access tokens as needed.
To explain what this is doing:
One perk about this phishing technique is that we do not need to build custom phishing infrastructure (e.g., creating a phishing server and landing page). We can use pretty much everything provided by Microsoft since we are technically leveraging their legitimate OAuth authentication flow.
Creating Azure Application
First, we need to create an Azure application. This application will serve as an endpoint where we will generate client_id and device_code, which are later used for obtaining the victim’s access_token, refresh_token and id_token.
Steps: Azure Portal → Azure Active Directory → App registrations → New registration
Next, enter a name for the application. This can be anything such as “Optiv Remote User Management”, etc. For Supported account types, select “Accounts in any organizational directory (Any Azure AD directory – Multitenant) and personal Microsoft accounts (e.g., Skype, Xbox)” so that target users could use their business Microsoft accounts to allow the application consents.
This will create our Azure application and make a note for the Application (client) ID value. This will serve as client_id value.
Finally, change Allow public client flows to “Yes” under the Authentication section and select “Save.”
Launching Phishing Campaign
To conduct the device code phishing, we first need to make a POST request to /devicecode endpoint to obtain user_code and device_code. Postman, an API testing and development platform, can be very useful for this.
*Note: A full list of the scope can be found at Microsoft.com. Make sure to carefully check permissions required for each scope since some require admin consent.
Next, upon obtaining the user_code, we need to send a phishing email to the victim. This is the only tricky part of this phishing attack since you need to lure the victim to visit the verification_uri and enter the user_code. Another caveat is that obtained user_code and device_code will expire 15 minutes after they have been generated. Thus, if they expire, you will be required to regenerate them and resend the phishing email.
For our engagement, we came up with the following phishing email template:
We registered our phishing domain to send emails from Microsoft Outlook. Also, the reason why we did not embed the hyperlink for the verification_uri (https://microsoft.com/devicelogin) was that our phishing email kept landing in the spam folder. Though we are not 100% sure, we think Microsoft may have done some subtle filtering for hyperlinked verification_uri and user_code combinations not originating from a Microsoft email domain. We observed this behavior from our dynamic testing at that time, so we decided to make our phishing email like the above.
If the phishing attempt was successful and the victim visited the verification_uri, entered the user_code, and completed authentication, the victim would have seen the following devicelogin and permission consent pages:
As for the attacker, they will need to keep checking whether the victim completed the authorization process by sending a POST request to /token API endpoint after the phishing email is sent. Once the authorization process is completed, it will present a bearer token formatted access_token and refresh_token, which you can use to mimic the victim’s access.
For example, with the access_token, the attacker can now access the victim’s email inbox using Microsoft Graph API.
Going back to our red team scenario, our goals were to:
We originally found a great open-source framework, TokenTactics created by revrsh3ll to conduct our phishing attack. The tool was designed to contain all the necessary functions and tactics to abuse Azure JSON Web Token (JWT). We highly recommend trying it out. Leveraging his tool, however, we decided to create a simple Python script to automate some of the device code phishing flow to solely meet our goals. The first function getDeviceCode() was created to request for user_code and device_code.
Next, using the newly obtained device_code, the getAccessToken() function continuously loops through the authorization process. If the phishing attack is successful, it will yield an access_token and refresh_token; otherwise, the loop will end after 15 minutes due to the token expiration.
With access_token, the getMail() function keeps looking for an email containing specific text. For our case, it was looking for a string “MFA – One Time Code” within the email text, so if we were to trigger the Email OTP, it would have sent the temporary code to the victim’s inbox. If it finds the right email, it prints out the email context with the OTP code and saves the email_id value.
Finally, with the stored email_id value, the deleteMail() function will delete the OTP email from the victim’s inbox.
The script used in this demo can be found here: Microsoft365-devicePhish
This device code phishing attack can be mitigated by making configuration changes for Azure AD. Under the Enterprise applications settings, prevent users from giving consent to all applications.
If the above solution is too restrictive, then please check out the following best practices provided by Microsoft:
Copyright © 2022 Optiv Security Inc. All rights reserved.
No license, express or implied, to any intellectual property or other content is granted or intended hereby.
This blog is provided to you for information purposes only. While the information contained in this site has been obtained from sources believed to be reliable, Optiv disclaims all warranties as to the accuracy, completeness or adequacy of such information.
Links to third party sites are provided for your convenience and do not constitute an endorsement by Optiv. These sites may not have the same privacy, security or accessibility standards.
Complaints / questions should be directed to Legal@optiv.com
June 17, 2021
Go365 performs user enumeration and password spraying attacks on organizations that use Office 365.
Optiv highlights the attack strategy of using forged Kerberos tickets to compromise a domain, and provides ways to defend against it.
June 02, 2021
Let us know what you need, and we will have an Optiv professional contact you shortly.