小言_互联网的博客

Python 爬虫进阶必备 | 某爬虫练习站之 js 混淆

356人阅读  评论(0)

今日网站

aHR0cDovL21hdGNoLnl1YW5yZW54dWUuY29tL21hdGNoLzE=

这个网站是某大佬搭建的闯关网站

无限 debugger 的绕过

打开开发者工具会出现 debugger

直接在 debugger 对应的行号,右键选择Never pause here即可跳过

抓包分析与定位

跳过 debugger,通过网络面板,找到我们需要分析的参数是下面这个请求的m参数

参数名字只有一个m,直接检索的话就会出现下面这么多的结果,所以放弃直接检索这个参数来查找位置。

所以转换思路,使用xhr断点查找参数位置

找到如下位置即为m参数的生成位置

这里没办法格式化,不好查看对应的逻辑,所以拷贝到 IDE 中查看

定位m可以看到下面的逻辑

这里的moo0O0window.f的值相加得到

加密分析与实现

上面我们定位了m的生成位置,这里需要分析出m的表达式的oo0O0window.f

先看oo0O0


   
  1. function oo0O0(mw) {
  2.     window.b =  '';
  3.      for ( var i =  0len = window.a.length; i <  len; i++) {
  4.         console.log(window.a[i]);
  5.         window.b += String[document.e + document.g](window.a[i][document.f + document.h]() - i - window.c)
  6.     }
  7.      var U = [ 'W5r5W6VdIHZcT8kU''WQ8CWRaxWQirAW=='];
  8.      var J = function (o, E) {
  9.         o = o -  0x0;
  10.          var N = U[o];
  11.          if (J[ 'bSSGte'] === undefined) {
  12.              var Y = function (w) {
  13.                  var m =  'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=',
  14.                     T = String(w)[ 'replace'](/=+$/,  '');
  15.                  var A =  '';
  16.                  for ( var C =  0x0, b, W, l =  0x0; W = T[ 'charAt'](l++); ~W && (b = C %  0x4 ? b *  0x40 + W : W, C++ %  0x4) ? A += String[ 'fromCharCode']( 0xff & b >> ( -0x2 * C &  0x6)) :  0x0) {
  17.                     W = m[ 'indexOf'](W)
  18.                 }
  19.                  return A
  20.             };
  21.              var t = function (w, m) {
  22.                  var T = [], A =  0x0, C, b =  '', W =  '';
  23.                 w = Y(w);
  24.                  for ( var R =  0x0, v = w[ 'length']; R < v; R++) {
  25.                     W +=  '%' + ( '00' + w[ 'charCodeAt'](R)[ 'toString']( 0x10))[ 'slice']( -0x2)
  26.                 }
  27.                 w = decodeURIComponent(W);
  28.                  var l;
  29.                  for (l =  0x0; l <  0x100; l++) {
  30.                     T[l] = l
  31.                 }
  32.                  for (l =  0x0; l <  0x100; l++) {
  33.                     A = (A + T[l] + m[ 'charCodeAt'](l % m[ 'length'])) %  0x100, C = T[l], T[l] = T[A], T[A] = C
  34.                 }
  35.                 l =  0x0, A =  0x0;
  36.                  for ( var L =  0x0; L < w[ 'length']; L++) {
  37.                     l = (l +  0x1) %  0x100, A = (A + T[l]) %  0x100, C = T[l], T[l] = T[A], T[A] = C, b += String[ 'fromCharCode'](w[ 'charCodeAt'](L) ^ T[(T[l] + T[A]) %  0x100])
  38.                 }
  39.                  return b
  40.             };
  41.             J[ 'luAabU'] = t, J[ 'qlVPZg'] = {}, J[ 'bSSGte'] = !![]
  42.         }
  43.          var H = J[ 'qlVPZg'][o];
  44.          return H === undefined ? (J[ 'TUDBIJ'] === undefined && (J[ 'TUDBIJ'] = !![]), N = J[ 'luAabU'](N, E), J[ 'qlVPZg'][o] = N) : N = H, N
  45.     };
  46.     eval(atob(window[ 'b'])[J( '0x0'']dQW')](J( '0x1''GTu!'),  '\x27' + mw +  '\x27'));
  47.      return  ''
  48. }

直接复制在控制台运行,得到结果是空

那么m的值由window.f决定,window.f在逻辑中没有找到。

但是每次运行oo0O0都会改变window.f的值,所以问题还是出在oo0O0中,所以进一步分析oo0O0的逻辑

oo0O0中虽然返回值是空的字符串,但是在返回前执行了下面这行代码

eval(atob(window['b'])[J('0x0'']dQW')](J('0x1''GTu!'), '\x27' + mw + '\x27'));

通过执行atob(window['b'])得到下面这一大串的逻辑

这里面就包含了window.f

再结合oo0O0中的JU可以得出J('0x0', ']dQW')J('0x1', 'GTu!')的结果如下

这样原有的代码

eval(atob(window['b'])[J('0x0'']dQW')](J('0x1''GTu!'), '\x27' + mw + '\x27'));

可以等价为


   
  1. // 这里的省略号为上面 atob(window['b']) 的结果
  2. eval( '........hex_md5(mwqqppz)'.replace( 'mwqqppz''\x27' + mw +  '\x27'));

所以这里的加密是通过将 hex_md5 的主体加密逻辑隐藏在 base64 编码里,然后将关键的参数通过字符串替换的方式替换,再使用eval执行

厉害厉害,比一般的商业网站还会玩

好了,今天的文章就到这里了,咱们下次再会~

对了,看完记得一键四连,这个对我真的很重要。


转载:https://blog.csdn.net/weixin_43189702/article/details/114811726
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场