Maestro

Maestro: Abusing Intune for Lateral Movement Over C2

If I have a command and control (C2) agent on an Intune admin’s workstation, I should just be able to use their privileges to execute a script or application on an Intune-enrolled device, right?

Not so fast.

I Wanna Go Fast!

The Problem

We often find ourselves in the context of a cloud administrator when following attack paths to objectives that require privileged access to Azure-hosted services. We want to use their Entra ID account’s privileges to execute actions in Azure, for example running arbitrary code on remote Intune devices (a.k.a. the “Death from Above” attack path detailed by Andy Robbins), but we have some hurdles to overcome to accomplish this from a C2 agent:

  • We don’t have the user’s cleartext password
  • Conditional access policies (CAPs) require multi-factor authentication (MFA) for access to the Intune Portal and/or a compliant, hybrid-joined device on a trusted network
  • We need to maintain stealth
  • We don’t have the knowledge, time, or patience to manipulate tokens and navigate the Azure portal or multiple tools

Let’s look at these problems one at a time and discuss the options available to us.

No Cleartext Credentials / MFA Required

No password? No problem. We already asked the admin nicely for their creds and they didn’t bite, and their password hygiene on the host is solid, but if the device has an identity in Entra ID, we can dump primary refresh token (PRT) cookies from the machine with tools like Lee Chagolla-Christensen’s RequestAADRefreshToken, Dirk-jan Mollema’s ROADToken, Evan McBroom’s LSA Whisperer, Daniel Heinsen’s, SharpGetEntraToken, or aad_prt_bof by wotwot563. These PRT cookies will even have an MFA claim if Windows Hello for Business was used for logon, allowing us to comply with MFA requirements enforced by CAPs or the new default security policy for Azure sign-in.

Stealth

We want to only execute tools that are code-signed and legitimately used in the environment, otherwise keep tool execution within our current process or proxied into the environment from a machine we control that isn’t subject to the organization’s security stack.

We could use our shiny new PRT cookie to interact with Azure using a web browser proxied through the administrator’s workstation, but:

  • fumbling through the portal requires prior experience or time to figure out, and features are added, removed, or moved all the time
  • information made available by the Azure APIs we’re interested in is not always displayed to the user or is difficult to find
  • we have to take frequent screenshots and manual activity logs for deconfliction and reporting instead of letting our C2 framework handle all that, gross
  • we may still hit CAPs preventing access without a compliant and/or hybrid-joined device

We could use our C2 agent to run command line tools that are likely to be already installed on cloud administrator workstations (e.g., PowerShell’s Invoke-RestMethod, Microsoft.Graph, AzureAD, or Intune modules, curl.exe, etc.) and interact with Azure APIs, but they don’t directly support BYO PRT cookies, they require multiple steps to obtain refresh and access tokens after dumping a PRT cookie (let alone execute actions with those tokens), and they may generate suspicious parent/child process relationships and command line arguments.

We could dump refresh or access tokens from the memory of applications the cloud admin has used to authenticate to Entra ID (e.g., their browser, the ConfigMgr console in co-management setups, etc.) with tools like the office_tokens BOF from TrustedSec, but we need some luck to obtain creds with the correct client ID, scope, and resource for the actions we want to take or that can be swapped for creds that meet these requirements.

Device Compliance / Hybrid-joined Device

An appropriately scoped refresh or access token would enable us to proxy in excellent open-source tools like ROADTools, AADInternals, BARK, AzureHound, TokenTactics/TokenTacticsV2, or GraphRunner, but we still may be blocked by CAPs requiring device compliance or a hybrid-joined device when exchanging refresh tokens for access tokens or by Continuous Access Evaluation when trying to use stolen access tokens. Further, we need a solid understanding of token manipulation, which at least for me was confusing and not easy to learn without a lot of help, trial and error, and training from Dirk-jan Mollema at Outsider Security.

While it’s possible to fake device compliance with AADInternals thanks to Dr. Nestori Syynimaa (@DrAzureAD) and just a few days ago, Dirk-jan Mollema posted a screenshot of a fake device he created that satisfied ten device compliance requirements, these techniques are not guaranteed to work in all organizations. Device compliance may also be determined and reported to Intune by Microsoft Configuration Manager (formerly SCCM) if the device is co-managed, complicating this attack vector further.

It’s also possible to satisfy conditional access policies requiring a hybrid-joined/registered device by joining a rogue/fake device to Entra ID or by overwriting an existing one, but these techniques require credentials to execute and don’t necessarily allow us to enroll the device in Intune to achieve device compliance.

In any case, CAPs may prevent us from proxying in the tools needed to pull off these attacks or from using them off network, and executing PowerShell directly on the admin’s workstation is risky. I’d rather just use the Intune admin’s compliant hybrid-joined device to reach my objectives.

Using the Azure Portal and Other Tools

Let’s say the problems above are all figured out or we luck out and stumble upon an access token with exactly the attributes we need and there are no CAPs preventing us from using it. We still need to figure out how to use the token to make the appropriate calls to the Microsoft Graph API to execute scripts, applications, and queries on Intune-enrolled devices, which is a complicated, multi-step process.

The Solution

These problems kept resurfacing and none of the available options were ideal for my use case, so I decided to write Maestro to automate them away.

Maestro, an open-source tool sponsored by SpecterOps, was first released at DEF CON 2024 Demo Labs. You can find the code here. If compiling from source, make sure you use the Release build (or the copy on GitHub, if you trust me

31 October 2024


>>More