反爬蟲破解系列-汽車之家利用css樣式替換文字破解方法


網站:

汽車之家:http://club.autohome.com.cn/ 以論壇為例

反爬蟲措施:

在論壇發布的貼子正文中隨機抽取某幾個字使用span標簽代替,標簽內容位空,但css樣式顯示為所代替的文。這樣不會

影響正常用戶的閱讀,只是在用鼠標選擇的時候是選不到被替換的文字的,對爬蟲則會造成采集內容不全的影響。

原理分析:

  先看一下span標簽的樣式

截圖是火狐瀏覽器的firebug的html面板。我們可以看到正文中每個span標簽的樣式都是一個文字,我們只需要找到每個

span標簽的class屬性於文字的對應關系即可還原正文內容,於是我找了一下css樣式是在哪里定義的。找到了這樣一個文

件,在firebug的css面板中可以看到所有的css文件,然后我嘗試打開了一下這個url,發現結果還是帖子頁面而非css文件

通過抓包也沒有抓到類似這樣的css文件,一番嘗試無果后,我明白了,這個css文件應該是利用js生成的,於是我開始尋

找生成這樣的文件的js代碼,基本上就是拿各種關鍵詞到各個js文件或者源代碼中搜索,例如 ::before、content、hs_kw

等。然后發現js代碼存在於網頁源代碼中,可以利用搜索 HS_ZY來定位到這段js代碼,下面就是對js代碼的分析破解了,

復制這段js代碼到 http://jsbeautifier.org/ 一個js格式化工具網站。格式化之后,發現js代碼是被混淆過的,這就比較蛋疼

了,幸好之前也接觸過此類混淆,大概明白混淆的原理,無非就是將變量名隨機替換,將完整代碼拆分后用變量相加之類的,

於是在一番很麻煩的將各種變量手工替換回去之后,大概明白了js代碼的主邏輯。

(function(hZ_) {
    
    functionEW_() { = DV_()[decodeURIComponent]('%E3%80%81%E3%80%82%E4%B8%80%E4%B8%8A%E4%B8%8B%E4%B8%8D%E4%BA%86%E4%BA%94%E5%92%8C%E5%9C%B0%E5%A4%9A%E5%A4%A7%E5%A5%BD%E5%B0%8F%E5%BE%88%E5%BE%97%E6%98%AF%E7%9A%84%E7%9D%80%E8%BF%9C%E9%95%BF%E9%AB%98%EF%BC%81%EF%BC%8C%EF%BC%9F'Ÿ yc_()); 
    = la_((yc_() 23; 3; 19; 17; 9; 1; 8; 12; 18; 13; 2; 4; 16; 5; 6; 21; 15; 11; 22; 14; 24; 0; 10; 7; 20), lf_(;)); 
    = la_((10 _7, 6 _0; 2 _33, 14 _18; 8 _45, 8 _36; 0 _71, 16 _54; 13 _76, 3 _72; 0 _107, 16 _90; 15 _110, 1 _108; 4 _139, 12 _126; 9 _152, 7 _144; 10 _169, 6 _162; 4 _193, 12 _180; 11 _204, 5 _198; 3 _230, 13 _216; 1 _250, 15 _234; 13 _256, 3 _252; 6 _281, 10 _270; 9 _296, 7 _288; 13 _310, 3 _306; 6 _335, 10 _324; 7 _352, 9 _342; 6 _371, 10 _360; 5 _390, 11 _378; 5 _408, 11 _396; 7 _424, 9 _414; 6 _443, 10 _432lf_(;)), yc_(;));
            Uj_();
            return;;
        }
    function mS_() {
        for (Gx_ = 0; Gx_ < nf_.length; Gx_++) {
            var su_ = Pn_(nf_[Gx_], ',');
            var KN_ = '';
            for (Bk_ = 0; Bk_ < su_.length; Bk_++) {
                KN_ += ui_(su_[Bk_]) + '';
            }
            Kx_(Gx_, KN_);
        }
    }
    function NH_(Gx_) {
        return '.hs_kw' + Gx_ + '_maindC';
    }
    function Ln_() {
        return '::before { content:'
    }
})(document);

很簡單的邏輯,預先定義好哪幾個字要被替換,上面代碼中的那個很多%的字符串就是被替換的文字串,然后定義好每個文

字的序號,最后按照文字的序號對文字串進行重新排序並生成css樣式,注意,最一開始的span標簽的class屬性中是有個序

號的,這個序號就是用來定位應該對應哪個文字。

接下來要做的就是無非就是從js代碼中找到這個文字串,找到文字串的順序,然后進行重排,然后根據span標簽序號對原文

進行反向替換,從而得到完整的內容。

破解步驟:

簡單整理一下:

1、從js代碼中找到被替換的文字串和順序

2、重排文字串

3、對原文中span標簽根據class序號進行替換

其實2、3都比較簡單,重點是第一步,找到被替換的文字串和順序,由於源代碼中js代碼是被混淆過的,無法直接看出哪個

是文字串,所以首先應該對js代碼進行反混淆,這個反混淆也不是說非得完整的還原所有的js代碼,其實只要能反混淆到能

讓我們看出文字串和順序是什么就行了。

說一下反混淆的思路,其實很簡單。就是執行起來比較麻煩而已,混淆是利用將一個簡單的變量定義成復雜的js代碼的方法

實現的,但這種混淆方式其實是有限的(這個有限指的是混淆用的工具在生成混淆代碼時肯定是人為預先定義好了幾種模式

,人為定義的肯定是有限的,只要你把所有的模式找出來,就可以還原了)。舉個例子

function iq_() {
        'return iq_';
        return '3';
    }

這段代碼其實你可以簡單的認為就是變量iq()等於'3',使用正則匹配這樣的代碼模式,然后提取關鍵字:函數名和最后一個

return的值,然后將提取到的信息保存起來用於對js代碼進行全文替換。

function cz_() {
        function _c() {
            return 'cz_';
        };
        if (_c() == 'cz__') {
            return _c();
        } else {
            return '84';
        }
    }

這段代碼復雜了一些,增加了判斷,不過也簡單,利用正則匹配這樣的模式,然后提取關鍵字:函數名、第一個return的值,

判斷中==后面的值,最后一個return的值,然后自己進行判斷來確定cz_()的值應該是多少,保存起來進行全文替換。

以此類推,每種模式都可以使用正則來提取關鍵字並進行全文替換來反混淆,最后我們會得到一個大概被還原的js代碼,其

中的文字串和順序都清晰可見,再使用正則匹配出來就可以了。需要注意的一點是有時候被替換的不是單個文字,而是一些

詞語,這是找到的順序是"3,1;23,5"這樣的,不過這些小伎倆應該不算什么,很好解決。

PS1:

  發現一種新的模式,以前沒注意,span的class屬性hs_kw后面還有一串字符,估計是用來標示類別的,一般的網頁

上只有一種class,出現多種的時候對應的源碼中就會存在多段js代碼,每段js代碼對應一種class,關鍵是找到js代碼對應的

class類型,然后分類型替換就行了。

結語:

這個建議大家自己動手做一下,還是比較有意思的,完整的破解代碼見我的github

https://github.com/duanyifei/antispider/blob/master/autohome.py

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM