As I said in part one, I began by checking the osx-attacks pack for existing rules. While there were no rules to detect the newest APT32 associated variants, I used the pack as a template for writing my own. Packs have only a few necessary elements. The first element in the osx-attacks pack is a platform key that specifies the value for macOS ("darwin"). The next element, "queries", quite naturally contains the rules we want applied, formatted as a series of SQL queries.
Before going any further, a brief note on the syntax. The osx attacks pack includes a bash-style backslash to indicate line continuation. Other example configuration files from the Facebook osquery repository include C-style comments (//). These elements were compatible with the json parser in earlier versions of osquery, but may not be compatible with newer versions. The parser in version 3.1.0, the latest version installed by Brew as of my writing this post, throws errors on these non-compliant elements. I have confirmed this via experimentation and talking to osquery developers via the Slack channels.
Now let's go back to that table "launchd", and answer "what is a .plist?" and "why are we looking for them?" For additional information you can always check out my talks from BloomCon 2018 and BSides Columbus 2018. The short answer is that property lists (.plist) and launchd are the way at least half of macOS malware variants, according to my own completely un-scientific estimate, achieve persistence.
Within the .plist file for the APT32 variant shown here, a "RunAtLoad", "true" key-value pair ensures persistence through a shutdown or restart, while "KeepAlive", "true" key-value pair ensures the process is restarted if stopped. Lastly, the "ProgramArguments", "/Users/thewoz/Library/Containers/com.apple.lateragent/Data/Library/Preferences/hidd" key-value pair gives us the full path of the Mach-O binary "hidd", which is written to disk in the victim's ~/Library/Containers folder and concealed with a "hidden" xattribute, which launchd is required to run on startup.
Using this information, we can create two rules for query pack. The first will follow our osx-attacks pack template and query the launchd table to detect the presence of "com.apple.hidd.shared.plist", a good indicator of this variant. The second rule will query the "file" table for that persistent Mach-O binary. Results can either be logged locally to the default /var/osquery/log/osqueryd.results.log, or can be aggregated for ingestion by Splunk, LogStash, Fluentd, or other options. But that will have to wait for a future post.