1. 服务端监听¶
代理这一需求主要使用的是mitmproxy来做监听
mitmproxy 项目的工具是一组暴露通用底层功能的前端。
mitmproxy 是一个具有 SSL / TLS 功能的交互式拦截代理,具有用于HTTP / 1,HTTP / 2和 WebSockets 的控制台界面。
mitmdump 是 mitmproxy 的命令行版本。将 tcpdump 用于 HTTP。
mitmweb 是用于 mitmproxy 的基于 Web 的界面。
文档,教程和分发软件包可在 mitmproxy 网站上找到。
我们只用到 mitmproxy, mitmdump ,另一个 mitmweb,可以到官网去查看。
1.1. 创建项目环境¶
用 pipenv 新建一个项目环境:
$ mkdir wechatpay && cd wechatpay
我这里指定环境 python 版本为 3.6:
$ pipenv --python 3.6
修改 pipenv 使用国内镜像:
$ sed -i 's/https:\/\/pypi.org\/simple/https:\/\/pypi.tuna.tsinghua.edu.cn\/simple/g' ${PWD}/Pipfile
提示
mac下使用sed 会出现 extra characters at the end of l command 错误,需要-i 后跟双引号
$ sed -i "" 's' file
安装 mitmporxy:
$ pipenv install mitmproxy
测试mitmdump是否正常工作:
$ pipenv run mitmproxy -p 8081 # -p 指定监听端口号
提示
关键的几个常用的快捷键 ?: 帮助 q: 返回 或退出 z: 清屏 j: 上一个或向上滑动 k: 下一个或向下滑动 回车键: 查看选中的请求 h: 查看 请求内容 下一个 l: 查看请求内容 上一个 tab: 查看请求内容 下一个
1.2. 手机设置代理抓包¶
设置手机的代理,确定连接的是同一个网络,配置代理,设置如下:

接着打开微信 - 支付,观察 mitmproxy 监听命令窗口,会有很多数据包。 我们继续 微信操作进入 钱包 - 账单,这里发现提示安全警告, 该网站的安全证书存在问题,可选择“继续”在浏览器中访问。说明我们https抓包还没成功。 接下来我们给mitmdump配置https抓包
1.3. 设置https抓包¶
安装mitmproxy证书的最简单方法是使用内置的证书安装应用程序。 现在启动设备上的浏览器,并访问域名mitm.it。您应该会看到以下内容:
提示
如果使用的是iOS设备,则应使用Safari浏览器,以便它打开安装证书的正确提示。

单击相关图标,按照所用平台的设置说明进行操作,安装。
ios 手机设置流程
访问 mitm.it 后会下载一个描述文件,访问设置-通用-描述文件 安装
访问设置-关于本机-证书信任设置 启用mitmproxy
1.4. 微信支付抓包¶
访问微信的账单,发现数据包抓取成功。

从中分析出需要的数据请求地址:
https://wx.tenpay.com/userroll/userrolllist?classify_type=0&count=20&csrf_token=gDzdiW8dF7bQ9ekmP2andDPllx%2FukYM&exportkey=AS949HauKUqyrvQsZwuJe3E%3D&sort_type=1
从上面的抓包出来的请求,与cookies,可以很容易拉起请求,因为认证是通过cookies来认证的。 我们拿到请求,我们先来分析下他的参数。从程序开发的角度。这些参数是很重要的:
{
"classify_type": 0, # 账单的分类,红包,转账,群收款,二维码收款等等。
"count": 20, # 一页显示的数量。
"csrf_token": "", # csrf token 一般是表单的东西
"exportkey": "", # 什么key东西
"sort_type": "" # 排序的方法
}
从字面意思,先来猜想,要想验证猜想,只要换不同的参数去请求这个地址就能得到验证了。
最后去掉不必要的参数最终得到 url:
https://wx.tenpay.com/userroll/userrolllist?classify_type=0&count=20
因为我们获取到的请求是直接有csrf_token与exportkey了,而cookies才是访问请求的关键。直接有的,并不需要我们去前面的页面获取csrf_token, exportkey 理论都是可行的,怕篇幅太长,这里就不讲了,小伙伴们可以自行研究。
现在我们可以用 curl 命令:
$ curl 请求的链接 --cookie "获取到的Cookies"
也可以用postman 来请求:

这里面有我们需要的数据:
{
"bill_id": "",
"bill_type": 10,
"current_state": "",
"fee": 2038,
"fee_attr": "negtive",
"fee_type": "CNY",
"icon_url": "",
"out_trade_no": "",
"timestamp": "",
"title": "",
"trans_id": ""
}
看到数据,就是分析其参数是否有我们可以利用的地方。发现这里的信息并没有我们想要的关联参数,也就是备注。
提示
在做这个文章前,以前的这个列表参数是都在这个API里,在写文章时,微信支付的API有做变化,备注是在订单详情API里,道高一尺,魔高一丈,总有办法。
那我们通过抓包,查到了他的详情API:
$ curl https://wx.tenpay.com/userroll/userrolldetail?trans_id=trans_id --cookie "获取到的Cookies"
请求后看到了我们想要的备注:
{
...
"preview": [
...
{
"label": {
"name": "付款方留言",
"actionsheet": []
},
"value": [
{
"name": "101",
"actionsheet": []
}
],
"sequence": []
},
...
]
}
1.5. 抓取微信登陆cookies¶
代理所需要的功能,就是定时返回支付账单的请求cookies, 并存到某个地方,供服务器读取。所以这里安装redis:
$ pipenv install redis
先写 mitmdump 的解析脚本 fetch_cookies.py
import redis
import json
r = redis.Redis(host='localhost', port=6379, db=3)
# 这个地方必须这么写 函数名:response
def response(flow):
# 通过抓包软包软件获取请求的接口, 获取到cookies后,存入redis
if 'userroll/userrolllist' in flow.request.url:
# 数据的解析
data = {
'userroll_encryption': flow.response.cookies.get('userroll_encryption')[0],
'userroll_pass_ticket': flow.response.cookies.get('userroll_pass_ticket')[0]
}
r.set('wechat_cookies', json.dumps(data))
print('请求成功一次', data)
定义了一个redis client, response 解析函数, 主要是解析到cookies后,存入redis.
我们现在关闭掉 mitmproxy 的监听,并启用 mitmdump 来返回当前请求的 cookies:
$ pipenv run mitmdump -s fetch_cookies.py -p 8081 '~u https://wx.tenpay.com/'
注意: ~u https://wx.tenpay.com/
的意思是过滤抓包的规则,匹配到这个域名,才进入解析.
再次访问手机账单后,再试试 redis 是否写入成功:
$ redis-cli
127.0.0.1:6379> SELECT 3
OK
127.0.0.1:6379[3]> GET wechat_cookies
"{\"userroll_encryption\": \"mGpO/JhIzKKeplJhBhiD4J4VG1yNvn8mZQ1wyjn3UpZP01uFy1c22s79xxrSilDLhUxQ3p3rxdL+hPkGLDTKD7PwkmSbXwgw7SzMgemcXmuH4t9nTXaxnx4ZDvEdV/BGZx8fJMf3HL3U+l2v59D9qA==\", \"userroll_pass_ticket\": \"g5mdGJCudEJSK0XXvRcPJ1ptaoJONpTaJmg762zsoRh0IO2FGpDjN8SYUyCv9sJp\"}"
当你刷新你微信的支付-账单时,再调用 redis ,会发现 wechat_cookies
会更新最新获取的 cookies