mitmproxy - 开源、免费的HTTP抓包分析工具

mitmproxy 是一款支持 HTTP/HTTPS 的中间人代理工具。

mitmproxy 包含如下套件:

  • mitmproxy 提供了一个控制台接口用于动态拦截和编辑 HTTP 数据包。不同于 Fiddler2、burpsuite 等类似功能工具,mitmproxy 可在终端下运行。mitmproxy 使用 Python 语言开发,是辅助 web 开发&测试、移动端调试、渗透测试的工具。
  • mitmdump 是 mitmproxy 的命令行接口,功能类似于 HTTP 中的 tcpdump。
  • mitmweb 是 mitmproxy 的 Web 页面接口。

mitmproxy 的功能特性

  • 拦截 HTTP 和 HTTPS 请求和响应。
  • 保存 HTTP 会话并进行分析。
  • 模拟客户端发起请求。
  • 模拟服务端返回响应。
  • 利用反向代理将流量转发给指定的服务器。
  • 支持 Mac 和 Linux 上的透明代理。
  • 利用 Python 对 HTTP 请求和响应进行实时处理。

mitmproxy

在 Terminal 终端上,使用 mitmproxy 工具实现 http 客户端请求数据的拦截和服务响应数据的拦截。

安装和运行 mitmproxy

这里给出两种安装 mitmproxy 的方式,一种是 Homebrew,另外一种是 pip。

通过 Python 包管理工具安装 mitmproxy

  1. 先要在Mac中安装 pip(Python包管理工具,主要是用于安装 PyPI 上的软件包,可以替代 easy_install 工具),打开 Terminal 终端,输入如下命令:

    $ sudo easy_install pip
    Searching for pip
    Reading https://pypi.python.org/simple/pip/
    ...
    
  2. 安装mitmproxy

    $ sudo pip install mitmproxy --ignore-installed six
    

通过 HomeBrew 安装

在 Mac OS 系统中,可以通过 HomeBrew 安装 mitmproxy:

$ brew install mitmproxy

启动 mitmproxy:

$ mitmproxy

在终端下输入命令 ifconfig en0 可以查询 Mac 系统连接网络的当前 IP 地址:

你也可以通过:键盘按住 option 键,然后鼠标左击 Mac 桌面菜单栏左上角的 Wi-Fi 图标查看本机 IP 地址。

iPhone 上设置 HTTP 代理(系统设置-无线局域网-点击当前网络 WI-FI 图标右侧的感叹号-配置 HTTP 代理),填写查询到的本机 IP 地址,端口号默认填写 8080:

第一次使用 mitmproxy 的时候,还需要在 iPhone 上安装 mitmproxy 的 CA 证书,iPhone 上的 HTTP 代理设置并保存完成后,手机浏览器打开 mitm.it,安装对应系统的 CA 证书即可。

查看 mitmproxy 流量

以 baidu.com 为例,手机浏览器打开该网页,即可查看到通过 mitmproxy 的流量。

在该请求列表界面:

  • 通过 j、k 或者上下方向键实现各个请求之间的逐项移动操作。
  • 通过 G 移至最后一个请求。
  • 通过 g 移至第一个请求。
  • 在任意单个请求上,按回车键即可进入请求详情页面。再按 q 即可从请求详情页面返回到请求列表页面。

在请求详情界面:

  • 通过 h、l 或者左右方向键实现 Request、Response、Detail 页面之间的切换。
  • 也可以通过 Tab 键实现 Request、Response、Detail 页面之间的切换。

拦截 HTTP 请求

在请求列表界面中输入 i,进入 Intercept filter 拦截模式,可以通过正则表达式过滤的方式拦截指定的 HTTP 流量。

按 ESC 可以退出 Intercept filter 拦截模式。

比如说,你想要拦截所有通过 http://google.com 的流量,那么你就输入:

google.com

然后按回车。这时候所有通过 http://google.com 的流量都会被拦截,并用红色字体标出:

箭头索引到该请求上之后,键盘可以执行以下指令:

  • a ,即 accept,放行流量;
  • r,即 replay,重发 request 请求;
  • d,即 delete,删除当前 field;

如果想要编辑该请求,可以回车键跳转到请求详情页面,按 e,即 edit,进入编辑模式,进入编辑模式后,具体的操作和 vi 操作相同。

如果你需要编辑请求的 query 字段,可以通过上下左右方向键切换要编辑的参数。还可以通过 a 增加查询参数。编辑完成后,按 esc 即可退出编辑模式,再按 q 返回到请求详情页面。

请求编辑完成后,退回到请求列表界面,按 a 即可放行流量。收到服务器的响应数据后,你也同样可以编辑响应参数,再执行放行操作。

mitmdump

使用 mitmproxy 时,我们可以查看 HTTP 流量,也可以以交互式的方式实现拦截、编辑、放行流量。

但如果你只是想要修改请求或响应数据,而响应数据又是 JSON 数据类型或者 image 图片数据时,在 vim 编辑器中修改数据也不是非常方便。

而且当我想要进行移动端的 HTTP 抓包,并实时修改请求和响应数据时,即使 mitmproxy 使用非常熟练,一顿操作猛如虎,也很难保证在移动端 APP 请求超时之前在命令行中完成以上所有的操作。

我们还可以通过 mitmdump 工具,以脚本的方式自动执行相关的操作。

运行 mitmdump 的命令如下:

$ mitmdump -s script.py

其中,-s 参数表示当前目录下所对应的脚本文件,即 script.py

示例 python 脚本文件

改写请求头

该脚本向每个请求的请求头中都添加 User-Agent 字段:

def request(flow):
    flow.request.headers['User-Agent'] = 'mitmproxy'
    print(flow.request.headers)

代码释义:

  • 第一行:定义了一个 request() 方法,参数为 flow,它其实是一个 HTTPFlow 对象,通过 request 属性即可获取到当前请求对象。
  • 第二行:将请求头中的 User-Agent 字段修改为 mitmproxy
  • 第三行:通过 print() 方法在控制台打印输出请求的请求头。

Request 的常用功能

from mitmproxy import ctx

def request(flow):
    request = flow.request
    info = ctx.log.info
    info(request.url)
    info(str(request.headers))
    info(str(request.cookies))
    info(request.host)
    info(request.method)
    info(str(request.port))
    info(request.scheme)

直接赋值即可对任意属性作修改:

def request(flow):
    url = 'https://httpbin.org/get'
    flow.request.url = url

日志输出

mitmdump 提供了专门的日志输出功能,可以设定不同级别以不同颜色输出日志结果:

from mitmproxy import ctx

def request(flow):
    flow.request.headers['User-Agent'] = 'MitmProxy'
    ctx.log.info(str(flow.request.headers))
    ctx.log.warn(str(flow.request.headers))
    ctx.log.error(str(flow.request.headers))

代码释义:调用 ctx 模块,它有一个 log 功能,调用不同的输出方法就可以输出不同颜色的结果,以方便调试。例如:

  • info() 方法输出白色文本。
  • warn() 方法输出黄色文本。
  • error() 方法输出红色文本。

修改响应的消息体

通过读取 json 文件的字符串并返给客户端:

from mitmproxy import http, ctx
import json

class Modify:
  def response(self, flow):
    if flow.request.url.startswith("http://example.com"):
      with open('file.json','rb') as file:
        response = json.load(file)
      flow.response.set_text(json.dumps(response))
      ctx.log.info("modify json data.")

addons = [
  Modify()
]

把要返回的 JSON 数据文件放在和脚本文件相同的目录下。终端目录切换到该脚本文件的目录下,然后执行:

$ mitmdump -s script.py

运行应用,mitmdump 就会自动帮你替换响应数据。

附:mitmproxy 常用快捷键

以下 vim 命令可通过 ? 获得

This view:

A 接收所有被拦截的流
a 只接收该被拦截的流
b 保存 request/response 体
C 导出流到剪切板
d 删除流
D 重复流
e 切换事件日志
E 导出流到文件
f 过滤视图
F 切换follow流列表
L 加载保存的流
m 切换流标记
M 切换标记的流视图
n 创建一个新的request
r 重复request
S 服务器重复request
U 取消标记所有被标记的流
V 还原更改的请求
w 保存流
W 把流stream入文件
X 杀死和删除流,即使它正被拦截
z 清楚流或事件日志
tab 选项卡在事件日志和流列表之间切换
enter 查看流
l 运行脚本

Movement

j,k 下移,上移
h,l 左移,右移(在某些文本中)
g,G 移至开头,结尾
space 翻页
page up/down 翻页
ctrl+b /ctrl+f 翻页
方向键 上下左右移动

Global keys

i 设置拦截模式
o 选项
q 后退,返回
Q 退出而不需要确认提示
R 从文件中重复运行requests/responses
快捷键 描述
~a 匹配 response:CSS,JavaScript,Flash,image
~b regex Body
~bq regex request 请求体
~bs regex response 响应体
~c int HTTP response code
~d regex 匹配特定的 Domain
~dst regex 匹配目标地址
~e 匹配错误
~h regex Header
~hq regex Request header
~hs regex Response header
~http 匹配 http 流
~m regex Method
~marked 匹配标记的流
~q 匹配 request
~s 匹配 response
~src regex 匹配源地址
~t regex Content-type header
~tcp 匹配 TCP 流
~tq regex Request Content-type header
~ts regex Response Content-type header
~u regex URL
!
&
l
(...) 集合
  • 正则表达式是 Python 风格的。
  • 正则表达式可以被指定为带引号的字符串。
  • Header匹配(h,hq,~hs)是针对“name:value”形式的字符串。
  • 没有运算符的表达式与URL的正则表达式匹配
  • 默认的二进制运算符是 &
正则表达式示例 说明
google.com URL包含“google.com”
~q ~b test Request请求体中包含“test”
!(~q & ~t "text/html") 除了Request请求中带有 “text/html” 的内容类型
~c 404 拦截指定 HTTP 响应状态码 404
~m POST 拦截所有的 POST 请求

参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,468评论 5 473
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,620评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,427评论 0 334
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,160评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,197评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,334评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,775评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,444评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,628评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,459评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,508评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,210评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,767评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,850评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,076评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,627评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,196评论 2 341

推荐阅读更多精彩内容