• 【JavaScript 逆向】猿人学 web 第五题:乱码增强


    案例目标        

    网址:第五题 js 混淆 乱码增强 - 猿人学

    本题目标:抓取全部 5 页直播间热度,计算前 5 名直播间热度的加和

    常规 JavaScript 逆向思路

    一般情况下,JavaScript 逆向分为三步:

    • 寻找入口:逆向在大部分情况下就是找一些加密参数到底是怎么来的,关键逻辑可能写在某个关键的方法或者隐藏在某个关键的变量里,一个网站可能加载了很多 JavaScript 文件,如何从这么多的 JavaScript 文件的代码行中找到关键的位置,很重要;
    • 调试分析:找到入口后,我们定位到某个参数可能是在某个方法中执行的了,那么里面的逻辑是怎么样的,调用了多少加密算法,经过了多少赋值变换,需要把整体思路整理清楚,以便于断点或反混淆工具等进行调试分析;
    • 模拟执行:经过调试分析后,差不多弄清了逻辑,就需要对加密过程进行逻辑复现,以拿到最后我们想要的数据

    接下来开始正式进行案例分析:

    寻找入口

    F12 打开开发者人员工具,刷新网页进行抓包,在 Network 中可以看到数据接口为 5?m=xxx,响应预览中可以看到当前页面各视频的热度数据:

    响应负载中有两个请求参数 m 和 f,值皆为一串数字,现在还不知道其具体含义:

    本题提示:本页 cookie 有效期仅有 50 秒钟,所以 cookie 是动态变化的,其中肯定有加密变化的参数,查看 cookie 内容:

    1. cookies = {
    2. "Hm_lvt_c99546cf032aaa5a679230de9a95c7db": "1661925145",
    3. "tk": "32908618934039056",
    4. "sessionid": "XXXXXXXXXX",
    5. "Hm_lvt_9bcbda9cbf86757998a2339a0437208e": "1661925158",
    6. "Hm_lpvt_9bcbda9cbf86757998a2339a0437208e": "1661925158",
    7. "Hm_lpvt_c99546cf032aaa5a679230de9a95c7db": "1661926425",
    8. "m": "ccf558ed48325553e5722eda1a6396a6",
    9. "RM4hZBv0dDon443M": "ZgkOG30tdlJwtFEATbMdoGlnULtE4JYL5Z/yt6IiNO141Ts+Awkzavph6S1BvG6Qx1L/AOBjNbcRht65iEvusilk0J5jNyY/YGewrhLXophJ2dkIvf4hEbv1iaCXv/bhq0NAJzeH8x3vmVVZklcPNuOjCbnm1C3A1hzn2M0aIUsQ3P0NROyB5l/iMcz271DCPiQeHcUkxQwn342efQU4OGNAe+SUNlFMOhUBlKC94tk="
    10. }

    经过观察对比,m 和 RM4hZBv0dDon443M 参数的值是在动态变化的,接下来就需要找到这两个参数的具体加密位置。

    调试分析

    接口处点击 Initiator, 跟栈进入 send:

    点击 { } 格式化,send 处位于 jquery.min.js:formatted 文件的第 3801 行,在该行打断点调试分析,刷新网页会在该处断住: 

    向下跟栈到虚拟机 VMXXXXX 中,格式化后跳转到了第 1976 行,文件内容经过 OB 混淆: 

    在该行打下断点调试,_$UH[0x1a] 值为 setInterval,则此处即为定时器,0x1f4 值为 500,与本题提示中 50 s 变换一次 cookie 匹配:

    ctrl + f 局部搜索加密参数,RM4hZBv0dDon443M 搜索不到被混淆了,搜索 m 的值会发现有几百个结果,这里参数都是被加密赋值的,所以直接搜索 m=,缩减到了只有六个结果:

    在第 978 行我可看到以下代码,前面一连串字符串拼起来就是 RM4hZBv0dDon443M,所以此处即为该参数赋值加密的位置:

    • _$Fe:cookie,
    • _0x3d0f3f[_$Fe]:cookie 的值 
    _0x3d0f3f[_$Fe] = 'R' + 'M' + '4' + 'h' + 'Z' + 'B' + 'v' + '0' + 'd' + 'D' + 'o' + 'n' + '4' + '4' + '3' + 'M=' + _0x4e96b4['_$ss'] + ';\x20path=/';
    

    在该行打下断点调试分析,_0x3d0f3f[_$Fe] 即 cookie 的值,这里是将 RM4hZBv0dDon443M 参数加密后赋值给 cookie,_0x4e96b4['_$ss'] 即加密值,所以想要知道关键的加密方法,需要进一步跟进到 _0x4e96b4 的定义位置,ctrl + f 局部搜索 _0x4e96b4,在第 221 行找到了其加密位置:

    var _0x4e96b4 = window,即 _0x4e96b4 为 window 对象,那么只能搜索 ‘_$’ 看看怎么生成的,有一个结果,在第 1229 行:

    '_$' + _$UH[0x348][0x1] + _$UH[0x353][0x1] 对应的 '_$ss' ,同时我们在上面能看到 mode、padding,这段代码部分如下:

    1. _$Ww = _$Tk[_$UH[0x2db]][_$UH[0x2dc]][_$UH[0xff]](_0x4e96b4['_$pr'][_$UH[0x1f]]()),
    2. _0x29dd83 = _$Tk['A' + _$UH[0x32d]][_$UH[0x337] + _$UH[0x336]](_$Ww, _0x4e96b4[_0xc77418('0x6', 'OCbs')], {
    3. 'mode': _$Tk[_$UH[0x339] + _$UH[0x33a]][_$UH[0x2e5]],
    4. 'padding': _$Tk[_$UH[0x33b]][_$UH[0x33c] + _$UH[0x33d]]
    5. }),
    6. _0x4e96b4['_$' + _$UH[0x348][0x1] + _$UH[0x353][0x1]] = _0x29dd83[_$UH[0x1f]]();

    经过调试可以改写为:

    1. _$Ww = _$Tk['enc']['utf-8']['parse'](_0x4e96b4['_$pr']['toString']()),
    2. _0x29dd83 = _$Tk['AES'](_$Ww, _0x4e96b4['_$qF'], {
    3. 'mode': _$Tk['mode']['ECB'],
    4. 'padding': _$Tk['pad']['pkcs7']
    5. }),
    6. _0x4e96b4['_$ss'] = _0x29dd83['toString']();

    从优化后的代码中可以看到,这里值是通过 AES 加密的,加密模块为 ECB,填充方式为 pkcs7,_0x4e96b4['_$qF'] 为秘钥,_0x4e96b4['_$pr'] 即 window['_$pr'] 为明文数组数据:

    先来分析秘钥,ctrl + f 搜索 '_$qF',搜索到了两个结果,在第 1444 行:

    _0x4e96b4['_$qF'] = CryptoJS['enc']['Utf8'][_$UH[0xff]](_0x4e96b4['btoa'](_0x4e96b4['_$is'])['slice'](0x0, 0x10));

    打断点调试优化:

    _0x4e96b4['_$qF'] = CryptoJS['enc']['Utf8']['parse'](_0x4e96b4['btoa'](_0x4e96b4['_$is'])['slice'](0x0, 0x10));
    

    (0x0, 0x10) 值为 16,秘钥为将 _0x4e96b4['_$is'] 的值经过 base64 编码后取前 16 位的结果:

    一开始请求参数 m 和 f,定义在 5 文件中:

    • m: window._$is
    • f: window.$_zw[23]

    所以 _0x4e96b4['_$is'] 的值及 m 的值,通过 node 改写:

    1. var srcs = '1661936832793';
    2. var value = Buffer.from(srcs).toString('base64').slice(0, 16);

     RM4hZBv0dDon443M 参数整段加密改写如下:

    1. var CryptoJS = require('crypto-js');
    2. var pr = [
    3. "fcc46223494363e55ecdcf6089b315bb"
    4. ,"8cad38560777d3294ec95b097e48e047"
    5. ,"cdd3058695571a4fe8018423b006f260"
    6. ,"c1a21cb2a6cda710a74395973ad4e98b"
    7. ,"06301ae5a05fbaf499e6aec8ea042d46"
    8. ];
    9. var params = '1661936832793';
    10. var value = Buffer.from(params).toString('base64').slice(0, 16);
    11. function RM4(){
    12. var srcs = CryptoJS.enc.Utf8.parse(pr.toString());
    13. var key = CryptoJS.enc.Utf8.parse(value);
    14. var encrypted = CryptoJS.AES.encrypt(srcs, key, {
    15. mode: CryptoJS.mode.ECB,
    16. padding: CryptoJS.pad.Pkcs7
    17. });
    18. return encrypted.toString();
    19. }
    20. console.log(RM4());

    运行效果:

    以上将值固定了,只能说是梳理出了大致逻辑,我们还需要知道 pr 数组具体是怎么生成的,局部搜索 _0x4e96b4['_$pr'] 跟进到数组生成位置,pr 总共有五个值,前四个值生成逻辑是在第 1717 行的 _0x474032(_$Wa) 这:

    断点调试,生成第五个值时就会跳转到第 868 行_0x474032(_$yw) 这里:

    第五个值的时间戳 _$yw 不仅是 pr 的元素,也是请求参数 m,同时还是 AES 加密的 key 参数,f 即 _$Wa,需跟进 _0x474032 定义位置找到加密方式,后文会讲,现在先找到另一个 cookie 加密参数 m,通过搜索 m= 同样可以找到 cookie 参数 m 的传值位置,在 VM 虚拟机的第 1716 行打断点调试分析:

    0x3d0f3f[_$Fe] = 'm=' + _0x474032(_$Wa) + ';\x20path=/';
    • _$Fe:cookie,
    • _0x3d0f3f[_$Fe]:cookie 的值 
    • _$Wa:1661928127000,可能为时间戳
    • _0x474032(_$Wa):将 _$Wa 加密后的结果

    _$Wa 第 1715 行定义,跟进到 _0x12eaf3 函数中,在第 275 行定义,根据控制台打印出来的结果可以确定 _$Wa 的值为时间戳:

    •  _$Wa = Date['parse'](new Date())

    ctrl + f 搜索 _$yw,定义在第 672 行,_$yw = _0x2d5f5b()[_$UH[0x1f]](),跟进 _0x2d5f5b,跳转到第 278 行,返回值为 _0x35bb1d[_$UH[0xff]](new _0x35bb1d()),断点调试后优化:

    • _$yw = new Date()['valueOf']().toString()

    _$Wa 跟 _$yw 一样同样经过 _0x474032 加密的,进一步跟进 _0x474032 的定义位置,看是什么加密方式,鼠标悬停其上,点击进入:

    定义在该文件的第 455 行,返回值嵌套了几个三元表达式: 

    1. function _0x474032(_0x233f82, _0xe2ed33, _0x3229f9) {
    2. return _0xe2ed33 ? _0x3229f9 ? v(_0xe2ed33, _0x233f82) : y(_0xe2ed33, _0x233f82) : _0x3229f9 ? _0x41873d(_0x233f82) : _0x37614a(_0x233f82);
    3. }

    在第 456 行 return 处打断点调试, _0xe2ed33 和 _0x3229f9 皆为 undefined,_0x37614a(_0x233f82) 即为加密后的结果:

    这里可以将代码简化:

    1. function _0x474032(_0x233f82, _0xe2ed33, _0x3229f9) {
    2. return _0x37614a(_0x233f82);
    3. }

    _0x233f82 为传入的时间戳,所以进一步跟进到 _0x37614a 中,其定义在第 452 行,在第 453 行打断点调试,控制台中打印结果如下:

    所以这里时间戳经过 _0x41873d 加密后再由 _0x499969 方法加密后得到了最后的加密结果,然后跟进到 _0x41873d 中,思路是这样的,就不接着往后面一个个描述了,这里边扣边对方法补全调用就行了,把需要的函数都加上,_$UH[ ] 中混淆的也改成对应的字符串,扣了挺久的,改写后的 JavaScript 文件如下:

    JavaScript 代码

    1. var _0x4e96b4 = window = {};
    2. var _0x1171c8 = 0x67452301;
    3. var _0x4dae05 = -0x10325477;
    4. var _0x183a1d = -0x67452302;
    5. var _0xcfa373 = 0x10325476;
    6. var _0x30bc70 = String;
    7. function _0x48d4b5(_0xabcf4d) {
    8. var _0x10430a = _0xabcf4d['length'];
    9. var _0x4c73dc, _0x324511 = new Array(_0x10430a - 0x1), _0x4a9df7 = _0xabcf4d['charCodeAt'](0x0) - 0x61;
    10. for (var _0x399f28 = 0x0, _0x3a7b53 = 0x1; _0x3a7b53 < _0x10430a; ++_0x3a7b53) {
    11. _0x4c73dc = _0xabcf4d['charCodeAt'](_0x3a7b53);
    12. if (_0x4c73dc >= 0x28 && _0x4c73dc < 0x5c) {
    13. _0x4c73dc += _0x4a9df7;
    14. if (_0x4c73dc >= 0x5c)
    15. _0x4c73dc = _0x4c73dc - 0x34;
    16. } else if (_0x4c73dc >= 0x61 && _0x4c73dc < 0x7f) {
    17. _0x4c73dc += _0x4a9df7;
    18. if (_0x4c73dc >= 0x7f)
    19. _0x4c73dc = _0x4c73dc - 0x1e;
    20. }
    21. _0x324511[_0x399f28++] = _0x4c73dc;
    22. }
    23. return _0x2b11f1['apply'](null, _0x324511);
    24. }
    25. function _0x48d200(_0x4b706e, _0x3c3a85, _0x111154, _0x311f9f, _0x5439cf, _0x38cac7, _0x26bd2e) {
    26. return _0xaaef84(_0x3c3a85 & _0x111154 | ~_0x3c3a85 & _0x311f9f, _0x4b706e, _0x3c3a85, _0x5439cf, _0x38cac7, _0x26bd2e);
    27. }
    28. function _0x12e4a8(_0x7542c8, _0x5eada0) {
    29. var _0x41f81f = (0xffff & _0x7542c8) + (0xffff & _0x5eada0);
    30. return (_0x7542c8 >> 0x10) + (_0x5eada0 >> 0x10) + (_0x41f81f >> 0x10) << 0x10 | 0xffff & _0x41f81f;
    31. }
    32. function _0x3634fc(_0x5803ba, _0x1ce5b2) {
    33. return _0x5803ba << _0x1ce5b2 | _0x5803ba >>> 0x20 - _0x1ce5b2;
    34. }
    35. function _0x3180ec(_0x401705, _0x240e6a, _0x56b131, _0x5a5c20, _0x1f2a72, _0x2bfc1, _0x19741a) {
    36. return _0xaaef84(_0x240e6a & _0x5a5c20 | _0x56b131 & ~_0x5a5c20, _0x401705, _0x240e6a, _0x1f2a72, _0x2bfc1, _0x19741a);
    37. }
    38. function _0x32032f(_0x520fdf, _0x13921d, _0x1af9d5, _0x4a2311, _0xb6d40a, _0x1d58da, _0x361df0) {
    39. return _0xaaef84(_0x13921d ^ _0x1af9d5 ^ _0x4a2311, _0x520fdf, _0x13921d, _0xb6d40a, _0x1d58da, _0x361df0);
    40. }
    41. function _0x4b459d(_0x8d8f2a, _0x406d34, _0x53e7d7, _0x26c827, _0xec41ea, _0x52dead, _0x3f66e7) {
    42. return _0xaaef84(_0x53e7d7 ^ (_0x406d34 | ~_0x26c827), _0x8d8f2a, _0x406d34, _0xec41ea, _0x52dead, _0x3f66e7);
    43. }
    44. function _0xaaef84(_0xaf3112, _0x2a165a, _0x532fb4, _0x10aa40, _0x41c4e7, _0x1cb4da) {
    45. return _0x12e4a8(_0x3634fc(_0x12e4a8(_0x12e4a8(_0x2a165a, _0xaf3112), _0x12e4a8(_0x10aa40, _0x1cb4da)), _0x41c4e7), _0x532fb4);
    46. }
    47. function _0x11a7a2(_0x193f00, _0x1cfe89) {
    48. _0x193f00[_0x1cfe89 >> 0x5] |= 0x80 << _0x1cfe89 % 0x20,
    49. _0x193f00[0xe + (_0x1cfe89 + 0x40 >>> 0x9 << 0x4)] = _0x1cfe89;
    50. // try {
    51. // var _0x42fb36 = _0x4e96b4[_$UH[0x260]][_$UH[0x8]]['DONE'] * 0x4;
    52. // } catch (_0x1b1b35) {
    53. // var _0x42fb36 = 0x1;
    54. // }
    55. var _0x42fb36 = 4 * 0x4;
    56. op = 26;
    57. b64pad = 1;
    58. // try {
    59. // _0x4e96b4['$_z2'][0x0] = 'Q';
    60. // } catch (_0x4c574d) {
    61. // try {
    62. // op = _0x4e96b4['$_zw'][_$UH[0x6c]];
    63. // } catch (_0x58af26) {
    64. // var _0x3b7935 = 0x0;
    65. // for (var _0x1badc3 = 0x0; _0x1badc3 < 0xf4240; _0x1badc3++) {
    66. // _0x3b7935 = _0x3b7935 + _0x1badc3[_$UH[0x1f]]();
    67. // history['pushState'](0x0, 0x0, _0x3b7935);
    68. // }
    69. // }
    70. // if (op > 0x14) {
    71. // eval('b64pad = _0x4e96b4[\'$_zw\'][9][\'length\'];');
    72. // } else if (op < 0xa) {
    73. // _0x4e96b4['$_zw'] = [0x1, 0x8, 0x2, 0x4, 0x17, 0x2d, 0x8, 0xf, 0x51, 0x44, 0xd, 0x48, 0x46];
    74. // }
    75. // }
    76. var _0x1badc3, _0x38ca59, _0x431764, _0x43f1b4, _0x5722c0, _0x3e0c38 = _0x1171c8, _0xdb4d2c = _0x4dae05, _0x1724c5 = _0x183a1d, _0x257ec6 = _0xcfa373;
    77. // try {
    78. // if (_0x4e96b4['_$6_']) {} else {
    79. // _0x4e96b4['_$6_'] = 0x20dc5d57f;
    80. // }
    81. // } catch (_0x15bf3f) {
    82. // _0x4e96b4['_$6_'] = 0x2421603;
    83. // }
    84. window['_$6_'] = -389564586;
    85. window['_$tT'] = -660478335;
    86. window['_$Jy'] = -405537848;
    87. for (_0x1badc3 = 0x0; _0x1badc3 < _0x193f00['length']; _0x1badc3 += _0x42fb36)
    88. _0x38ca59 = _0x3e0c38,
    89. _0x431764 = _0xdb4d2c,
    90. _0x43f1b4 = _0x1724c5,
    91. _0x5722c0 = _0x257ec6,
    92. _0x3e0c38 = _0x48d200(_0x3e0c38, _0xdb4d2c, _0x1724c5, _0x257ec6, _0x193f00[_0x1badc3], 0x7, 0x7d60c),
    93. _0x257ec6 = _0x48d200(_0x257ec6, _0x3e0c38, _0xdb4d2c, _0x1724c5, _0x193f00[_0x1badc3 + 0x1], 0xc, _0x4e96b4['_$6_']),
    94. _0x1724c5 = _0x48d200(_0x1724c5, _0x257ec6, _0x3e0c38, _0xdb4d2c, _0x193f00[_0x1badc3 + 0x2], 0x11, 0x242070db),
    95. _0xdb4d2c = _0x48d200(_0xdb4d2c, _0x1724c5, _0x257ec6, _0x3e0c38, _0x193f00[_0x1badc3 + 0x3], 0x16, -0x3e423112),
    96. _0x3e0c38 = _0x48d200(_0x3e0c38, _0xdb4d2c, _0x1724c5, _0x257ec6, _0x193f00[_0x1badc3 + 0x4], 0x7, -0xa83f051),
    97. _0x257ec6 = _0x48d200(_0x257ec6, _0x3e0c38, _0xdb4d2c, _0x1724c5, _0x193f00[_0x1badc3 + 0x5], 0xc, 0x4787c62a),
    98. _0x1724c5 = _0x48d200(_0x1724c5, _0x257ec6, _0x3e0c38, _0xdb4d2c, _0x193f00[_0x1badc3 + 0x6], 0x11, -0x57cfb9ed),
    99. _0xdb4d2c = _0x48d200(_0xdb4d2c, _0x1724c5, _0x257ec6, _0x3e0c38, _0x193f00[_0x1badc3 + 0x7], 0x16, -0x2b96aff),
    100. _0x3e0c38 = _0x48d200(_0x3e0c38, _0xdb4d2c, _0x1724c5, _0x257ec6, _0x193f00[_0x1badc3 + 0x8], 0x7, 0x698098d8),
    101. _0x257ec6 = _0x48d200(_0x257ec6, _0x3e0c38, _0xdb4d2c, _0x1724c5, _0x193f00[_0x1badc3 + 0x9], 0xc, -0x74bb0851),
    102. _0x1724c5 = _0x48d200(_0x1724c5, _0x257ec6, _0x3e0c38, _0xdb4d2c, _0x193f00[_0x1badc3 + 0xa], 0x11, -0xa44f),
    103. _0xdb4d2c = _0x48d200(_0xdb4d2c, _0x1724c5, _0x257ec6, _0x3e0c38, _0x193f00[_0x1badc3 + 0xb], 0x16, -0x76a32842),
    104. _0x3e0c38 = _0x48d200(_0x3e0c38, _0xdb4d2c, _0x1724c5, _0x257ec6, _0x193f00[_0x1badc3 + 0xc], 0x7, 0x6b901122),
    105. _0x257ec6 = _0x48d200(_0x257ec6, _0x3e0c38, _0xdb4d2c, _0x1724c5, _0x193f00[_0x1badc3 + 0xd], 0xc, -0x2678e6d),
    106. _0x1724c5 = _0x48d200(_0x1724c5, _0x257ec6, _0x3e0c38, _0xdb4d2c, _0x193f00[_0x1badc3 + 0xe], 0x11, -0x5986bc72),
    107. _0xdb4d2c = _0x48d200(_0xdb4d2c, _0x1724c5, _0x257ec6, _0x3e0c38, _0x193f00[_0x1badc3 + 0xf], 0x16, 0x49b40821),
    108. _0x3e0c38 = _0x3180ec(_0x3e0c38, _0xdb4d2c, _0x1724c5, _0x257ec6, _0x193f00[_0x1badc3 + 0x1], 0x5, -0x9e1da9e),
    109. _0x257ec6 = _0x3180ec(_0x257ec6, _0x3e0c38, _0xdb4d2c, _0x1724c5, _0x193f00[_0x1badc3 + 0x6], 0x9, -0x3fbf4cc0),
    110. _0x1724c5 = _0x3180ec(_0x1724c5, _0x257ec6, _0x3e0c38, _0xdb4d2c, _0x193f00[_0x1badc3 + 0xb], 0xe, 0x265e5a51),
    111. _0xdb4d2c = _0x3180ec(_0xdb4d2c, _0x1724c5, _0x257ec6, _0x3e0c38, _0x193f00[_0x1badc3], 0x14, -0x16493856),
    112. _0x3e0c38 = _0x3180ec(_0x3e0c38, _0xdb4d2c, _0x1724c5, _0x257ec6, _0x193f00[_0x1badc3 + 0x5], 0x5, -0x29d0efa3),
    113. _0x257ec6 = _0x3180ec(_0x257ec6, _0x3e0c38, _0xdb4d2c, _0x1724c5, _0x193f00[_0x1badc3 + 0xa], 0x9, 0x2441453),
    114. _0x1724c5 = _0x3180ec(_0x1724c5, _0x257ec6, _0x3e0c38, _0xdb4d2c, _0x193f00[_0x1badc3 + 0xf], 0xe, _0x4e96b4['_$tT']),
    115. _0xdb4d2c = _0x3180ec(_0xdb4d2c, _0x1724c5, _0x257ec6, _0x3e0c38, _0x193f00[_0x1badc3 + 0x4], 0x14, _0x4e96b4['_$Jy']),
    116. _0x3e0c38 = _0x3180ec(_0x3e0c38, _0xdb4d2c, _0x1724c5, _0x257ec6, _0x193f00[_0x1badc3 + 0x9], 0x5, 0x21e1cde6),
    117. _0x257ec6 = _0x3180ec(_0x257ec6, _0x3e0c38, _0xdb4d2c, _0x1724c5, _0x193f00[_0x1badc3 + 0xe], 0x9, -0x3cc8aa0a),
    118. _0x1724c5 = _0x3180ec(_0x1724c5, _0x257ec6, _0x3e0c38, _0xdb4d2c, _0x193f00[_0x1badc3 + 0x3], 0xe, -0xb2af279),
    119. _0xdb4d2c = _0x3180ec(_0xdb4d2c, _0x1724c5, _0x257ec6, _0x3e0c38, _0x193f00[_0x1badc3 + 0x8], 0x14, 0x455a14ed),
    120. _0x3e0c38 = _0x3180ec(_0x3e0c38, _0xdb4d2c, _0x1724c5, _0x257ec6, _0x193f00[_0x1badc3 + 0xd], 0x5, -0x5caa8e7b),
    121. _0x257ec6 = _0x3180ec(_0x257ec6, _0x3e0c38, _0xdb4d2c, _0x1724c5, _0x193f00[_0x1badc3 + 0x2], 0x9, -0x3105c08),
    122. _0x1724c5 = _0x3180ec(_0x1724c5, _0x257ec6, _0x3e0c38, _0xdb4d2c, _0x193f00[_0x1badc3 + 0x7], 0xe, 0x676f02d9),
    123. _0xdb4d2c = _0x3180ec(_0xdb4d2c, _0x1724c5, _0x257ec6, _0x3e0c38, _0x193f00[_0x1badc3 + 0xc], 0x14, -0x72d5b376),
    124. _0x3e0c38 = _0x32032f(_0x3e0c38, _0xdb4d2c, _0x1724c5, _0x257ec6, _0x193f00[_0x1badc3 + 0x5], 0x4, -0x241282e),
    125. _0x257ec6 = _0x32032f(_0x257ec6, _0x3e0c38, _0xdb4d2c, _0x1724c5, _0x193f00[_0x1badc3 + 0x8], 0xb, -0x788e097f),
    126. _0x1724c5 = _0x32032f(_0x1724c5, _0x257ec6, _0x3e0c38, _0xdb4d2c, _0x193f00[_0x1badc3 + 0xb], 0x10, 0x6d9d6122),
    127. _0xdb4d2c = _0x32032f(_0xdb4d2c, _0x1724c5, _0x257ec6, _0x3e0c38, _0x193f00[_0x1badc3 + 0xe], 0x17, -0x21ac7f4),
    128. _0x3e0c38 = _0x32032f(_0x3e0c38, _0xdb4d2c, _0x1724c5, _0x257ec6, _0x193f00[_0x1badc3 + 0x1], 0x4, -0x5b4115bc * b64pad),
    129. _0x257ec6 = _0x32032f(_0x257ec6, _0x3e0c38, _0xdb4d2c, _0x1724c5, _0x193f00[_0x1badc3 + 0x4], 0xb, 0x4bdecfa9),
    130. _0x1724c5 = _0x32032f(_0x1724c5, _0x257ec6, _0x3e0c38, _0xdb4d2c, _0x193f00[_0x1badc3 + 0x7], 0x10, -0x944b4a0),
    131. _0xdb4d2c = _0x32032f(_0xdb4d2c, _0x1724c5, _0x257ec6, _0x3e0c38, _0x193f00[_0x1badc3 + 0xa], 0x17, -0x41404390),
    132. _0x3e0c38 = _0x32032f(_0x3e0c38, _0xdb4d2c, _0x1724c5, _0x257ec6, _0x193f00[_0x1badc3 + 0xd], 0x4, 0x289b7ec6),
    133. _0x257ec6 = _0x32032f(_0x257ec6, _0x3e0c38, _0xdb4d2c, _0x1724c5, _0x193f00[_0x1badc3], 0xb, -0x155ed806),
    134. _0x1724c5 = _0x32032f(_0x1724c5, _0x257ec6, _0x3e0c38, _0xdb4d2c, _0x193f00[_0x1badc3 + 0x3], 0x10, -0x2b10cf7b),
    135. _0xdb4d2c = _0x32032f(_0xdb4d2c, _0x1724c5, _0x257ec6, _0x3e0c38, _0x193f00[_0x1badc3 + 0x6], 0x17, 0x2d511fd9),
    136. _0x3e0c38 = _0x32032f(_0x3e0c38, _0xdb4d2c, _0x1724c5, _0x257ec6, _0x193f00[_0x1badc3 + 0x9], 0x4, -0x3d12017),
    137. _0x257ec6 = _0x32032f(_0x257ec6, _0x3e0c38, _0xdb4d2c, _0x1724c5, _0x193f00[_0x1badc3 + 0xc], 0xb, -0x1924661b),
    138. _0x1724c5 = _0x32032f(_0x1724c5, _0x257ec6, _0x3e0c38, _0xdb4d2c, _0x193f00[_0x1badc3 + 0xf], 0x10, 0x1fa27cf8),
    139. _0xdb4d2c = _0x32032f(_0xdb4d2c, _0x1724c5, _0x257ec6, _0x3e0c38, _0x193f00[_0x1badc3 + 0x2], 0x17, -0x3b53a99b),
    140. _0x3e0c38 = _0x4b459d(_0x3e0c38, _0xdb4d2c, _0x1724c5, _0x257ec6, _0x193f00[_0x1badc3], 0x6, -0xbd6ddbc),
    141. _0x257ec6 = _0x4b459d(_0x257ec6, _0x3e0c38, _0xdb4d2c, _0x1724c5, _0x193f00[_0x1badc3 + 0x7], 0xa, 0x432aff97),
    142. _0x1724c5 = _0x4b459d(_0x1724c5, _0x257ec6, _0x3e0c38, _0xdb4d2c, _0x193f00[_0x1badc3 + 0xe], 0xf, -0x546bdc59),
    143. _0xdb4d2c = _0x4b459d(_0xdb4d2c, _0x1724c5, _0x257ec6, _0x3e0c38, _0x193f00[_0x1badc3 + 0x5], 0x15, -0x36c5fc7),
    144. _0x3e0c38 = _0x4b459d(_0x3e0c38, _0xdb4d2c, _0x1724c5, _0x257ec6, _0x193f00[_0x1badc3 + 0xc], 0x6, 0x655b59c3),
    145. _0x257ec6 = _0x4b459d(_0x257ec6, _0x3e0c38, _0xdb4d2c, _0x1724c5, _0x193f00[_0x1badc3 + 0x3], 0xa, -0x70ef89ee),
    146. _0x1724c5 = _0x4b459d(_0x1724c5, _0x257ec6, _0x3e0c38, _0xdb4d2c, _0x193f00[_0x1badc3 + 0xa], 0xf, -0x644f153),
    147. _0xdb4d2c = _0x4b459d(_0xdb4d2c, _0x1724c5, _0x257ec6, _0x3e0c38, _0x193f00[_0x1badc3 + 0x1], 0x15, -0x7a7ba22f),
    148. _0x3e0c38 = _0x4b459d(_0x3e0c38, _0xdb4d2c, _0x1724c5, _0x257ec6, _0x193f00[_0x1badc3 + 0x8], 0x6, 0x6fa87e4f),
    149. _0x257ec6 = _0x4b459d(_0x257ec6, _0x3e0c38, _0xdb4d2c, _0x1724c5, _0x193f00[_0x1badc3 + 0xf], 0xa, -0x1d31920),
    150. _0x1724c5 = _0x4b459d(_0x1724c5, _0x257ec6, _0x3e0c38, _0xdb4d2c, _0x193f00[_0x1badc3 + 0x6], 0xf, -0x5cfebcec),
    151. _0xdb4d2c = _0x4b459d(_0xdb4d2c, _0x1724c5, _0x257ec6, _0x3e0c38, _0x193f00[_0x1badc3 + 0xd], 0x15, 0x4e0811a1),
    152. _0x3e0c38 = _0x4b459d(_0x3e0c38, _0xdb4d2c, _0x1724c5, _0x257ec6, _0x193f00[_0x1badc3 + 0x4], 0x6, -0x8ac817e),
    153. _0x257ec6 = _0x4b459d(_0x257ec6, _0x3e0c38, _0xdb4d2c, _0x1724c5, _0x193f00[_0x1badc3 + 0xb], 0xa, -1120211379),
    154. _0x1724c5 = _0x4b459d(_0x1724c5, _0x257ec6, _0x3e0c38, _0xdb4d2c, _0x193f00[_0x1badc3 + 0x2], 0xf, 0x2ad7d2bb),
    155. _0xdb4d2c = _0x4b459d(_0xdb4d2c, _0x1724c5, _0x257ec6, _0x3e0c38, _0x193f00[_0x1badc3 + 0x9], 0x15, -0x14792c01),
    156. _0x3e0c38 = _0x12e4a8(_0x3e0c38, _0x38ca59),
    157. _0xdb4d2c = _0x12e4a8(_0xdb4d2c, _0x431764),
    158. _0x1724c5 = _0x12e4a8(_0x1724c5, _0x43f1b4),
    159. _0x257ec6 = _0x12e4a8(_0x257ec6, _0x5722c0);
    160. return [_0x3e0c38, _0xdb4d2c, _0x1724c5, _0x257ec6];
    161. }
    162. function _0x12b47d(_0x149183) {
    163. var _0xabbcb3, _0x1145c3 = '', _0x4fce58 = 0x20 * _0x149183['length'];
    164. for (_0xabbcb3 = 0x0; _0xabbcb3 < _0x4fce58; _0xabbcb3 += 0x8)
    165. _0x1145c3 += _0x30bc70['fromCharCode'](_0x149183[_0xabbcb3 >> 0x5] >>> _0xabbcb3 % 0x20 & 0xff);
    166. return _0x1145c3;
    167. }
    168. function _0x35f5f2(_0x243853) {
    169. var _0x139b8b, _0xa791a1 = [];
    170. for (_0xa791a1[(_0x243853['length'] >> 0x2) - 0x1] = void 0x0,
    171. _0x139b8b = 0x0; _0x139b8b < _0xa791a1['length']; _0x139b8b += 0x1)
    172. _0xa791a1[_0x139b8b] = 0x0;
    173. var _0x41a533 = 0x8 * _0x243853['length'];
    174. for (_0x139b8b = 0x0; _0x139b8b < _0x41a533; _0x139b8b += 0x8)
    175. _0xa791a1[_0x139b8b >> 0x5] |= (0xff & _0x243853['charCodeAt'](_0x139b8b / 0x8)) << _0x139b8b % 0x20;
    176. return _0xa791a1;
    177. }
    178. function _0x2b8a17(_0x36f847) {
    179. return unescape(encodeURIComponent(_0x36f847));
    180. }
    181. function _0x1ee7ec(_0x206333) {
    182. return _0x12b47d(_0x11a7a2(_0x35f5f2(_0x206333), 8 * 13));
    183. }
    184. function _0x499969(_0x82fe7e) {
    185. var _0x5bdda4, _0x322a73, _0xd0b5cd = '0123456789abcdef', _0x21f411 = '';
    186. for (_0x322a73 = 0x0; _0x322a73 < _0x82fe7e['length']; _0x322a73 += 0x1)
    187. _0x5bdda4 = _0x82fe7e['charCodeAt'](_0x322a73),
    188. _0x21f411 += _0xd0b5cd['charAt'](_0x5bdda4 >>> 0x4 & 0xf) + _0xd0b5cd['charAt'](0xf & _0x5bdda4);
    189. return _0x21f411;
    190. }
    191. function _0x41873d(_0x5a6962) {
    192. return _0x1ee7ec(_0x2b8a17(_0x5a6962));
    193. }
    194. function _0x37614a(_0x32e7c1) {
    195. return _0x499969(_0x41873d(_0x32e7c1));
    196. }
    197. function _0x474032(_0x233f82, _0xe2ed33, _0x3229f9) {
    198. return _0xe2ed33 ? _0x3229f9 ? v(_0xe2ed33, _0x233f82) : y(_0xe2ed33, _0x233f82) : _0x3229f9 ? _0x41873d(_0x233f82) : _0x37614a(_0x233f82);
    199. }
    200. var CryptoJS = require('crypto-js');
    201. function RM4(_$yw, pr){
    202. var value = Buffer.from(_$yw).toString('base64').slice(0, 16);
    203. var srcs = CryptoJS.enc.Utf8.parse(pr);
    204. var key = CryptoJS.enc.Utf8.parse(value);
    205. var encrypted = CryptoJS.AES.encrypt(srcs, key, {
    206. mode: CryptoJS.mode.ECB,
    207. padding: CryptoJS.pad.Pkcs7
    208. });
    209. return encrypted.toString();
    210. }
    211. function getCookie() {
    212. pr = [];
    213. for (i = 1; i < 5; i++) {
    214. var _$Wa = Date['parse'](new Date()).toString();
    215. pr['push'](_0x474032(_$Wa))
    216. }
    217. _$yw = new Date()['valueOf']().toString();
    218. pr['push'](_0x474032(_$yw));
    219. cookie_m = pr[4];
    220. cookie_RM4 = RM4(_$yw, pr['toString']());
    221. return{
    222. "cookie_m": cookie_m,
    223. "cookie_RM4": cookie_RM4,
    224. "m": _$yw,
    225. "f": _$Wa
    226. }
    227. }
    228. // console.log(getCookie());

    运行结果:

    python 代码 

    sessionid 要改为自己的: 

    1. import execjs
    2. import requests
    3. import re
    4. headers = {
    5. "user-agent": "yuanrenxue,project",
    6. }
    7. def main():
    8. heat_value_total = []
    9. for page_num in range(1, 6):
    10. with open('yrx5.js', 'r', encoding='utf-8') as f:
    11. encrypt = f.read()
    12. encrypt_params = execjs.compile(encrypt).call('getCookie')
    13. cookies = {
    14. "sessionid": " your sessionid ",
    15. "m": encrypt_params['cookie_m'],
    16. "RM4hZBv0dDon443M": encrypt_params['cookie_RM4']
    17. }
    18. params = {
    19. "m": encrypt_params['m'],
    20. "f": encrypt_params['f']
    21. }
    22. url = "https://match.yuanrenxue.com/api/match/5?page=%s" % page_num
    23. response = requests.get(url, headers=headers, cookies=cookies, params=params)
    24. for i in range(10):
    25. value = response.json()['data'][i]
    26. heat_value = re.findall(r"'value': (.*?)}", str(value))[0]
    27. heat_value_total.append(heat_value)
    28. heat_value_total.sort(reverse=True)
    29. top_three_sum = 0
    30. for i in range(5):
    31. top_three_sum += int(heat_value_total[i])
    32. print(top_three_sum)
    33. if __name__ == '__main__':
    34. main()
  • 相关阅读:
    下一代架构设计:云原生、容器和微前端的综合应用
    多个Bean自动注入成Map @Autowired @Service 策略模式
    每天一道算法题:125. 验证回文串
    【原创】基于SSM的体育场地预约管理系统(毕业设计源码)
    Mysql 、Redis 数据双写一致性 更新策略与应用
    nmap端口扫描工具——LInux
    Java版分布式微服务云开发架构 Spring Cloud+Spring Boot+Mybatis 电子招标采购系统功能清单
    设计模式 -- 状态模式(State Pattern)
    ES的常用查询
    联想刘军:做深做透全栈AI产品方案和服务,建立差异化竞争优势
  • 原文地址:https://blog.csdn.net/Yy_Rose/article/details/126622701