Blog: Cloud Security

Living off the Cloud. Cloudy with a Chance of Exfiltration

Jan Masters 11 Oct 2022

Part one of a series aimed at demonstrating malicious usage of Office 365 services.


Unless default settings are changed, typical Office 365 (O365) licences come loaded with various services that are all usable by end users without special permissions. Power Automate can be used maliciously by compromised users or insider threats to systematically capture and exfiltrate data without having to contend with network safeguards.

Power Automate. Introduction

Power Automate is an O365 service that is included with common place licenses such as Office 365 E1, E3 and E5 that are commonly used by organisations. Power Automate can also be used with a free licence suitably named “Microsoft Power Automate Free”. Both versions come with plenty of capabilities, known as connectors. This service is a visual scripting service that allows users to automate different activities and duties to streamline processes.

The below image demonstrates the visual layout of this service, which allows you to create flows (cloud-hosted scripts) with all the typical scripting concepts such as loops, if statements, declaring variables, etc. The below example flow generates a spreadsheet with trending documents for everyone in the target group. Please note that you can only see shared documents.

Figure 1 – Example flow

TL;DR on connectors

Connectors are the lube that allows the user to pull and push information from various sources, both native O365 and third-party services. Fortunately for us, there are two categories of connectors: free (standard) and premium, which is covered by another licence. There are currently 142 standard and 507 premium connectors at the time of writing.

Each connector is broken down into triggers and actions that either drive the autonomous nature of the flow or perform an action. Not all connectors will have assigned triggers and actions.

Some connectors such as Azure AD will require admin approval, which may also be applicable for other connectors (depending on your configuration).

Figure 2 – Example connector

Power Automate. Malicious Use Case

Strict internet access policies are slowly becoming common place within most organisations and within their Microsoft Cloud environments with the use of conditional access policies. I have had several experiences where exfiltration has either been impossible or extremely long winded. This flow will change that as the attacker does not have to contend with firewall or proxy rules / configurations; they can leverage Office 365 to capitalise on the lack of network-based control held by organisations.

This is the annotated flow:

The below images detail a successful run of the automated flow and the output created by said flow.

Figure 3 – Successful flow run

Figure 4 – Exfiltrated files

Power Automate. Post Incident Investigation

Right off the bat, post investigation capabilities for Power Automate could be improved. One thing to note is that administrators cannot easily view users’ flow configurations. Figure 5 shows the high-level details you can view from the Power Platform admin portal. You will need to add yourself to flows via “Share”, which will grant you access but will also notify the attacker as the flow will move from “Cloud flows” to “Shared with me”.

Figure 5 – Admin perspective of flows

Figure 6 – Different tabs

The primary source of information is the compliance portal (, specifically the Audit solution that is highlighted in the below image.

Figure 7 – Audit search

As previously mentioned, the returned audit logs leave much to be desired as the high-level information is vague other than rudimentary categorisations listed in the below screenshot. Moaning aside, the main artifacts are IP addresses and user agents as any flow activity will come from Azure-based IP addresses and originate from Logic Apps.

Figure 8 – Audit log sample

Figure 9 – Artifact #1 (information from

Figure 10 – Artifact #2

You cannot filter by user agent or IP address unless you export a spreadsheet version, which you can then manipulate with spreadsheet and JSON magic. Unfortunately for you, the .CSV version contains JSON formatted data in “AuditData” column, which contains all the juicy information.

Figure 11 – Sample data from exported csv

Power Automate. Hardening

You know about the attack and the Indicators of Compromise but how do we prevent this school of attack? From my experience, there are three possible routes; however, all three should be actioned as part of a defence-in-depth approach.

All recommendations should be diligently implemented and tested.

Restricting licence sign-ups

Option 1) restricting the ability for users to sign up for various licence types that grant access to Power Automate, as well as other services. This can be achieved by using the below PowerShell commands:

# Installing required modules.
Install-Module MSOnline
Install-Module -Name Microsoft.PowerApps.Administration.PowerShell
Install-Module -Name Microsoft.PowerApps.PowerShell -AllowClobber

# Connect to services.

# Make required changes.
Set-MsolCompanySettings -AllowAdHocSubscriptions $false
Remove-AllowedConsentPlans -Types @("Internal", "Viral")

Implementing data policies

Option 2) Power Automate has Data Loss Prevention policies that can be created and implemented to restrict access and data sharing between two categories. You can read more here:

You can leverage DLP policies to block unnecessary or high-risk connectors for all or selected Power Automate environments; the use of multiple environments could be used to provide access to high-risk connectors for specific users as these are not fine-grained policies.

Figure 12 – Creating DLP policy

Figure 13 – Blocked automation

Restricting access via conditional access policies

Option 3) restricting or blocking access to the Power Automate service via conditional access policies within Azure AD. This route can be configured to meet your requirements; however, we recommend that Power Automate and potentially others are blocked by default for everyone and then exceptions are created and documented.

Further reading