樹(shù)美滑塊js逆向調(diào)試

今天帶來(lái)一篇某(shu)某(mei)滑塊的js調(diào)試經(jīng)歷,案例鏈接

一、初始化滑塊

  1. 按照慣例,打開(kāi)鏈接,鼠標(biāo)右鍵查看源代碼,啥也沒(méi)有,啥也不是,不用說(shuō)了肯定是ajax異步加載了


    image
  2. F12后刷新網(wǎng)頁(yè),觀察請(qǐng)求,有個(gè)regist的請(qǐng)求有點(diǎn)可疑,細(xì)細(xì)觀察一下,嗯,就是你了,響應(yīng)是一些滑塊的基本信息,后面會(huì)用到


    image
  3. 我們看一下請(qǐng)求,沒(méi)啥難的,紅框內(nèi)的參數(shù)都是固定的,callback是一個(gè)毫秒級(jí)的時(shí)間戳,這里篇幅有限,讀者自行實(shí)現(xiàn)一下,或者看下我的代碼


    image

二、驗(yàn)證滑塊

  1. 我們先清空歷史請(qǐng)求,滑動(dòng)一下滑塊(不要驗(yàn)證成功),找一下驗(yàn)證的請(qǐng)求,這個(gè)fverify請(qǐng)求太明顯了啊,看一下響應(yīng),REJECT拒絕,可以啊,有點(diǎn)對(duì)上了啊


    image
  2. 咱們?cè)倩淮悟?yàn)證成功的,刷刷的出來(lái)這么多請(qǐng)求,咱搜索一下fverify,出來(lái)兩個(gè)請(qǐng)求,看下第一個(gè),這不就是第一個(gè)失敗的驗(yàn)證嗎?再看一下第二個(gè),啥也沒(méi)有,別慌,雙擊請(qǐng)求,PASS通過(guò),好家伙


    image

    image

三、分析請(qǐng)求

  1. 咱們直接看fverify請(qǐng)求的參數(shù),畫紅線的參數(shù)沒(méi)啥難度,基本寫死,參數(shù)callback同初始化滑塊請(qǐng)求一個(gè)套路,參數(shù)rid是初始化滑塊請(qǐng)求的返回值,剩下的參數(shù)才是重頭戲,看到這些參數(shù)都是以=號(hào)結(jié)尾,我立馬就想到了base64,很可惜,并不是,那來(lái)吧,真男人都是硬剛的


    image
  2. 咱們?nèi)nitiator看一下它的前世今生,checkApi,check啥呢,管它是啥,先打個(gè)斷點(diǎn)調(diào)試一下


    image
  3. 我們?cè)趕ource面板打開(kāi)captcha-sdk.min.js文件,美化一下,在美化后的代碼中搜索checkApi,看到這熟悉的switch,case,這不就是控制流平坦化嗎,話不多說(shuō),switch那行(5270)打個(gè)斷點(diǎn),滑動(dòng)一下,very good!成功斷上


    image
  4. 看一下switch的執(zhí)行順序(),1 -> 5 -> 6 -> 3 -> 0 -> 7 -> 2 -> 4 -> 8,好的,我們按順序過(guò)一遍
// 定義一個(gè)變量
case '1':
    var _0x3c0fd6;
    continue;
// 定義多個(gè)變量,并賦值
case '5':
    var _0xf2a5df = this[_0x2721b1] // config object
        , _0x2352cc = _0xf2a5df[_0x2519b2] // captcha.fengkongcloud.com
        , _0x4a8aee = _0xf2a5df[_0x2978b9] // /ca/v2/fverify
        , _0x57f0e6 = _0x1191f0[_0x14e9('0x1c5')](_0x4a8aee, undefined) ? _0x5f2e73 : _0x4a8aee // /ca/v2/fverify
        , _0x351641 = _0xf2a5df[_0x48b1b5] // eR46sBuqF0fdw7KWFLYa
        , _0x48b6e3 = _0xf2a5df[_0x5314e9] // default
        , _0x626842 = _0xf2a5df[_0x13a5ad] // web
        , _0x425cd2 = _0xf2a5df[_0x5dc37e] // 1.0.1
        , _0x5882ed = _0xf2a5df[_0x4ffe15] // zh-cn
        , _0x729c21 = _0xf2a5df[_0x435fdd]; // 1.1.3
    continue;
// 定義一個(gè)變量,并賦值
case '6':
    var _0x2d5d9f = this[_0x23b339](_0x39eb51); // 2020061923141589973e0f44c1b1f909
    continue;
// 定義一個(gè)變量,接收getMouseAction函數(shù)的返回值,這里即驗(yàn)證滑塊接口的部分加密參數(shù),這個(gè)函數(shù)是我們重點(diǎn)分析對(duì)象
case '3':
    var _0x352a92 = this[_0x34b0ce]();
    /*
    {
        "act.os": "web_pc"
        "be": "1mcjoxidh7A="
        "dj": "6EmPUIMzqW8="
        "jr": "osPWhvfh55w="
        "ke": "i3H/MW2BvA0="
        "kw": "3IHDWudhp8I="
        "nw": "yxr7iVoFUnE="
        "wz": "5dHGjcUFGUQeKPcpckf/"dHePXFxpARwxyPcm3aaozR2Y696w4+PIXuPqITNsJk5eXWBm"+3CjnCe8TIkfLrGIYgq97Kd6xYBVu02TWOALgMmal4AFTnB/+H2qWOduLjPP"
        "zy": "bq4s2WHJ5YY="
    }
    */
    continue;
// 定義一個(gè)變量,并賦值
case '0':
    var _0x16baf1 = _0x3b171f; // web
    continue;
// 定義一個(gè)變量,并賦值
case '7':
    var _0x5e801b = _0x238b36[_0x1fdcad][_0x35a24d]((_0x3c0fd6 = {'organization': _0x351641}, // organizationorganization,eR46sBuqF0fdw7KWFLYa
    (_0x69c4cb, _0x566231[_0x1fdcad])(_0x3c0fd6, _0x5cf804[_0xdffe2f], this[_0x4a490f](_0x48b6e3)), // ik,pQ/2b0RtqwE=,getEncryptContent('default'),因?yàn)檫@三個(gè)加密參數(shù)和其他加密參數(shù)過(guò)于相似,我懷疑是同一加密函數(shù),所以會(huì)在分析getMouseAction函數(shù)時(shí)寫明
    (_0x69c4cb, _0x566231[_0x1fdcad])(_0x3c0fd6, _0x5cf804[_0x55eafe], this[_0x4a490f](_0x626842)), // bx,5xp18atYFl8=, getEncryptContent('web')
    (_0x69c4cb, _0x566231[_0x1fdcad])(_0x3c0fd6, _0x5cf804[_0x29fbfc], this[_0x4a490f](_0x5882ed)), // ly ey/BLBP7+Sc=,getEncryptContent('zh-cn')
    (_0x69c4cb, _0x566231[_0x1fdcad])(_0x3c0fd6, _0x39eb51, _0x2d5d9f), // rid,2020061923141589973e0f44c1b1f909
    (_0x69c4cb, _0x566231[_0x1fdcad])(_0x3c0fd6, _0x573912, _0x425cd2), // rversion,1.0.1
    (_0x69c4cb, _0x566231[_0x1fdcad])(_0x3c0fd6, _0x59e760, _0x729c21), // sdkver,1.1.3
    (_0x69c4cb, _0x566231[_0x1fdcad])(_0x3c0fd6, _0x5ca3e7, _0x5cf804[_0x30e79e]), // protocol,4
    (_0x69c4cb, _0x566231[_0x1fdcad])(_0x3c0fd6, _0x251c0f, _0x16baf1), _0x3c0fd6), _0x352a92); // ostype,web
    continue;
// 定義一個(gè)變量并賦值
case '2':
    var _0x33ae65 = _0x238b36[_0x1fdcad][_0x2b1c84](); // 1592580515130
    continue;
// 給已定義的變量賦值
case '4':
    _0x238b36[_0x1fdcad][_0x232778][_0x368fac] = _0x33ae65; // 1592580515130
    continue;
// 調(diào)用getJSONP函數(shù)
case '8':
    _0x5c1d93[_0x283873](_0x21da6a, _0x2352cc, _0x57f0e6, _0x5e801b, _0x1daed1);
    continue;
  1. 在上面的代碼分析中我們發(fā)現(xiàn)getMouseAction函數(shù)返回了必要的加密參數(shù),我們搜索getMouseAction,又是一個(gè)控制流平坦化,直接看順序,14 -> 10 -> 0 -> 11 -> 8 -> 9 -> 3 -> 6 -> 7 -> 4 -> 13 -> 12 -> 2 -> 1 -> 5

14:估計(jì)是定義一個(gè)slide吧


image

10:從初始化滑塊獲取一些基本信息,驗(yàn)證了我們前面的想法


image

0:base64decode,看到這里,可以打開(kāi)console面板驗(yàn)證一下我們的想法,window.atob('CSAEgk97Hm4='),結(jié)果完全一致
image

11:DES,這里用的是CBC模式,用0填充,密碼是sshummei,并取0-8位

//看到'sshummei'和_0x516e7e,猜測(cè)其中一個(gè)作為密碼,另一個(gè)作為密文
//看到['substr'](0, 8),這里很明顯的趣結(jié)果0-8位
//看到0,0,猜測(cè)應(yīng)該是zeropadding填充
//然后寫代碼測(cè)試,猜的還是挺準(zhǔn)的。。。
var _0x24b6fc = _0x4403df['default']['DES']('sshummei', _0x516e7e, 0, 0)['substr'](0, 8);
image

8:這里定義了多個(gè)變量,賦值mouseData、startTime、...、blockWidth,具體意思可以根據(jù)變量名猜測(cè)

var _0x12d747 = this['_data']
 , _0x2b08e7 = _0x12d747['mouseData']
 , _0xa71082 = _0x12d747['startTime']
 , _0x2cb8d7 = _0x12d747['endTime']
 , _0x45a948 = _0x12d747['mouseEndX']
 , _0x42a39b = _0x12d747['trueWidth']
 , _0x325810 = _0x12d747['trueHeight']
 , _0x3ab199 = _0x12d747['selectData']
 , _0x463fbc = _0x12d747['blockWidth'];

9:定義了一個(gè)變量,值為'web_pc'

//var 'web_pc' = this['getOs']();
var _0x554304 = this[_0x576853]();
var 'web_pc' = this['getOs']();

3、6:分別定義了一個(gè)空的object

var _0x753835 = {};
var _0x130e3f = {};

7:這里經(jīng)過(guò)多次調(diào)試,可以確認(rèn)一些值為固定值,需要解決的參數(shù)為zy、dj、wz


image

根據(jù)上圖可知zy,dj,wz分別是k5、k7、k6,這里根據(jù)值還是很好分析的,zy為滑塊到缺口的距離/400,dj為按下滑塊到松下滑塊的時(shí)間,wz為滑動(dòng)軌跡,分別是鼠標(biāo)的x坐標(biāo)、y坐標(biāo)、以及時(shí)間
4:console的值為1


image

13:這里給ke變量賦值runBotDetection函數(shù)的返回值,檢測(cè)是否使用了webdriver,1為使用了,0為未使用
image

12:這里給nw變量賦值為1


image

2:使用getEncryptContent函數(shù)對(duì)7處獲取的數(shù)據(jù)逐一加密,即DES加密
image

1:獲取11處的key
image

5:返回值正是我們?cè)赾heckApi中獲取的值
image

四、總結(jié)

1、基本上分析了所有的參數(shù),有些參數(shù)是固定值,就交給你們了
2、完整代碼,該項(xiàng)目不再維護(hù),分析過(guò)程、參數(shù)加密方法已于文章說(shuō)明
3、該項(xiàng)目?jī)H供學(xué)習(xí)參考, 請(qǐng)勿用作非法用途! 如若涉及侵權(quán), 416828817@qq.com/18355094977@163.com, 收到必刪除!!!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容