树美滑块js逆向调试

今天带来一篇某(shu)某(mei)滑块的js调试经历,案例链接

一、初始化滑块

  1. 按照惯例,打开链接,鼠标右键查看源代码,啥也没有,啥也不是,不用说了肯定是ajax异步加载了


    image
  2. F12后刷新网页,观察请求,有个regist的请求有点可疑,细细观察一下,嗯,就是你了,响应是一些滑块的基本信息,后面会用到


    image
  3. 我们看一下请求,没啥难的,红框内的参数都是固定的,callback是一个毫秒级的时间戳,这里篇幅有限,读者自行实现一下,或者看下我的代码


    image

二、验证滑块

  1. 我们先清空历史请求,滑动一下滑块(不要验证成功),找一下验证的请求,这个fverify请求太明显了啊,看一下响应,REJECT拒绝,可以啊,有点对上了啊


    image
  2. 咱们再滑一次验证成功的,刷刷的出来这么多请求,咱搜索一下fverify,出来两个请求,看下第一个,这不就是第一个失败的验证吗?再看一下第二个,啥也没有,别慌,双击请求,PASS通过,好家伙


    image

    image

三、分析请求

  1. 咱们直接看fverify请求的参数,画红线的参数没啥难度,基本写死,参数callback同初始化滑块请求一个套路,参数rid是初始化滑块请求的返回值,剩下的参数才是重头戏,看到这些参数都是以=号结尾,我立马就想到了base64,很可惜,并不是,那来吧,真男人都是硬刚的


    image
  2. 咱们去initiator看一下它的前世今生,checkApi,check啥呢,管它是啥,先打个断点调试一下


    image
  3. 我们在source面板打开captcha-sdk.min.js文件,美化一下,在美化后的代码中搜索checkApi,看到这熟悉的switch,case,这不就是控制流平坦化吗,话不多说,switch那行(5270)打个断点,滑动一下,very good!成功断上


    image
  4. 看一下switch的执行顺序(),1 -> 5 -> 6 -> 3 -> 0 -> 7 -> 2 -> 4 -> 8,好的,我们按顺序过一遍
// 定义一个变量
case '1':
    var _0x3c0fd6;
    continue;
// 定义多个变量,并赋值
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;
// 定义一个变量,并赋值
case '6':
    var _0x2d5d9f = this[_0x23b339](_0x39eb51); // 2020061923141589973e0f44c1b1f909
    continue;
// 定义一个变量,接收getMouseAction函数的返回值,这里即验证滑块接口的部分加密参数,这个函数是我们重点分析对象
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;
// 定义一个变量,并赋值
case '0':
    var _0x16baf1 = _0x3b171f; // web
    continue;
// 定义一个变量,并赋值
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'),因为这三个加密参数和其他加密参数过于相似,我怀疑是同一加密函数,所以会在分析getMouseAction函数时写明
    (_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;
// 定义一个变量并赋值
case '2':
    var _0x33ae65 = _0x238b36[_0x1fdcad][_0x2b1c84](); // 1592580515130
    continue;
// 给已定义的变量赋值
case '4':
    _0x238b36[_0x1fdcad][_0x232778][_0x368fac] = _0x33ae65; // 1592580515130
    continue;
// 调用getJSONP函数
case '8':
    _0x5c1d93[_0x283873](_0x21da6a, _0x2352cc, _0x57f0e6, _0x5e801b, _0x1daed1);
    continue;
  1. 在上面的代码分析中我们发现getMouseAction函数返回了必要的加密参数,我们搜索getMouseAction,又是一个控制流平坦化,直接看顺序,14 -> 10 -> 0 -> 11 -> 8 -> 9 -> 3 -> 6 -> 7 -> 4 -> 13 -> 12 -> 2 -> 1 -> 5

14:估计是定义一个slide吧


image

10:从初始化滑块获取一些基本信息,验证了我们前面的想法


image

0:base64decode,看到这里,可以打开console面板验证一下我们的想法,window.atob('CSAEgk97Hm4='),结果完全一致
image

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

//看到'sshummei'和_0x516e7e,猜测其中一个作为密码,另一个作为密文
//看到['substr'](0, 8),这里很明显的趣结果0-8位
//看到0,0,猜测应该是zeropadding填充
//然后写代码测试,猜的还是挺准的。。。
var _0x24b6fc = _0x4403df['default']['DES']('sshummei', _0x516e7e, 0, 0)['substr'](0, 8);
image

8:这里定义了多个变量,赋值mouseData、startTime、...、blockWidth,具体意思可以根据变量名猜测

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:定义了一个变量,值为'web_pc'

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

3、6:分别定义了一个空的object

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

7:这里经过多次调试,可以确认一些值为固定值,需要解决的参数为zy、dj、wz


image

根据上图可知zy,dj,wz分别是k5、k7、k6,这里根据值还是很好分析的,zy为滑块到缺口的距离/400,dj为按下滑块到松下滑块的时间,wz为滑动轨迹,分别是鼠标的x坐标、y坐标、以及时间
4:console的值为1


image

13:这里给ke变量赋值runBotDetection函数的返回值,检测是否使用了webdriver,1为使用了,0为未使用
image

12:这里给nw变量赋值为1


image

2:使用getEncryptContent函数对7处获取的数据逐一加密,即DES加密
image

1:获取11处的key
image

5:返回值正是我们在checkApi中获取的值
image

四、总结

1、基本上分析了所有的参数,有些参数是固定值,就交给你们了
2、完整代码,该项目不再维护,分析过程、参数加密方法已于文章说明
3、该项目仅供学习参考, 请勿用作非法用途! 如若涉及侵权, 416828817@qq.com/18355094977@163.com, 收到必删除!!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,284评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,115评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,614评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,671评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,699评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,562评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,309评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,223评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,668评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,859评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,981评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,705评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,310评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,904评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,023评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,146评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,933评论 2 355

推荐阅读更多精彩内容