mouzhunwang webpack 逆向分析

You konw more than you think you do. ——《了不起的麦瑟尔夫人》

你远比自己想象的要出色。

PS: 本文仅供学习参考、仅供学习参考、仅供学习参考,不得用于商业用途。

请求分析

本次目标站点

aHR0cHM6Ly93d3cua2Fuemh1bi5jb20vZmlybS93YWdlLzFuVl8ydGt+Lmh0bWw/a2E9Y29tLXNhbGFyeS1tb2R1bGUtZXhwb3Nl

  经过分析可以明显看到该请求的参数以及响应都是加密过的。

JS 分析

  全局搜索大法,搜索关键词 kiv,最终仅有一个文件含有该关键词,进入该文件,再次搜索 kiv,发现共出现15次,好像有点多,继续往下看

  在第二次出现 kiv 的地方发现了 400 和 200,这俩怎么看怎么像响应状态码,但是这里仅有参数 kiv 没有 参数 b,指定不是发请求的地方,继续往下看

  经过多次寻找与测试,最终在1万3千来行附近找到了构造请求参数的地方,同样也是发请求的地方

  为了方便调试,如下图所示打上一个条件断点

  这个站点直接刷新是断不上断点的,需要点击其他板块,再点击需要分析的板块才能成功断上,如下图

参数 b 和 kiv

  通过上图我们可以看到参数 kiv 就是 o,参数 b 就是 t,接下来我们挨个分析。

  将关键代码扣下来,精简一下

  可以看到 t 的生成需要 o,而 o 是由 P._A() 生成的。在控制台输出测试一下,发现每次执行的结果都不一样,P._A 这个方法很好扣,但是我们需要的不止这一点,因为不管是 o 的生成还是 t 的生成都需要 P,那我们往上找找 P 是怎么来的

  P 是由 n(60591) 生成的,在这个位置打个断点刷新一下,跟进去

   发现进入到了另一个 js 文件,这个文件仅有一百来行,加载器就在这,将其全部扣下里放进编辑器里

   将之前第一次分析的 js 文件整个扣下来,放到编辑器另一个文件中,折叠一下代码,有11万行

  掐头去尾将大括号里的所有模块都扣下来,放到加载器中,如下图,一定不要忘了大括号

  接下来我们需要修改下这个自执行函数,因为我们需要在自执行函数外部调用,所以需要声明一个全局变量 get_P,并且自执行函数里的一些方法也都属于 t,所以在函数最后新增一行,在开头添加一个参数 r,并将在函数中声明的一些变量修改,如下图

  运行一下,报错了 self is not defined,定位到错误的位置,将 self 修改为 window,并在最开头声明一个 window

  再次运行,报错 P is not defined,利用全局变量 get_P 去声明一下 P

  再次运行,打印参数 o,可以正常输出了。接下来分析 t,参数 t 还需要一个参数 n,回到控制台重新断点

  执行到合适的位置,在控制台查看,发现 encCompanyId 的值有点眼熟,然后你抬头看了眼链接,😯哦!原来在链接里

  然后发现代码少扣了一行,尴尬😅

  将这行代码扣下来精简一下,然后打印,正常输出

  通过 Postman 模拟一下请求,响应状态码 200 且有响应内容

响应加密

  还记得上面在搜索 kiv 时,疑似状态码的地方吗!在这打上断点,成功断上

  经过调试,发现在执行到 JSON.parse(t) 的时候响应明文就出来了,并且这边也有一个 P

  将关键代码扣下来精简一下,上图中的 e.data 就是加密的响应,kiv 和上面生成的一致

精简代码

  跟到上面这一步,修改一下就已经可以用 Python 调用了,但是这11万行实在是太多了,不优雅

  在代码开头声明两个全局变量,并在加载器新增如下图代码

  在代码尾部加上一个 debugger,并将加解密代码放开,保证都会运行

  执行调试,并将控制台输出的内容清空,输入 codes 然后回车,然后将输出的内容全部复制下来,替换到自执行函数中

  最后一大堆模块就剩两个了,再次运行,结果正常。11万行就剩下5千来行了,nice!

写在最后

  至此整个加密分析与 webpack 加密代码扣取结束,将加解密逻辑封装一下就可以使用了,你要是想更优雅,可以考虑将整体逻辑使用 Python 或其他语言复现。如果觉得这篇文章有不足之处,欢迎您的留言。

参考:
JavaScript之webpack加密代码扣取
webpack导出方法 - HKEN_