mitmproxy是一个代理工具(类似于Charles),可以实现抓包的功能。除此以外,他还可以集成Python脚本,在请求和响应中用代码进行自定义操作。

1.安装和报错

基于 Python3.9.10 解释器创建了个虚拟环境,然后在虚拟环境中安装 mitmproxy

1
pip install mitmproxy

报错信息:

1
2
3
4
5
return _msvc14_get_vc_env(plat_spec)
File "E:\PycharmProjects\mitmproxy_example\.venv\lib\site-packages\setuptools\msvc.py", line 270, in _msvc14_get_vc_env
raise distutils.errors.DistutilsPlatformError(
setuptools._distutils.errors.DistutilsPlatformError: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build Tools": https://visualstudio.mi
crosoft.com/visual-cpp-build-tools/

需要去下载Visual C++ Build Tools for Visual Studio 2015安装到电脑,然后再重新 pip install mitmproxy 才行。

https://my.visualstudio.com/Downloads?q=Visual%20Studio%202015%20update%203

image-20240517203603734

解压 mu_visual_cpp_build_tools_2015_update_3_x64_dvd_dfd9a39c.iso文件,然后默认安装。

image-20240517203623140

再次安装成功:

1
pip install mitmproxy

image-20240517203631179

2.Https请求

默认只能抓取http请求包,想要支持https请求,就需要安装证书。

2.1 启动

常见的启动方式:

mitmweb

1
mitmweb -p 9888

网页版,提供一个类似于Charles抓包的页面。

image-20240517203645144

image-20240517203652191

mitmproxy(不推荐)

1
mitmproxy -p 9888

在终端命令行,显示请求和数据。

image-20240517203701454

image-20240517203708721

mitmdump

1
mitmdump  -p 9888

image-20240517203718562

image-20240517203727504

2.2 关闭电脑防火墙

image-20240517203736082

2.3 手机系统代理

image-20240517203744068

2.4 下载安装证书

image-20240517203751434

2.5 抓包测试

案例:唯品会v7.83.3

image-20240517203759371

案例:京东v12.6.0

image-20240517203809777

3.集成Python脚本

3.1 读取请求

1
>>>mitmdump -q  -p 9888 -s v1.py
1
2
3
4
5
6
7
8
9
10
11
12
13
from mitmproxy import http
from mitmproxy.http import Request


def request(flow):
print("请求-->", flow.request.url)
print("请求-->", flow.request.host)
print("请求-->", flow.request.path)
print("请求-->", flow.request.query)
print("请求-->", flow.request.cookies)
print("请求-->", flow.request.headers)
print("请求-->", flow.request.method)
print("请求-->", flow.request.content)

image-20240517203819095

3.2 修改请求

1
2
>>>mitmdump -q  -p 9888 -s v2.py
>>>mitmweb -q -p 9888 -s v2.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from mitmproxy import http
from mitmproxy.http import Request
from mitmproxy.http import HTTPFlow


def request(flow: HTTPFlow):
print('-' * 60)
print(flow.request.url)
flow.request.query['mine'] = 'wupeiqi'
flow.request.cookies["token"] = "40c31b0d89c0299458ef44e09e379cb3"
flow.request.headers['info'] = "wupeiqi"
# flow.request.cookies = [
# ("token","40c31b0d89c0299458ef44e09e379cb3")
# ]

image-20240517203827811

image-20240517203833498

3.3 拦截请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from mitmproxy import http
from mitmproxy.http import Request
from mitmproxy.http import HTTPFlow
from mitmproxy.http import Response


def request(flow: HTTPFlow):
if flow.request.url.startswith("https://www.5xclass.cn/"):
# 设置返回值
flow.response = Response.make(
200, # (optional) status code
b"Hello World", # (optional) content
{"Content-Type": "text/html"} # (optional) headers
)
1
2
3
4
5
6
7
8
from mitmproxy import http
from mitmproxy.http import Request
from mitmproxy.http import HTTPFlow


def request(flow: HTTPFlow):
if flow.request.url.startswith("https://www.5xclass.cn/"):
flow.kill()

image-20240517203842764

案例:账号共享(油联)

版本:油联合伙人v1.4

先正常登录 APP 或 网页 ,获取对应的凭证信息,然后再在其他请求中携带过去。

1
461cc0cab38d4c41a148820a46c2820c1713252333598

image-20240517203852256

image-20240517203859220

1
2
3
4
5
6
7
8
from mitmproxy.http import HTTPFlow


def request(flow: HTTPFlow):
print(flow.request.url)
# flow.request.headers.add("X-Token","461cc0cab38d4c41a148820a46c2820c1713252333598")
flow.request.headers["X-Token"] = "461cc0cab38d4c41a148820a46c2820c1713252333598"

1
2
>>>mitmweb -q  -p 9888 -s v4.py
>>>mitmdump -q -p 9888 -s v4.py

image-20240517203907475

3.4 响应内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from mitmproxy import http
from mitmproxy.http import Request
from mitmproxy.http import HTTPFlow
from mitmproxy.http import Response


def response(flow: http.HTTPFlow):
print(flow.request.url)

print(flow.response.status_code)
print(flow.response.cookies)
print(flow.response.headers)
print(flow.response.content)

# mitmdump -q -p 9888 -s v5.py

3.5 修改响应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from mitmproxy import http
from mitmproxy.http import Request
from mitmproxy.http import HTTPFlow
from mitmproxy.http import Response


def response(flow: http.HTTPFlow):
print(flow.request.url)
print(flow.response.status_code)
print(flow.response.cookies)
print(flow.response.headers)
# print(flow.response.content)

flow.response = Response.make(
200, # (optional) status code
b"Hello World", # (optional) content
{"Content-Type": "text/html"} # (optional) headers
)

# mitmdump -q -p 9888 -s v5.py

案例:采集评论(汽车之家)

版本:汽车之家v11.60.5

人工操作手机,代码自动将评论保存起来。

image-20240517203918555

image-20240517203925578

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import json
from mitmproxy import http
from mitmproxy.http import Request
from mitmproxy.http import HTTPFlow
from mitmproxy.http import Response


def response(flow: http.HTTPFlow):
if flow.request.url.__contains__("/reply_v10.0.0/news/objectcomments2"):
# print(flow.response.text)
data_dict = json.loads(flow.response.text)
for item in data_dict['result']['list']:
print(item)

# mitmweb -q -p 9888 -s v5.py

3.6 websocket

案例:京东v12.6.0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from mitmproxy import http

def websocket_start(flow: http.HTTPFlow):
pass

def websocket_message(flow: http.HTTPFlow):
message = flow.websocket.messages[-1]

if message.from_client:
print(f"客户端发送: {message.text}")
else:
print(f"服务端发送: {message.text}")

# manipulate the message content
# message.content = b"hello"

# kill the message and not send it to the other endpoint
# message.drop()

def websocket_end(flow: http.HTTPFlow):
pass

image-20240517203935221

案例:抖音弹幕(web抖音)

Web版抖音直播间的弹幕信息,是基于:WebSocket + Protobuf协议实现。

1
pip install protobuf==4.24.2

Protobuf和抖音弹幕相关相关:https://www.bilibili.com/video/BV17A411Q7eZ?p=2

1
mitmweb -q  -p 9888 -s v6.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import gzip
from mitmproxy import http
from douyin_pb2 import PushFrame, Response, ChatMessage, MemberMessage


def websocket_start(flow: http.HTTPFlow):
pass


def websocket_message(flow: http.HTTPFlow):
message = flow.websocket.messages[-1]

if message.from_client:
# print(f"客户端发送: {message.content}")
pass
else:
# print(f"服务端发送: {message.content}")
frame = PushFrame()
frame.ParseFromString(message.content)
# 对PushFrame的 payload 内容进行gzip解压
origin_bytes = gzip.decompress(frame.payload)

# 根据Response+gzip解压数据,生成数据对象
response = Response()
response.ParseFromString(origin_bytes)

# 获取数据内容(需根据不同method,使用不同的结构对象对 数据 进行解析)
# 注意:此处只处理 WebcastChatMessage ,其他处理方式都是类似的。
for item in response.messagesList:

# if item.method == "WebcastMemberMessage":
# message = MemberMessage()
# message.ParseFromString(item.payload)
# print(message)

if item.method == "WebcastChatMessage":
message = ChatMessage()
message.ParseFromString(item.payload)
# print(message)
info = f"【{message.user.id}{message.user.shortId} {message.user.nickName}{message.content} "
print(info)
print("-" * 50)


def websocket_end(flow: http.HTTPFlow):
pass

image-20240517203948061

4.抓包-电脑端

想要使用mitmproxy在电脑端进行抓包,也需要在电脑上安装https证书。

4.1 启动

同2.1需要先启动mitmproxy

1
2
3
mitmweb -p 9888
mitmproxy -p 9888
mitmdump -p 9888

4.2 下载证书

方式1:当启动mitmproxy之后,可以在电脑本地读取证书。

image-20240517203959352

方式2:配置代理,然后下载证书。

在电脑上配置mitmproxy为代理,访问 http://mitm.it/下载证书。

image-20240517204007032

image-20240517204014959

4.3 安装证书

image-20240517204026268

image-20240517204032463

image-20240517204039606

image-20240517204046450

image-20240517204053305

image-20240517204059638

4.4 配置代理 & 抓包

image-20240517204106154

image-20240517204113427

5. 笔记

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
1.mitmproxy
类似于Charles抓包工具,好处:集成Python脚本。

1.1 安装和报错

1.2 启动使用
>>>mitmweb -p 9888 提供Web界面【推荐】
>>>mitmproxy -p 9888 提供终端界面
>>>mitmdump -p 9888 不提供界面(python脚本)【推荐】

手机抓包:
- 手机配置系统代理
- 手机启动APP + 抓包 => http请求包
- 安装证书
- 手机启动APP + 抓包 => https请求包

1.3 手机中安装证书
- 关机电脑防火墙
- 配置系统代理
- 访问 mitm.it 下载证书
- 双击安装证书 + move cert模块

扩展:
- 启动mitmproxy
- 电脑安装证书
- 电脑本地有个文件存储证书文件,双击安装即可
- 配置代理 + 下载证书文件 + 安装
- 配置系统代理 + 抓包

1.4 集成Python脚本

1.读取请求信息
mitmweb -q -p 9888 -s v1.py

2.修改请求

3.请求拦截 & 返回内容

案例:账号共享(油联)
- 正常登录某个APP,抓包获取凭证信息
- 定制requests函数,让每个请求到来时,主动添加X-token请求体
- mitmproxy局域网内,启动
- request函数集成token信息
- 手机A,配置系统代理+安装https证书
- 手机B,配置系统代理+安装https证书
- 手机C,配置系统代理+安装https证书
# 大商天狗APP

4.读取响应内容

5.修改响应内容

扩展:
- Http协议 -> 明文
- Https协议 -> 密文(安装证书)

案例:读取评论信息(汽车之家app)
- 手动打开APP+滑动
- mitmproxy返回时,将响应内容输出(写入到某个地方)

6.websocket

案例:京东直播间
案例:抖音直播间弹幕(web端)
- mitmproxy抓取电脑的请求数据包
- 配置电脑系统代理
- 打开mitmproxy + 打开网页
- 抖音 vs 京东
- 京东,展示数据,json格式 数据->json->数据
- 抖音,乱码 ,protobuf 数据->protobuf->数据

- 视频:
https://www.bilibili.com/video/BV17A411Q7eZ?p=2
注意:
- 寻找ws地址(缺少signature参数)
- 发送请求,读取弹幕信息【分析protobuf格式】

2.TLS指纹

现象:
- 浏览器访问某个网站,结果正常 (参数) 【指纹 1230123123】
- requests模块发送请求,结果不正常(参数) 【指纹 5555555222】

尝试基于TLS指纹去解决。

原理:...

解决方案:
- Python有两种方案
- Golang有1种方法

视频教程:https://www.bilibili.com/video/BV17C4y1E7fK/

3.关于抖音
目前已知:http、https、tcp、websocket
目前抖音:Quic(基于UDP开发) + Https
-> libttboringssl.so SSL_write SSL_read + 调用栈 + libcronet.so + Java..
-> libssl.so SSL_write SSL_read

脚本:强制抖音降级。

function hookso_ssl(){
Java.perform(function(){
var class_ = Java.use("org.chromium.CronetClient");
class_.tryCreateCronetEngine.implementation = function(a,b,c,d,e,f,g,h){
console.log(a,b,c,d,e,f,g,h);
//var result = this.tryCreateCronetEngine(a,b,c,d,e,f,g,h);
// console.log("result==>",result);
var result;
return result;
}
})
}

__END__