当前位置:   article > 正文

JS安全防护算法与逆向分析——webpack改写方案

webpack改写

webpack改写方案

本次案例以天安保险登录为例。

首先是XHR断点,断到关键部位,之后查看右边的调用堆栈,找到password相关,进入加密JS。突然卡死了,原来要扣的代码特别多,而且循环嵌套,会引用其他包,需要的代码太多了,有十二万行!!最外边是一个括号包含webpack,是一个数组,压入了许多数据。但是这些文件都是直接被压入的,里边导入的包没有运行。

那我们在console里先执行webpack,之后取出函数来看能不能运行?不行,因为缺少参数,这样一来第一反应是其他地方调用了。我们在首页里边查看script,发现引用了不少script文件,但是你单独去调试它们的话,因为网站过大可能会卡死奔溃。

  1. <script type="text/javascript" src="runtime.288d04140a139e9db1a1.js"></script>
  2. <script type="text/javascript" src="polyfills.fe1c0f9fd9f3421c06da.js"></script>
  3. <script type="text/javascript" src="vendor.fa7691b546a5ad5b0c54.js"></script>
  4. <script type="text/javascript" src="main.106c62a84f7eaae10682.js"></script>
  5. <script src="assets/js/slideVerification.js"></script>

我们进入第一个script,发现里边定义了webpack,这里它覆盖了push方法,那我们一开的找到的push方法就会调用这个。那显然这些脚本使我们需要的,我们下断点,调试进入

  1. var i = window.webpackJsonp = window.webpackJsonp || []
  2. , f = i.push.bind(i);
  3. i.push = r,
  4. i = i.slice();
  5. for (var c = 0; c < i.length; c++)
  6. r(i[c]);
  7. var l = f;
  8. t()

发现了一个非常关键的call方法

  1. function a(r) {
  2. if (n[r]) return n[r].exports;
  3. var t = n[r] = {
  4. i: r,
  5. l: !1,
  6. exports: {
  7. }
  8. };
  9. return e[r].call(t.exports, t, t.exports, a),
  10. t.l = !0,
  11. t.exports
  12. }

我们进入查看,发现它能够回调函数,那这个玩意就关键的很了,我们需要把它抠出来

  1. 1: function (t, n, e) {
  2. t.exports = e('hN/g')
  3. },

它在一个匿名函数里边,我们怎么拿出来呢?很好办,我们定义一个全局变量取出来即可,比如losenine,

  1. this.window=this;
  2. var losenine=null;
  3. !function (e) {
  4. function r(r) {
  5. for (var n, a, i = r[0], f = r[1], c = r[2], d = 0, p = [
  6. ]; d < i.length; d++) a = i[d],
  7. o[a] && p.push(o[a][0]),
  8. o[a] = 0;
  9. for (n in f) Object.prototype.hasOwnProperty.call(f, n) && (e[n] = f[n]);
  10. for (l && l(r); p.length; ) p.shift() ();
  11. return u.push.apply(u, c || [
  12. ]),
  13. t()
  14. }
  15. function t() {
  16. for (var e, r = 0; r < u.length; r++) {
  17. for (var t = u[r], n = !0, i = 1; i < t.length; i++) {
  18. var f = t[i];
  19. 0 !== o[f] && (n = !1)
  20. }
  21. n && (u.splice(r--, 1), e = a(a.s = t[0]))
  22. }
  23. return e
  24. }
  25. var n = {
  26. },
  27. o = {
  28. 0: 0
  29. },
  30. u = [
  31. ];
  32. function a(r) {
  33. if (n[r]) return n[r].exports;
  34. var t = n[r] = {
  35. i: r,
  36. l: !1,
  37. exports: {
  38. }
  39. };
  40. return e[r].call(t.exports, t, t.exports, a),
  41. t.l = !0,
  42. t.exports
  43. }
  44. losenine=a;
  45. a.e = function (e) {
  46. var r = [
  47. ],
  48. t = o[e];
  49. if (0 !== t) if (t) r.push(t[2]);
  50. else {
  51. var n = new Promise(function (r, n) {
  52. t = o[e] = [
  53. r,
  54. n
  55. ]
  56. });
  57. r.push(t[2] = n);
  58. var u,
  59. i = document.createElement('script');
  60. i.charset = 'utf-8',
  61. i.timeout = 120,
  62. a.nc && i.setAttribute('nonce', a.nc),
  63. i.src = function (e) {
  64. return a.p + '' + ({
  65. }
  66. [
  67. e
  68. ] || e) + '.' + {
  69. 1: 'd9234d91e50a53c6ac2e',
  70. 6: '19a0da142e67165fe85a',
  71. 7: '9e63622e2f9e88f9c1f5',
  72. 8: '79d337966225585daf3f',
  73. 9: 'bf347bd0b85841d3696a',
  74. 10: '723594d0cc27a410d93f',
  75. 11: 'de941b69ea0b58948bb8',
  76. 12: '3090819dee86121eba12',
  77. 13: 'c158abd12f23735e1d20'
  78. }
  79. [
  80. e
  81. ] + '.js'
  82. }(e),
  83. u = function (r) {
  84. i.onerror = i.onload = null,
  85. clearTimeout(f);
  86. var t = o[e];
  87. if (0 !== t) {
  88. if (t) {
  89. var n = r && ('load' === r.type ? 'missing' : r.type),
  90. u = r && r.target && r.target.src,
  91. a = new Error('Loading chunk ' + e + ' failed.\n(' + n + ': ' + u + ')');
  92. a.type = n,
  93. a.request = u,
  94. t[1](a)
  95. }
  96. o[e] = void 0
  97. }
  98. };
  99. var f = setTimeout(function () {
  100. u({
  101. type: 'timeout',
  102. target: i
  103. })
  104. }, 120000);
  105. i.onerror = i.onload = u,
  106. document.head.appendChild(i)
  107. }
  108. return Promise.all(r)
  109. },
  110. a.m = e,
  111. a.c = n,
  112. a.d = function (e, r, t) {
  113. a.o(e, r) || Object.defineProperty(e, r, {
  114. enumerable: !0,
  115. get: t
  116. })
  117. },
  118. a.r = function (e) {
  119. 'undefined' != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, {
  120. value: 'Module'
  121. }),
  122. Object.defineProperty(e, '__esModule', {
  123. value: !0
  124. })
  125. },
  126. a.t = function (e, r) {
  127. if (1 & r && (e = a(e)), 8 & r) return e;
  128. if (4 & r && 'object' == typeof e && e && e.__esModule) return e;
  129. var t = Object.create(null);
  130. if (a.r(t), Object.defineProperty(t, 'default', {
  131. enumerable: !0,
  132. value: e
  133. }), 2 & r && 'string' != typeof e) for (var n in e) a.d(t, n, (function (r) {
  134. return e[r]
  135. }).bind(null, n));
  136. return t
  137. },
  138. a.n = function (e) {
  139. var r = e && e.__esModule ? function () {
  140. return e.default
  141. }
  142. : function () {
  143. return e
  144. };
  145. return a.d(r, 'a', r),
  146. r
  147. },
  148. a.o = function (e, r) {
  149. return Object.prototype.hasOwnProperty.call(e, r)
  150. },
  151. a.p = '',
  152. a.oe = function (e) {
  153. throw console.error(e),
  154. e
  155. };
  156. var i = window.webpackJsonp = window.webpackJsonp || [
  157. ],
  158. f = i.push.bind(i);
  159. i.push = r,
  160. i = i.slice();
  161. for (var c = 0; c < i.length; c++) r(i[c]);
  162. var l = f;
  163. t()
  164. }([]);

显然,这样我们就可以在外边操作这个回调函数了。

之后就是把那十二万行的巨额webpack放在我们的这个回调函数下边,然后写我们自己的调用函数去除加密结果

  1. function test(){
  2. var t = c.enc.Utf8.parse('t171420100302rsa'),
  3. n = c.enc.Utf8.parse('t171420100302rsa'),
  4. e = c.enc.Utf8.parse('{\"body\":{\"loginMethod\":\"1\",\"name\":\"13520791022\",\"password\":\"123456789\"},\"head\":{\"userCode\":\"13520791088\",\"channelCode\":\"101\",\"transTime\":1589554105813,\"transToken\":\"\",\"customerId\":null,\"transSerialNumber\":\"\"}}'),
  5. a = c.AES.encrypt(e, t, {
  6. iv: n,
  7. mode: c.mode.CBC,
  8. padding: c.pad.Pkcs7
  9. });
  10. return c.enc.Base64.stringify(a.ciphertext)
  11. }

我们运行一下,完毕。

  1. -----------------------------运行结果-----------------------------
  2. NBLetNAD6tHSqG1kmgP12SFiv6oyyRDdvklJemP+PaWrJqZR5Q0Uh7Bd0P1PEWmQCZ7pTCy4yKvrnybusMV3iqREjywYAqWfDykowenMf3s9N0+hvsoU2SVY2xVXUx0k9DrYQaHQ1ipE2QK+2mekVQ03uxjwNdHA5JbHYbE5fUHQk0N+Pfcw/wSY0GIHz3J4idb7eDp++fb0V163aR1ajNleNRPffRNbqk4OrGIPsX8Uvwin1oCoIUT3s1bASOaq5/um9iiZbQKpK7JmW5I9NocG9jPR8fEfPtO4vhwfoBE=
  3. -----------------------------运行结果-----------------------------

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/945485
推荐阅读
  

闽ICP备14008679号