首先还是来看看这个小程序的要求流量。当正凡人一眼望去,丝毫理不清通报的是什么,我们基本就可以断定,其对流量进行了加密处理。
然后我们再看看返回要求——依然一头雾水:
经由上面两张图,可以判断这个小程序存在流量加密的情形。至于是全局的流量加密,还是部分流量加密,这个须要经由剖析之后才能判断。

如果只是部分流量加密,那么还可以测一测有没有漏网之鱼,如果是全局流量加密的话,就必须对小程序进行逆向获取源代码,再进行剖析了。
对某信小程序的逆向采取某神仙仿照器加一个6.X版的某信。由于高版本的安卓和某信不再信赖系统的证书,这会造成无法抓包的情形,以是利用安卓5加6.X版本的某信。
再参考网上的文章,从仿照器中脱到了小程序的wxapkg文件。这个文件在我的环境中位于:
/data/data/com.tencent.mm/MicroMsg/7e3e7c706/appbrand/pkg
由于小程序比较多,不知道哪一个才是目标文件。通过adb把这几个wxapkg文件全部下载下来,然后便是从wxapkg文件中提取源代码,这里利用wxappUnpacker一键提取:
获取到的目标小程序的源代码文件构造如下,之后便是进入剖析阶段了。
二、剖析式
【→所有资源关注我,私信回答“资料”获取←】1、网络安全学习路线2、电子书本(白帽子)3、安全大厂内部视频4、100份src文档5、常见安全口试题6、ctf大赛经典题目解析7、全套工具包8、应急相应条记
进入代码审计环节,来剖析前真个代码算法。
上面的小程序经由逆向,获取到的源代码构造如下:
由于之前没有剖析过某信小程序,以是这里首先学习了一下小程序的一些基本知识。重点有两个,第一个是app.js,这个文件是全体项目的入口文件,通过App()方法来注册一个小程序,并确定了全体程序的生命周期。
第二个便是module.exports,某信小程序的模块化,个人理解便是对外暴露的方法,可以供其他方法调用这个模块,类似于public方法。
理解完上面这两个点,再回到项目的源代码本身,通过浏览全体文件构造,创造对付加密的方法定义都位于/utils文件下。
个中须要关注的是encrypt.js文件,里面定义了关于流量的加解密方法。直接上代码。
从上面的代码中看到encrypt.js通过module.exports对外暴露了encrypt和decrypt两个方法。这两个该当便是用于对流量进行加密和解密的方法了。先来剖析encrypt函数:
Encrypt函数通报两个参数e和n,然后将参数n通过r函数处理之后赋值给s,个中r函数内容如下。为了安全里面的字符串,截取长度均已经修正,与原程序不同:
r函数将通报的参数截取一段然后与字符串进行拼接,然后利用SHA256函数署名,再截取中间一部分,将字母转换成大写之后返回。
再回到encrypt函数,变量i存储的AES加密解密的密钥,此处利用硬编码的办法写在代码当中。然后变量u存储格式化之后的s变量,变量c存储格式化之后的参数e。
之后便是加密部分了。
先理解一下AES的加密。对付AES有不同的模式,本程序中利用了CBC的模式,这种模式是先将明文切分成多少小段,然后每一小段与初始块或者上一段的密文段进行异或运算后,再与密钥进行加密。
在利用CBC模式进行加解密过程中,须要定义一个初始向量。初始向量用于随机数据加密,达到的效果是对相同的明文,通报相同的密钥。不同的初始向量可以产生不同的密文。
再回到代码本身。可以看到encrypt函数调用了AES模块的encrypt方法进行加密,通报的参数,依次为c明文,i密钥,然后变量u表示初始向量,采取CBC模式进行加密。
Encrypt函数剖析完了,再看decrypt函数,上代码:
Decrypt函数还是通报两个参数e,s然后通过formatString函数将参数e处理一下,个中formString函数详细内容如下,对e参数进行去除换行空格的处理:
变量i还是存储r函数处理后的参数s,变量u存储的还是格式化的密钥,变量c存储格式化后的变量i,末了调用AES模块的decrypt函数进行解密,结果存储在变量o当中。
进行解密的参数通报,e密文,u密钥,c初始化向量,采取CBC模式解密。这里加密和解密的初始化向量都是由r函数进行处理的。
在上面剖析中,加密解密通报的都是两个参数,然后个中一个参数是用于天生初始向量的。由于在上面的过程中,这个参数不是固定的,以是须要剖析这个参数的来源,这样才能完全的对全体数据进行解密。
再回到项目本身,在app.js中引入了一个request.js文件,在这个文件当中封装了http要求的方法,并对外暴露接口:
在第108行中,有一段代码:
r=(0,n.encrypt)(JSON.stringify(r),d)
这段代码该当便是调用加密函数对要求数据进行了加密。这里通报了两个参数,个中d参数便是加密过程中用于天生iv向量的参数,而在第103行末了可以看到,d参数的来源是函数getRandomUuid。接下来看看这个函数的内容:
这个函数的浸染只是天生一个随机的字符串然后返回。但是在上一张图的第105行代码将这个d赋值给了i.uuid,在我们最开始看要求数据包的时候,在http要求的要求体中就存在一个uuid的字段:
以是可以确认,这个uuid的字段便是用于天生iv向量的参数。
然后连续跟进我们的代码,在进行流量加密之后,会调用一个c函数,然后再return。以是我们须要看一下这个c函数的详细内容,由于解密的过程该当在这个c函数当中:
在第61行的位置发送一个http要求,如果要求成功进入回调函数,对数据进行解密,这个解密可以看到通报的参数c.uuid便是要求包中的uuid字段。
三、解密式全体小程序的剖析到这里基本就结束了,接下来只须要根据上面的密钥、iv向量天生、算法等等写一个解密的脚本就可以了。
为了高(tou)效(lan)作(mo)业(yu),利用之前搞开拓写的PHP版AES解密脚本改了改,末了的效果如下:
输入uuid参数和密文,点击解密之后返回明文,将明文修正之后点击加密,返回密文。
返回包的解密:
好了,这个小程序的流量加密剖析到这就全部结束了。