Threat hunting with osquery: 5 macOS malware techniques and how to find them
This previous blog post explored ways to use osquery for macOS malware analysis. Using the same methodology introduced there, we analyzed five additional macOS malware variants and recorded their behavior to understand the techniques they used. Below, you’ll find the techniques used by Calisto, Dummy, HiddenLotus, LamePyre and WireLurker. Read on to explore how to translate the techniques used by these malware into queries you can run to hunt for the active presence or historical artifacts using osquery.
Before we construct the hunting queries for the above techniques, let’s first understand what threat hunting is.
Threat hunting is a proactive approach to identify potential malware infections. In general, organizations deploy various detection technologies like antivirus, sandbox solutions, IDS/IPS etc. to detect threats. These detection technologies provide some protection, but as attackers are using novel techniques to bypass these very detection systems, it becomes important to use proactive approaches to find malware infections or system compromises before it’s too late.
The main advantage of threat hunting is it’s an interactive human intelligence driven approach. When we have an understanding of specific malware techniques, we can quickly construct queries and look for anomalies in our systems. There are some key challenges with this approach though, such as the constant evolution of malware techniques and the added complexity of hybrid infrastructure. The human analysts not only need to keep up with the latest bad actor techniques, but also the myriad tools required to hunt across hybrid environments. Sophisticated attackers are also using multiple stages of attacks, and often hiding their tracks, so hunting on live machines (or real time hunting) alone might not be effective to uncover malicious activities. As I discussed in my previous blog, this is where historical data scanning is equally important to provide a 360 degree confidence that the systems have not been compromised by malicious software. For these reasons, I think of threat hunting in two parts:
Active threat hunting: Active threat hunting means we look for the threats on live machines using real time queries (i.e we apply the threat intel on the current state of the system).
For example: The security community publishes APT32 indicators of compromise, so we run a query to see if any of our systems are infected right now.
Passive threat hunting: Passive threat hunting means we scan historical data of the systems that has been stored in the cloud and compare against the latest threat intelligence.
For example: The security community publishes APT32 indicators of compromise, so we run a query on the historical data to see if any of our systems were infected at any point in time in the past.
Now how can we accomplish these tasks with osquery? The open source osquery agent can be used to query a single live machine (you can also build an ecosystem that allows for distributed querying as described here). Alternatively, specialized osquery analytics platforms with access to historical system data, like Uptycs, can be used for both active and passive threat hunting across your entire infrastructure.
Now, let's build some hunting queries based on the techniques we know each malware is using as outlined in the table above.
Threat hunting queries
Case 1: Property List Files
All five of the malware are adding property list file in LaunchAgents or LaunchDaemons using cp, mv, touch and mkdir commands. So we can create the following queries to detect these activities:
Malware using cp:
select * from process_events where path like '%bin/cp%' and cmdline like '%Library/Launch%'
Malware using mv:
select * from process_events where path like '%bin/mv%' and cmdline like '%Library/Launch%'
Malware using touch:
select * from process_events where path like '%bin/touch%' and cmdline like '%/Library/Launch%'
Malware using mkdir:
select * from process_events where path like '%bin/mkdir%' and cmdline like '%Library/Launch%'
Case 2: Calisto
Calisto uses sqlite3 to add entry in TCC.db for accessibility privileges so the following query can detect this activity:
select * from process_events where path like '%bin/sqlite3%' and cmdline like '%com.apple.TCC/TCC.db%'
Calisto also uses zip to archive the keychains so the following query can be used to detect this activity:
select * from process_events where path like '%bin/zip%' and cmdline like '%/Keychains%'
Case 3: Dummy
Dummy uses chmod and chown with sudo to change the file/folder permissions. So the following query can be used to detect this activity:
select * from process_events where path like '%bin/sudo%' and cmdline like '% -p%' and cmdline like '%chmod%'<
select * from process_events where path like '%bin/sudo%' and cmdline like '% -p%' and cmdline like '%chown%'
Case 4: Hidden Lotus
HiddenLotus uses the ‘open’ command to open the pdf file from tmp directory so we can use the following query to detect this activity.
select * from process_events where path like '%bin/open%' and cmdline like '%/tmp/%' and cmdline like '%.pdf%'
The above queries can be easily launched on historical data using Uptycs by selecting the global query mode as shown in the figure below.
I hope the above analysis helps to demonstrate how powerful osquery can be for macOS threat hunting. Active hunting on a single machine can be done with the free, open source agent while active and passive hunting at scale will require some additional tooling.
Learn more about osquery:
Subscribe for new posts
- Building Your Cyber Security Strategy: A Step-By-Step Guide
- SOC 2 Compliance Requirements: Essential Knowledge For Security Audits
- Osquery: What it is, how it works, and how to use it
- IcedID campaign spotted being spiced with Excel 4 Macros
- 8 Docker Security Best Practices To Optimize Your Container System