# Objective-See's Blog
**objective-see.com/blog/blog_0x62.html**
Arm'd & Dangerous
malicious code, now native on apple silicon
by: Patrick Wardle / February 14, 2021
š š¾ Want to play along?
[Iāve uploaded a sample (password: infect3d).](https://objective-see.com/downloads/blog/blog_0x62/GoSearch.zip)
...please donāt infect yourself!
## Background
[Thanks to the amazing support of the āFriends of Objective-Seeā (such as](https://objective-see.com/friends.html) [Jamf and](https://www.jamf.com/?utm_source=objective-see&utm_medium=sponsored-link&utm_campaign=next-gen-security&utm_content=2021-02-05_protect)
[1Password) and my amazing patrons, I recently was able to step down from my 9-5 job to](https://1password.com/?utm_medium=parnter&utm_source=Objective-See&utm_campaign=gp&utm_content=sponsorship)
focus exclusively on all things Objective-See, including:
[š Objective-Seeās free, open-source tools](https://objective-see.com/products.html)
[š The free, āThe Art of Mac Malwareā book series](https://taomm.org/)
[š„ The community focused āObjective by the Seaā Mac security conference](https://objectivebythesea.com/v4/)
One of my main focuses has been working to (re)build all of Objective-Seeās tools to run
[natively on Appleās new M1 systems. For example LuLu now runs natively on Apple Silicon:](https://objective-see.com/products/lulu.html)
LuLu, now native on Apple Silicon (M1).
M1 (aka āApple Siliconā) is Appleās new (system on a) chip. As an arm-based SoC, the CPU
supports an `arm64 ( AArch64 ) instruction set architecture (ISA).`
-----
The arm64 binary file format has been used by Apple s iOS and tvOS for many years.
Thus, in order for a binary to natively run on an M1 system (2021 MacBook Air, MacBook
Pro, etc.) it must be compiled as an Mach-O 64-bit arm64 binary ā¦which means developers
must (re)compile their applications.
āBut wait!ā you might say, āI know can still run many older applications on my shiny new M1
_system!?ā. And you are correct! Apple (wisely) realized that ābackwards compatibilityā was_
essential to ensure wide-spread customer adoption of their new M1 Mac systems ā¦and thus
released Rosetta(2).
"
Rosetta is a translation process that allows users to run apps that contain x86_64
instructions on Apple silicon. "
To the user, Rosetta is mostly transparent. If an executable contains only Intel
instructions, macOS automatically launches Rosetta and begins the translation
process. When translation finishes, the system launches the translated executable in
place of the original. However, the translation process takes time, so users might
perceive that translated apps launch or run more slowly at times.
The system prefers to execute an app's arm64 instructions on Apple silicon." -Apple
As noted in the quotation above, Rosetta will transparently translate `x86_64 (Intel)`
instructions into native `arm64 instruction so older applications can run (almost) seamlessly`
on M1 systems.
However two points to note:
Non- arm64 code will not run natively on M1 systems (the CPU only āspeaksā `arm64 )`
ā¦it has to be translated first!
As `arm64 code does not have to be translated, applications (re)compiled for M1 will`
run natively, and thus faster. And wonāt be subject to any issues or nuances of Rosetta.
For more information on M1 and Rosetta, see Apple's documentation:
[About the Rosetta Translation Environment.](https://developer.apple.com/documentation/apple_silicon/about_the_rosetta_translation_environment)
Based on the fact that native ( arm64 ) applications run faster (as they avoid the need for
runtime translation), and that Rosetta (though amazing), has a few bugs (that may prevent
certain older apps from running), developers are wise to (re)compile their applications for
M1!
-----
```
1Process: oahd helper [36752]
2Path: /Library/Apple/*/oahd-helper
3Identifier: oahd-helper
4Version: 203.13.2
5Code Type: ARM-64 (Native)
6Parent Process: oahd [506]
7Responsible: oahd [506]
8User ID: 441
9
10Date/Time: 2021-02-12 10:34:15.107 -1000
11OS Version: macOS 11.1 (20C69)
12
13Crashed Thread: 0 Dispatch queue: com.apple.main-thread
```
Lost in Translation ...a Rosetta(2) Crash.
...hence why I'm working on (re)compiling all of Objective-See's tools to natively run on M1!
## Identifying Native M1 Code
As I was working on rebuilding my tools to achieve native M1 compatibility, I pondered the
possibility that malware writers were also spending their time in a similar manner. At the end
of the day, malware is simply software (albeit malicious), so I figured it would make sense
that (eventually) weād see malware built to execute natively on Apple new M1 systems.
Before going off hunting for native M1 malware, we need have to answer the question, āHow
_can we determine if a program was compiled natively for M1?ā Well, in short, it will contain_
```
arm64 code! OK, and how do we ascertain this?
```
One simple way is via the macOSās built-in `file tool (or` `lipo -archs ). Using this tool,`
we can examine a binary to see if it contains compiled `arm64 code.`
Letās look at Objective-Seeās [LuLu:](https://objective-see.com/products/lulu.html)
```
% file /Applications/LuLu.app/Contents/MacOS/LuLu
LuLu.app/Contents/MacOS/LuLu: Mach-O universal binary with 2 architectures:
[x86_64:Mach-O 64-bit executable x86_64] [arm64:Mach-O 64-bit executable arm64]
LuLu.app/Contents/MacOS/LuLu (for architecture arm64): Mach-O 64-bit executable
arm64
LuLu.app/Contents/MacOS/LuLu (for architecture x86_64): Mach-O 64-bit executable
x86_64
```
As LuLu has been rebuilt to natively run on M1 systems, we can see it contains `arm64`
code (" Mach-O 64-bit executable arm64 ").
In order to maintain compatibility with older non-M1 systems, LuLu also contains native Intel
(x86_64) code.
A binary that contains code to run on multiple architectures (e.g. Intel and Apple Silicon), is
called a "Universal" or (more traditionally) a "fat" binary.
-----
At run time, macOS will automatically select the correct (native) architecture.
On the other hand, programs that have not been (re)built for M1 systems, will not have the
any `arm64 code within them. For example, letās look at` [BlockBlock (which Iāve yet to](https://objective-see.com/products/blockblock.html)
recompile):
```
% file BlockBlock.app/Contents/MacOS/BlockBlock
BlockBlock.app/Contents/MacOS/BlockBlock: Mach-O 64-bit executable x86_64
```
As BlockBlock currently on contains Intel ( x86_64 ) code, it will not run natively on M1
systems ā¦and instead will have to be translated at runtime via Rosetta(2) in order to
execute.
Ok, so now we know what how to identify if program has been natively build to M1 systems.
Time to go hunting!
## Malicious Code ā¦now Armād?
Since Iām an independent macOS security researcher, I donāt have access private or
[proprietary malware collections or feeds. Luckily VirusTotal is generous enough to offer (free)](https://www.virustotal.com/gui/home/search)
researcher accounts. Mahalo! ļæ½
VirusTotal also supports a wide range of search modifiers, that will be essential in our hunt
for malicious (native M1) code.
[Consulting their documentation, we find several relevant search modifiers, including:](https://support.virustotal.com/hc/en-us/articles/360001385897-File-search-modifiers)
```
macho (type)
```
The file is a `Mach-O (Apple) executable.`
```
arm (tag)
```
The file contains `ARM code/instructions.`
```
64bits (tag)
```
The file contains `64-bit code`
```
multi-arch (tag)
```
The file contains support for multiple architectures (i.e. its a universal/fat binary).
```
signed (tag)
```
The file is signed.
From these we can craft a query that should give us a list of candidate files.
Some of the aforementioned tags are used simply to pare down the list (but might incur false
negatives).
-----
For example, it seems reasonable to assume that if malware authors are natively compiling
code for M1 systems this code will be found within a universal/fat binary such their malicious
creations will retain compatibility with older (Intel-based). As such, we leverage the āmultiarchā tag. Similarly since M1 systems will be running Big Sur which requires code to be
signed, we assume the malware will be signed (and thus leverage the āsignedā tag).
Of course just combining these tags will yield tens of thousands of results, as there are a ton
of legitimate multi-architecture `Mach-O binaries! So, letās add another search query to look`
for binaries that are flagged by at least two anti-virus engines. (Yes, this will limit us to known
malware, but the assumption is that as weāre looking at universal binaries, the detection will
likely be due to the Intel code).
As such, our final search query is: `type:macho tag:arm tag:64bits tag:multi-arch`
```
tag:signed positives:2+
```
ā¦which results in 255 matches:
Candidate Matches.
-----
Digging thru these, many are purely iOS binaries (that true, are universal binaries, but in the
sense that they are compiled to run on multiple iOS architectures e.g. `armv7,` `armv64 ā¦`
not macOS). A quick triage indicates these iOS files are largely flagged due to their relation
to jailbreaks, and/or are known iOS malware:
A (known) iOS Jailbreak Sample.
I didn't find a way to create a search that would filter out iOS binaries. Though VirusTotal
supports tags such as "iPhone" and "iOS" and inversion logic (e.g. "NOT tag:iPhone"), these
weren't applicable as the files themselves had not been tagged with these tags.
If you have suggestion how to create a search query that ignores iOS files, Iād love to learn
how!
Skipping over the iOS binaries, we soon find a promising candidate, a file named
```
GoSearch22 ( SHA-256:
b94e5666d0afc1fa49923c7a7faaa664f51f0581ec0192a08218d68fb079f3cf ):
```
-----
A Promising Candidate!
ā¦is this malicious code compiled to run natively on Appleās new M1 systems?
## Triaging GoSearch22
First, letās confirm this indeed is a macOS (vs. iOS) binary ā¦that can run natively on M1
systems:
```
$ file GoSearch
GoSearch: Mach-O universal binary with 2 architectures:
[x86_64:Mach-O 64-bit executable x86_64] [arm64:Mach-O 64-bit executable arm64]
GoSearch (for architecture x86_64): Mach-O 64-bit executable x86_64
GoSearch (for architecture arm64): Mach-O 64-bit executable arm64
```
So far, looks good! Itās universal (fat) Mach-O binary, that supports both Intel ( x86_64 ) and
Apple Silicon ( arm64 ). However to be sure, letās track down the full application bundle, and
check its `Info.plist file.`
Thanks to VirusTotalās āRelationsā logic, we can track down the binaryās parent ā¦a full
[application bundle, unsurprisingly named GoSearch22.app.](https://www.virustotal.com/gui/file/6a79efe8e690d18292c2f47b33f7001d9adde6439a4be981232a757c5d12f611/details)
First, letās double check the standalone binary we uncovered matches the binary in the
application bundle:
```
% shasum -a256 GoSearch22.app/Contents/MacOS/GoSearch22
b94e5666d0afc1fa49923c7a7faaa664f51f0581ec0192a08218d68fb079f3cf
% shasum -a256 GoSearch/GoSearch
b94e5666d0afc1fa49923c7a7faaa664f51f0581ec0192a08218d68fb079f3cf
```
ā¦as expected they match. This is good news, as having a full application bundle (vs. just the
applicationās binary) provides a wealth of additional information.
-----
For example in the application s `Info.plist file, we can confirm that indeed this is an`
application, compatible with macOS (not iOS):
```
% cat GoSearch/GoSearch22.app/Contents/Info.plist
CFBundleExecutable
GoSearch22
CFBundleIdentifier
com.GoSearch22
CFBundleInfoDictionaryVersion
6.0
CFBundleName
GoSearch22
CFBundlePackageType
APPL
CFBundleShortVersionString
1.0
CFBundleSupportedPlatforms
MacOSX
CFBundleVersion
146
LSMinimumSystemVersion
10.12
LSMultipleInstancesProhibited
LSUIElement
NSAppTransportSecurity
NSAllowsArbitraryLoads
NSPrincipalClass
NSApplication
```
ā¦specifically note that the `CFBundleSupportedPlatforms key is set to an array containing`
(only) `MacOSX .`
Hooray, so weāve succeeding in finding a macOS program containing native M1 ( arm64 )
code ā¦that is detected as malicious! This confirms malware/adware authors are indeed
working to ensure their malicious creations are natively compatible with Appleās latest
hardware. ļæ½
-----
It is also important to note that `GoSearch22 was indeed signed with an Apple developer ID`
( hongsheng yan ), on November 23rd, 2020:
Signed w/ an Apple Developer ID.
ā¦what is not known is if Apple notarized that code. We cannot answer this question,
because at this time Apple has (now) revoked the certificate:
-----
Certificate, now Revoked.
What we do know is as this binary was detected in the wild (and submitted by a user via an
Objective-See tool) ā¦so whether it was notarized or not, macOS users were infected.
As Apple has revoked the certificate, the malicious application will no longer run on macOS
(unless of course, the attackers re-sign it with another certificate).
Looking at the (current) detection results (via the anti-virus engines on VirusTotal), it appears
the `GoSearch22.app is an instance of the prevalent, yet rather insidious, āPirritā adware:`
Detections: Pirrit
[In a (guest) blog post in 2016, Amit Serper dove into Pirrit:](https://twitter.com/0xAmit)
-----
[Analysis of an Intrusive Cross-Platform Adware; OSX/Pirrit. ...although it should be noted](https://objective-see.com/blog/blog_0x0E.html)
that since then, it has evolved significantly.
This version/variant of `Pirrit appears to:`
persist a launch agent
install itself as a malicious Safari extension.
As this adware is rather well known, we wonāt dig into it too much (today) ā¦though we will
note it implements various anti-analysis logic. For example, anti-debugging logic:
```
10000000100054118 movz x0, #0x1a
2000000010005411c movz x1, #0x1f
30000000100054120 movz x2, #0x0
40000000100054124 movz x3, #0x0
50000000100054128 movz x16, #0x0
6000000010005412c svc #0x80
```
In the above `arm64 disassembly, the malicious code is invoking` `ptrace ( 0x1a ) via a`
supervisor call ( SVC #0x80 ), with the `PT_DENY_ATTACH ( 0x1f ) flag. This attempts to`
prevent debugging, or if being debugged, will cause the program to terminate.
The malicious code also attempts to detect if its running in virtual machine by looking for
various virtual machine āartifactsā:
```
# ProcessMonitor.app/Contents/MacOS/ProcessMonitor -pretty
{
"event": "ES_EVENT_TYPE_NOTIFY_EXEC",
"process": {
"name": "bash",
"path": "/bin/bash",
"arguments": ["/bin/sh", "-c", "readonly
VM_LIST=\"VirtualBox\|Oracle\|VMware\|Parallels\|qemu\";is_hwmodel_vm(){ ! sysctl -n
hw.model|grep \"Mac\">/dev/null;};is_ram_vm(){(($(($(sysctl -n hw.memsize)/
1073741824))<4));};is_ped_vm(){ local -r ped=$(ioreg -rd1 -c
IOPlatformExpertDevice);echo \"${ped}\"|grep -e \"board-id\" -e \"product-name\" -e
\"model\"|grep -qi \"${VM_LIST}\"||echo \"${ped}\"|grep \"manufacturer\"|grep -v
\"Apple\">/dev/null;};is_vendor_name_vm(){ ioreg -l|grep -e \"Manufacturer\" -e
\"Vendor Name\"|grep -qi \"${VM_LIST}\";};is_hw_data_vm(){ system_profiler
SPHardwareDataType 2>&1 /dev/null|grep -e \"Model Identifier\"|grep -qi
\"${VM_LIST}\";};is_vm(){
is_hwmodel_vm||is_ram_vm||is_ped_vm||is_vendor_name_vm||is_hw_data_vm;};main(){
is_vm&&echo 1||echo 0;};main \"${@}\""],
...
}
}
```
Before wrapping up this section on triaging the malicious application, letās briefly focus on the
browser extension component. First, note that application bundle contains a plugin,
```
GoSearch22 Extension.appex :
```
-----
GoSearch22's Extension.
Below is the (abridged) the `Info.plist file of the plugin ( GoSearch22`
```
Extension.appex/Contents/Info.plist ):
```
-----
```
% cat GoSearch22 Extension.appex/Contents/Info.plist
CFBundleDisplayName
GoSearch22 Extension
CFBundleExecutable
GoSearch22 Extension
CFBundleIdentifier
com.GoSearch22.Extension
...
NSExtension
NSExtensionPointIdentifier
com.apple.Safari.extension
NSExtensionPrincipalClass
SafariExtensionHandler
SFSafariContentScript
Script
script.js
...
SFSafariWebsiteAccess
Allowed Domains
*
Level
All
```
From the pluginās `Info.plist file, itās clear itās a Safari browser extension. And looking at`
the value specified by the `SFSafariContentScript key, we can see its logic is contained`
in the `script.js file:`
-----
GoSearch22's Extension Script.
The script is unsurprisingly heavily obfuscated:
```
% cat "GoSearch22 Extension.appex/Contents/Resources/script.js"
var a0a=['wr0bRjtVP8KbeFo=','LMOPwqMwNg==','wpfDqMOtw4Rtw6s=','wrpFw5rDhMOG',
'XFtr','YcOmw41Mw6U=','wqAWwrHCryXDngUnw5fCrg==','CCo/biE=','w77DhiTDsV4=',
'wpdLw4jCv8Ok','w60Ow5fDrRA=','MsOIwqYPPn7DmnzDvMO8','a8OQw5low45iw4s=',
'wrhyw5jCusK1JSdfw5dy','wr1Jw6XCpMKS','w70QGMKowrk=','w44hw4/DkjU=',
'Zgd8wrnDgw==','AMKGHHbCvw==','wqoNw4xkwoU=','w4oSFmhE','AsKoY8Or','WsOTwo/D
...
f7;}else{if(a0b('0x169','Lv[Q')===a0b('0x106','uAqz')){f6['bDFeq'](f7,0x0);}
else{var fM=document[a0b('0x210','j]sZ')];fM&&f6[a0b('0x76','2PcE')](f6[a0b(
'0x21','TrXZ')],fM[a0b('0xf3','BKpl')][a0b('0x97','uAqz')])&&window[a0b('0xd'
,'tvLM')][a0b('0x1e3','[egw')](location[a0b('0x1bc','TpDR')]);}}}catch(fN){}}
```
[Online sources, note](https://www.pcrisk.com/removal-guides/19782-gosearch22-virus-mac) `GoSearch22 performs standard adware-type behaviors:`
-----
_When users have apps like GoSearch22 installed on a browser and/or the operating_
_system, they are forced to occasionally see coupons, banners, pop-up ads, surveys,_
_and/or ads of other types. Quite often ads by apps like GoSearch22 are designed to_
_promote dubious websites or even download and/or install unwanted apps by_
_executing certain scripts. Moreover, adware-type apps like GoSearch22 tend to be_
_designed to collect browsing data. For instance, details like IP addresses, addresses of_
_visited web pages, entered search queries, geolocations, and other browsing-related_
_information."_
```
GoSearch22 in the Wild
```
In terms of this specific (M1-native) specimen, we can see it was originally submitted to
VirusTotal at the end December 2020:
Initial Submission.
Rather awesomely, if we analyze details of the VirusTotal submission, it turns out this sample
[was submitted (by a user) directly through one of Objective-Seeās tools (likely KnockKnock)](https://objective-see.com/products/knockknock.html)
ā¦after the tool flagged the malicious code, due to its persistence mechanism:
GoSearch22, Detected via Objective-See.
## Why This All Matters
-----
Today we confirmed that malicious adversaries are indeed crafting multi-architecture
applications, so that their code will natively run on M1 systems. The malicious `GoSearch22`
application may be the first example of such natively M1 compatible code.
The creation of such applications is notable for two main reasons.
First, (and unsurprisingly), this illustrates that malicious code continues to evolve in direct
response to both hardware and software changes coming out of Cupertino. There are a
myriad of benefits to natively distributing native `arm64 binaries, so why would malware`
authors resist?
Secondly, and more worrisomely, (static) analysis tools or anti-virus engines may struggle
with `arm64 binaries. In a simple experiment, I separated out the` `x86_64 and` `arm64`
binaries from the universal `GoSearch22 binary (using macOS built-in` `lipo utility):`
```
% lipo GoSearch22 -thin x86_64 -output GoSearch22_ARM64
% lipo GoSearch22 -thin arm64 -output GoSearch22_X86_64
% file ~/Desktop/GoSearch22_*
GoSearch22_ARM64: Mach-O 64-bit executable x86_64
GoSearch22_X86_64: Mach-O 64-bit executable arm64
```
I then uploaded both (the now separated) binaries to VirusTotal and initiated scans of each.
In theory both binaries would be detected at the same rate, as they both contain the same
logically equivalent malicious code.
[Unfortunately detections of the arm64 version dropped roughly 15% (when compared to the](https://www.virustotal.com/gui/file/a0d34d3f767078c34fbc72e8cb02aa99196e2136fa88d633f66f717892759e3b/detection)
[standalone x86_64 version).](https://www.virustotal.com/gui/file/e60ca9d6073dd942207bb8acaee980ed4284e6471a6de32a633a5ce26c9e8964/detection)
ā¦several industry leading AV engines (who readily detected the `x86_64 version) failed to`
flag the malicious `arm64 binary. š¢`
Some AV engines that (correctly) flag both the x86_64 and arm64 binaries, however present
differing names for their detections, of what logically is the same file.
For example, Trojan:MacOS/Bitrep.B vs. Trojan:Script/Wacatac.C!ml
...such naming confusions, may indicate inconsistencies when processing the differing binary
file formats.
## Conclusions
Appleās new M1 systems offer a myriad of benefits, and natively compiled `arm64 code runs`
blazingly fast. Today, we highlighted the fact that malware authors have now joined the ranks
of developers ā¦(re)compiling their code to `arm64 to gain natively binary compatibility with`
Appleās latest hardware.
-----
Specifically, we highlighted a `Pirrit variant ( GoSearch22.app ) that was first discovered`
and submitted thanks to Objective-Seeās free, open-source tools!
And while the `x86_64 and` `arm64 code appears logically identical (as expected), we`
showed that defensive security tools may struggle to detect the `arm64 binary š„`
š The Art of Mac Malware
If this blog posts pique your interest, definitely check out my new book on the topic of Mac
Malware Analysis:
["The Art Of Mac Malware: Analysis"](https://taomm.org/)
...it's free online, and new content is regularly added!
## š Support Us:
[Love these blog posts? You can support them via my Patreon page!](https://www.patreon.com/bePatron?c=701171)
-----