Azure Outlook Command & Control. Threat Emulation Tool for North Korean APT InkySquid / ScarCruft / APT37. TTP = Abuse Microsoft Graph API for C2 Operations.
Azure Outlook C2
Azure Outlook Command & Control that uses Microsoft Graph API for C2 communications & data exfiltration.
Control a compromised Windows Device from your Outlook mailbox.
About Azure Outlook C2
This project consists of an implant that “beacons” out to an Attacker Controlled Azure Infrastructure. The implant is hardcoded with an Azure Refresh Token when compiled by the Attacker. When the implant is executed on a compromised Windows device, it accesses the Attackers Draft mailbox via the Microsoft Graph API. The implant reads the Attackers mailbox to receive instructions. The implant executes those instructions and sends the standard output back to the Attacker via creation of new Draft messages. The implant will continue this behavior until the host process ends.
Why I Built This
I recently started Red Teaming about half a year ago on the SpiderLabs Red Team at Trustwave. During an engagement I had the honor to work with the legendary Stephan Borosh (rvrsh3ll|@424f424f). Steve taught me all about Azure Domain Fronting, and I was blown away that Command & Control traffic could be exfiltrated out via HTTPS using legit domains like ajax.microsoft.com
. It even uses Microsoft’s TLS Certificates! Unfortunately for me, I began Red Teaming at the same time Domain Fronting died on Azure. Even though Domain Fronting on Azure was dead, there was still allot of awesome Red Team techniques that could be done with Azure.
Steve introduced me to Azure Device Code Phishing. During this time I dived deep into Azure and the Microsoft Graph API for Red Teaming. We created the tool TokenTactics, derived from the great work of Dr. Nestori Syynimaa (@DrAzureAD), and we made The Art of the Device Code Phish blog if you are interested in our methodology.
While creating TokenTactics and experimenting with the MS Graph API, I discovered it was possible to use the Microsoft Graph API as a C2 channel. There are many different ways to use the MS Graph API as a C2 channel, and I am not the only person (or the first) to discover this. VX-Underground, created by @smelly__vx – the creator/publisher of the HellsGate technique, released information last month that the North Korean Advanced Persistent Threat (APT) group “InkySquid” (AKA ScarCruft and APT37) uses the Microsoft Graph API for C2 operations. After releasing a teaser of this project on Twitter & LinkedIn, several DFIR professionals commented that this technique of using the Microsoft Graph API for C2 operations is actively being used by ransomware groups in the wild, dating back months.
During the Red Team engagement, I attempted to get Cobalt Strike working with the MS Graph API as the C2 channel. Unfortunately, I failed, but this is still a future goal. The issue I face with getting this to work with Cobalt Strike, is that the MS Graph API uses 2 tokens for communications. The first token is the Refresh Token which can last up to 90 days. The second token, the Access Token, is a temporary token that last around an hour. Direct communications to the MS Graph API are done via authenticating with the Access Token. Once an Access Token expires, the Refresh Token can be used to get new Access Tokens. Since I am still new to Red Teaming & Cobalt Strike development, I could not figure out how to use the Cobalt Strike Malleable C2 profile to support constantly getting new Access Tokens and sending these changing Access Tokens in the Authorization
header of HTTPS beacon’s requests. Since releasing the teaser on Twitter, Joe Vest, Alfie Champion, and other rockstars of the community have given me some epic direction on how to get this to work with Cobalt Strike! Hopefully there will be a Cobalt Strike follow up to this project in the future 😉
Implant Execution Flow
- Get an Access Token to the MS Graph API using the hard-coded Refresh Token of the Attacker.
- This is done via HTTPS TCP communications to the host
graph.microsoft.com
. - This traffic is encrypted using the TLS Certificate returned from the legitimate Microsoft web server.
- The implant uses the
WinInet
Dynamic-link library for HTTPS communications. - The hard-coded Attacker Refresh Token should be good for 90 days.
- If the implant is compromised, the Attacker can revoke the hard-coded Refresh Token to restrict access from Malware Reverse Engineers.
- After the implant receives an Access Token for the Attackers MS Graph API, the implant enters an infinite loop.
- If there is no internet connection or internet connection is disrupted during the loop, the implant will sleep for 3 minutes and try again.
- The implant keeps track of time, and if 15 minutes has passed, it will get a new Access Token to continue communications.
- The first task in the loop is to use the MS Graph API Access Token to access the Attackers Draft mailbox and read the most recent message for commands to execute on the compromised Windows device.
- The Draft mailbox was chosen because this way there are no emails being sent via SMTP.
- Once the command is received, it is parsed to determine which meta command it will execute. Currently there are 3 meta commands:
cmd
,sleep
,exit
cmd
: Takes the following string after the meta command and executes it by spawning a child process.sleep
: Takes the following word after the meta command and will change the implants sleep to the value supplied (in milliseconds).exit
: Exits/kills the host process.
- If the meta command is
cmd
the implant will create a child process to execute the command, the child process will write its standard output to a pipe, the child process exits after command execution, and the host implant process will read the output of the child process via the pipe. - After the implant gets the output from the executed command, the implant will use the MS Graph API to create a new draft email which contains the command output.
- The implant will then create a second draft email with a blank body.
- This allows logging of the command output within the Attackers Draft mailbox.
- This queues the Attacker with a fresh draft message to enter the next command the implant will execute.
- After the command has been executed and the output returned to the Attacker, the implant will sleep for a time controlled by the attacker, and then repeat this loop.
Instructions
- Standup Red Team Azure Infrastructure that will be used as the Command & Control by following my blog post The Art of the Device Code Phish to setup:
- Azure Account Subscription
- Azure Active Directory Tenant
- Office 365 for Azure Active Directory
- Create a user for the Outlook Command & Control mailbox
- Install the TokenTactics PowerShell Module
- Use TokenTactics to get the Tenant ID of the Azure AD you just created:
PS C:\Users\boku\Desktop\TokenTactics-main> Import-Module .\TokenTactics.psd1 PS C:\Users\boku\Desktop\TokenTactics-main> Get-TenantID -domain theharvester.world 1d5551a0-f4f2-4101-9c3b-394247ec7e08
- Add your TenantID to the
char tenantId[]
variable within theazureOutlookC2.c
file. - Get an Azure Refresh Token by using TokenTactics to device code phish yourself with the C2 mailbox user:
# Import the TokenTactics module into the PowerShell session
PS C:\Users\boku> cd .\TokenTactics
PS C:\Users\boku\TokenTactics> Import-Module .\TokenTactics.psd1
# Start a Device Code phish request to get a 'user_code'
PS C:\Users\boku\> Get-AzureToken -Client Graph
user_code : ERDVDCNHH
- Go to microsoft.com/devicelogin, enter the
user_code
from TokenTactics, and login with the C2 mailbox user. - In the PowerShell session running TokenTactics, copy the refresh token from the successful device code phish on yourself.
- If you need more information on how TokenTactics works, please see The Art of the Device Code Phish
- Add your refresh token to the
char refreshToken[]
variable within theazureOutlookC2.c
file.
void main() {
// Variables
char refreshToken[] = "0.AXwAoFFVHfL0AUGcOzlCR-x-CNYOWdOzUgJBrv-q0ikqsBx8ACA.AgABAAAAAA...
// ^Put your refresh token here and compile
- Compile
azureOutlookC2.c
.
# Compile with x64 MinGW:
bobby.cooke$ cat compile.sh
x86_64-w64-mingw32-gcc -m64 -mwindows -Os azureOutlookC2.c -o azureOutlookC2.exe -lwininet
bobby.cooke$ bash compile.sh
- Execute the
azureOutlookC2.exe
PE file on a Windows Device. - As the attacker from the attacker computer, open a browser, login to
outlook.office.com
, and control the Windows device running the implant from your mailbox.
Initial Project Goals
- Make a working proof of concept that uses the Microsoft Graph API for a C2 channel and control a computer from my email.
Future Project Goals
- Implement this as a C2 channel for Cobalt Strike.
What This Project Is
- This project is a proof of concept, which demonstrates how an Attacker can use the Microsoft Graph API for C2 operations.
- The simple “beacon” in this project is NOT OPSEC SAFE.
- There are some hilarious bugs in this beacon that can result in some nasty crashes. Specifically with buffers and
sprintf()
😉 - If you are interested in using this project for Red Team engagements, you will have to put in the work.
- There are some hilarious bugs in this beacon that can result in some nasty crashes. Specifically with buffers and
- This project is intended for other offensive security researchers to learn from.
- I have not personally come up with any great ways to defend or detect this C2 channel. My hope is that by supplying this to greater defender minds than myself, it will result in some awesome defensive techniques.
What This Project Isn’t
- This project itself is not a fully functional C2, ready for OPSEC safe engagements.
Detection & Prevention Ideas from Defenders (To Add Please Submit a Pull Request )
Mehmet Ergene (@Cyb3rMonk) Detection Advice
- “Baselining applications connecting to Graph API and checking the anomalies might be an idea. Could be bypassed easily though.”
- “As always, detecting beaconing traffic. (I’ll make an improvement to cover Graph API and similar stuff)”
Credits / References
- Sektor7 Malware Development Courses
- @passthehashbrwn – Dynamic payload generation with mingw
- Raphael Mudge – Red Team Ops with Cobalt Strike (2 of 9): Infrastructure
- Raphael Mudge – Red Team Ops with Cobalt Strike (3 of 9): C2
- Microsoft Graph REST API v1.0
- Microsoft WinInet
- StackOverFlow – Create Process and Capture stdout
- Microsoft – Creating a Child Process with Redirected Input and Output