美文网首页
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