Over the past few years, we have seen an increase in the number of macOS environments we are asked to assess. While PoshC2 has “supported” macOS by way of Python since the very early days, increasingly Python support is changing in macOS. We wanted a way to run an implant that would be native to macOS, independent of the version of macOS in use, and would give more power than just running Python scripts. So, after months of development, we’re introducing JXA implants in PoshC2.
What is JXA?
JXA allows us to run on macOS environments from 10.10 (Yosemite) all the way to the latest release of BigSur (11.2).
PoshC2 + JXA
A new implant type has now been added to PoshC2. When starting your PoshC2 instance, you will notice the
dropper_jxa.js payload added to the project payloads directory.
This dropper is our stage 1 and when run on the target it will reach out and execute the core implant functionality. The dropper contains the code needed for performing encryption/decryption, the check-in URI, and also performs some basic checks about the user and PID the implant is running under.
Once executed, you should see the implant in the PoshC2 Implant Handler.
Core functionality will allow for running basic shell commands, changing the beacon time, uploading and downloading files, and clipboard monitoring. As with all other implant types, run help to see a list of commands.
Some features of note:
- beacon (set your beacon time)
- clipboard-monitor (monitor the clipboard for changes for a length of time and return all strings)
- upload-file / download-file (upload and download files)
- Shell commands (any commands run on the implant that are not built-in commands in PoshC2 are run as shell commands. This will spawn
/bin/shto execute the command)
- run-jxa (my favorite feature. See below for details)
We wanted to make sure that, as with the C# implant, the JXA implant is easily extensible and allows for you, the operator, to be able to add your tools without needing to re-write the server.
What this means is that if you have a favorite JXA script that you would like to run, you can simply drop in the
resources/modules directory of PoshC2, then execute the function you want to run. An example of this is HealthInspector, by @its-a-feature. HealthInspector is a great script to perform situational awareness on a macOS environment. There are a load of functions within the script, but simply running
run-jxa HealthInspector.js <function> you can obtain a ton of information without re-inventing the wheel.
Take a look below for a list of some of our favorite operational JXA scripts.
- HealthInspector: https://github.com/its-a-feature/HealthInspector – JXA situational awareness helper by simply reading specific files on a filesystem.
- PersistentJXA: https://github.com/D00MFist/PersistentJXA – Collection of macOS persistence methods and miscellaneous tools in JXA.
- SwiftBelt-JXA: https://github.com/cedowens/SwiftBelt-JXA – This is JXA implementation of some SwiftBelt functions (SwiftBelt is a macOS system enumerator that was originally written in Swift).
To ensure we empower our blue team friends, the following are some Indicators of Compromise (IoCs) specific to JXA implants.
osascript spawns /bin/sh
When running a shell script within JXA, osascript spawns
/bin/sh as a child process. This can be seen with Patrick Wardle’s Process Monitor app (https://objective-see.com/products/utilities.html#ProcessMonitor).
Running osascript to execute JXA scripts
Our initial dropper running using osascript could also be seen as an IoC. This is very much dependent on the environment, as JXA is used for legitimate purposes. If your organization does not use osascript, then checking for execution of
Also be sure to check out all the PoshC2 Indicators of Compromise (IoCs) at https://labs.nettitude.com/blog/detecting-poshc2-indicators-of-compromise
With the addition of the macOS JXA implant, you can now use the C2 you know and love to operate against any macOS target. Grab the latest version of PoshC2 from https://github.com/nettitude/PoshC2 and give it a spin. As always, if you encounter any issues or have any suggestions on improving PoshC2, submit a ticket on GitHub or come chat with us on the PoshC2 Slack channel at https://poshc2.slack.com.