# 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) -----