认识微信小程序
此处使用Windows版微信做介绍,但是Windows版和手机版稍微有点区别。先去获取一个Windows版的微信小程序包。默认位置在:C:\Users\user\Documents\WeChat Files\Applet
。移动端的包在/data/data/com.tencent.mm/MicroMsg/{id}/appbrand/pkg
,此处没有移动设备,不使用移动设备做演示。
目录下有一堆wx开头的目录,这些ID就是对应的小程序ID,可以在访问小程序抓包中获取到,如果懒得抓包也不知道小程序ID就把这些删掉,重新访问会再次下载,根据日期来找到对应的包即可。
Windows版的小程序包自动在外部加了一层的加密,我们看到的包名统一为:__APP__.wxapkg
。我们可以看到这样的文件头,V1MMWX标识就是加密后添加的标识。
这个是需要解密的,借助大佬的go语音项目来解密:https://github.com/BlackTrace/pc_wxapkg_decrypt
,同时也有编译后的程序,直接用即可。
那Windows版的小程序的加密流程为:
- 首先pbkdf2生成AES的key。利用微信小程序id字符串为pass,salt为saltiest 迭代次数为1000。调用pbkdf2生成一个32位的key
- 首先取原始的wxapkg的包得前1023个字节通过AES通过1生成的key和iv(the iv: 16 bytes),进行加密
- 接着利用微信小程序id字符串的倒数第2个字符为xor key,依次异或1023字节后的所有数据,如果微信小程序id小于2位,则xorkey 为 0x66
- 把AES加密后的数据(1024字节)和xor后的数据一起写入文件,并在文件头部添加V1MMWX标识
解密后,就能获得一个以微信小程序ID命令的包,这个包就是需要解析来获取小程序源码的包。先来看一下小程序的结构。
从十六进制中可以看到,旁边的文件目录文件。这种包并非一个压缩格式的包,而是一个二进制的包,需要特定的方法解包。
小程序解包
使用工具:https://gist.github.com/Integ/bcac5c21de5ea35b63b3db2c725f07ad
执行:python3 python.py wxid.wxapkg
,可以看到目录下生成的微信id的目录包。
或者使用:https://github.com/xuedingmiaojun/wxappUnpacker,一个nodejs的项目。提供Windows的安装版。
获取到小程序的源码格式包的时候,跟原来的源码还是稍微有点区别。在一级目录下,可以看到有三个文件,实际上不同的解包工具看到的不一样,有时候是四个文件。
app-service.jsapp-config.jsonpage-frame.html//app.js
app-service.js
是所以js的汇总,只是微信把js都压缩到这个js内。
app-config.json
: 小程序工程 app.json
以及各个页面的 JSON 配置文件汇总,可直接查看;
page-frame.html
: 所有页面的 .wxml
和 app.wxss
样式文件的汇总;
*.html
: 包含每个页面对应的 .wxss
信息,可读性较好;
static
: 各类图片、音频等资源文件。
获取解包后,小程序源码有什么用?
小程序内的信息泄露
有一部分开发者会把Appid和Secret放在小程序内请求,比如如下的开发者
如果这个appid和secret可以使用,就能获取到seesion_key。借用官方的登陆流程。
所以需要code和appid还有secret,code如何获取,只需要使用带有登陆功能的点,需要触发了wx.login()功能,点击登陆抓包即可。
一般打开小程序的时候就有流量交互了。比如,但这个code只能使用一次
构造一个请求,查看小程序官方文档:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html
curl https://api.weixin.qq.com/sns/jscode2session?appid=wxxxxx&secret=568wdxxx&js_code=041xxxx&grant_type=authorization_code
为了方便,此处使用云函数功能测试,需要小程序开启云函数。使用python的第三方包python-weixin
。但云函数功能不一定都开放,需要小程序开放才能查询。
from os import environ, pathfrom weixin import WxAppCloudAPIappid = environ.get("WXAPP_APPID", "wx88xxxxx")secret = environ.get("WXAPP_SECRET", "56xxxxx")env = "test-id"example_db = path.abspath(path.join(path.dirname(__file__), "./example_db"))app_cloud = WxAppCloudAPI( appid=appid, app_secret=secret, grant_type="client_credential")token = app_cloud.client_credential_for_access_token().get("access_token")print(token)cloud_api = WxAppCloudAPI(access_token=token)# 获取库的集合信息db_info = cloud_api.db_collection_info(json_body={"env": env, "limit": 10})print(db_info)
根据包的wiki来利用云函数操作小程序,文档:https://github.com/gusibi/python-weixin/wiki/%E5%B0%8F%E7%A8%8B%E5%BA%8F%E4%BA%91%E5%BC%80%E5%8F%91
利用accesstoken
获取session_key是用户数据的加密密钥,那accesstoken就是操作小程序的调用凭证。
先获取accesstoken,也可以利用上面提到的代码来获取accesstoken。
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
获取到token后可以利用官方的接口操作小程序来查询等操作,比如查询最近一天的访问
https://api.weixin.qq.com/datacube/getweanalysisappidvisitpage?access_token=ACCESS_TOKENdata = {"begin_date" : "20170313","end_date" : "20170313"}