mitmproxy抓包

参考文档:https://www.wenjiangs.com/doc/2fgfiorb

一,什么是Mitmproxy?

是一款免费、开放的基于Python 开发的交互式HTTPS代理工具。

二,Mitmproxy的工作原理与特性

工作原理如下图:


image

特性:
1、支持Web
2、支持终端
3、支持Python脚本
4、可以记录和重放

三,Mitmproxy与Fiddler、Charles异同

1、相同点

  • 都是用来捕获 HTTP,HTTPS 请求的(其他协议比如 TCP,UDP,IP,ICMP 等就用Wireshark)抓包、断点调试、请求替换、构造请求、模拟弱网等
    2、不同点
  • Fiddler只能运行在Windows系统;Mitmproxy、Charles是跨平台的,可运行在Windows、Mac或Linux系统等。
  • Fiddler、Mitmproxy开源免费、Charles是收费的(可破解)。
  • Mitmproxy支持命令行交互模式、GUI界面,Fiddler、Charles仅支持GUI界面(Fiddler底部有个命令行工具叫做 QuickExec)

四,安装Mitmproxy

pip install mitmproxy

五,使用

1,启动代理服务

mitmproxy 提供了三个命令,启动模式不同:

  • mitmproxy -> 提供一个命令行界面(该命令不支持windows)
    mitmproxy 快捷键操作如下:
按键 说明
q 退出(相当于返回键,可一级一级返回)
d 删除当前(黄色箭头)指向的链接
D 恢复刚才删除的请求
G 跳到最新一个请求
g 跳到第一个请求
C 清空控制台(C是大写)
i 可输入需要拦截的文件或者域名(逗号需要用\来做转译,栗子:feezu.cn)
a 放行请求
A 放行所有请求
? 查看界面帮助信息
^ v 上下箭头移动光标
enter 查看光标所在列的内容
tab 分别查看 Request 和 Response 的详细信息
/ 搜索body里的内容
esc 退出编辑
e 进入编辑模式
  • mitmdump -> 提供一个简单的终端输出


    image.png
  • mitmweb -> 提供一个浏览器界面,访问时端口为(8081),如果8081端口被占用就运行不了

#杀死windows进程
netstat -ano|findstr 8081
#找出进程程序
tasklist |findstr 1620
#杀死进程
taskkill /pid 1260 /F
image.png
ps:这三种方式启动都默认用8080端口,-p可指定其他端口
2,安装证书

1,设置代理(需要对哪个设备抓包就对哪个设备设置代理,要先设置代理才能抓包)

  • 电脑端设置代理(wifi手动设置或对浏览器设置代理)


    image.png

    image.png
  • 手机端设置代理(wifi手动设置代理)


    image.png

    window:


    image.png

2,下载并安装证书(不安装证书无法抓取https)
在(电脑/手机)浏览器中,手动设置代理后(不先设置代理无法下载证书),浏览器输入mitm.it,选择对应的系统证书,下载完成后,去设置-描述文件中安装,添加信任


image.png

六,-s参数可指定python脚本启动

  • 启动


    image.png
  • 脚本内容:
from mitmproxy import ctx


class Counter:
    def __init__(self):
        self.num = 0

    def request(self, flow):
        self.num = self.num + 1
        ctx.log.info("we've seen %d flows" % self.num)


if __name__ == '__main__':
    addons = [
        Counter()
          ]

七,核心组件

1,Addons(插件)
文档:https://docs.mitmproxy.org/stable/addons-overview/
2,Events(事件)
文档:https://docs.mitmproxy.org/stable/api/events.html
常用事件:

"""HTTP-specific events."""
import mitmproxy.http

class Events:
    def http_connect(self, flow: mitmproxy.http.HTTPFlow):
        """
             收到了来自客户端的 HTTP CONNECT 请求。在 flow 上设置非 2xx 响应将返回该响应并断开连接。CONNECT 不
             是常用的 HTTP 请求方法,目的是与服务器建立代理连接,仅是 client 与 proxy 的之间的交流,所以 CONNECT
              请求不会触发request、response 等其他常规的 HTTP 事件
        """


    def requestheaders(self, flow: mitmproxy.http.HTTPFlow):
        """
            来自客户端的 HTTP 请求的头部被成功读取。此时 flow 中的 request 的 body 是空的.
        """

    def request(self, flow: mitmproxy.http.HTTPFlow):
        """
            来自客户端的 HTTP 请求被成功完整读取
        """

    def responseheaders(self, flow: mitmproxy.http.HTTPFlow):
        """
            来自服务端的 HTTP 响应的头部被成功读取。此时 flow 中的 response 的 body 是空的.
        """

    def response(self, flow: mitmproxy.http.HTTPFlow):
        """
            来自服务端端的 HTTP 响应被成功完整读取
        """

    def error(self, flow: mitmproxy.http.HTTPFlow):
        """
            发生了一个 HTTP 错误。比如无效的服务端响应、连接断开等。注意与“有效的 HTTP 错误返回”不是一回事,后者\
           是一个正确的服务端响应,只是 HTTP code 表示错误而已
        """

八,示例

示例一:实现map local,更改雪球app行情看板从本地json文件取值
需要篡改客户端请求,所以实现一个 request 事件

 def request(self, flow: mitmproxy.http.HTTPFlow):
        """
            来自客户端的 HTTP 请求被成功完整读取
        """
        pathurl = '/stock.xueqiu.com/v5/stock/batch/quote.json'
        if pathurl in flow.request.pretty_url:
            with open("./quote.json", 'r', encoding="utf-8") as f:
                content = f.read()
                flow.response = mitmproxy.http.Response.make(
                    200,  # (optional) status code
                    content,  # (optional) content
                    {"Content-Type": "application/json"}  # (optional) headers
                )
        

示例二:实现Rewrite,更改雪球app行情看板的第二个股票名称价格和涨幅
需要篡改服务端返回,所以实现一个 response事件

    def response(self, flow: mitmproxy.http.HTTPFlow):
        """
            来自服务端端的 HTTP 响应被成功完整读取
        """
        pathurl = '/stock.xueqiu.com/v5/stock/batch/quote.json'
        if pathurl in flow.request.pretty_url:
            data = json.loads(flow.response.get_content())
            data['data']['items'][1]['quote']['name'] = data['data']['items'][1]['quote']['name'] + "test"
            data['data']['items'][1]['quote']['current'] = '50'
            data['data']['items'][1]['quote']['percent'] = '0.00'
            flow.response.text = json.dumps(data, ensure_ascii=True)
            ctx.log.info(flow.response.get_content())

结果:

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容