極驗反爬蟲防護分析之接口交互的解密方法補遺

本文要分享的內容是去年爲了搶鞋而分析 極驗(GeeTest)反爬蟲防護的筆記,由於篇幅較長(爲了多混點CB)我會按照我的分析順序,分成如下四個主題與大家分享:

  1. 極驗反爬蟲防護分析之交互流程分析
  2. 極驗反爬蟲防護分析之接口交互的解密方法
  3. 極驗反爬蟲防護分析之接口交互的解密方法補遺
  4. 極驗反爬蟲防護分析之slide驗證方式下圖片的處理及滑動軌跡的生成思路

本文是第三篇《接口交互的解密方法補遺》,書接上文,上一篇中,我們遺留了兩個問題:

  1. AES的密鑰如何生成。
  2. e的值是什麼內容,如何計算得到。

不過在後來的調試過程中發現,geetest並不是簡單的使用了base64加密,所以需要進一步分析一下,下面進入正文~


AES加密結果的BASE64編碼

在調試的過程中發現AES加密的結果並不是簡單的BASE64編碼,如下圖:

 

 

 看代碼像是BASE64編碼後提交給服務器的,但是我將o的值導出後,自己進行base64編碼的結果與這裏不一樣,因此跟進$_BABW方法繼續分析,如下圖:

 

 

 由此可知,最終的加密結果是由["res"]+["end"]拼湊起來的,具體的跟進 $_JJM方法繼續分析, 將混淆的代碼還原之後,JS代碼如下:

var Base64 = {
    "$_JGH": function(e){
        var t = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789()";
        return e < 0 || e >= t["length"] ? "." : t.charAt(e);
    },
    "$_JIY": function(e, t) {
        return e >> t & 1;
    },
    "$_JJM": function(e, o) {
        var $this = this;
        function t(e, t) {
            for (var n = 0, r = 24 - 1; 0 <= r; r -= 1) {
                1 === $this["$_JIY"](t, r) && (n = (n << 1) + $this["$_JIY"](e, r));
            }
            return n;
        }

        for (var n = "", r = "", a = e["length"], s = 0; s < a; s += 3) {
            var c;
            if (s + 2 < a) {
                c = (e[s] << 16) + (e[s + 1] << 8) + e[s + 2];
                n += this["$_JGH"](t(c, 7274496)) + this["$_JGH"](t(c, 9483264)) + this["$_JGH"](t(c, 19220)) + this["$_JGH"](t(c, 235));
            } else {
                var u = a % 3;
                2 == u ? (c = (e[s] << 16) + (e[s + 1] << 8), n += this["$_JGH"](t(c, 7274496)) + this["$_JGH"](t(c, 9483264)) + this["$_JGH"](t(c, 19220)), r = ".") : 1 == u && (c = e[s] << 16, n += this["$_JGH"](t(c, 7274496)) + this["$_JGH"](t(c, 9483264)), r = "." + ".");
            }
        }
        return {'res': n, 'end': r}
    },
    "encode": function (e) {
        var t = this["$_JJM"](e);
        return t["res"] + t["end"];
    }

}

// 使用方法,直接將要加密的字節數組傳入方法即可
var result = Base64["encode"]([92,25,128,...])
console.log(result);

導出官網要加密的數組,加密結果如下圖:

 

 

 

AES密鑰的生成方法

繼續向上追溯AES密鑰的生成方法,來到如下位置:

 

 跟進wr方法,得到如下代碼:

 

 

 由此,整理出來AES密碼的生成方法爲:

/**
 * AES密鑰的獲取方法
 */
function create_key() {
    return (65536 * (1 + Math.random()) | 0).toString(16).substring(1);
};

function get_aes_key() {
    return wr() + wr() + wr() + wr();
}

e值的來歷

跟進分析之後,發現e的值是從瀏覽器的window對象中依次獲取,如下內容的信息:

0: "textLength"
1: "HTMLLength"
2: "documentMode"
3: "A"
4: "ARTICLE"
5: "ASIDE"
6: "AUDIO"
7: "BASE"
8: "BUTTON"
9: "CANVAS"
10: "CODE"
11: "IFRAME"
12: "IMG"
13: "INPUT"
14: "LABEL"
15: "LINK"
16: "NAV"
17: "OBJECT"
18: "OL"
19: "PICTURE"
20: "PRE"
21: "SECTION"
22: "SELECT"
23: "SOURCE"
24: "SPAN"
25: "STYLE"
26: "TABLE"
27: "TEXTAREA"
28: "VIDEO"
29: "screenLeft"
30: "screenTop"
31: "screenAvailLeft"
32: "screenAvailTop"
33: "innerWidth"
34: "innerHeight"
35: "outerWidth"
36: "outerHeight"
37: "browserLanguage"
38: "browserLanguages"
39: "systemLanguage"
40: "devicePixelRatio"
41: "colorDepth"
42: "userAgent"
43: "cookieEnabled"
44: "netEnabled"
45: "screenWidth"
46: "screenHeight"
47: "screenAvailWidth"
48: "screenAvailHeight"
49: "localStorageEnabled"
50: "sessionStorageEnabled"
51: "indexedDBEnabled"
52: "CPUClass"
53: "platform"
54: "doNotTrack"
55: "timezone"
56: "canvas2DFP"
57: "canvas3DFP"
58: "plugins"
59: "maxTouchPoints"
60: "flashEnabled"
61: "javaEnabled"
62: "hardwareConcurrency"
63: "jsFonts"
64: "timestamp"
65: "performanceTiming"
66: "internalip"
67: "mediaDevices"
68: "DIV"
69: "P"
70: "UL"
71: "LI"
72: "SCRIPT"
73: "deviceorientation"
74: "touchEvent"

這些key對應的內容爲:

A: 337
BUTTON: 1
CPUClass: undefined
DIV: 648
HTMLLength: 185450
IFRAME: 7
IMG: 60
INPUT: 48
LABEL: 9
LI: 222
LINK: 17
P: 75
SCRIPT: 69
SECTION: 1
SPAN: 239
STYLE: 2
UL: 49
browserLanguage: "zh-CN"
browserLanguages: "zh-CN,zh,zh-TW,zh-HK,en-US,en"
canvas2DFP: "805a6cdeadd4f48ade985597f74928cb"
canvas3DFP: "cc03697d39800df1ef0d2229132a62e8"
colorDepth: 24
cookieEnabled: 1
devicePixelRatio: 1
deviceorientation: false
doNotTrack: 1
documentMode: "CSS1Compat"
flashEnabled: -1
hardwareConcurrency: 4
indexedDBEnabled: 1
innerHeight: 443
innerWidth: 1634
internalip: undefined
javaEnabled: 0
jsFonts: "AndaleMono,Arial,ArialBlack,ArialNarrow,ArialRoundedMTBold,ArialUnicodeMS,ComicSansMS,Courier,CourierNew,Geneva,Georgia,Helvetica,HelveticaNeue,Impact,LUCIDAGRANDE,MicrosoftSansSerif,Monaco,Palatino,Tahoma,Times,TimesNewRoman,TrebuchetMS,Verdana"
localStorageEnabled: 1
maxTouchPoints: 0
mediaDevices: -1
netEnabled: 1
outerHeight: 1027
outerWidth: 1634
performanceTiming: "-1,-1,0,0,0,0,0,123,208,1,99154,10,8,403,418,1005,-1,-1,-1,-1"
platform: "MacIntel"
plugins: ""
screenAvailHeight: 1027
screenAvailLeft: 44
screenAvailTop: 23
screenAvailWidth: 1636
screenHeight: 1050
screenLeft: 46
screenTop: 23
screenWidth: 1680
sessionStorageEnabled: 1
systemLanguage: undefined
textLength: 46216
timestamp: 1568186269219
timezone: -8
touchEvent: false
userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:69.0) Gecko/20100101 Firefox/69.0"

將這些值取爲數組並用 !!進行分隔生成字符串,就得到了e的值。因頁面內容相對固定,也取固定字符來用,省的每次單獨生成了。

至此,接口交互中參數加密解密的部分就都分析完畢了。下一篇也是最後一篇,我們一起來看如何繞過號稱基於大數據的智能行爲驗證組件Slide的內容: 《極驗反爬蟲防護分析之slide驗證方式下圖片的處理及滑動軌跡的生成思路

 

轉載:https://www.52pojie.cn/thread-1162951-1-1.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章