Running JXA Payloads from macOS Office Macros
Despite being quite antiquated, MS Office macros continue to be used by red teams (and attackers) due to the fact that they are easy to craft and they still work (and on the macOS side of the house, they often go undetected without building custom content). I have written MS Office macros for a couple different macOS C2 tools in the past…and in both I used python as the means of running the C2 payload:
With the landscape starting to shift in the macOS arena to moving away from python-based offensive tooling, I thought I would take a look at how to write macros for macOS without using python. Below I walk through that process.
I tried a few things to see what would and would not execute in the macOS app sandbox (where anything spawned by an MS Office macro is executed). I found that several utilities I wanted to use were not able to execute in the sandbox (I tested the items below from VBA execution using MacScript (“do shell script ….”)):
- I tried building Objective C code on the fly, compiling, and executing via the command line:
- Next I went very simple and just tried to invoke curl to download a hosted JXA .js payload and to invoke that payload via osascript…THAT DID WORK:
Note: There is nothing really advanced or complex in the code above. Since these command line binaries were allowed in the app Sandbox, this made for an easy way to perform this action without using python.
Here is my github repo with the macro generator code to produce VBA code with content similar to above:
Python3 script to generate MS Office macros for launching Mythic JXA payloads. This script generates an Office macro…
In my testing I used Mythic’s apfell http JXA .js payloads:
A cross-platform, post-exploit, red teaming framework built with python3, docker, docker-compose, and a web browser UI…
What is neat about Mythic is even though this method will launch the Mythic agent inside of the app sandbox, Mythic is still able to execute some functions outside of the sandbox due to how it is invoking ObjC calls to perform those functions.
Since my macro generator produces code that relies on the command line, detections are pretty straightforward. I ran Patrick Wardle’s ProcessMonitor tool (which uses the Endpoint Security Framework) in order to capture events when I launched the macro and connected to Mythic. Here is a screenshot of the capture:
In summary, parent-child detections can be used to detect this macro:
- Office Product (ex: Microsoft Word.app) → /bin/sh
- Office Product (ex: Microsoft Word.app) → /bin/bash
- Office Product (ex: Microsoft Word.app) → /usr/bin/curl
I recommend blue teams roll out the detections above, as there should be little to no valid activity stemming from the above parent-child relationships.