We’re going to demonstrate how combining two of our favorite new SaaS attack techniques - from our SaaS Attacks Matrix research - makes a simple, but very stealthy approach that maintains persistent access.
We’re going to demonstrate how combining two of our favorite new SaaS attack techniques - from our SaaS Attacks Matrix research - makes a simple, but very stealthy approach that maintains persistent access.
In this article, we’re going to demonstrate how combining two of our favorite new SaaS attack techniques makes a simple, but very stealthy persistence approach.
—----
This is the second post in a series on attack chains formed by combining techniques in the SaaS attack matrix. Last post we wrote about SAMLjacking a poisoned tenant.
This time we’ll be looking at combining shadow workflows with an evil twin integration for an especially sneaky and flexible method of persistence. We’ll be using Zapier integrating with Azure as our primary example.
What is a shadow workflow?
A shadow workflow is a technique for using SaaS automation apps to provide a code execution-like method for conducting malicious actions from a legitimate source using OAuth integrations. This could be a daily export of files from shared cloud drives, automatic forwarding and deleting of emails, cloning instant messages, exporting user directories — basically anything that is possible using the target app’s API.
The fact automation apps utilize OAuth integrations means they also function as a very effective method of maintaining persistence. Think of shadow workflows as the offensive PowerShell of the SaaS world.
What’s an evil twin integration?
Creating a new OAuth integration, even if using a legitimate SaaS application, could be viewed as suspicious if seen by a security team or the affected user. This is especially true if an account compromise is discovered and an IR team sees a consent for a new OAuth integration in the log that the compromised user does not recognize.
An evil twin integration, however, reduces the chances of discovery by reusing an existing legitimate integration for malicious purposes.
What’s the benefit of combining them?
While shadow workflows are incredibly powerful on their own, as malicious use of OAuth integrations becomes more common, security teams will start regularly checking for new, or unknown, integrations in response to security incidents. While automation apps are legitimate SaaS services, shadow workflow attacks could still raise question marks during incident response if it’s connected shortly after a compromise and/or if the affected user has no knowledge of it.
Additionally, as use of security tools that provide visibility of OAuth integrations (check out our product) increases, it will become increasingly dangerous for an adversary to create a new OAuth integration. That’s because the target user and possibly even security teams may be notified.
This leads us on to evil twin integrations. Their power is in making use of existing integrations so they can avoid appearing as a new integration and getting flagged or sending alerts to security teams. That makes them much stealthier and increases the likelihood of a successful attack.
There are three possibilities here that lead to two different levels of stealth for the attack:
Medium stealth option: Making use of an automation app used legitimately by the organization, but not by the target user, specifically
High stealth option 1: Making use of an automation app used legitimately by the target user themselves
High stealth option 2: Making use of an automation app that has been granted admin consent
Medium stealth option: Pre-existing use by organization
This option is by far the most likely option to be applicable in a real-world situation. Here’s how it works:
The consent for the targeted user will be new and will generate an audit event to show that, but the integration itself will not be new inside the organization and may even be formally approved by the security team already. This will help evade general detection mechanisms as it won’t be seen as a brand new integration at the organization level that requires careful scrutiny. It’s much harder to evaluate new consents on a per-user basis for existing integrations if the organization is of any significant size.
The downside, however, is that this attack stands a greater chance of detection if notifications are delivered directly to the affected user. Alternatively, if the original compromise is discovered, incident responders are more likely to discover this consent during an investigation. That’s because the affected user would know they aren’t using the automation app and incident responders are likely to explore logs showing consents to new OAuth integrations and permissions shortly after a successful compromise.
Using Azure as an example, while no new service principal is created in this case, the audit logs still show a new consent for the targeted user to the existing Zapier app:
High stealth option 1: Pre-existing use by targeted user
This is the holy grail option, but is likely to require more luck in the real world. It requires that the target user is already using an automation app, which the adversary could compromise and utilize. If the compromised user has already consented to permissions useful to the adversary, such as access to sensitive data like email and file stores, then new malicious workflows can be created without requiring the user to consent to new permissions.
Consequently, there will be no new integration observed at the organization level, no new user-specific consents for sensitive permissions and the target user would indicate they’re just using a legitimate app if questioned by incident responders.
None of the three audit log entries shown above would be present in this scenario either.
High stealth option 2: Azure admin consented app
There is a mixed scenario when permissions for an automation app (or any app you want to use for an evil twin integration) have been granted tenant-wide admin consent in Azure. In this case, the administrator has effectively consented to permissions for all users, even if they aren’t currently active users of the app.
This means when a new user integrates the app, it does not generate a new permission grant since it is effectively already granted. Consequently, the three log entries shown above would not be present in this scenario even if integrating the app for a user that has never used it before.
This gives the best level of flexibility for an adversary as they can avoid generating new permission grant logs for any user. However, it's not quite as stealthy as when the targeted user already makes use of the app as there is no history of legitimate app logins or activity for the user prior to the compromise to blend in with.
An example attack - Zapier
In this case, we’re going to use Zapier as our automation app example and Azure as the primary target for integrations and there will be no admin consent involved. We’ll also be using Google Workspace for data exfiltration. There are many other examples we could have used here, though - Make.com, IFTTT, Retool, Tines, Microsoft Power Automate and many other SaaS apps have powerful automation and integration capabilities and could be used for similar purposes.
Azure and Google Workspace are also obvious juicy targets for integrations, but automation apps support integrations with vast numbers of other SaaS applications,so there are many possible targets.
So, let’s say we’ve compromised a target user’s Azure account. Perhaps we have conducted a successful credential stuffing attack, a phishing attack including MFA code proxying or even achieved a traditional endpoint compromise and have stolen the user’s session tokens.
Whatever the case, we have temporary control of the user’s account, either until the session expires or the user changes their password. If the original compromise is detected, that could happen quickly, so we want to conduct some malicious actions to make use of the access while we have it and to also gain persistence so we maintain our access beyond a password change.
We want to use an automation app, but we’d prefer to be as stealthy as possible by also making it an evil twin integration. We’d like to see if the target user has existing integrations with any apps we’d like to use - especially an automation app for that high stealth option we mentioned above.
We’ve created a video demo of the full attack below. A step by step write up with more detail then follows:
Step 1 - Enumerating potential targets
We could perform something as simple as an email search for evidence of sign-ups, but that won’t necessarily show us if actual OAuth integrations have been configured and what permissions are in use. What we really need is a way to perform an OAuth token enumeration attack.
The first method: myapps.microsoft.com
Make use of https://myapps.microsoft.com to see which apps are listed and which permissions have been granted. We can see Zapier is in use and the user has granted it access to their email and files, making it a great target.
The second method: Microsoft’s graph API
Microsoft’s graph API doesn’t make it possible to list out service principals without admin permissions, but you can enumerate individual OAuth permission grants and app role assignments for your own user account.
The client ID listed for permission grants is actually the tenant-specific service principal ID, rather than the globally unique OAuth app ID, but the app role assignments call gives us the app display name. We can match up the IDs from the app role assignments with the OAuth permission grants to see which permissions have been granted to the given app.
Step 2 - Create shadow workflows
Ok, so we’ve figured out the user already makes use of Zapier and they’ve even already granted access to their email and files - that’s a juicy target we can’t turn down! So the next step is to create our own malicious workflows, or shadow workflows if you will, to get Zapier to do our dirty work for us.
First of all, we’ll see if we can scope out the user’s existing Zapier account to better understand the setup. Then we’ll create a new Zapier account and link it to the target user’s account that we’ve compromised. Here’s how that would work:
Scope out the existing Zapier account
If the user uses SSO or social logins then we can login directly and, since we now control their Azure account, we can just log directly into their Zapier account!
Alternatively, if they have created a standard password account, then we might already know the password if it’s the same used for their Azure account. Otherwise, we could potentially make use of an account recovery attack to gain access.
Once we have logged into their account, we can see their existing workflows and integrations. Technically, we could backdoor these or create new ones - a form of an abuse existing OAuth integrations attack. However, that runs the risk of the user discovering our shadow workflows and also almost certainly being locked out of the account during the next password change.
Instead, we can stick to an evil twin integration from our own Zapier account, which we’ll create later.
Now we can see what the user was actually using Zapier for — they’ve set up an integration with both Outlook and OneDrive so they can forward emails related to their business expenses to a folder in their OneDrive. Probably a time-saving hack, which we can take advantage of since it won’t be unusual to see Zapier regularly accessing their Outlook and OneDrive. That means our attack will be extra stealthy.
Create our own malicious Zapier account
Given in this case we, at least temporarily, control the user’s Azure account there is nothing stopping us connecting this to our own malicious Zapier account completely separately from the user’s legitimate Zapier account. We then maintain full control over the Zapier account and the user will not be able to discover our shadow workflows as they won’t have any knowledge of our Zapier account:
Let’s create our own shadow workflows:
One that sends every new OneDrive file to our own separate Google Drive account. This allows us to maintain a complete view of the user’s files into the future.
And one to forward every new Outlook email to our own GMail account.
We can now see we are logged in with a separate GMail account, but have created shadow workflows to forward emails from the user’s Outlook to our GMail account and harvest files from their OneDrive to our Google Drive.
The major benefit of creating our own Zapier account for an evil twin integration is that once we are locked out of the target user’s account via a password change or otherwise, not only do our existing shadow workflows continue to operate via OAuth, but we are able to create new shadow workflows and reuse the existing OAuth connections. That’s the power of having full control of the Zapier account.
One small downside to this approach is that creating the new OAuth integrations inside a new Zapier account generates an interactive login event for the Zapier integrations from the adversary’s IP address. This occurs due to creating integrations from the new Zapier account, but because the user has already consented to all the relevant permissions for Zapier’s own OAuth apps there are no audit logs for new consents or applications, just the login event itself.
However, determining that a successful login to an app a user legitimately uses is actually malicious in this case is obviously extremely difficult to build detection logic for.
Beyond the initial login events, the only evidence of malicious activity in the future will be from the activity logs showing the actions conducted by our shadow workflows every time they are triggered to run. For example, the following screenshots show that the Zapier Todo app (ClientAppId 29246358-1970-4d6d-bc75-acf34edc758b) has been seen both uploading a file and downloading a file:
The file upload in this case relates to the legitimate workflow and the file download relates to the shadow workflow. The IP addresses relate to Zapier’s legitimate infrastructure so really only a very thorough and specific investigation is going to be able to uncover that one of these events is malicious.
Step 3 - Profit
Now we just need to sit back and let our shadow workflows do the work for us, 24/7 and from Zapier’s infrastructure via a legitimate OAuth integration. Here we can see files the user created in OneDrive and emails they received in Outlook mirrored to our own GMail and Google Drive via the magic of shadow workflows.
Impact
Ok, we’ve covered a lot of ground here so it’s worth taking a step back and considering the key impact points of this attack chain:
An adversary who has gained (temporary) access to a user account that supports OAuth integrations can use shadow workflows to execute malicious actions and to maintain persistence
This access will continue even if the user changes their password or resets MFA
Not only do existing shadow workflows continue to work after password changes, an adversary can continue to create new ones and reuse the existing integrations.
Any relevant logs will show access via legitimate IP addresses and OAuth integrations for SaaS automation apps
Automation apps are so flexible that an adversary can do pretty much anything - it’s basically the offensive PowerShell of the SaaS world. Just some examples:
Monitor all emails and files the user creates
Delete email security alerts before the user sees them
Intercept password reset and passwordless login emails to access other apps
Monitor instant messaging apps and use it to send targeted internal social engineering emails
If targeted users are already using automation apps legitimately, it’s even more stealthy - you won’t even see any new integrations or permission grants appear as the user will have already granted these legitimately.
If admin consent has been granted to the automation app, any user can be targeted without generating new permission grant logs even if they have never used the app.
Conclusion
We have seen how two new SaaS-focused attack techniques can be combined into one more effective attack chain - in this case, a particularly nasty and stealthy persistence technique. This shows how even if a user compromise is detected very early, with password and MFA resets immediately issued, adversaries can maintain control over the account regardless.
This shows how even legitimate SaaS applications have incredibly powerful offensive use cases and very careful attention needs to be paid to integrations with highly sensitive permissions, even when they are approved and vetted applications. Incident response teams especially need to be well aware of these techniques when investigating potential user account compromises as persistence approaches can extend much further than endpoint implants and stolen passwords.