1. 程式人生 > >筆記-爬蟲-js程式碼解析

筆記-爬蟲-js程式碼解析

筆記-爬蟲-js程式碼解析

 

1.      js程式碼解析

1.1.    前言

在爬取網站時經常會有js生成關鍵資訊,而且js程式碼是混淆過的。

以瓜子二手車為例,直接請求https://www.guazi.com/bj/buy/會返回一個203狀態大小為5324的包,核心是js程式碼。

它負責生成cookie及跳轉,想要初始cookie,就需要解決它或繞過它。 

        <!DOCTYPE html>

        <html lang="en">

            <head>

                <meta charset="utf-8">

                <script type="text/javascript">

                    eval(fuas';var url='';xredirect(name,value,url,'https://');

      //js原始碼,很長一段,刪除了大部分

                </script>

            </head>

            <body>

            <p>正在開啟中,請稍後...<e style='float:right'>2018-11-22 12:05:37</e><p>

            </body>

        </html>

 

1.2.    解析/除錯

最簡單的除錯,建立一個test.html檔案,程式碼如下,使用chrome開啟。

就付一般爬蟲場景夠用了。

        <!DOCTYPE html>

        <html lang="en">

            <head>

                <meta charset="utf-8">

                <script type="text/javascript">

                   

                                   document.write(xredirect)

                                   document.write(anti)

                </script>

            </head>

            <body>

            <p>正在開啟中,請稍後...<e style='float:right'>2018-11-22 12:05:37</e><p>

            </body>

        </html>

 

其它的主要是對js函式的熟悉程度了;

 

1.3.    JS函式

常見函式

eval() 執行程式碼

function(){}()  函式定義及執行一體

parseInt() 類似於int(45,8)

 

 

2.      一些常見的js程式碼隱藏方式

欲勝則要知已知彼,也得學習一下前端的程式碼加密方式,下面是一些常用的js程式碼加密方式。

1、簡單壓縮

將多行程式碼去除多餘的空根和註釋壓縮成一行程式碼,這樣雖然沒什麼太大的作用,但是對於新手來說閱讀起來就會有些難度了。

比如:

1

2

3

4

5

6

7

8

function getCookie(name) {

    var preg = new RegExp("(^| )" + name + "=([^;]*)(;|$)", "g");

    if (preg.test(document.cookie)) {

        return RegExp.$2;

    } else {

        return "";

    }

}

壓縮後:

function getCookie(name){var preg=new RegExp("(^| )"+name+"=([^;]*)(;|$)","g");if(preg.test(document.cookie)){return RegExp.$2}else{return""}}

 

2、程式碼混淆

將程式碼中的變數重新命名成其他不規則變數,將程式碼中的中文轉換成unicode編碼或者16進位制程式碼降低可閱讀性。

1

function getCookie(b){var c=new RegExp("(^| )"+b+"=([^;]*)(;|$)","g");if(preg.test(document.cookie)){return RegExp.$2}else{return""}}

 

3、簡單加密

將程式碼換轉換成eval方式,這樣子就完全沒有之前程式碼的樣子了,只能通過一些關鍵詞或者函式名來查詢。

1

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||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1;};while(c--)if(k)p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k);return p;}('9 7(3){8 1=6 0("(^| )"+3+"=([^;]*)(;|$)","5");b(1.e(c.a)){4 0.$2}d{4""}}',15,15,'RegExp|preg||name|return|g|new|getCookie|var|function|cookie|if|document|else|test'.split('|'),0,{}))

當然這種方式很簡單就可以被解密。

 

4、base64加密配合eval來加密。

比如說:

1

alert(1);

這種寫法一眼就看懂了,那如果換一種寫法呢?

1

eval(atob('YWxlcnQoMSk7'));

這是什麼鬼?其實YWxlcnQoMSk7就是alert(1);經過base64加密後的密文,atob就是將YWxlcnQoMSk7還原成alert(1);然後再丟給eval去執行,atob是瀏覽器內建函式,用於解密base64密文,與之對應的還有btoa,用於將一個字串加密成base64密文。

 

5、進階加密

就是綜合使用了壓縮,混淆等方式進行的加密。

比如還是用文章開始那段setCookie的程式碼,加密後:

1

function getCookie(jvA1){var LQuH2=new window["\x52\x65\x67\x45\x78\x70"]("\x28\x5e\x7c \x29"+jvA1+"\x3d\x28\x5b\x5e\x3b\x5d\x2a\x29\x28\x3b\x7c\x24\x29","\x67");if(LQuH2['\x74\x65\x73\x74'](window["\x64\x6f\x63\x75\x6d\x65\x6e\x74"]['\x63\x6f\x6f\x6b\x69\x65'])){return window["\x52\x65\x67\x45\x78\x70"]['\x24']2}else{return""}}

接下來介紹幾個比較另類的隱藏程式碼的方式:

 

6、jsFuck

僅使用6種符號來編寫程式碼,(,),+,[,],!

比如:

1

alert(1)

加密後:

1

[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+(+[![]]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+!+[]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[!+[]+!+[]])+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]])()((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][[]]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[!+[]+!+[]+[!+[]+!+[]]]+[+!+[]]+([+[]]+![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[!+[]+!+[]+[+[]]])

加密的連他爹媽都很難認識了,雖然比較奇葩,但是如果你將上述程式碼拷貝到瀏覽器控制檯執行,會得到一個彈窗。缺點加密出來的程式碼超級長。

線上加密工具點選這裡

 

7、顏文字解密

將js程式碼轉換成表情符號

還是alert(1);

加密後:

1

゚ω゚ノ= /`m´)ノ ~┻━┻   //*´∇`*/ ['_']; o=(゚ー゚)  =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') ;(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_');(゚Д゚) [゚o゚]='\"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ (o^_^o)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_');

很詭異吧,但是他真的可以執行,不信可以試試。

線上加密工具點選這裡

除上述的方法外,也有很多很成熟的方案,比如:

1、YUI Compressor

2、Google Closure Compiler

3、UglifyJS

4、JScrambler

我麼也可以選擇將上述程式碼繼承到webpack中,自動為我們加密混淆js程式碼。當然具體場景具體分析,實際開發中還有許多其他的技巧,比如新增一些無用的程式碼來干擾實現,程式碼執行順序等等方面,如果感興趣的可以去找幾個做huichan的網站看看。

幾個線上加密網站:

線上加密工具Javascript線上解壓縮

線上加密工具So JSON Javscript線上加密