mitmproxy修改接口返回

公司的软件库没有charles,也没有fiddler,也不让自己下载安装,只好自己写个代理修改接口返回了

在windows上安装和配置mitmproxy

  1. 安装mitmproxy包
    pip install mitmproxy

  2. 在命令行打 mitmweb 看是否能起起来一个8081的web网页
    能打开下图2的网页则说明安装成功了,但是如果还没安装过证书的话,是还看不到任何请求的。

  3. 安装证书
    windows下,安装完mitmproxy后,系统会自动下载好了证书,路径在 C:\Users\你的用户名.mitmproxy

    3.1 双击mitmproxy-ca.p12,进入证书导入向导

    3.2 直接下一步后,不填密码,再直接下一步

    3.3 选择证书存储选【受信任的证书颁发机构】

    3.4 点击完成,证书就导入到当前用户\计算机的根证书存储里面了

chrome开代理

  1. 打开chrome的设置 -- 搜索“代理” -- 点击“打开您的计算机代理设置”, 此时会打开系统的代理设置窗口

  2. 在手动设置代理打开代理,设置好端口为8080, 保存。如果是要代理本地某些网段的端口,如172.18..,要注意地址是否写入了禁用列表,必须从列表移除掉才能抓到包。

  3. 此时再打开 mitmweb ,可以看到已经能抓到http包了

代码

  1. 获取请求头和request_body
    如下实例会打印请求头,并把请求body写入文件里
   # 来自client的 HTTP 请求被成功完整读取(包括请求头以及body)
    def request(self, flow: mitmproxy.http.HTTPFlow):
        filter_host = "172.18.34.102"
        url_path = "http://172.18.34.102:9005/xxx-api/containerType/query"
        if (str(flow.request.host) == filter_host) and (str(flow.request.url) == url_path):
            self.num += 1
            ctx.log(u"处理第 %d 个请求" % self.num)
            ctx.log(flow.request.headers) # 打印请求头

            with open(r'./request_body.txt', 'a', encoding="utf-8") as file:
                # file.write(str(flow.request.headers))
                file.write(str(flow.request.get_text())) # 保存请求body
                print("request_body 写入成功")

生成了一个request_body.txt的文件

  1. 修改repsonse
   # 来自server的 HTTP 响应被成功完整读取
    def response(self, flow: mitmproxy.http.HTTPFlow):
        filter_host = "172.18.34.102"
        url_path = "http://172.18.34.102:9005/xxx-api/base/getEnum"
        if (str(flow.request.host) == filter_host) and (str(flow.request.url) == url_path):
            res = json.loads(flow.response.get_text())
            res['data']['commonEnum']['containerKind'] = {'CARTON': "纸箱", 'PLASTIC': "塑料", 'AAA':'哈哈哈'} # 修改接口返回
            flow.response.set_text(json.dumps(res))
            ctx.log('modified limitCount: {}'.format(res))

  1. 完整代码
import mitmproxy.http
from mitmproxy import ctx
import json
from mitmproxy.tools.main import mitmweb

class proxy_example(object):
    '''
    利用mitmproxy模拟一获取\修改HTTP数据
    '''

    def __init__(self):
        self.num = 0

    # 来自client的 HTTP 请求被成功完整读取(包括请求头以及body)
    def request(self, flow: mitmproxy.http.HTTPFlow):
        filter_host = "172.18.34.102"
        url_path = "http://172.18.34.102:9005/xxx-api/containerType/query"
        if (str(flow.request.host) == filter_host) and (str(flow.request.url) == url_path):
            self.num += 1
            ctx.log(u"处理第 %d 个请求" % self.num)
            ctx.log(flow.request.headers)

            with open(r'./request_body.txt', 'a', encoding="utf-8") as file:
                # file.write(str(flow.request.headers))
                file.write(str(flow.request.get_text()))
                print("request_body 写入成功")

    # 来自server的 HTTP 响应被成功完整读取
    def response(self, flow: mitmproxy.http.HTTPFlow):
        filter_host = "172.18.34.102"
        url_path = "http://172.18.34.102:9005/xxx-api/base/getEnum"
        if (str(flow.request.host) == filter_host) and (str(flow.request.url) == url_path):
            res = json.loads(flow.response.get_text())
            res['data']['commonEnum']['containerKind'] = {'CARTON': "纸箱", 'PLASTIC': "塑料", 'AAA':'哈哈哈'}
            flow.response.set_text(json.dumps(res))
            ctx.log('modified limitCount: {}'.format(res))

    # 处理响应异常, HTTP错误
    def error(self, flow: mitmproxy.http.HTTPFlow):
        pass
    
    def websocket_message(self, flow: websocket.WebSocketMessage):
        assert flow.websocket is not None  # make type checker happy
        # get the latest message
        message = flow.websocket.messages[-1]

        # was the message sent from the client or server?
        if message.from_client:
            logging.info(f"Client sent a message: {message.content!r}")
        else:
            logging.info(f"Server sent a message: {type(message.content)} {message.content!r}")

            # manipulate the message content
            # message.content = re.sub(rb"^Hello", b"HAPPY", message.content)
            content = byte_to_dict(message.content)
            event = content.get('event', None)
            if event and event == 'station_info':
                if content['data']['station'] ['code'] == '15':
                    content = readJson('station_info_15.json')
                    message.content = dic_to_byte(content)
addons = [
    proxy_example()
]

if __name__ == '__main__':
    mitmweb()

在控制台输入 mitmdump -p 8080 -s test_proxy.py

posted @ 2022-11-30 11:37  水天需  阅读(695)  评论(0编辑  收藏  举报