Of late, adware is becoming the most prevalent threat to the macOS platform. Some of these are also beginning to extend their boundaries even further, by exhibiting functionalities nearly equivalent to that of a malware. This blog gets into the nuances about one such adware, the infamous OSX.Pirrit, which has been soaring in cyberspace these days and exhibiting malware like features. This adware is known for its  notorious activities like creating hidden users, redirecting traffic through a proxy, etc. We were however intrigued by this recent Pirrit variant which used techniques to hinder the analysis process, as these traits were not even observed in advanced macOS threats.

We started our research when a user posted in the official Apple Support community complaining about the annoying pop-ups on his Mac machine, running the latest version of Catalina. The user also posted that the system information report contained an entry to a suspicious application named AppAssitDaemon.app, which was also unsigned and it also had the LaunchDaemons entry, which is a way of gaining persistence.  


We searched for similar files in our database and found one which was a 64-bit Mach-O executable. Upon inspecting the code, we realised that a few well-known obfuscation techniques were being used in that binary. Looking at the functions statically would have yielded nothing as it was using some kind of a protector, which needed to be dealt with before we actually found something interesting in its code.

On deeper analysis, we noticed the following techniques being employed which would be explained in detail later.

  • Control Flow Flattening
  • Dynamic Method Resolving 
  • Anti-VM technique

Control Flow Flattening

The function control flow in the binary was obfuscated using a control flow flattening technique where the program flow is distributed as horizontal code snippets which makes it difficult for analysis. The program flow is controlled by a switch-case which starts at the dispatcher node as highlighted in red in Figure 1, where an artificial variable is assigned to a register and undergoes a series of comparisons which alter the control flow. The green highlighted blocks are the original code blocks. 

Figure 1: Control Flow Graph

Dynamic Method Resolving

We used the class dump tool to generate the objective C class declarations which would give us better insights on the capabilities of the binary. While some classes had only initialize methods as shown in the  image below, we later found that the methods to the classes were added dynamically providing another layer of obfuscation.

Figure 2: Class Dump

In particular, the initialize class method of each class adds other methods during runtime by using two objective C functions:
1) sel_registerName which registers the method name
2) class_replaceMethod which replaces the implementation of a method for a given class. If the original method identified by the name does not exist then class_addMethod function is called which adds a new method to the class.

In the image below, the execute method is added to ShExecutor class. First, a method name execute is registered using the sel_registerName function. The implementation of the method is added by calling class_replaceMethod. These above mentioned objective C functions are also resolved dynamically. It’s done by using dlopen and dlsym functions which are similar to LoadLibrary and GetProcAddress APIs in the Windows OS. 

Figure 3: Disassembly of + [ShExecutor initialize] method

Anti-VM Technique

One variant had code to detect execution in a VM by using the ioreg command and looking for strings like VirtualBox, Oracle, VMware and Parallels. 

Figure 4: Dumping the shell command which is executed (LLDB debugger view)

AppAssistDaemon had the capabilities to execute shell commands and scripts.  The writeScriptToFile method of the ShExecutor class is responsible for the execution of a bash script which is obtained from the server after posting the victim’s Mac hardware UUID (Universally Unique Identifier). The bash script downloads a tar archive that contains another Mach-O executable. 

Figure 5: Dumping the bash script (LLDB debugger view)

The second Mach-O executable’s symbols are obfuscated and it seems the binary was packed with PreEmptive Protector.  It downloads an AES encrypted data blob from what appears to be a C&C. Upon decryption, a bash script of 400 lines is obtained, which is the Pirrit adware script. This script is created as a sub-process using the NSTASK class and the receiver’s executable is “/bin/sh”.

Figure 6: Symbols and decompiled code view of the second Mach-O binary

Basically the shell script downloads components that inject ads into the browser, which is behaviour resembling Pirrit’s previous campaign as documented by Amit Serper. The script downloads a tar archive which contains a Macver binary which executes an Apple script to inject JavaScript into the browser. The screenshot below shows a browser redirection to download the MacKeeper application with a bogus alert.  

Figure 7: Browser redirection to  the landing page of MacKeeper application with a bogus alert

Project Yolik

Continuing our research, we searched for earlier variants of Pirrit and found a string in the file which was in plain text revealing the username and the development environment of the project. The project name was “Yolik” which led us to the “http://yolik.net” website.

Fig 8: Development environment for Yolik project

The need of the hour is for users to follow good security hygiene.  Use a reputed security software such as K7 Antivirus for Mac which not only protects against the latest threats but is also proactive enough to safeguard the users against possible future threats.

Like what you're reading? Subscribe to our top stories.

If you want to subscribe to our monthly newsletter, please submit the form below.