记录一次逆向小程序破解加密js的方法

逆向js加密可以说是一项特别有难度的技能。小程序目前(以后就不知道)相对安卓来说是比较好逆向的,因为安卓app要上架应用市场,按国家规定必须得要加固的,所以反编译出安卓app的源码比较难,相比而言小程序源码就很容易反编译出来。

首先声明: 此次逆向Js只为学习交流使用,切勿用于其他非法用途,关键代码均打码

  • 首先找到小程序的安装包,可以找个手机,点开小程序后,找到手机文件目录。
#  一般是这样的目录, 当然有的手机我找了很多就是没有,
/data/data/com.tencent.mm/MicromMsg/3444assdaqwqeqwe..../appbrand/pkg/*.wxapkg
# 当然你如果用的某模拟器的话, 可以把问件复制到以下文件夹取出
# /mnt/shared/Other

然后剩下的就是反编译的事情了。

开始逆向

准备工具

  • 微信开发者工具(需要任意的开发者账号登陆)
  • charles抓包工具(需要配置SSL证书)

首先源代码是这样的 在这里插入图片描述 里面全是这种 "0x3" 这种字符, 第一眼看上去非常蒙,0x开头看上去像16进制的,后面发现上面有一排定义变量的列表,看起来似乎有些奇怪。 在这里插入图片描述 然后在看下上面的js代码,发现列表里面的变量应该是放到下面 0x3这种字符串的。然后照着思路,用Python写了一段脚本,把变量给还原。如下图. 在这里插入图片描述

突破第一关,感觉感觉和打游戏一样,一关一关突破,特别有成就感。

后来才知道,这个代码使用 javascript-obfuscator 这种方式混淆的,就是变量的一些替换,参考 网站 http://blog.w3cub.com/blog/2019/04/01/js-confusion/

虽然目前突破了很多,但是依据不知道从何看起,于是我们开始从抓的接口入手,全局搜索关键的参数。接口返回值类似以下这种:

post https://xxx.xxx.com/xx/getList
# 一些header
# 请求json data
{
    "ct": "xxxxxxxxxxxxxxxxxxsTgmWw7daVIPgHybg4A5OzJk7SUsD+76+KshYmiwCxUfGh1XO2UkwAgcpAbIjNg2gOhVUlZYpDzxjLbmD7vExvZgCGiQ4G25Uftd/Pt/hVctE2lMMLVHY8xzyv3Qrf8MmldLzyCvc6olNKyIs4bY/nKTdyC3YM/4TkXNouLNWoGY/h618Mq0H+1pd2Co8e6NfiZ8+1axwkiebN8cagIG1yCdW4oH83zeK+AjCavorDVMm",
    "iv": "xxxxxxxxxxxac200a8059d86fc65651bbc68b",   // 长度32
    "s": "xxxxxx6dfb6e66"
}

# 返回的json 一样格式的json
{
    "ct": "特别长的字符串xxxxxxxxxxxxxxxxxxsTgmWw7daVIPgHybg4A5OzJk7SUsD+76+KshYmiwCxUfGh1XO2UkwAgcpAbIjNg2gOhVUlZYpDzxjLbmD7vExvZgCGiQ4G25Uftd/Pt/hVctE2lMMLVHY8xzyv3Qrf8MmldLzyCvc6olNKyIs4bY/nKTdyC3YM/4Txxx.....",
    "iv": "xxxxxxxxxxxxxxxxxxxxx",    // 长度32
    "s": "xxxxxxxxxexxxxxxx"
}

看到抓取的iv参数的时候,第一反应用的是aes加密,aes有好几种加密方式,光知道这个参数也毫无卵用,于是我全局开始搜索 post 地址的关键参数getList,果不其然,没有搜索到。 因为有时候别人为了防止被逆向,不会直接在代码里面写上getlist 这样的变量,而是通过单个字母,然后通过一系列的干扰操作,然后合成这个变量,所以全局搜索根本就搜不到。搜到的只是单个字母,而单个字母,在整个项目代码里面,跟没有一样。(tip: 有时候用ide配合正则全局搜索,会有意想不到的结果)

换个思路,着手试着启动下小程序hook一下,试着看看各个参数,跑起来究竟是什么。(其中有些小坑,比如设置不校验域名合法之类的) 稍微可行,但是还是有些盲目,于是我开始搜索发送post请求的地方,没想到居然给搜出来了。 在这里插入图片描述 但是还是不明白,没办法就只能一步步向上,看这个a函数在哪被引用,这时候就很枯燥了,其中还有很多js函数的小知识点,比如闭包函数呀,还有什么js的常量参数,没有js的知识,基本到这里 就劝退了。

.........

经过很长时间,我终于找到了生成关键参数所在的位置! 在这里插入图片描述 我所打印的o就是生成的参数,e就是加密之前的原始参数,基本就和请求参数对上了。然后试着用这个参数,用Python requests函数,模拟着发送一次请求, 测试看看,测试发现成功返回了,参数看来是正确的。

于是就开始,往上找e这个参数经过的路由函数,一顿找,边找边调试。 ....

终于找到了加密的地方所在。代码里面引入了很多加密的库文件,但是用到的只有md5 和 aes 库。

具体代码我就不贴出来了。写了很多干扰 无用的js函数,幸好能调试,一步步打印找到了。然后用node.js环境本地把关键的地方复制出来,跑一遍,测试能否生成一样的参数

本想着用Python还原aes加密解密的, 实现来实现去,还是和原始js生成的不一样。算了还是直接用 pyexecjs 库直接调用js函数,虽然性能上慢一些,但是不碍事。

至此加密解密就结束了。

  • 总结:
  • [x] wx小程序的写法,文件目录结构都比较统一,而且基本都是js代码,但是安卓客户端就不一样了,难度一下子就高了起来。
  • [x] 客户端的加密解密都是能破解的,这次逆向,我觉得最主要的就是能跑起来,可以调试。当然不能跑起来,也能找到加密解密方法,但是耗时和难度就更长一些。
  • [x] 逆向js说实话,经验作用不是太大,无非就是工具熟练一些,因为要面对的是不同公司写的加密解密代码,所以每次逆向都是新的挑战。

文章作者: 王小右
版权声明: 咳咳想白嫖文章?本文章著作权归作者所有,任何形式的转载都请注明出处。 https://www.charmcode.cn !
  目录