最近在搞 App 爬虫,不过万事入门难,我得自己研究研究 Mitmproxy 虽然不知道到底是不是那么强啦,就是得要会用,所以我就亲自入坑,并把自己的一下观点比较记录下来,毕竟好记性不然烂笔头嘛。
mitmproxy 是一个支持 HTTP 和 HTTPS 的抓包程序,有类似 Fiddler、Charles 的功能,只不过它是一个控制台的形式操作。
mitmproxy 还有两个关联组件。一个是 mitmdump ,它是 mitmproxy 的命令行接口,利用它我们可以对接Python 脚本,用Python实现监听后的处理。另一个是 mitmweb,它是一个 Web 程序,通过它我们可以清楚观察 mitmproxy 捕获的请求。本文将主要讲解,mitmproxy 如果本文在看超过 30,将为你继续奉上 mitmdump 。
1. 准备工作
接下来我将给同学们讲解 Mitmproxy 抓包工具的安装及介绍,之前我分享了 Fiddler 抓包工具的安装以及简单操作,通过 Fiddler 抓包工具我们可以抓取 Web 端和 App 端的数据——有兴趣的小伙伴可以自行点击链接了解:https://www.aiyc.top/archives/485.html 今天给大家介绍另一款强大的抓包工具同样可以抓取 Web 端和 App 端的数据,并且可以和 Python 语言融合在一起,通过爬虫来抓取数据—— Mitmproxy 。
1.1 前言
Mitmproxy 其实就是用来做中间人攻击的,那什么是中间人工具呢?
- Mitmproxy 就是用于 MITM 的 Proxy
- MITM 即中间人攻击(Man-in-the-middle attack)
其实,上面这张图(图一)和我们上节课讲的 Fiddler 那张图很像,我们的 Mitmproxy 就和 Fiddler 一样,在上图的 Man in the Middle 位置一样,在中间做一些截取和查看,用于中间人代理其实和正常的一样,会将我们客户端发起的请求截取,然后转发给我们的服务器(不过是多了一个中间人,这个中间人可以修该或者不修改你发起请求的数据),服务器收到请求之后会收到响应,同样我们的 Mitmproxy 会截获这个响应,最后再转发给我们的 Client 。所以总结下来就是以下三点:
- 和正常的代理一样转发请求,保障服务端与客户端之间的通信;
- 会适时的查询记录也就是:
- 拦截请求
- 修改请求(其实,也就是修改请求内容,比如你百度查询:Python,然后中间人修改你请求的内容,比如修改成:AI悦创,这样返回的内容就不是 Python 相关了。)
- 返回请求
- 修改返回(其实,也就是修改返回内容,比如你百度查询:Python,百度原本给你返回 Python 相关的内容,但中间人比如就改成一句:你好,我是悦创。这样结果就被改变了)
- 可以载入自定义 Python 脚本。
Mitmproxy 不同于 Fiddler 之类的抓包工具,不仅可以截获数据并且可以帮助开发者查看分析等操作,更可以自定义脚本来进行二次开发,举个例子来讲:利用 Fiddler 可以过滤出浏览器对某个特定 URL 的请求,并且查看和分析数据,**但是,实现不了高度的定制化需求。**例如:截获对该浏览器的请求,将返回数据为空并将真实的返回数据存到某一个数据库中或者出现异常的时候发出邮件通知。
上面所说的功能 Fiddler 实现不了,但对于 Mitmproxy 来说,可以使用载入自定义的 Python 脚本来实现,Mitmproxy 并不会对无辜的人发起攻击,由于我们的 Mitmproxy 工作在 HTTP 中,而当前通过 HTTPS 的普及,使客户端拥有检测规避中间人的能力,所以要让我们 Mitmproxy 正常工作的话必须让我们客户端或者 App 信任 Mitmproxy 的 SSL 证书或者忽略证书异常。
其实和 Fiddler 差不多,Fiddler 也是安装了一个自己的证书使的客户端信任,所以 Mitmproxy 一样也是要让浏览器或者 App 信任该证书,让 Mitmproxy 在中间充当一个中间人的角色——达到截获请求或者响应。
这个不是在做黑产,而是在做我们的开发测试。
1.2 Mitmproxy 抓包工具安装
在正式安装之前,我们先来看看 Mitmproxy 需要一个怎样的安装环境。
- 基于 Python 环境(我电脑使用的是:Python 3.7)
- Windows 操作系统中需要安装 Microsoft Visual C++ V14.0 以上(否则会出现保存无法安装)
- Linux 操作系统则直接基于 Python 安装即可
首先,我们需要打开我们的命令行工具 CMD ,直接在命令行命令输入以下命令:
1 | pip install mitmproxy |
回车就可以安装了,如果以上安装不了出现问题,建议先给自己的 pip 换源一下:Windows pip 换源,但是如果出现报错,咱们继续往下看 。
1.2 pip 安装出现错误解决方法
1.2.1 解决方法一
如果出现以下类似的报错信息(图二)我们有两种解决方法,第一种安装
上图(图二)出现的报错信息,最重要的是:error:Microsoft Visual C++ 14.0 is required. Get it with “Microsoft Visual c++ Build Tools”:http://landinghub.visualstudio.com/visual-cpp-build-tools
记住!认真看报错信息,按你具体提示是链接去浏览器访问。当然有可能链接会访问失败出现 404 之类的。
那如果不行,同学们可以直接点击下面链接直接下载 https://aiyc.lanzous.com/ic7kttc 下载完成之后,我来进行安装,安装也非常的方便,直接运行安装程序即可。这里我简单的把安装截图演示出来(图三):
出现下图(图四)就已经正在安装了:
安装时间看具体电脑,会比较久一些。通过一段时间等待,就安装成功了,需要你重启计算机,重启之后再次运行以下命令即可:
1 | pip install mitmproxy |
1.2.1 解决方法二
此方法如果不能解决还需要用方法解决,请同学们灵活选择。
点击下面链接下载文件,放到桌面(当然,你也看放到其他位置,放到桌面主要为了小白方便,链接:https://www.aiyc.top/mitmproxy-5.1.1-py3-none-any.whl 下载之后,比如我这里演示的时候,
1 | pip install C:\Users\clela\Desktop\mitmproxy-5.1.1-py3-none-any.whl |
如果没有报错,则安装成功。如果其他问题可以自行百度或者底栏留言即可。
1.3 验证安装是否成功
那我们该如何验证呢?我们可以查看一下 mitmproxy 的版本,我们在命令行输入:
1 | mitmproxy --version |
但是结果报错了 ,我们来看看报错内容:
1 | Error: mitmproxy's console interface is not supported on Windows. You can run mitmdump or mitmweb instead. |
我们来简单翻译一下:
但是,我们可以看见上面报错提示:
一般我们抓包用的是:
那接下来我们来看一下
1 | mitmdump --version |
输出结果如下:
1 2 3 4 | Mitmproxy: 5.1.1 Python: 3.7.6 OpenSSL: OpenSSL 1.1.1g 21 Apr 2020 Platform: Windows-10-10.0.18362-SP0 |
由上面的结果可知,我们的 Mitmproxy 版本:5.1.1 基于我的 Python 版本:3.7.6 等信息,表明我们 Mitmproxy 安装成功的,而我们的安装平台是:Windows-10-10.0.18362-SP0 (也就是 Windows 10)。
1.4 Linux 里面安装 Mitmproxy
上面我们在 Windows 平台上安装了 Mitmproxy 接下来我们来看看如何在 Linux 上安装。
在 Linux 里面也是基于 Python 安装的,我们也使用如下命令:
1 | pip3 install mitmproxy |
这里使用 pip3 的原因是,Linux 自带 Python2 所以这里是为了区分也是为了使用 Python3 所以使用。
这里我们也是可以查看 mitmproxy 版本号,这回就不会出现 Windows 里面报错的信息了,命令如下:
1 | mitmproxy --version |
1.5 小结
上面给大家讲解了 Mitmproxy 在 Windows 、Linux 平台的安装,如果你对安装有任何问题欢迎留言!
2. Mitmproxy 的功能
接下来,我们来看看 Mitmproxy 有哪几项功能,如下:
-
拦截HTTP和HTTPS请求和响应。
-
保存HTTP会话并进行分析。
-
模拟客户端发起请求,模拟服务端返回响应。
-
利用反向代理将流量转发给指定的服务器。
-
支持 Mac 和 Linux 上的透明代理。
-
利用Python对HTTP请求和响应进行实时处理。
3. 抓包原理
和 Charles 一样,Mitmproxy 运行于自己的 PC 上,mitmproxy 会在 PC 的 8080 端口运行,然后开启一个代理服务,这个服务实际上是一个 HTTP/HTTPS 的代理。
手机和 PC 在同一个局域网内,设置代理为 mitmproxy 的代理地址,这样手机在访问互联网的时候流量数据包就会流经 mitmproxy,mitmproxy 再去转发这些数据包到真实的服务器,服务器返回数据包时再由 mitmproxy 转发回手机,这样 mitmproxy 就相当于起了中间人的作用,抓取到所有 Reques t和 Response,另外这个过程还可以对接 mitmdump,抓取到的 Request 和 Response 的具体内容都可以直接用 Python 来处理,比如得到Response 之后我们可以直接进行解析,然后存入数据库,这样就完成了数据的解析和存储过程。
4. 设置代理
首先,我们需要运行 mitmproxy,命令如下所示:
启动 mitmproxy 的命令如下:
1 | mitmproxy |
之后会在8080端口上运行一个代理服务,如下图所示。
右下角会出现当前正在监听的端口。
或者启动 mitmdump,它也会监听 8080 端口,命令如下所示:
1 | mitmdump |
运行结果如下图所示。
将手机和 PC 连接在同一局域网下,设置代理为当前代理。首先看看PC的当前局域网IP。
Windows 上的命令如下所示:
1 | ipconfig |
Linux 和 Mac 上的命令如下所示:
1 | ifconfig |
输出结果如下图所示。
Linux/Mac:
Windows:
一般类似
这样我们就配置好了mitmproxy的的代理。
5. mitmproxy的使用
确保 mitmproxy 正常运行,并且手机和 PC 处于同一个局域网内,设置了 mitmproxy 的代理,具体的配置方法可以参考官方文档。
运行 mitmproxy,命令如下所示:
1 | mitmproxy |
设置成功之后,我们只需要在手机浏览器上访问任意的网页或浏览任意的 App 即可。
不过还要安装证书才可以使用,操作方法启动 mitmproxy 之后,在手机上也设置代理之后,打开浏览器输入:mitm.it 下载手机平台的证书并安装。操作如下动图(我会把代理设置也会重新操作一遍):该操作动图过大,请把链接复制使用浏览器访问:https://images-aiyc-1301641396.cos.ap-guangzhou.myqcloud.com/20200516184549.gif
例如在手机上打开 https://www.aiyc.top/ ,mitmproxy 页面便会呈现出手机上的所有请求,如下图所示。
这就相当于之前我们在浏览器开发者工具监听到的浏览器请求,在这里我们借助于mitmproxy完成。Charles完全也可以做到。
这里是刚才手机打开百度页面时的所有请求列表,左下角显示的 1/36 代表一共发生了 36 个请求,当前箭头所指的是第一个请求。
每个请求开头都有一个 GET 或 POST,这是各个请求的请求方式。紧接的是请求的 URL。第二行开头的数字就是请求对应的响应状态码,后面是响应内容的类型,如 text/html 代表网页文档、image/gif 代表图片。再往后是响应体的大小和响应的时间。
当前呈现了所有请求和响应的概览,我们可以通过这个页面观察到所有的请求。
如果想查看某个请求的详情,我们可以敲击回车,进入请求的详情页面,如下图所示。
可以看到 Headers 的详细信息,如 Host、Cookies、User-Agent 等。
最上方是一个Request、Response、Detail的列表,当前处在Request这个选项上。这时我们再点击TAB键,即可查看这个请求对应的响应详情,如下图所示。
最上面是响应头的信息,下拉之后我们可以看到响应体的信息。针对当前请求,响应体就是网页的源代码。
这时再敲击TAB键,切换到最后一个选项卡 Detail,即可看到当前请求的详细信息,如服务器的IP和端口、HTTP协议版本、客户端的IP和端口等,如下图所示。
mitmproxy 还提供了命令行式的编辑功能,我们可以在此页面中重新编辑请求。
敲击 e 键即可进入编辑功能,这时它会询问你要编辑哪部分内容,如 Cookies、Query、URL 等,每个选项的第一个字母(或数字)会高亮显示。
敲击要编辑内容名称的首字母(或数字)即可进入该内容的编辑页面,如敲击 5 即可编辑请求的方式,敲击 6 即可修改 GET 请求参数 Query 。
这时我们敲击 6,进入到编辑 Query 的页面。我们可以看到已经有一些参数了,我们可以敲击 a 来增加一行,然后就可以输入参数对应的 Key 和 Value,如下图所示。
这里我们输入 Key 为 wd,Value 为 www.aiyc.top。
然后再敲击 esc 键和 q 键,返回之前的页面,再敲击 e 和 4 键修改 Path 。和上面一样,敲击 a 增加 Path 的内容,这时我们将 Path 修改为 aiyuechuang,如下图所示。
再敲击 esc 和 q 键返回,我们就再修改一下请求,也是敲击 e 和 5 修改 method,这个时候会出现如下结果,操作如下动图:
这时我们可以看到最上面的请求链接变成了:https://www.aiyc.top/usr/themes/handsome/libs/Get.php/aiyuechuang?type=song&wd=www.aiyc.top&media=netease&id=1363948882 。
敲击 a 保存修改,敲击 r 重新发起修改后的请求,即可看到上方请求方式前面多了一个回旋箭头,这说明重新执行了修改后的请求。这时我们再观察响应体内容,即可看到请求失败,因为我的博客是不存在这个请求链接的,如下图所示。
以上内容便是 mitmproxy 的简单用法。利用 mitmproxy ,我们可以观察到手机上的所有请求,还可以对请求进行修改并重新发起。
接下来,我们对编辑操作进行简单的小结:
| 键名 | 功能 |
|---|---|
| e | 进入 Part |
| a | 增加一行 |
5.4 Mitmproxy 快捷键
主界面操作快捷键:
| 快捷键 | 功能 |
|---|---|
| ? | 帮助文档 |
| q | 返回/退出程序 |
| b | 保存 response body |
| f | 输入过滤条件 |
| k | 上 |
| j | 下 |
| h | 左 |
| l | 右 |
| space | 翻页 |
| enter | 进入接口详情 |
| z | 清屏 |
| e | 编辑 |
| r | 重新请求 |
5.5 Mitmproxy 过滤表达式(Filter expressions)
过滤请求,和上面的操作类似,只不过接下来的操作,是按键 f 开始,输入 f 之后你会看见如下位置会有相对应的显示:
接下来,我们就可以过滤请求了,这个地方我们来筛选请求结果不是 200 的(也就是得到请求不是 200 的结果),我们需要添加的命令为:
1 | : set view_filter '!(~c 200)' |
详细的呢,我们来下面来讲:
5.5.1 Filter expressions
Many commands in the mitmproxy tool make use of filter expressions. Filter expressions consist of the following operators:
mitmproxy 工具中的许多命令都使用了过滤表达式。过滤器表达式由以下操作符组成:
注意: 这里把英文写出来不是为了炫技,而是希望看见这篇的小伙伴也顺便学习一下英文,英文真的很重要!
| 命令(The command) | 作用(Role) | 翻译(translate) |
|---|---|---|
| ~a | Match asset in response: CSS, Javascript, Flash, images. | 匹配响应中的:CSS、JavaScript、Flash、Images。 |
| ~b regex | Body | 使用正则表达式,匹配响应体 Body |
| ~bq regex | Request body | 请求体 |
| ~bs regex | Response body | 响应体 |
| ~c int | HTTP response code | 匹配 HTTP 状态码 |
| ~d regex | Domain | 域名(可以理解成 url,但不准确) |
| ~dst regex | Match destination address | 匹配目的地址 |
| ~e | Match error | 匹配错误 |
| ~h regex | Header | 匹配头部 |
| ~hq regex | Request header | 匹配请求头 |
| ~hs regex | Response header | 匹配响应头 |
| ~http | Match HTTP flows | 匹配 HTTP 流 |
| ~m regex | Method | 匹配模式(方法) |
| ~marked | Match marked flows | 匹配标记流 |
| ~q | Match request with no response | 匹配请求无响应 |
| ~s | Match response | 匹配响应 |
| ~src regex | Match source address | 匹配源地址 |
| ~t regex | Content-type header | 内容类型的头 |
| ~tcp | Match TCP flows | 与 TCP 流 |
| ~tq regex | Request Content-Type header | 请求的 content - type 头 |
| ~ts regex | Response Content-Type header | 响应的 content - type 头 |
| ~u regex | URL | URL |
| ~websocket | Match WebSocket flows | 匹配 WebSocket 流量 |
| ! | unary not | not |
| & | and | and |
| | | or | or |
| (…) | grouping | 分组 |
- Regexes are Python-style
- Regexes can be specified as quoted strings
- Header matching (~h, ~hq, ~hs) is against a string of the form “name: value”.
- Strings with no operators are matched against the request URL.
- The default binary operator is &.
Fiddler、Charles 也有这个功能,而且它们的图形界面操作更加方便。那么 mitmproxy 的优势何在?
mitmproxy 的强大之处体现在它的另一个工具 mitmdump,有了它我们可以直接对接 Python 对请求进行处理。代码可以关注本账号私信获取哦!