This blog post is going to demonstrate a proof of concept (PoC) of sending an e-mail to trigger the Mail app (mail.app) to create a reverse shell. The Mail app has built-in functionality that can trigger an Applescript to execute code when certain conditions (new e-mail in inbox from bob, deletion of e-mail, or an e-mail containing certain text) occur within the Mail app. This functionality provides a method to initiate a reverse shell without user interaction or placing a persistent mechanism in a well-known location. The method below will utilize this functionality to monitor e-mails from a particular user, upon receiving an e-mail from said user, a reverse shell will call back to our Powershell Empire server.
The information contained in this blog post is for educational purposes ONLY! HoldMyBeerSecurity.com/HoldMyBeer.xyz and its authors DO NOT hold any responsibility for any misuse or damage of the information provided in blog posts, discussions, activities, or exercises.
Mail.app mail rules
You can attach an AppleScript script to a Mail rule. For example, you could have an incoming message trigger a script that copies information from the message and pastes it into a database that works with Script Editor. In this blog post, we are going to use this functionality to execute a script to create a reverse shell.
Empire is a post-exploitation framework that includes a pure-PowerShell2.0 Windows agent, and a pure Python 2.6/2.7 Linux/OS X agent. It is the merge of the previous PowerShell Empire and Python EmPyre projects. The framework offers cryptologically-secure communications and a flexible architecture. On the PowerShell side, Empire implements the ability to run PowerShell agents without needing powershell.exe, rapidly deployable post-exploitation modules ranging from key loggers to Mimikatz, and adaptable communications to evade network detection, all wrapped up in a usability-focused framework.
Install/Setup Powershell Empire
- Spin up a Kali Linux VM
apt-get update -y && apt-get upgrade -y
git clone https://github.com/BC-SECURITY/Empire.git
set Name http80
set Port 80
Generate Applescript stager with Empire
set Listener http80
set OutFile /tmp/applescript
- Copy the above output
Since this script can be used for nefarious activity, I will not be demonstrating any methods to automate enabling this script from the command line. This section will demonstrate how to place this script in the proper location with the terminal but will use the GUI to enable our script. Additionally, to prevent the weaponization of this technique this section is missing steps to make this PoC work.
echo "<contents of Empire payload above>" > ~/Library/Application\ Scripts/com.apple.mail/ps_empire.scpt
- Open Mail.app
- Login into an e-mail account
- Select Mail > Preferences >Rules
- Select “Add rule”
- Enter “Empire-shell” for description
- Rule conditions
- Select “From”, “is equal to”, and enter an e-mail
- Rule actions
- Select “Run AppleScript” and “ps_shell”
- Select Ok
Sending the e-mail
- Select “New message” in the top left
- Enter “<YOUR e-mail>” into To:
- Enter “Test” into the subject
- Enter “test” into the body
- Send e-mail
Principle of least privilege
The principle of least privilege is the biggest deterrent against this technique. This technique requires administrative privileges to copy the script into the directory.
From my testing, it seems that our malicious AppleScript is executed as a child process of UserScriptService. I ASSUME that when an app like Mail.app runs an Applescript it makes an internal API call to this process to execute the script. The child process spawned by UserScriptService has a
-T flag which specifies the application that made the request to spawn this AppleScript. The query below starts by querying the process table for the PID of Mail. Next, it queries the process_events table for all the command lines that initiated a process that have a prefix of “osascript”. Finally, the query extracts the parent PID from any processes starting with “osascript” and compares the PID to the Mail app PID. Effectively this query is looking for any Applescript initiated by Mail.app
SELECT * FROM process_events WHERE cmdline like '%osascript%' AND trim(substr(cmdline,23,5)) like (SELECT pid FROM processes WHERE name='Mail');
Creation and modification date
With Osquery we can query the following directory
~/Library/Application Scripts/com.apple.mail for recent modifications.
SELECT f.path, datetime(f.mtime,'unixepoch') AS file_last_modified_time, datetime(f.ctime,'unixepoch') AS file_last_status_change_time, datetime(f.btime,'unixepoch') AS file_created_time, ROUND((f.size * 10e-7),4) AS size_megabytes FROM file f LEFT JOIN users u ON f.uid = u.uid LEFT JOIN groups g ON f.gid = g.gid WHERE path like "/Users/%/Library/Application Scripts/com.apple.mail/%';
Decompile Applescript binary
file <file path to file>
osadecompile <file path to file>