美文网首页
fuckadblock插件的分析与绕过

fuckadblock插件的分析与绕过

作者: 烤土豆啦 | 来源:发表于2018-10-31 16:29 被阅读0次

fuckadblock插件的分析与绕过

0x01 简介

最近在访问csdn的时候,总是弹出您正在使用adblock。我日你娘,老子用插件还烦我?于是打开F12,开始分析一波


1.png

我认为吧,对于这种js,chrome动态打断点+静态分析,多锻炼自然会了。权当抛砖引玉啦,大神们看看就好

0x02 check-adblock.js

这个js的内容比较短,直接贴出代码就好

!
function() {
    var c, e;
    function t() {
        console.log("AdBlock is not enabled")
    }
    function n() {
        var c, e, t;
        console.log("Adblock is enabled"),
        c = "adblock",
        e = {
            step: "install"
        },
        t = window.location.protocol + "//statistic.csdn.net/",
        $.get(t + c, e);
        var n; !
        function() {
            var c = document.createElement("div");
            c.innerHTML = '<div class="adblock"><img src="https://g.csdnimg.cn/check-adblock/1.0.0/img/monkey@2x.png"/><span>亲爱的用户,您使用了广告屏蔽软件,广告是CSDN向您免费提供服务与产品的重要支持,希望您将csdn.net加入AdBlock Plus<a class="check_a" href="https://bbs.csdn.net/topics/392458005" target="_blank">白名单</a>,感谢支持!</span><em class="check_close"><svg t="1539053811268" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7199" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M512 438.378667L806.506667 143.893333a52.032 52.032 0 1 1 73.6 73.621334L585.621333 512l294.485334 294.485333a52.074667 52.074667 0 0 1-73.6 73.642667L512 585.621333 217.514667 880.128a52.053333 52.053333 0 1 1-73.621334-73.642667L438.378667 512 143.893333 217.514667a52.053333 52.053333 0 1 1 73.621334-73.621334L512 438.378667z" fill="#8a8a8a" p-id="7200"></path></svg></div>';
            var e = document.body.firstChild;
            document.body.insertBefore(c, e)
        } (),
        $(".check_close").length && $(".check_close").on("click",
        function(c) {
            c.stopPropagation(),
            $(this).parents(".adblock").remove(),
            "function" == typeof window.csdn.insertcallbackBlock && window.csdn.insertcallbackBlock()
        }),
        (n = new Date).setDate(n.getDate() + 7),
        document.cookie = "c_adb=1; expires=" + n.toGMTString() + "; domain=csdn.net; path=/",
        "function" == typeof window.csdn.insertcallbackBlock && window.csdn.insertcallbackBlock()
    }
    if (void 0 === window.csdn && (window.csdn = {}), c = "https://g.csdnimg.cn/check-adblock/1.0.8/css/check-adblock.css", (e = document.createElement("link")).rel = "stylesheet", e.type = "text/css", e.href = c, document.getElementsByTagName("head")[0].appendChild(e), "undefined" != typeof fuckAdBlock || "undefined" != typeof FuckAdBlock)
         n();
    else {
        var o = document.createElement("script");
        o.onload = function() {
            fuckAdBlock.onDetected(n),
            fuckAdBlock.onNotDetected(t)
        },
        o.onerror = function() {
            n()
        },
        o.type = "text/javascript",
        o.src = "https://g.csdnimg.cn/lib/fuckadblock/3.2.1/fuckadblock.min.js",
        document.head.appendChild(o)
    }
} ();

这个js会运行(废话)。函数t与函数n的作用很明显,t是未检测到adblock时运行的函数,函数n时检测到adblock时运行的函数。在函数t中,主要行为是:

  1. 访问https://statistic.csdn.net/adblock?step=install,推测是上报并统计adblock的数量
  2. 在网页最顶端创建一个div,用以提示用户,你正在使用adblock
  3. 创建一个key为c_adb的cookie

该函数首先会从第33行的if开始运行。而且,那行比较长的代码,其实都是if中判断语句。

void 0 === window.csdn && (window.csdn = {}), c = "https://g.csdnimg.cn/check-adblock/1.0.8/css/check-adblock.css", (e = document.createElement("link")).rel = "stylesheet", e.type = "text/css", e.href = c, document.getElementsByTagName("head")[0].appendChild(e), "undefined" != typeof fuckAdBlock || "undefined" != typeof FuckAdBlock

按照逗号,一个一个的执行,然后检查fuckAdBlock这个对象。
这行作用是,创建一个adblock一定会拦截的css,然后检查。如果检测到fuckAdBlock这个对象,说明存在adblock,然后提示用户。这个判断主要是在页面完全加载后,如果再有判断adblock的任务,则无需调用检测,直接就可以完成。

如果是页面刚加载的时候,是会绕过这个if的。所以,会创建一个script标签,src是fuckadblock的代码。然后创建一个onload事件,去调用fuckAdBlock。

0x03 fuckadblock.min.js

这个代码有点长,直接截图分析吧。。。

这个代码会创建一个FuckAdBlock的类,也就是图中的e。首先会执行构造函数(深受java荼毒,不太会描述)。设置window的onload事件,也就是等待页面加载完之后再执行check函数。在onload的o函数中,再延迟1秒钟执行check函数,推测是为了更准确的检测adblock,防止出现页面未加载完而导致的判断失效。


2.png

然后开始分析check函数。check函数混淆的比较严重,我精简了一下。该函数的主要作用是:

  1. 调用_checkBait创建一个页面上不可见,但是一定会被adblock拦截的div
  2. 调用setTimeout,设置1秒钟后调用_checkBai函数,检测刚才创建的div对象是否还存在。

我们可以通过动态调试的方式,看一下_checkBait所创建的div是什么样子的。


3.png
1. _checkBai函数
4.png

这个嘛,先通过getComputedStyle获取刚才创建的div的css,然后对比一下。然后调用emitEvent返回结果。
可以看一下if语句中的内容

null !== t.document.body.getAttribute("abp") || null === this._var.bait.offsetParent || 0 == this._var.bait.offsetHeight || 0 == this._var.bait.offsetLeft || 0 == this._var.bait.offsetTop || 0 == this._var.bait.offsetWidth || 0 == this._var.bait.clientHeight || 0 == this._var.bait.clientWidth) && (i = !0), void 0 !== t.getComputedStyle

如果找到创建的这个div对象,说明没有adblock。设置变量i为false。否则,就是已经被adblock拦截。设置i为true。在最后一行代码,判断i,并调用emitEvent。

2. emitEvent函数
    e.prototype.emitEvent = function (t) {
        this._options.debug === !0 && this._log("emitEvent", "An event with a " + (t === !0 ? "positive" : "negative") + " detection was called");
        var e = this._var.event[t === true ? "detected" : "notDetected"];
        for (var i in e) this._options.debug === !0 && this._log("emitEvent", "Call function " + (parseInt(i) + 1) + "/" + e.length),
            e.hasOwnProperty(i) && e[i]();
        return this._options.resetOnEnd === !0 && this.clearEvent(),
            this
    }

该函数作用根据上一步的结果,调用相应的函数。可以看一下this._var.event里面的内容。如图


5.png

可以明了哇,如果detected有多个函数的话,则分别调用。有点像观察者模式了。那么现在有个疑问,detected是啥时候设置的呢?我们要回到开头check-adblock.js中创建script时设置的onload时间

fuckAdBlock.onDetected(n),
fuckAdBlock.onNotDetected(t)

然后看一下fuckAdBlock.onDetected函数

    e.prototype.on = function(t, e) {
        return this._var.event[t === !0 ? "detected": "notDetected"].push(e),
        this._options.debug === !0 && this._log("on", 'A type of event "' + (t === !0 ? "detected": "notDetected") + '" was added'),
        this
    },
    e.prototype.onDetected = function(t) {
        return this.on(!0, t)
    },
    e.prototype.onNotDetected = function(t) {
        return this.on(!1, t)
    },

主要是根据相应的事件,添加到对应的数组里,其中,e.prototype.on的第一行代码this._var.event[t === !0 ? "detected": "notDetected"].push(e)中的push是关键,其中,e是对应事件的处理函数。

至此,就分析完流程了。下面讲一下如何bypass

0x04 tampermonky插件

tampermonky插件可以通过安装各类脚本对网站进行定制。我们只需要写一个脚本就行啦。

  1. 右键添加新脚本


    6.png
  2. 在弹出的界面中输入以下代码

        
        // ==UserScript==
    // @name         Fuck FuckAdblock
    // @namespace    http://tampermonkey.net/
    // @version      0.1
    // @description  try to take over the world!
    // @author       Potatso
    // @match        *://blog.csdn.net/*
    // match 是设置该脚本适用的网站
    // @grant        none
    // ==/UserScript==
    
    (function() {
        'use strict';
        // 等待window加载完,将FuckAdBlock的check函数替换为我们自己的函数
        window.addEventListener('load', function() {
            FuckAdBlock.prototype.check = function(t) {}
        }, false);
    })();
    
  3. 然后点击文件,保存即可


    7.png

检查一下,完成

8.png

相关文章

网友评论

      本文标题:fuckadblock插件的分析与绕过

      本文链接:https://www.haomeiwen.com/subject/hxiatqtx.html