top of page
  • Luis Miguel Acosta Guzmán

Incident Response Trick- Find email OOB persistence after account compromise in Microsoft 365.

Email is still the number 1 attack vector; phishing and spear phishing attacks continue to be one of the attacker's favorite weapon of choice to propagate malware or gain access to organizations. The reason for this is simple: humans can be tricked and deceived, so it is natural that attackers may try to "exploit us" using the "weaknesses" we expose in places such as social media. Elliot Alderson's character described this with perfection in the TV series "Mr. Robot" (S01, E05): "If you can hack the right person, all of the sudden, you have a piece of powerful malware. People always make the best exploits. I've never found it hard to hack most people. If you listen to them, watch them, their vulnerabilities are like a neon sign screwed into their heads."

Many organizations have relied on Microsoft Office and Windows as a business tool for many years, so, migrating to a Microsoft 365 subscription has been a natural step for most of them. Microsoft 365 subscription includes a cloud based email service with some security features intended to stop malicious emails from reaching the user's inbox, some of these features are included in the entry E3 version and some of them are added in the E5 tier. If you have worked with Microsoft 365 as a security professional, you surely know that these security features, even the ones added in E5, are not enough (particularly when dealing with spear phishing attacks) and some malicious emails, links and attached files will eventually end up in user's computers. I always recommend the IT and Cybersecurity teams I advise, to add extra layers of protection to email security incorporating reputation verification, threat intelligence, dynamic malware analysis, artificial intelligence capabilities along with user awareness campaigns to train users not to fall for the phish, but that's a topic for another post.

I've witnessed many phishing attacks with the single purpose of compromising Microsoft 365 user accounts by stealing user's credentials. The attack consists of malicious emails presenting the user with a fake Microsoft 365 login page through a fake URL or malicious attachment and appealing to some kind of sentiment or sense of urgency to make the user put its credentials in the fake login site. If you think about it, owning Microsoft 365 users credentials would allow an attacker to access data in their emails, One Drive and Sharepoint; plus, it is very likely permissions have already been delegated to third party apps through OAuth, so attackers really have a strong motif.

What if user's credentials have been already exposed and the user has no MFA enabled yet (I strongly recommend you to add MFA to every single user application)? Many times I've found that attackers love to configure forwarding and redirection rules in compromised users mailboxes to keep an out-of-band persistent access to some part of the data; that is probably because they know it is very likely someone will find out about the compromise, reset the user's password and maybe even enable MFA after the breach ( many organizations "shut the stable door after the horse has bolted"). In this post I'm gonna show you a very useful trick to find if an attacker has created an email forwarding rule to gain out-of-band persistence to the user's emails contents. To do so, you need to connect to Exchange Online using PowerShell and run some queries. For this you need the following:

  • A supported Windows computer

  • PowerShell 7

  • Microsoft .NET Framework 4.5 or later

  • Windows Management Framework 5.1 or later

  • A user with administrative permissions over Exchange Online

First you need to verify that basic authentication is enabled on WinRM in the computer you will be using PowerShell by running the following command in a Windows Command Prompt running as administrator (note that basic authentication should be enabled by default):

winrm get winrm/config/client/auth  

If the result is not showing "Basic=true" it will be necessary to run the following command to enable basic authentication:

 winrm set winrm/config/client/auth @{Basic="true"}  

Now we can move to a PowerShell console also running with Administrator permissions. First use the following command to make sure all the scripts that run into PowerShell are required to be signed by a trusted publisher, this is a good security practice:

Set-ExecutionPolicy RemoteSigned

Now, we need to install Exchange Online PowerShell V2 module (EXO V2) running the following command:

Install-Module -Name ExchangeOnlineManagement

Now we can use the module to authenticate to Microsoft 365 and connect to Exchange Online using the user principal name (UPN) of the respective tenant, for example,

Import-Module ExchangeOnlineManagement

Connect-ExchangeOnline -UserPrincipalName <UPN e.g.>

You should now be prompted with a Microsoft authentication portal to put your credentials. After a successful authentication you will be able to start interacting with Exchange Online.

You can list the tenant's user mailboxes using the following command, to verify that the connection was successful:


First, we need to list all existing user mailboxes and save them into a variable:

$mailboxes = get-mailbox –resultSize unlimited

Then we need to go through the list and find if there are any rules configured for each mailbox. We save that into a rule list:

$rules = $mailboxes | foreach { get-inboxRule –mailbox $_.alias }

Then, from the rule list we look for rules that are forwarding or redirecting emails. Note that we are escaping the output with a pipe and choosing only to display the name of the rule, the identity of the mailbox and the identity of the rule:

$rules | where { ( $_.forwardAsAttachmentTo –ne $NULL ) –or ( $_.forwardTo –ne $NULL ) –or ( $_.redirectTo –ne $NULL ) } | ft name,identity,ruleidentity

To check the details of a rule you can use the following command substituting the mailbox\identity value obtained from the previous step. In this example we are escaping the output using a pipe and selecting the name of the rule and the "Forward To", "Forward As Attachment To" and "RedirectTo" values to identify the destination email for the rule. Typically and attacker will use a randomly generated email address hosted on a free email service provider such as Gmail to receive all the stolen data. Using the command without escaping it would also return human readable information:

Get-InboxRule –identity <mailbox\identity ID> | fl name,forwardTo,forwardAsAttchmentTo,redirectTo


Get-InboxRule –identity <mailbox\identity ID>

Of course not all rules you identify are going to be created necessarily by an attacker using compromised credentials but it can happen. In some cases you might also find some users doing the old school "corporate-information external proactive backup" (aka data exfiltration).

Make sure to disconnect the remote PowerShell session before closing the terminal to avoid keeping a session hung up:


Bonus Trick

Have you heard of "Have I Been Pwned" ( It is a really cool online tool that will allow you to investigate if email address passwords have been exposed after a third party security breach. For example, maybe you use your Gmail address to login in to LinkedIn, If somebody would ever breach LinkedIn's users database (it has actually happened in the past) the password or hash (salted hash) you were using to login to LinkedIn could've been exposed and it is common that many people uses the same password to login to many different applications, services and accounts. That means that the exposure of your credentials by a breach in a third party could mean exposing the credentials for all your services.

"Have I Been Pwned" allows you to search unique email addresses for free. However, it also has a payed API service (for only $3.50 USD per month) that you can use to automate searches for multiple addresses. I recommend you to use the API in conjunction with "pwned", a tool that allows you to interact with the "Have I Been Pwned" API through a CLI without actually worrying about the code to make the API calls; all you have to do is to configure "pwned" with your own API key.

Here is an example of how to install "pwned" (along with "npm" which is a dependency) and configure it in the latest version of Kali Linux (as of today):

#install node.js
curl -sL | sudo -E bash -
sudo apt update
sudo apt install nodejs

#install pwned
sudo npm install pwned -g

#configure api key
pwned apiKey <key provided by Have I Been Pwned once you pay>

If you would like to know the exposure level of your organization's emails, I recommend you to search for all of the email addresses of the organization in the "Have I Been Pwned" tool; that will give an idea of which users are using their corporate email to register to third party services and accounts, as it would tell you if a user's password has been potentially exposed (users love to use the same password for all their accounts). You can just export the email addresses into a txt file and use some code to automate the search using "pwned". Here is an example of a bash script (I recommend you to use a sleep function so that the "Have I Been Pwned" service doesn't block your automated requests if interpreted as a DoS):

for line in $(cat [email_address_list.txt])
echo “--------------------”
echo $line pwned search $p
sleep 10

In this example we are using the "pwned" search function which will return breaches and "pastes". Here is the explanation of breaches and "pastes" right from the source ( "Often when online services are compromised, the first signs of it appear on "paste" sites like Pastebin. Attackers frequently publish either samples or complete dumps of compromised data on these services. Monitoring and reporting on the presence of email addresses on the likes of Pastebin can give impacted users a head start on mitigating the potential fallout from a breach.

When you search for an email address on this site, both known data breaches and pastes are searched simultaneously. After the results are returned, they both appear side by side with an indication of where the address was found in a breach versus in a paste."

Now you can add two tricks into your incident response playbooks ready for the next time a user chooses to trust a Nigerian prince who wants to share his fortune reaching through email.


a security artist

122 views0 comments

Recent Posts

See All


bottom of page