吾愛破解 - LCG - LSG |安卓破解|病毒分析|破解軟件|www.pyclye.live

 找回密碼
 注冊[Register]

QQ登錄

只需一步,快速開始

搜索
查看: 20407|回復: 241
上一主題 下一主題

[調試逆向] 簡書網頁劫持分析,使用 Chrome DevTools 調試 JavaScript 技巧,利用 CSP 預防劫持

    [復制鏈接]
跳轉到指定樓層
樓主
Ganlv 發表于 2019-12-9 06:26 回帖獎勵
本帖最后由 Ganlv 于 2019-12-10 01:24 編輯

簡書網頁劫持分析,瀏覽器指紋信息,使用 Chrome DevTools 調試 JavaScript 技巧,Android Chrome 遠程調試,利用 CSP 預防劫持

CC0 Mark
本作品沒有已知的著作權限制。
本文可以隨意轉載,無需向我申請。有條件的話希望能注明原文鏈接,有任何問題可以回帖討論。

摘要

最近,每天第一次打開簡書都會跳轉到一個惡意網頁,它以瀏覽器錯誤問題引導用戶下載一個安裝包。這個安裝包安全性未知。另外打開網頁時還會自動向剪貼板中寫入一個淘口令,打開淘寶的時候會自動打開一個紅包。頁面跳轉似乎是同一個 IP 每天只有第一次會觸發,自動復制淘口令每次都會觸發。另外,惡意網頁的域名隔一段時間會更換。

經過分析得出,此問題準確來說不算是網頁劫持,而是簡書自己的一個廣告供應商的問題。惡意代碼是直接嵌入正常業務代碼的,排除了被劫持的可能。由于已經持續很長一段時間了,所以說不定是簡書默許了這個行為。此外,CSDN 似乎某些情況下也有這個問題(不確定)。

文章末尾介紹了使用 CSP (Content Security Policy) 預防頁面劫持的方法。

關鍵詞: 簡書 劫持 網頁 廣告 惡意跳轉 分析 DevTools 調試 JavaScript 指紋 Canvas Fingerprint CSP Cookie webpack

注意: 如果想知道如何劫持 HTTPS 網頁的,抱歉這里沒有,目前也不太可能出現 HTTPS 網頁劫持或證書劫持的問題。

問題引出

最近(其實已經很長時間了),每天第一次打開簡書都會跳轉到一個惡意網頁,它以瀏覽器錯誤問題引導用戶下載一個安裝包。這個安裝包安全性未知。另外打開網頁時還會自動向剪貼板中寫入一個淘口令,打開淘寶的時候會自動打開一個紅包。

頁面跳轉似乎是同一個 IP 每天只有第一次會觸發,自動復制淘口令每次都會觸發。

因為用電腦訪問并不會出現任何問題,所以我曾經一度以為是我的手機中病毒了。iOS 也不會觸發,他們似乎僅針對 Android 手機。

所以我就用電腦對網頁的腳本分析了一下,這里把分析過程分享給大家。說白了就是內嵌了一段 js 腳本(不過里面能發現很多有趣的東西)。這篇文章的主要目的也是介紹一些 JavaScript 的調試技巧。

目錄

  • 抓包
  • 分析 js 代碼依賴關系
  • 格式化代碼
  • 分析代碼邏輯與目的
  • 為什么會出現這種問題
  • 前端開發者如何預防這種問題
  • 其他相關的思考與感想

抓包

打開 Chrome 瀏覽器,按 F12 打開 Chrome DevTools(Chrome 開發者工具),切換到 Network 標簽中勾選 Preseve log,然后訪問一個簡書的網頁。

網頁是我在 Bing 上隨便找到 site:jianshu.com - 國內版 Bing

等待頁面加載完成。簡單瀏覽一下域名,看看有沒有外部腳本。

似乎 PC 端不太行,那個頁面似乎只能在安卓端觸發,這里采用一種方法模擬一下手機端。點擊開發者工具左上角的手機圖標,然后在網頁上方多出的工具欄中選擇一個 Android 機型,刷新頁面再看看。

這里有一個小技巧,右鍵列表的表頭,勾選 Domain。然后按照域名排序,你就可以輕松忽略大量相同域名的文件了。

我們似乎有意外發現,來自非簡書的域名

臥槽!這么多奇奇怪怪名字的域名,一看就不是什么好東西。這得有多少使用簡書的人被這幫惡意腳本 X 啊。

分析 js 代碼依賴關系

我們可以看到文件是這樣加載的

為了防止不必要的外鏈風險,文中所有的域名均使用下劃線 _ 代替了點 .

https://www_jianshu_com/p/bc916e388452
    https://cdn2_jianshu_io/asimov/2.c90dbb2ede007dc39cbf.js
        https://ox86_xu7b_com/m301650.js
            https://s9_cnzz_com/z_stat.php?id=1277879054&web_id=1277879054
            https://ws2_hbssjd_cn/ms/a.js?b=200473!301650!88!640!150!200&u=5!5.0!0!1!c20tZzkwMHA%3D!8!77.0.3865.75!1&c=1!0!x!6!4!1!24!640!360!0!5!0!x!1!d2luMzI%3D!1!0!0!0!0!1!3!x!d3d3LmppYW5zaHUuY29t!1!1!1!R29vZ2xlSW5jLn5BTkdMRShJbnRlbChSKUhER3JhcGhpY3M0NjAwRGlyZWN0M0QxMXZzXzVfMHBzXzVfMCk%3D!12!1!1!1!42!56!-1!-1!2585131335&f=83338
                https://s5_cnzz_com/z_stat.php?id=1277762915&web_id=1277762915
                https://vi12x_xcle_cn/sucnew/640x150/20190909sg150.png
        https://yun_lvehaisen_com/h5-mami/msdk/tmk.js
            https://engine_tuistone_com/api/v1/activity/get4web?request_id=2NQi3x8zovefyJ6WYcB8c8K2L1Zz8Jn3Haz5vKiixtlv8Swe1574800139758&app_key=2NQi3x8zovefyJ6WYcB8c8K2L1Zz&slotId=304277&device_id=8Jn3Haz5vKiixtlv8Swe1574800139758&callback=jsonp_0020308437386842737
            https://engine_tuistone_com/api/v1/activity/spm4web?slotId=304277&app_key=2NQi3x8zovefyJ6WYcB8c8K2L1Zz&device_id=8Jn3Haz5vKiixtlv8Swe1574800139758&activity_id=2000017418%2C923%2C923&sdk_type=JSSDK&sdk_version=3.3.1&sdk_source=jianshu.com&type=0&click_url=https%3A%2F%2Factivity.tuipear.com%2Factivity%2Findex%3Fid%3D17418%26slotId%3D304277%26login%3Dnormal%26appKey%3D2NQi3x8zovefyJ6WYcB8c8K2L1Zz%26deviceId%3D8Jn3Haz5vKiixtlv8Swe1574800139758%26dsm%3D1.304277.0.0%26dsm2%3D1.304277.2.17418%26tenter%3DSOW%26subActivityWay%3D48%26tck_rid_6c8%3D0acc3777k3fjua4n-4603223%26tck_loc_c5d%3Dtactivity-17418%26dcm%3D401.304277.0.923%26&data1=0acc3777k3fjua4n-4603223&data2=%7B%22clickUrl%22%3A%22%2Factivity%2Findex%3Fid%3D17418%26slotId%3D304277%26login%3Dnormal%26appKey%3D2NQi3x8zovefyJ6WYcB8c8K2L1Zz%26deviceId%3D8Jn3Haz5vKiixtlv8Swe1574800139758%26dsm%3D1.304277.0.0%26dsm2%3D1.304277.2.17418%22%2C%22materJson%22%3A%22%7B%5C%22content%5C%22%3A%5C%22%5B%7B%5C%5C%5C%22imageUrl%5C%5C%5C%22%3A%5C%5C%5C%22%2F%2Fyun.tuitiger.com%2Fmami-media%2Fimg%2Fqm1eti6pdn.gif%5C%5C%5C%22%2C%5C%5C%5C%22width%5C%5C%5C%22%3A150%2C%5C%5C%5C%22height%5C%5C%5C%22%3A150%2C%5C%5C%5C%22msItemId%5C%5C%5C%22%3A22%7D%5D%5C%22%2C%5C%22gmtCreate%5C%22%3A1503470517000%2C%5C%22gmtModified%5C%22%3A1565093474000%2C%5C%22id%5C%22%3A923%2C%5C%22md5%5C%22%3A%5C%22DVt9EZ6wUcKxAg6mAseK8n%5C%22%2C%5C%22msId%5C%22%3A22%2C%5C%22pictureGroup%5C%22%3A%5C%224%5C%22%2C%5C%22pictureSize%5C%22%3A21%2C%5C%22pictureType%5C%22%3A%5C%220%5C%22%2C%5C%22pictureVal%5C%22%3A%5C%22150*150%5C%22%2C%5C%22title%5C%22%3A%5C%22%E6%91%87%E4%B8%80%E6%91%87%5C%22%7D%22%2C%22materialId%22%3A923%2C%22sckFromType%22%3A%22null%22%2C%22sckId%22%3A923%7D&refer_host=www.jianshu.com&md=×tamp=&nonce=&signature=&connect_type=undefined&callback=jsonp_039959120667317904
            https://yun_tuitiger_com/mami-media/img/qm1eti6pdn.gif

萬惡之源都是這個 2.c90dbb2ede007dc39cbf.js,它加載了 m301650.jstmk.js 這兩個文件,似乎 tmk.js 是用來加載頁面右下角的廣告的。而另一個就是跳轉到騙人下載安裝包那個頁面。

這個 m301650.js 接入 cnzz 站長統計,看來訪問量不小,都需要分析訪客來源了。說不定分析之后還要針對性投放瀏覽器惡意下載頁面呢。

分析代碼

然后就是分析代碼的目的了。

這種明知道被 X 了,卻不知道對面在做什么的感覺很難受。我非得把它扒的一干二凈不可。

我們需要分析一下 m301650.js a.js tmk.js 這三個文件,如果有需要的話也可以分析一下 2.c90dbb2ede007dc39cbf.js,看看惡意代碼是怎樣嵌入到項目主代碼中的。

前方高能!想學技術的仔細瞧,吃瓜群眾湊個熱鬧就行了。

格式化代碼

右鍵選擇 Open in Sources panel。

點擊代碼編輯器左下角的格式化代碼按鈕。

嘗試分析代碼

然而事情并沒有那么簡單,簡單瀏覽一下就會發現,這里有很多加密后的常量,還有疑似的解碼算法。

解密字符串

這里有很多種方法,下斷點是最容易的,依賴于 Chrome 強大的調試功能,輕松就能找到解密函數。

動態調試往往比靜態分析要簡單。動態調試你能獲取到程序運行時的第一手資料,靜態調試只能靠一層層的推斷。不過動態調試可能被檢測出來,靜態調試則沒有這個問題。

方法 1:下斷點調試

  1. 先在被混淆函數 d 那一行下一個斷點
  2. 刷新頁面,重新執行一次這個函數,觸發斷點
  3. 直接在控制臺輸入被混淆的函數名 d,然后回車,調試工具會直接輸出當前上下文環境中的 d 的值。

這樣我們很容易就能找到這個解密代碼。

方法 2:嘗試搜索所有動態語句

如果我們直接找不到某個變量或函數名,那么他應該是動態生成的。

  1. 搜索 eval, new Function 動態執行語句
  2. 查找 String.fromCharCode, String.charAt 等可能動態生成標識符的函數

先搜索 eval,這種加密雖然最簡單,但對于大多數不懂的人也是足夠有效的。

二八定律處處存在,可能這個加密只是最簡單的那 20% 的加密方法,但他卻能阻止 80% 的人破解代碼。(比例不一定對,但是這種現象是經常存在的)

m301650.js 中只有一處 eval

eval(function(p, a, c, k, e, d) {
    e = function(c) {
        return c.toString(36)
    };
    if (!''.replace(/^/, String)) {
        while (c--) {
            d[c.toString(a)] = k[c] || c.toString(a)
        }
        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
}('6 d(b){5 a,c="";4(a=0;a<b.1;a+=2)c+=3.7(8(b.e(a,a+2),9));f c}', 16, 16, '|length||String|for|var|function|fromCharCode|parseInt|16|||||slice|return'.split('|'), 0, {}));

解密很簡單,把 eval(...) 括號中的部分放到控制臺執行就行了(注意括號對應關系),輸出的內容就是被加密的代碼原始的樣子。

https://tool.lu/js,這個網站可以自動解密 eval 加密的 js 代碼,把 eval(...) 粘貼進文本框,點擊 解密(Decrypt) 即可解密到源碼。你可以試試再點擊 加密(Encrypt) 你會發現加密后的源碼和我們之前看到的類似,看來這段代碼的作者也是比較偷懶,直接用現成的加密方法了。

function d(b) {
        var a, c = "";
        for (a = 0; a < b.length; a += 2) c += String.fromCharCode(parseInt(b.slice(a, a + 2), 16));
        return c
}

這就是我們要找的那個 d 函數。這個代碼很容易理解,就是一個 hex2bin 的功能,將十六進制字符串轉換為二進制字符串。

對于 JavaScript 這種動態性極強的語言,盡量還是采用第一種方式。

比如 d("7265676D6F64654669656C6431"),先加載 d 函數,然后運行這條語句就行了。

批量解密字符串

上面知道了解密函數,但是我不想手動替換每一個加密的地方,我需要把所有 d(...) 自動解密。

上重量級武器——語法解析器!我使用了 acorn 這個解析器(Parser),將 js 代碼轉換成 AST(抽象語法樹),使用 acorn-walk 對 AST 中所有對 d 函數的調用都解碼,最后再使用 escodegen 將 AST 轉換回原來的代碼。

注意:你的電腦必須安裝了 Node.js 才可以執行下面的步驟

新建一個文件夾(例如附件的 decoder/ 文件夾),進入這個文件夾。

首先安裝依賴

npm install acorn acorn-walk escodegen

然后新建一個文件(例如 index.js),并編寫代碼

const fs = require('fs');
const acorn = require('acorn');
const walk = require("acorn-walk")
const escodegen = require('escodegen');

function d(b) {
    var a, c = "";
    for (a = 0; a < b.length; a += 2) c += String.fromCharCode(parseInt(b.slice(a, a + 2), 16));
    return c
}

const content = fs.readFileSync('../samples/m301650.js');
const ast = acorn.parse(content);
walk.simple(ast, {
    CallExpression(node) {
        if (node.callee.name === 'd' && node.arguments[0].type === 'Literal') {
            node.type = 'Literal';
            node.value = d(node.arguments[0].value);
        }
    }
});
const decodedContent = escodegen.generate(ast);
fs.writeFileSync('../samples/m301650.decoded.js', decodedContent);

執行腳本

node index.js

上面的腳本會自動讀取原始代碼 ../samples/m301650.js,把解碼后的代碼寫入 ../samples/m301650.decoded.js 文件。

../samples/m301650.js 是我從之前那些鏈接手動下載的。

開始分析代碼

代碼總共不到 900 行,認真閱讀一下就會理解。

這里談談一個我個人學習時的思想。學習可以大概分兩種類型,第一種是教科書式學習,看教科書的目錄就可以明白,它交給你所有的知識點,怎么組織知識結構由你自己來做。第二種是工具書式學習,用到什么查什么,沒用到的東西雖然書上有,但是暫時不用去了解。在算法中,就類似于廣度優先搜索和深度優先搜索。在數據緩存方面,就類似 eager load(饑餓)和 lazy load(懶加載)。在學校通常是第一種方式學習,在工作中通常是第二種方式學習。

這里的代碼怎么閱讀呢?也有兩種方法,一個就是按照順序讀代碼,了解各個函數的用途,然后再分析主程序。另外一個就是直接讀主程序代碼,先了解有哪些函數,但不需要看內容,然后分析主程序,主程序中調用了哪個函數,再去看那個函數。(放在 C 語言中,頭文件就是存放那個函數聲明的地方,其他語言中的 include import require using 也是做這個用的)

圖靈機的思想就是“讀取當前的狀態→程序進行某種運算→最終寫入新狀態”。從這三個方面任意一方面開始像其他兩方面展開分析都是可以的,但是從中間向兩側分析是最簡單的。因為我們分析程序的目的就是了解程序究竟做了什么。(這個可以暫時不用理解,因為實戰中多體會幾次就會發現這樣最方便)

分析代碼時,我們通常想找出那些影響整個程序狀態的代碼。在通常意義的破解中,就是找出對系統 API 的調用(分析跨模塊調用)。在 js 中就是對瀏覽器內置的函數的調用。

這里先去除到暫時不會改變狀態的代碼(聲明性的代碼),單純的聲明變量或函數對程序是沒有影響的。程序的第一層大致是這樣的。

(function (q, p) {
    function A() {
    }
    function B(b, a, c) {
    }
    function v(b, a, c, d) {
    }
    function C(b, a) {
    }
    var n = {
    };
    B.prototype = {
    };
    A.prototype = {
    };
    n.V = 'https://ewn.hfqxjx.cn/ms/g.js';
    n.N = '301650';
    C(navigator.userAgent);
    try {
    } catch (b) {
        n.l(b, 'f_1');
    }
    var F = new function (b, a) {
    }(navigator.userAgent, n);
    q = new B(q, p, n);
    p = '';
    try {
        p = 'u=' + F.J();
    } catch (b) {
        n.l(b, 'maCal_1');
    }
    try {
        var z = q.J('kwashhhh');
        p = p + '&c=' + z.pa;
    } catch (b) {
        n.l(b, 'maCal_2');
    }
    try {
        var t = n.u('kwashhhhfgp');
        if (!t && z) {
            t = new A().get(z.qa);
            var E = new Date();
            E.setHours(48, 0, 0, 0);
            n.v('kwashhhhfgp', t, E);
        }
        t && (p = p + '!' + t + '&f=' + Math.floor(100000 * Math.random() + 1));
    } catch (b) {
        n.l(b, 'macal_3');
    }
    try {
        var _hmt = _hmt || [];
        var oscr = document.createElement('script'), osdiv = document.createElement('div');
        oscr.src = 'https://s9.#/z_stat.php?id=1277879054&web_id=1277879054';
        osdiv.style.display = 'none';
        osdiv.appendChild(oscr);
        document.body.appendChild(osdiv);
    } catch (b) {
        n.l(b, 'macal_4');
    }
    try {
        n.h('1', 'https://ewn.hfqxjx.cn/ms/a.js?b=200473!301650!88!640!150!200&' + p);
    } catch (b) {
        n.l(b, 'macal_5');
    }
})('kwashhhh', '301650'));

其中 A B v C 函數都是聲明,沒有執行,暫時不用分析。n B.prototype A.prototype 基本上不用分析,因為他們基本上只是定義變量,不會修改全局狀態。n.V = n.N = 修改的是程序的局部變量,對全局不會造成影響。

C(navigator.userAgent) 是第一個需要分析的代碼,后面的所有語句幾乎都可能與全局狀態有關,都需要分析。

等等!我們真的需要這么麻煩嗎?上面的方法適用于靜態分析,不過動態分析比靜態分析要簡單!我們只需要在程序的第一句話下斷點,然后一直單步運行就可以走完程序的邏輯了。

單步運行代碼

在 Chrome DevTools 中 F8 是繼續運行,F10 是單步步過,F11 是單步步入,Shift + F11 是執行跳出當前函數,更多快捷鍵可以在 右上角的三點 > Settings > Shortcuts > Debugger 看到。

m301650

我新建了一個 m301650.html 里面只有一句話 <script src="m301650.decoded.js"></script> 這樣我們可以打開這個本地的網頁就可以進行測試了,同時這樣也不會有其他代碼的干擾。

這個過程雖然不難,但是非常的枯燥,用文字敘述也十分麻煩,此處省略,直接給出分析結果。

這個腳本收集了 window navigator 對象提供的各種各樣的信息,例如:計算機或手機品牌型號、計算機操作系統(Windows、Linux、Mac OS、Android、iOS)、版本、CPU 核心數、瀏覽器種類(Chrome、IE、Opera、Firefox、Edge、Safari、微信、QQ、360、小米、OPPO、百度)、版本、排版引擎(WebKit、Trident、Gecko)、WEBGL 渲染引擎版本、Canvas Fingerprint、屏幕寬度、高度、色彩深度、是否支持觸摸、觸控點數、是否開啟 Cookie、是否支持 LocalStorage、SessionStorage、IndexedDB。

這個腳本最后會加載 https://ewn_hfqxjx_cn/ms/a.js 并附加上這些獲取的參數。a.js 又會做一堆事情,我們繼續分析。

a

這個 a.js 并沒有做什么過分的事情,腳本會在頁面某個位置添加一個圖片,例如下面這個頁面中間京東的廣告。

這個廣告看上去像是簡書自己添加的,不是什么惡意廣告,只是域名讓人看起來非?梢。

不過,讓我覺得很煩的是。到目前為止,我剛分析了 2 個 js 文件,就已經加載了 3 個 cnzz 的統計腳本了。我已經將 # 加入我的屏蔽域名中了。

反混淆工具

tmk

這個腳本也很復雜,也是單步調試慢慢看。在我心情煩躁時,我嘗試搜索了一下 Reverse uglify js,我發現了 http://jsnice.org 這個網站,真的跟網站域名說的一樣,Nice!

他可以自動推斷值的類型,并據此來重命名變量,例入通過 var a = document.createElement('script'),會被轉換成 var script_element = document.createElement('script')。他還會把 uglify 中常用的 &&|| 轉換成 if (xxx) 或者 if (!xxx),總之就是一個字:爽!

代碼的內容并不復雜,tmk.js 只提供了一個 TuiSDK 類,真正調用的地方在 2.c90dbb2ede007dc39cbf.js

var t = document.createElement("div");
new TuiSDK({
    container: t,
    appKey: "2NQi3x8zovefyJ6WYcB8c8K2L1Zz",
    slotId: "304277"
});

這個廣告使用 jsonp 返回數據,這個廣告 SDK 只是根據這個返回值在網頁上添加一個圖標和一個鏈接,雖然這個廣告圖片特別像那種流氓網站(下面這張圖片右下角的“送”字),但其實并沒做什么過分的事情。

不過 jsonp 不僅僅可以返回數據,還是可以植入代碼的,這個 SDK 是否可信我不太清楚,我測試的時候沒有發現 jsonp 加載惡意代碼的情況。

2

到目前為止都并沒有腳本修改跳轉鏈接,也沒有往剪貼板中寫入數據,看來問題回到了最開始調用他們的 2.js 中,難道是簡書出現了內鬼?我黑我自己?我們來分析 2.js

這個腳本沒有混淆字符串,直接搜索鏈接就可以搜索出很多可以的網址。直接搜索 //(.+?\.)+.+?/ 這個正則表達式。

  • showTui: //yun_lvehaisen_com/h5-mami/msdk/tmk.js
  • jumpTui: https://engine_seefarger_com/index/activity?appKey=44oLpJM9AkUsZMnyoGDaEZQfADeo&adslotId=296981
  • clickShengyao: https://cm_bilibili_com/mgk/page/284698023573377024/
  • insertGT: https://ad_lflucky_com/janes/js/jans.js
  • goZhangxin: http://newspool_zhangxinzhixun_com/waifangsspgrlm/s1/index.html?appKey=7271ef91d1d5113
  • insertAMC: https://ox86_xu7b_com/m301650.js
  • fetchSoHoAd: //statics_itc_cn/aap/prod/js/1.0.0/sohu_aap.js
  • .gu-pao-ad: https://www_jianshu_com/p/428251ede1aa

好多廣告,包括最后一個站內鏈接也是廣告,接廣告沒啥問題,主要是某些廣告平臺的跳轉頁面令人惡心,誰知道什么時候會下載一個病毒或流氓軟件,感覺太不靠譜了。

關于瀏覽器檢測

jans

比如那個向剪貼板寫入淘口令的就是 https://ad_lflucky_com/janes/js/jans.js。這么多淘口令,一天兩個,不帶重樣的。

這個腳本里面也有用戶隱私統計。不過值得注意的是,他甚至根據各種瀏覽器的特性(例如:電腦端不支持這個 UA 不可能擁有這個功能),判斷出哪些瀏覽器信息是經過偽造的,然后上報這些偽造數據。

例如我用 PC 版 Chrome 模擬 Android Chrome 時,就會是下面這樣的結果

navigator.platform
"Win32"
navigator.userAgent
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36"

統計腳本發現 platformWin32 而 UA 中寫的卻是 Linux,則他會認為我是假的 OS,新建了一個 iframe,鏈接為 https://ad_lflucky_com/janes/fk.html?fk=fakeOS,這個 iframe 的內容很簡單,就是一個 cnzz 的統計腳本。

這個想法很有意思,把 cnzz 當做一個計數器,自己都不需要動態的服務器,只需要部署靜態文件就可以進行數據統計了。

此外他還會利用各種特性檢測假瀏覽器、假信息、假語言、假分辨率。例如:

  • navigator.productSub 在 IE 上時 undefined,在 Safari 類瀏覽器下為 20030107
  • eval.toString().length 在不同瀏覽器上不同
  • object.toSource() 僅在 Firefox 類瀏覽器上受支持。
  • screen.height 不能比 screen.availHeight 小,因為前者是屏幕高度,后者是去除任務欄后的瀏覽器窗口可用的高度。

遠程調試

我其實很好奇為什么電腦端沒有觸發跳轉到下載瀏覽器 apk 那個廣告,我懷疑能是腳本對瀏覽器真偽進行了檢測,只有真正的安卓端才會彈。

繞過方式也不難。Chrome 支持遠程調試,我可以拿一臺 Android 真機來運行 Chrome,這樣就可以避免所有的檢測。

開啟調試

接上 USB 線,打開開發者選項,打開 USB 調試。

打開 chrome://inspect

正常的話直接點 inspect 就可以了。這里有個問題,如果無法訪問 Google 的話,不能正常使用這個 inspect,Chrome 提供了一種備選方案,當 PC 端 Chrome 版本低于 Android Chrome 時,inspect fallback 會出現,我需要用些小技巧讓他強制出現。

在這個頁面打開 F12 開發者工具,在 Sources 中找到 Overrides,啟用,然后選擇一個本地文件夾保存文件(例如:我選擇的是 D:\Temp\chrome-local-override)。

切換到 Page,找到 inspect.js,搜索 fallback,找到這兩行注釋掉,然后 Ctrl + S 保存。你會發現文件圖標上多了一個紫色的小點。

刷新頁面,就會顯示 inspect fallback 功能了。(Local Override 只會在開著 DevTools 時啟用,關閉開發者工具之后,就會取消文件替換功能。)

調試

看到這個加載記錄,我們可以明確了 m301650.js -> a.js -> d.js -> p7090z.html 這一個過程了,

其中可以看到一堆 d.js 的加載,仔細看看都是 302 重定向。點開看詳情,全都是各種 App 的跳轉(網址域名中的點 . 已經替換成下劃線 _

openapp.jdmobile://virtual?params={"category":"jump","des":"m","url":"https://u_jd_com/UKBirM","keplerID":"0","keplerFrom":"1","kepler_param":{"source":"kepler-open","otherData":{"mopenbp7":"0"},"channel":"cedad4c0ad02455c9a818f1b3d98da1a"},"union_open":"union_cps"}

https://878928_xyz/2019llq_5/m.878928.xyz/7090.html

openapp.jdmobile://virtual?params={"category":"jump","des":"m","url":"https://u_jd_com/M7fTMi","keplerID":"0","keplerFrom":"1","kepler_param":{"source":"kepler-open","otherData":{"mopenbp7":"0"},"channel":"2de699902eec4131927c7b68871512b3"},"union_open":"union_cps"}

vipshop://goHome?tra_from=tra%3AC01V4m36ysoz00q7%3A%3Amig_code%3A1xx1%3Aac013b3kbkgv6tsf9mhia46zu7m1fufx

tbopen://m_taobao_com/tbopen/index.html?source=auto&action=ali.open.nav&module=h5&bootImage=0&spm=2014.ugdhh.2200612145320.219258-1604-32768&bc_fl_src=growth_dhh_2200612145320_219258-1604-32768&materialid=219258&h5Url=https%3A%2F%2Fh5.m.taobao.com%2Fbcec%2Fdahanghai-jump.html%3Fspm%3D2014.ugdhh.2200612145320.219258-1604-32768%26bc_fl_src%3Dgrowth_dhh_2200612145320_219258-1604-32768

tbopen://m_taobao_com/tbopen/index.html?source=auto&action=ali.open.nav&module=h5&bootImage=0&spm=2014.ugdhh.2200612145320.219272-1604-32768&bc_fl_src=growth_dhh_2200612145320_219272-1604-32768&materialid=219272&h5Url=https%3A%2F%2Fh5.m.taobao.com%2Fbcec%2Fdahanghai-jump.html%3Fspm%3D2014.ugdhh.2200612145320.219272-1604-32768%26bc_fl_src%3Dgrowth_dhh_2200612145320_219272-1604-32768

newsapp://startup/doc/EVLBFM6D0001899O?s=jixinkeji&spsug=ug&spsugdate=0&spsugextend=jixinkeji07

uclink://www_uc_cn/cc77796ca7c25dff9607d31b29effc07?action=open_url&src_pkg=sxmhx&src_ch=sxmhx133&src_scene=pullup&url=ext%3Ainfo_flow_open_channel%3Ach_id%3D100%26insert_item_ids%3D4556851981770947449%26type%3Dmultiple%26from%3D6001

uclink://www_uc_cn/cc77796ca7c25dff9607d31b29effc07?action=open_url&src_pkg=sxmhx&src_ch=sxmhx134&src_scene=pullup&url=ext%3Ainfo_flow_open_channel%3Ach_id%3D100%26insert_item_ids%3D4556851981770947449%26type%3Dmultiple%26from%3D6001

這里面的第二個就是那個惡意軟件的頁面,PC 版 Chrome 打開直接提示危險網頁。

不知道為什么,這些鏈接都沒有成功打開?赡芤驗樘D到新頁面,直接把 Pending 的 Response 都 Cancel 了。

分析跳轉流程

他們似乎對 IP 有檢測,我再次訪問這個鏈接時,并沒有關于剛才那些鏈接的代碼。

https://ewn_hfqxjx_cn/ms/a.js?b=200473!301650!88!640!150!200&u=5!8.1.0!3!1!bWltYXgz!8!78.0.3904.96!1&c=1!2!Y2VsbHVsYXI%3D!3!8!7!24!786!393!0!5!0!x!3!bGludXhhcm12OGw%3D!1!1!1!0!0!1!1!x!d3d3LmppYW5zaHUuY29t!1!1!1!UXVhbGNvbW1%2BQWRyZW5vKFRNKTUxMg%3D%3D!13!1!1!1!33!62!-1!-1!2276550266&f=90265

似乎重新換一個 IP 有用,并且也可能跟時間有關,可能是每 1 個小時刷新某些東西(這里不確定)。

這個 a.js 是動態生成的,里面的廣告圖片鏈接每次刷新都會變,跳轉到惡意下載的那部分代碼,通常時候是沒有的,換 IP 之后會出現 1 次。

這個跳轉流程并不復雜,就是根據 d.js URL 中的 n=1157258&a=125977 這個參數使用 location.href 跳轉到各個不同的 URL。具體可以看上面的代碼圖片(或 ./samples/a.v2.js)。

里面這個 https://nw44_zmlled_cn/js/mob/sjas.js 腳本又通過 iframe 引入了另外一個頁面 https://dqj77_bkyhq_cn/js/tmp/ImgTj.html,這個頁面包含大量 img 標簽,可能都是用來進行訪問統計的,真的恐怖,有必要搞這么多嗎?

分析 URL 參數

我們可以具體明確一下 URL 中的那些參數都是哪些瀏覽器數據。生成這些數據的代碼都在 m301650.js(因為 a.js 是從 m301650.js 發起的)。

b=200473!301650!88!640!150!200&u=5!8.1.0!3!1!bWltYXgz!8!78.0.3904.96!1&c=1!2!Y2VsbHVsYXI%3D!3!8!7!24!786!393!0!5!0!x!3!bGludXhhcm12OGw%3D!1!1!1!0!0!1!1!x!d3d3LmppYW5zaHUuY29t!1!1!1!UXVhbGNvbW1%2BQWRyZW5vKFRNKTUxMg%3D%3D!13!1!1!1!33!62!-1!-1!2276550266

b=200473!301650!88!640!150!200 是固定值,然后后面分為 u c f 三部分,f 是一個隨機數。

我的瀏覽器 User Agent 是 Mozilla/5.0 (Linux; Android 8.1.0; MI MAX 3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.96 Mobile Safari/537.36 你可以找到這些數據。

u
原始內容 說明
5 Windows = 1, Mac OS = 2, Linux, 模擬器 = 4, Android = 5
8.1.0 系統版本
3 UA 包含 mi = 3
1 手機 = 1, 平板 = 2, iPod = 3, 模擬器 = 4, 桌面 = 5
bWltYXgz mimax3 設備制造商
8 瀏覽器種類:Safari = 1, AppleWebKit = 2, MSIE = 3, IEMobile 或 Windows CE 或 Windows Phone 或 WP7 = 4, Opera = 5, Namoroka = 5, Shiretoko = 5, Firefox = 6, Minefield = 6, Netscape = 7, Chrome = 8, chromeframe = 9, UCWEB = 10, QQBrowser 或 MQQBrowser = 11, 360EE = 12, MicroMessenger = 13, QQ = 14, 華為手機或其他 = 15, miuibrowser = 16, oppobrowser = 17, baiduboxapp = 18
78.0.3904.96 瀏覽器版本
1 渲染引擎:WebKit 或 AppleWebKit = 1, KHTML = 2, Gecko = 3, Presto = 4, Trident = 5
c
原始內容 說明
1 document.cookieEnabled 啟用 Cookie = 1, 不啟用 = 0, 獲取出錯 = -1
2 navigator.connection 網絡類型:Wi-Fi = 2, 移動網絡 = 1, 其他 = 0
Y2VsbHVsYXI%3D cellular navigator.connection.type 詳細網絡類型(Wi-Fi 或蜂窩網絡 2G、3G、4G,未知 = x)
3 history.length 訪問歷史長度
8 navigator.hardwareConcurrency CPU 線程數
7 如果 Cookie 有 kwashhhhnrfr 則直接返回,否則判斷 Referer:未知 = 1, baidu.com = 2, .google. = 3, sogou.com = 4, so.com = 5, m.sm.cn = 6, bing.com = 7, 本站 = 8, 然后再將這些寫入 Cookie
24 screen.colorDepth 色彩深度
786 screen.width 屏幕的長邊像素
393 screen.height 屏幕的短邊像素
0 window !== top 是否被嵌入:被嵌入 = 1, 頂級頁面 = 0
5 navigator.userAgent 操作系統類型:windows = 1, mac = 2, linux = 3, iphone 或 ipad = 4, android = 5, windows phone = 6
0 navigator.oscpu 操作系統和 CPU 類型:win = 1, mac = 2, linux = 3, 其他 = 11
x navigator.oscpu 具體值,沒有 = x
3 navigator.platform 平臺類型:win = 1, mac = 2, linux = 3, android = 3, pike = 3, ipad 或 ipod 或 iphone = 4, 其他 = 12, 如果不支持 navigator.plugins 并且 UA 不是 Windows 或 Windows Phone = 13
bGludXhhcm12OGw%3D linuxarmv8l navigator.platform
1 navigator.maxTouchPoints 最大觸摸點數
1 45 分鐘新訪客:在 Cookie 中設置一個 kwashhhhuuxs 記錄從本周周一 0 點開始到現在的分鐘數,如果不存在返回 1,超過 45 分鐘再次訪問或無法解析返回 2,否則返回 0
1 今日新訪客:如果 Cookie kwashhhhuuxx 存在則返回 0,不存在設為 12 過期時間設為明天 0 點,返回 1
0 距離上次訪問過去天數,使用 kwashhhhudd 記錄 訪問時間 / 86400 * 86400,今年訪問天數,計算得出
0 今年訪問天數,如果上兩行的今日新訪客為 1 則今年訪問天數 + 1
1 1
1 PV: 對當前 location.href 進行 Hash,然后在 Cookie 中記錄訪問次數
x x
d3d3LmppYW5zaHUuY29t www.jianshu.com document.domain,如果沒有則用 obj.referrer 中的 host
1 window.localStorage 可用
1 window.sessionStorage 可用
1 window.indexedDB 可用
UXVhbGNvbW1%2BQWRyZW5vKFRNKTUxMg%3D%3D Qualcomm~Adreno(TM)512 WEBGL_debug_renderer_info gl.getParameter(ext.UNMASKED_VENDOR_WEBGL) + "~" + gl.getParameter(ext.UNMASKED_RENDERER_WEBGL)
13 document.getElementsByTagName("script").length
1 navigator.maxTouchPoints 最大觸摸點數
1 document.createEvent("TouchEvent") 是否支持觸摸事件
1 "ontouchstart" in window
33 document.title.length      標題長度
62 document.getElementsByTagName("div").length  div 個數
-1 document.getElementById('kwashhhh').offsetLeft 嵌入的 div 被排版在什么位置
-1 document.getElementById('kwashhhh').offsetTop
2276550266 由各種瀏覽器參數組成的 Hash,包括:localStorage sessionStorage indexedDB WEBGL_debug_renderer_info navigator.maxTouchPoints document.createEvent("TouchEvent") "ontouchstart" in window oscpu platform userAgent navigator.language colorDepth 屏幕寬高 document.body.addBehavior openDatabase IE ActiveXObject navigator.plugins Canvas Fingerprint

為什么會出現這種問題

引入未經驗證的其他域的腳本

本案例中其他域的腳本不在自己網站的可控范圍內,不論其是否可信,都應該嘗試進行監控,避免對網站用戶帶來不必要的損失。

不知道法律上怎么判,但是假如用戶通過簡書頁面加載的廣告下載到了惡意 App,并造成了財產損失,簡書肯定要承擔責任,看就是看有沒有人故意搞簡書了。

只要使用 script 標簽加載了其他域的腳本,當前網頁就很難受你自己的控制了,他可以進行任何可能的操作,包括覆蓋當前網頁已有的比如 jQuery 庫,甚至假如你的代碼隔離不夠,把某個 XHR 庫暴露給全局了,他就可能攔截你所有的請求數據。

所以這種廣告 SDK 盡量通過 CORS 跨域執行 XHR 請求,也不要盲目的使用 <script> 或 jsonp 加載不可控來源的腳本。

前端開發者如何預防這種問題

這里講的是如何預防,而不是如何解決。解決掉這個問題的方法只能是把所有依賴的 package 或 SDK 親自過一遍。

JavaScript 不支持反射,你沒法在運行時對其他代碼進行檢測。(當然,幸虧他不支持反射,否則你的完美隔離的代碼和數據也可以被外來腳本獲取到了)

所以這里只講如何預防,預防的方法很簡單,但是處理起來很麻煩。

CSP (Content Security Policy 內容安全策略)

在 HTTP 返回頭或 <meta> 中添加 Content-Security-Policy,即可限制資源來源,具體請參考 Content Security Policy (CSP) - HTTP | MDN。

處理完之后,在較新的瀏覽器中訪問你的網頁時,任何外部腳本攻擊均不能執行。這些請求頭讓瀏覽器僅加載受控域名下的資源,任何企圖使用來自其他域名的資源的操作都會直接報錯。禁止加載來自未知域名的 JS 腳本,禁止使用未知域名的 CSS 樣式文件,禁止使用未知域名的圖片,甚至也禁止未知域名的內嵌 iframe,以及被其他域名以 iframe 形式引入。

優點是,你所有的東西都來自自己可控的域名下,缺點是你必須把所有你有的域名都列出來,包括執行內嵌代碼都需要顯示指出。

來自 MDN 的示例

一個網站管理者允許網頁應用的用戶在他們自己的內容中包含來自任何源的圖片,但是限制音頻或視頻需從信任的資源提供者 (獲得),所有腳本必須從特定主機服務器獲取可信的代碼.

Content-Security-Policy: default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com

在這里,各種內容默認僅允許從文檔所在的源獲取,但存在如下例外:

圖片可以從任何地方加載 (注意 "*" 通配符)。
多媒體文件僅允許從 media1.com 和 media2.com 加載 (不允許從這些站點的子域名)。
可運行腳本僅允許來自于 userscripts.example.com。

其他

此外還有很多可用的安全選項。例如可以啟用 HSTS 強制使用 HTTPS。聲明 Cookie 為 HttpOnly 禁止 js 中獲取 Cookie 內容。不過這些是防劫持用的而不是防止外部腳本的。

其他相關的思考與感想

簡書x百度

另外也不知道簡書跟百度有什么交易,一個頁面竟然加載了好幾百個百度的資源。

概率性 Bug

概率性的 Bug 往往讓人捉摸不透。作為一名程序員,改 Bug 也是常有的事情,碰到那些無法復現的 Bug 極為頭疼,不過這個問題真的沒有什么好的調試辦法,只能不斷的調試找到代碼中可能有錯誤的位置。

不過換個方向思考一下,如果這不是一個 Bug,而是一個故意設的陷阱呢?部分游戲反外掛使用概率性封號、延遲封號的方法,讓外掛制作者不知道到底是哪個功能過檢測失敗了。也有一種“蜜罐”方法,正常玩家不可能執行到“蜜罐”中的方法,而外掛制作者可以看到這部分代碼,好好組織代碼結構,讓他我以為這段代碼有用,可實際上一旦這段代碼被執行到了,他會向服務器報告這個人使用了外掛。

本例中,目標網站的腳本是動態生成的,必須換 IP 才能抓到 1 次,這篇文章前前后后花了大約 2 周零零散散的時間。真的直到我發這篇文章的前一天我才真正抓到那個惡意跳轉的腳本。

這種概率性 Bug 真的很麻煩。比如各種游戲的抽卡,如果玩家想要測試卡池概率有沒有問題,只能大量花錢,靠頻率接近概率的方式測試。

Webpack

Webpack 通過 bundle 的方式增加了網頁的加載效率,但是這種打包容易讓一些毫無用處的代碼一起加入發布的版本中,不過這些都沒有隱藏惡意代碼這個問題嚴重。應該不會有人去查看 bundle 的代碼吧,最多利用 map 文件看看引入了哪些文件。沒有 webpack 時我們很明確我們依賴了哪些 js 文件,但有了 webpack,我們沒有再專注于代碼安全,接入廣告商的 SDK 直接打包進 bundle 了,甚至都不知道其中有惡意代碼。

總結

簡書移動端頁面會加載一堆 webpack bundle 其中的 2.js 包含廣告功能,其中一個廣告功能的代碼加載了一個外部腳本。這個外部腳本是動態生成的,他會判斷訪問者的 IP,同 IP 每天第一次訪問會跳轉到惡意下載頁面,之后不會再跳轉。這個廣告還接入了大量統計平臺,加載一次頁面就有好幾百的請求。還另外一個廣告也引入了外部代碼,其中嵌入了向剪貼板中寫入淘口令的指令。

本文分析了惡意代碼對外的表現,基本弄清簡書接入的廣告的問題,主要目的還是學習和分享各種 JavaScript 動態調試技能。

希望簡書盡快解決這個問題吧。(會不會簡書內部已知,并且默許呢?)

相關鏈接

附件

jianshu-hijacking.7z (426.69 KB, 下載次數: 135)

最后,我自己經常說的一句話:所有能插入中間操作的代碼都可以被調試破解。

免費評分

參與人數 251吾愛幣 +261 熱心值 +228 收起 理由
shenRain + 1 感謝您的寶貴建議,我們會努力爭取做得更好!
superProxx + 1 [email protected]!
sdieedu + 1 鼓勵轉貼優秀軟件安全工具和文檔!
akria00 + 1 + 1 我很贊同!
yuqiaobin + 1 + 1 用心討論,共獲提升!
wqkeep + 1 + 1 我很贊同!
mansound + 1 我很贊同!
Hello_World_ZTS + 1 + 1 熱心回復!
幼稚鬼 + 1 感謝發布原創作品,吾愛破解論壇因你更精彩!
henrylong1989 + 1 + 1 感謝發布原創作品,吾愛破解論壇因你更精彩!
mmliuliuliu + 1 用心討論,共獲提升!
此用戶無法顯示 + 1 + 1 鼓勵轉貼優秀軟件安全工具和文檔!
dt8333 + 1 用心討論,共獲提升!
ForeverAK + 1 + 1 用心討論,共獲提升!
牧之8017 + 1 + 1 用心討論,共獲提升!
愛折騰 + 1 + 1 分析到位
lyh9140 + 1 + 1 歡迎分析討論交流,吾愛破解論壇有你更精彩!
zyxm2013 + 1 + 1 鼓勵轉貼優秀軟件安全工具和文檔!
牧魚龍 + 1 + 1 [email protected]!
x8424602 + 1 + 1 歡迎分析討論交流,吾愛破解論壇有你更精彩!
Haleclipse + 1 + 1 感謝發布原創作品,吾愛破解論壇因你更精彩!
NewType + 2 + 1 [email protected]!
rsnodame + 1 + 1 用心討論,共獲提升!
Seper + 1 + 1 鼓勵轉貼優秀軟件安全工具和文檔!
kibaamor + 1 + 1 用心討論,共獲提升!
oudy + 1 + 1 歡迎分析討論交流,吾愛破解論壇有你更精彩!
junty + 1 + 1 感謝發布原創作品,吾愛破解論壇因你更精彩!
huaji23333333 + 1 + 1 [email protected]!
Coolman + 1 + 1 用心討論,共獲提升!
簟紋燈影 + 1 + 1 用心討論,共獲提升!
q8321393 + 1 + 1 用心討論,共獲提升!
xiaofanxiaoyu + 1 我很贊同!
雞蛋羹 + 1 + 1 感謝發布原創作品,吾愛破解論壇因你更精彩!
rekcahacker + 1 + 1 用心討論,共獲提升!
小松 + 1 + 1 我很贊同!
miss85246 + 1 + 1 感謝發布原創作品,吾愛破解論壇因你更精彩!
chw1999 + 1 用心討論,共獲提升!
一杯只姝小屁 + 1 + 1 我很贊同!
yzyuan007 + 1 + 1 感謝發布原創作品,吾愛破解論壇因你更精彩!
紅燒排骨 + 1 熱心回復!
shijei2012 + 1 + 1 我很贊同!
sos218909 + 1 用心討論,共獲提升!
魔幻冰揚 + 1 + 1 用心討論,共獲提升!
xiong_online + 1 + 1 用心討論,共獲提升!
silme + 1 + 1 我很贊同!
Plus_0426 + 1 + 1 用心討論,共獲提升!
sunshine_昊 + 1 + 1 前端大佬,牛逼!
52896009 + 1 熱心回復!
z978768269 + 1 + 1 原來如此
蘿蕾拉 + 1 + 1 我很贊同!
w516258928 + 1 + 1 [email protected]!
ttao88 + 1 [email protected]!
944076047 + 1 + 1 用心討論,共獲提升!
aixxa + 1 + 1 用心討論,共獲提升!
快樂小纏 + 1 + 1 牛!
很過分的人 + 1 + 1 感謝發布原創作品,吾愛破解論壇因你更精彩!
小旺 + 1 + 1 用心討論,共獲提升!
GloryNotes + 1 + 1 我很贊同!
nullable + 1 + 1 我很贊同!
studio + 1 + 1 [email protected]!
Liu0827 + 1 + 1 熱心回復!
smk418 + 1 + 1 用心討論,共獲提升!
xiaohaoit + 1 + 1 歡迎分析討論交流,吾愛破解論壇有你更精彩!
frain19910214 + 1 + 1 歡迎分析討論交流,吾愛破解論壇有你更精彩!
a3512740 + 1 + 1 [email protected]!
T_Tzzz + 1 + 1 我很贊同!
qaz007 + 1 + 1 用心討論,共獲提升!
隨意的個字 + 1 + 1 我很贊同!
虞美人草 + 1 + 1 應該是廣告商干的,交一份廣告費然后暗地加東西
森林生靈 + 1 + 1 CSDN 手機頁面也有相同劫持
AirCrayon + 1 + 1 我很贊同!
蕭瑟秋風 + 1 + 1 大佬,傳授我前端知識吧。。。!
熊二不二 + 1 + 1 我很贊同!
zbcxa + 1 + 1 精品
zhclwr + 1 + 1 我很贊同!
孤僻木魚 + 1 + 1 [email protected]!
drakpj + 1 + 1 很不錯,學習了
DreamYouth + 1 + 1 [email protected]!
w396657279 + 1 + 1 用心討論,共獲提升!
zy1234 + 1 + 1 鼓勵轉貼優秀軟件安全工具和文檔!
namedlxd + 1 熱心回復!
自強 + 1 + 1 [email protected]!
moril + 1 + 1 用心討論,共獲提升!
HEHE139 + 1 + 1 熱心回復!
盤踞 + 1 + 1 用心討論,共獲提升!
qingyise + 1 + 1 我很贊同!
7086pp + 1 + 1 我很贊同!
我是靚仔 + 1 + 1 厲害了大佬
Yu__Geng + 1 + 1 我很贊同!
abset + 1 + 1 我很贊同!
痞老板的員工 + 1 + 1 [email protected]!
a8730151a + 1 + 1 感謝發布原創作品,吾愛破解論壇因你更精彩!
coolcalf + 1 + 1 鼓勵轉貼優秀軟件安全工具和文檔!
zlm110 + 1 + 1 用心討論,共獲提升!
Gnod + 1 + 1 我很贊同!
yhr123 + 1 + 1 [email protected]!
小黃路邊歌手 + 1 + 1 歡迎分析討論交流,吾愛破解論壇有你更精彩!
chenhongyuan + 1 + 1 我很贊同!
you920928 + 1 + 1 [email protected]!
seckillZED + 1 鼓勵優秀!

查看全部評分

本帖被以下淘專輯推薦:

發帖前要善用論壇搜索功能,那里可能會有你要找的答案或者已經有人發布過相同內容了,請勿重復發帖。

推薦
Hmily 發表于 2019-12-9 08:13
看起來要么廣告商干的,要么是cdn投毒了,可以用17ce看下是不是所有節點的js都被緩存成惡意代碼了。

免費評分

參與人數 1吾愛幣 +1 熱心值 +1 收起 理由
fuzball + 1 + 1 我很贊同!

查看全部評分

頭像被屏蔽
推薦
w5645060 發表于 2019-12-9 12:03
csdn有同樣問題,太特么惡心了&#129314;,用安卓機那會,一訪問csdn頁面就會自動打開淘寶,(╯‵□′)╯︵┻━┻
4#
qqvcd010 發表于 2019-12-9 07:36
5#
fnycwfj 發表于 2019-12-9 07:58
有點難度,學習!
6#
yu13740000 發表于 2019-12-9 08:04
tai太厲害了,學習了
7#
qq8945051 發表于 2019-12-9 08:07
遇到過同樣問題  看看學習學習。。
8#
ziliansha 發表于 2019-12-9 08:18
學習了。。。
9#
pidea 發表于 2019-12-9 08:33
頂頂,我是說有時候怎么打開淘寶就莫名其妙領了個紅包
10#
qwt99987 發表于 2019-12-9 08:40
收藏了學習一
11#
love514415 發表于 2019-12-9 08:43
強大. 學習了
您需要登錄后才可以回帖 登錄 | 注冊[Register]

本版積分規則 警告:本版塊禁止灌水或回復與主題無關內容,違者重罰!

快速回復 收藏帖子 返回列表 搜索

RSS訂閱|小黑屋|聯系我們|吾愛破解 - LCG - LSG ( 京ICP備16042023號 | 京公網安備 11010502030087號 )

GMT+8, 2020-4-8 10:00

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回復 返回頂部 返回列表
腾讯二分彩骗局