Osquery Logs
There are two styles of results logs in osquery, snapshots and differential logs. Snapshots are exactly what the name suggests, results of queries executed at a single point in time. Differential logs only add a row when results of a query change. As a simple example, I have created an osquery.conf file with scheduled queries for listening_ports and launchd tables. Applying these configs gives us a differential log.
The first set of entries from launchd are the baseline. This log can be saved or discarded. For our purposes we just need the subsequent changes, which will list any new property lists added to the launchd paths. We could get the same information without using osquery by running "launchctl list" and writing a script to parse it, but osquery is a convenient tool to use for this purpose.
The next step is to take a snapshot on my virtual machine, and then run the trojan PDF from part one. After the Mach-O binary executes, we see the decoy document appear.
Checking our osqueryd.results.log again, we can see we have a new row in our log. Reading through the results we can see that indeed the malware has added a property list to our launch directory for persistence. We can also see the paths we need to locate the property list, which will in turn yield the path to the persistent executable, as we saw in part two.
This is an extremely simple example of dynamic analysis. The technique could be automated further with scripting to create our own custom "sandbox". With it we could quickly find low-hanging fruit indicators from our macOS malware sample, or from suspected phishing email attachment. Additional tables can be added to monitor other potential persistence mechanisms like crontab, or even more stealthy methods like @xorrior's emond based persistence.
I am still exploring the capabilities of osquery for ways to detect other malicious behavior and indicators. For example, I've been exploring the best way to capture network information using only osquery tables. I experimented with the listening_ports table and found that it does indeed log processes listening on a port. I am able to see, for instance the mDNSResponder service listening as expected on UDP port 5353. Unfortunately, listening_ports does not address reverse-shells or other backdoor and C2 mechanisms.
Another interesting table I have experimented with is file_events, and it seems to have some cool possibilities. One use case would be to create a substitute for Windows Security Event ID 4663, and use it for something like @neu5ron's canary files. I'll keep exploring, and keep blogging about what I find.