Hi, my name is Nevada and Cam and I created a tool called Squarefish that combines QR codes and OAuth 2.0 device code flow. We are going to go over some QR code and OAuth device code flow introductory material, touch on some previous research, and then demo both Squarefish and a Squarefish sub-tool called Refresh. Thank you for joining us. Who are we? Cam and I work at SecureWorks and do security research and red teaming. We wrote a tool called Fish in Suits last year and expanded on that research this year with Squarefish. I've been doing InfoSec stuff for over 15 years and have held a number of roles through that time with a love of all things offensive. The past six years have really been focused on offensive security and research. Cam has been in InfoSec for six years and has authored a large number of tools including O365 Spray, BridgeKeeper, Redirect.Rules, and WhiskeySaml. So, we're going to start with the basics. What is a QR code? I mean, at this point, pretty much everyone knows what a QR code is. It's a barcode of sorts that contains data, often in the form of a URL. You can even do some cool things with them, like the moving QR code you see on the screen. I think everyone can probably guess where that QR code leads you. Although QR codes have been around for a long time, their usage has really exploded in the last five to ten years. We see them everywhere, including restaurant menus, user manuals, MFA registration, and even on Super Bowl commercials. People have become accustomed to using QR codes in their everyday life, and as we saw during the Super Bowl, many will scan them without concern for their content. So, what is a QR code to an attacker? The most obvious is probably just redirecting users to malicious sites. It probably can also work to help bypass some spam and phishing filters, although it's worth noting that Microsoft appears to be checking URLs that are in QR codes in certain formats. We can talk a bit more about this later. Another cool way to use QR codes is to embed buzzing or injection type strings in them to test QR code reading software for the applications that consume the data from it. OAuth device code flow probably isn't as well known, or at least as well understood, as QR codes are, but most folks have probably used it at some point. The most familiar implementation of this would probably be TV streaming apps and devices. This is really a great use case for the flow. It prevents users from having to enter passwords into on-screen keyboards using only a remote control. Device code flow is also used by Microsoft as well as other cloud providers. Oftentimes, this involves a client application asking for authentication and OAuth grants. Here's an illustration of the OAuth device code flow. The client uses a client ID which identifies the application and a scope which identifies the requested permissions. The endpoint responds with the device code, user code, and verification URI. The user can then visit that URI and enter the user code. They will then be prompted to authenticate and grant the access requested as defined in the application scope. While this is happening, the original client is polling the back end, waiting for authentication to happen, basically getting a wait response until the user authenticates. This generally has about a 15-minute window. After the user authenticates, the response to the polling request will include an access token, a refresh token, if needed for the requested scope, and an ID token. Last year, when we first looked at the OAuth device code flow, we thought it would be useful as a phishing mechanism, so we wrote a tool called Phish and Suits. One of the things we were really excited about was that client IDs of verified apps could be found online, and as long as the public flow was enabled on them, you didn't need a client secret to use them for phishing. The prompt on the right shows the requested permissions when using a verified app with Phish and Suits and getting the verified app check mark. This was a huge improvement over prior OAuth phishing, which often required registering your own application and usually came with a big unverified warning. The other great part was that there was no malicious URL required. Straight from an email or text, a user visited the legitimate Microsoft site and entered the code. We weren't the only ones that noticed this behavior and how it might be useful for phishing, and other folks published the technique and similar tools as well. I encourage anyone who wants a deeper dive into the topic to check out their research. So we've covered some of the pros of OAuth device code phishing, like verified and first-party apps can be used, it adds a layer of obfuscation, and the user enters their credentials into the actual Microsoft site. But there is a pretty big con. There's only a 15-minute window from the time the initial code is sent via text or email to when the authentication has to happen. Since so much of our work is based on statistics and based around a small percentage of success, having our email expire before many users even have the chance to read it obviously creates a problem. Squarefish is a Python tool that we developed. It aims to combine QR codes with the OAuth device flow in order to decouple the device flow from the initial phishing email. This is to prevent the device code that was emailed from expiring prior to the user interacting with it. An attacker will send a target victim an email that will contain a QR code and information relating to a given pretext. For example, an attacker will send an email that will contain information regarding the target's Microsoft Authenticator token expiring. The email will then instruct the user to scan the provided QR code in order to generate a new Microsoft Authenticator token. The provided QR code will be embedded with a link that directs the target victim to an attacker-controlled Squarefish server. Once the victim scans the QR code that was provided in the initial phishing email, they will be directed to an attacker-controlled Squarefish server. The user's email will be passed along as a GET parameter. Once the victim request is received by the Squarefish server, several tasks occur in the background. First, the user's browser is redirected away from the Squarefish server to Microsoft's device code authentication webpage. This happens instantly. Second, Squarefish will use the victim's email provided via a GET parameter to initiate the OAuth device code flow and retrieve a new device code. Third, Squarefish will send a follow-up email to the victim containing the retrieved OAuth device code. The email will attempt to replicate the look and design of an authentic Microsoft OAuth device code email and will provide the direct link to the legitimate Microsoft device code authentication endpoint. Lastly, once the email has been sent, Squarefish will begin polling Microsoft for authentication until the device code expires. Once the victim receives the follow-up email from Squarefish that contains the device code, they will visit the legitimate Microsoft endpoint to authenticate the device code. Once the user enters the provided device code, they will be prompted with a permission request for the given application's client ID. Since we are able to leverage legitimate existing applications found on the web, we are able to prevent any sort of unverified application warnings displayed to the user. In many cases, we can leverage verified applications and the user will see a verification blue check mark. Once the user submits their credentials and authenticates the application via the device code flow, the polling done by Squarefish in the background will identify and pull down the authentication and refresh tokens for the associated user. The data is then saved locally as a JSON file. On the next slide, you will see a demo execution of Squarefish. The demo will include a user scanning the provided QR code off screen. Additional considerations when using Squarefish. What about MFA? So if MFA is required, the user will use it when they're prompted to authenticate. Although if they are already authenticated, they might not need to enter a password or use MFA at all, depending on their corporate policies. What about sending emails and the account used to send emails? Squarefish was built and tested using a Gmail account for sending emails. And for many reasons, this may not be the best option for actual engagements. It's also worth noting that the QR code does contain a malicious domain. This was something that we were able to avoid with our earlier tool Fish and Suits. There are a couple of things to note here. One, if malware analysis, either automated or human, checks the link, they will be redirected to the legitimate Microsoft device code site. So they may not identify it as a phishing site at all. Two, if anything hits that link, it will send the second email without user interaction. So you may want to wait to bring the server up a few minutes after you've sent the initial phishing email. Three, you will want to use all of your other malicious domain tricks to ensure the domain itself isn't flagged. And four, the big advantage here is that the malicious domain will be visited by the QR code reader on the user's phone, which probably won't be on the corporate network. And since they are using the QR code reader, it won't be open from the email application. Also, be sure you're utilizing all your other good phishing techniques and tactics. And there's some links on this slide for additional resources there. Now that we have a user's refresh token, we wanted to look into what exactly we could do with it. Research done by public researchers, as well as our own SecureWorks researchers, Ryan Cobb and Tony Gore, identified what is known as FOCI, or Family of Client IDs. According to the Family of Client IDs GitHub, undocumented functionality in Azure Active Directory allows a group of Microsoft OAuth client applications to obtain special family refresh tokens, which can be redeemed for bearer tokens as any other client in the family. What this means is we can effectively exchange our refresh token for a new refresh token associated to a different application. Along with requesting a new refresh token, we can also modify the scope of the token requested. With this process, we created a small tool called Refresh to provide an automated and easy method of obtaining a refresh token for a different application and leveraging that access to search and extract data. Refresh will take in the outputted authentication JSON file from Squarefish and will exchange the refresh token for a token associated with the Microsoft Graph API. With this token, we are able to search emails, users, groups, organizations, OneDrive, and even SharePoint. Refresh will scrape and search the Microsoft Graph API using the newly exchanged token and will save all of the found data into user-associated JSON files for easy parsing. The next slide will show a demo execution of Refresh. That is it for our presentation. We really appreciate you taking the time to watch it. If you're interested in learning more about us or our tools, feel free to check out the links here. Thanks again.