亚洲国产精品乱码一区二区,美景房屋2免费观看,哎呀哎呀在线观看视频高清国语,从镜子里看我是怎么C哭你

Article / 文章中心

極驗第四代滑塊驗證碼破解(四):請求分析及加密參數(shù)破解

發(fā)布時間:2022-06-17 點擊數(shù):15107

一、極驗請求分析

1. 滑塊測試網(wǎng)站入口

https://www.geetest.com/adaptive-captcha-demo

2. 滑塊驗證過程抓包

與極驗三代滑塊驗證碼相比,極驗四代簡化了驗證過程,加密參數(shù)w的生成也變簡單了。和極驗三代驗證碼一樣的分析流程,擼就完了。

 

3. 請求詳解

3.1. adaptive-captcha-demo

請求介紹
極驗第四代驗證碼測試主頁,主要是獲取下個請求中的url(這個url是動態(tài)變化的,所以這個步驟必須要)

請求參數(shù)

沒啥參數(shù)
1
請求響應

響應為html文檔,通過正則匹配下個步驟的請求url
href="(.\*?adaptive-captcha-demo\.js)"

3.2. adaptive-captcha-demo.js

請求介紹
獲取w參數(shù)加密需要的參數(shù)captchaId

請求參數(shù)
實際破解滑塊過程中,此請求可忽略。

沒啥參數(shù)
請求響應

響應為js文件,通過正則匹配captchaId參數(shù)的值
captchaId:"([0-9a-z]+)"

3.3. load

請求介紹
獲取驗證碼信息,包括:驗證碼類型、驗證碼背景圖、驗證碼滑塊圖、lot_number參數(shù)、靜態(tài)文件url等

請求參數(shù)

captcha_id: 24f56dc13c40dc4a02fd0318567caef5    // 上個請求中獲取
challenge: f8beca82-84a4-4b32-a01d-dae1697f1236 // 由js代碼生成,下面會詳細講解生成過程
client_type: web                                // 固定值
risk_type: slide                                // 驗證碼類型
lang: zh                                        // 固定值
callback: geetest_1641878914316                 // 當前時間戳

請求響應
響應中的c、s在后續(xù)無感驗證生成w參數(shù)時需要使用,其中c為定值,s為變化值。

{
    "status": "success",
    "data": {
        "lot_number": "c574cd8c30a541b28597fb4582542c61",
        "captcha_type": "slide",
        "js": "/js/gcaptcha4.js",
        "css": "/css/gcaptcha4.css",
        "static_path": "/v4/static/v1.4.4",
        "slice": "pictures/v4_pic/slide_2021_07_14/Group81/slide/019d7acaf9aa4f488a332b6baff7176b.png",
        "bg": "pictures/v4_pic/slide_2021_07_14/Group81/bg/019d7acaf9aa4f488a332b6baff7176b.png",
        "ypos": 116,
        "gct_path": "/v4/gct/gct4.5258a91d0f5f0bb73c65d4d18d48d93f.js",
        "arrow": "arrow_1",
        "show_voice": false,
        "feedback": "https://www.geetest.com/Helper",
        "logo": true,
        "pt": "1",
        "captcha_mode": "risk_manage",
        "language": "zh",
        "custom_theme": {
            "_style": "stereoscopic",
            "_color": "hsla(224,98%,66%,1)",
            "_gradient": "linear-gradient(180deg, hsla(224,98%,71%,1) 0%, hsla(224,98%,66%,1) 100%)",
            "_hover": "linear-gradient(180deg, hsla(224,98%,66%,1) 0%, hsla(224,98%,71%,1) 100%)",
            "_brightness": "system",
            "_radius": "4px"
        }
    }
}

3.4. verify

請求介紹
該請求是極驗驗證請求,gcaptcha4.js收集滑動軌跡,與上個請求中的lot_number參數(shù),加密生成w參數(shù)。

請求參數(shù)

captcha_id: 24f56dc13c40dc4a02fd0318567caef5      // 與上個請求中的captcha_id參數(shù)相同
challenge: e29f82f7-78db-42de-913f-fb1b01d3e30b   // 與上個請求中的challenge參數(shù)相同
client_type: web                                  // 固定值
lot_number: c574cd8c30a541b28597fb4582542c61      // 上個請求的響應中l(wèi)ot_number參數(shù)值
risk_type: slide                                  // 驗證碼類型
pt: 1                                             // 上個請求的響應中pt參數(shù)值
w: c742e66584e3b20ad523c2ddff...                  // gcaptcha4.js收集滑動軌跡加密生成
callback: geetest_1641878916958                   // 當前時間戳

請求響應
驗證成功,拿到seccode。

{
    "status": "success",
    "data": {
        "lot_number": "5b79a07bfb1640c1955ef28fbe28bef0",
        "result": "success",
        "fail_count": 0,
        "seccode": {
            "lot_number": "5b79a07bfb1640c1955ef28fbe28bef0",
            "pass_token": "f5b3b3d7664e032bc06730d56f83433046af98878bfa796d5e4b5b5f48904e40",
            "gen_time": "1641880037",
            "captcha_output": "2W2T6RrNJ8qVlCuIQxrHVp0imaZt_LrywRPCvYEbTHwQyoZwHIYvpYM5zF0-qSl8LQF_m8ggUDGiA0b8IDdrjji1YjjbEERRWAP9SxWj-G090QRaou4m8NnZL0NVmBie"
        },
        "score": "1"
    }
}

二、js破解前準備工作

1. gcaptcha4.js反混淆

通過AST語法樹將混淆的gcaptcha4.js文件還原,具體還原方式請看 極驗第四代滑塊驗證碼破解(一):AST還原混淆JS

2. 找到w參數(shù)

 

3. 使用chrome插件reres替換js文件

配置chrome插件reres,將網(wǎng)頁加載的js文件替換成對應的反混淆后的js文件。

打開開發(fā)者工具,刷新網(wǎng)頁,觸發(fā)滑塊操作。然后,就可以任意打斷點分析啦。

 

三、load請求中challenge參數(shù)破解

經(jīng)過測試,下面有兩種方式生成challenge

1. 通過python的uuid庫代碼直接生成

import uuid
challenge = uuid.uuid1().__str__()

2. 通過構造challenge的函數(shù)生成

第一步:找到構造challenge的函數(shù)入口

第二步:刷新網(wǎng)頁,進入斷點分析,找到構造challenge的函數(shù)入口

 

第三步:進入uuid函數(shù),這個函數(shù)特別簡單,直接改成py

 

import random
def uuid():
    """
    var uuid = function () {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            var r = Math.random() * 16 | 0;
            var v = c === 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        });
    };
    """

    def __random(c):
        r = int(random.random() * 16)
        v = r if c == 'x' else (r & 0x3 | 0x8)
        return hex(v)[2:]

    string = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
    ret = ''
    for i in string:
        if i in 'xy':
            i = __random(i)
        ret += i
    return ret

 

四、w參數(shù)破解

1. w參數(shù)分析

滑動滑塊,觸發(fā)debugger,從w生成位置開始往上一步一步分析,看看生成w參數(shù)需要哪些關鍵函數(shù)。

下面分析對w參數(shù)的分析過程,依照下圖所示。

2. e 對象參數(shù)詳情

通多上面對w參數(shù)的分析,可以得出:w參數(shù)=加密函數(shù)(序列化函數(shù)(e對象)
下面是e對象中各參數(shù)的詳解

{
    "setLeft": 99,                         // 滑塊滑動距離
    "track": [[38, 15, 0], ... ],          // 滑塊滑動軌跡
    "passtime": 146,                       // 滑塊滑動過程時長
    "userresponse": 98.41476022585691,     // 通過滑塊滑動距離計算得到
    "lot_number": "4b4ef3e583444e0fb...",  // load響應中的lot_number參數(shù)
    "device_id": "A59C",                   // 可為定值,可省略此參數(shù)
    "geetest": "captcha",                  // 可為定值,可省略此參數(shù)
    "lang": "zh",                          // 可為定值,可省略此參數(shù)
    "ep": "123",                           // 可為定值,可省略此參數(shù)
    "nz8c": "255401529",                   // 可為定值,可省略此參數(shù)
    "em": {"ph": 0, ...}                   // 可為定值,可省略此參數(shù)
}

3. 序列化函數(shù):d[“default”][“stringify”]

斷點進入d[“default”][“stringify”]函數(shù),發(fā)現(xiàn)此函數(shù)中有外部函數(shù)調用,所以將外部函數(shù)整個摳出來

 

 

4. 加密函數(shù):h[“default”]

斷點進入h[“default”]函數(shù),這里需要注意:此函數(shù)中對第二個入?yún)⒅械闹颠M行了很多判斷,實際沒有進行運算,這里我們修改下函數(shù),直接繞過判斷

 

5. e 對象參數(shù)破解

e對象作為入?yún)?,因此需要通過調用棧,跳轉到上層函數(shù)調用,分析e對象中每個參數(shù)的構造函數(shù)

 

5.1. 參數(shù)破解:track

小伙伴們看這個哦: 極驗第四代滑塊驗證碼破解(三):滑塊軌跡構造

5.2. 參數(shù)破解:passtime

滑動消耗時長就直接從滑動軌跡中累加了

function get_passtime(track) {
    var passtime = 0;
    for (i = 0; i < track.length; i++) {
        passtime += track[i][2]
    }
    return passtime
}

5.3. 參數(shù)破解:setLeft

滑動距離也從滑動軌跡中累加吧

function get_setLeft(track) {
    var setLeft = 0;
    for (i = 1; i < track.length; i++) {
        setLeft += track[i][0]
    }
    return setLeft
}

5.4. 參數(shù)破解:userresponse

從上文知道 userresponse = setLeft / t["KaTeX parse error: Can't use function '\]' in math mode at position 7: _BGBb"\?]?,那就分析一下t\["_BGBb"]函數(shù)

 

function get_userresponse(setLeft, captcha_width) {
    var e = 340
    var i = .8876 * e / captcha_width
    return setLeft / i
}

五、w參數(shù)破解完整代碼

感謝小伙伴們看了這么久,直接上干貨吧。w參數(shù)破解的全量代碼奉上,其中只有3個函數(shù)需要大家摳出來(原封不動的摳出來就行,太長了沒法粘貼進去)

var window = {
    "navigator": {
        "appName": "Netscape"
    },
    "crypto": {
        "getRandomValues": getRandomValues
    }
}
var navigator = window["navigator"]

function randoms(min, max) {
    return Math.floor(Math.random() * (max - min + 1) + min)
}

function getRandomValues(buf) {
    var min = 0,
        max = 255;
    if (buf.length > 65536) {
        var e = new Error();
        e.code = 22;
        e.message = 'Failed to execute \'getRandomValues\' : The ' + 'ArrayBufferView\'s byte length (' + buf.length + ') exceeds the ' + 'number of bytes of entropy available via this API (65536).';
        e.name = 'QuotaExceededError';
        throw e;
    }
    if (buf instanceof Uint16Array) {
        max = 65535;
    } else if (buf instanceof Uint32Array) {
        max = 4294967295;
    }
    for (var element in buf) {
        buf[element] = randoms(min, max);
    }
    return buf;
}


function get_passtime(track) {
    var passtime = 0;
    for (i = 0; i < track.length; i++) {
        passtime += track[i][2]
    }
    return passtime
}

function get_userresponse(setLeft, captcha_width) {
    var e = 340
    var i = .8876 * e / captcha_width
    return setLeft / i
}

function get_setLeft(track) {
    var setLeft = 0;
    for (i = 1; i < track.length; i++) {
        setLeft += track[i][0]
    }
    return setLeft
}

function get_w(track, captcha_width, lot_number) {
    var d = function () {
        // 內(nèi)容需要自己摳出來
    }();
    d["default"] = d;

    function get_h(e, t) {
        var _ = function () {
            // 內(nèi)容需要自己摳出來
        }();
        _["default"] = _;
        var guid = function () {
            function e() {
                return (65536 * (1 + Math["random"]()) | 0)["toString"](16)["substring"](1);
            }

            return function () {
                return e() + e() + e() + e();
            }
                ;
        }();

        var i = function () {
            // 內(nèi)容需要自己摳出來
        }();
        i["default"] = i;

        function arrayToHex(e) {
            for (var t = [], s = 0, a = 0; a < 2 * e["length"]; a += 2)
                t[a >>> 3] |= parseInt(e[s], 10) << 24 - a % 8 * 4,
                    s++;

            for (var o = [], n = 0; n < e["length"]; n++) {
                var r = t[n >>> 2] >>> 24 - n % 4 * 8 & 255;
                o["push"]((r >>> 4)["toString"](16)),
                    o["push"]((15 & r)["toString"](16));
            }

            return o["join"]("");
        }

        var a = guid(),
            o = new _["default"]()["encrypt"](a);


        var n = i["default"]["encrypt"](e, a);
        return arrayToHex(n) + o;
    }

    var passtime = get_passtime(track),
        setLeft = get_setLeft(track),
        userresponse = get_userresponse(setLeft, captcha_width);
    var e = {
        "setLeft": setLeft,
        "track": track,
        "passtime": passtime,
        "userresponse": userresponse,
        "device_id": "A59C",
        "lot_number": lot_number,
        "geetest": "captcha",
        "lang": "zh",
        "ep": "123",
        "nz8c": "255401529",
        "em": {
            "ph": 0,
            "cp": 0,
            "ek": "11",
            "wd": 1,
            "nt": 0,
            "si": 0,
            "sc": 0
        }
    }
    return get_h(d["default"]["stringify"](e))
}

console.log('====================== 測試區(qū) ======================')

var track = [[47, 17, 0],],
    captcha_width = 300,
    lot_number = "13e35cf1c2834cb9afd01b89006c8f41";

var w = get_w(track, captcha_width, lot_number)
console.log(w)

六、結語

極驗第四代滑塊驗證碼破解系列文章就到此結束啦,后期更新更多爬蟲知識與破解技術。點贊加關注,免得找不到路。。。