雪球App抓包与Mock实战(二)- 课程贴

对本次课的反馈与建议

https://hogwarts.jinshuju.com/f/gPIZNX

mitmproxy

作业

安装配置

安装

官网的安装说明

三端安装

windows 安装

  • windows使用cmd安装mitmproxy
  • 命令:
    pip install pipx
    pipx install mitmproxy
  • 安装之后需要配置环境变量:安装成功的提示中会给出需要配置的目录,将其配置到path环境变量中重启cmd即可

安装成功验证

mitmdump --verison
image

证书配置

  1. 电脑配置

    1. 先启动下mitmproxy 或者 mitmdump
    2. 配置好浏览器的代理,端口设置为mitmproxy的默认端口8080
    3. 进入http://mitm.it/ 页面 , 选择对应系统,下载证书
  2. 手机配置

  • 同上

可能存在的坑

  1. cannot import name 'PyAsn1UnicodeDecodeError' from 'pyasn1.error' (/usr/local/lib/python3.7/site-packages/pyasn1/error.py)

解决办法:


pip3 uninstall pyasn1

pip3 install pyasn1

三种方式

  1. command line
    mitmproxy

  2. web interface
    mitmweb

  3. python API
    mitmdump

常见参数

  1. -p ,指定代理server端口号
  2. -h,查看帮助
  3. -s,和python交互

案例

“map local” 实现文件替换

from mitmproxy import http

def request(flow: http.HTTPFlow):
    # redirect to different host
    if "quote.json" in flow.request.url:
        with open("/Users/lixu/project/tmp/quote.json") as f:
            flow.response = http.HTTPResponse.make(
                200, f.read(),
            )

“rewrite”修改某个字段

import json
from pprint import pprint

from mitmproxy import http

def response(flow: http.HTTPFlow):
    # redirect to different host
    if "quote.json" in flow.request.url and "x=" in flow.request.url:
        ## 先接收到返回信息
        data = json.loads(flow.response.content)
        print("=============修改前的信息============================")
        pprint(data)
        ## 中间做一些修改
        data["data"]["items"][0]["quote"]["name"] = data["data"]["items"][0]["quote"]["name"]+"hogwarts"
        data["data"]["items"][1]["quote"]["name"] = data["data"]["items"][1]["quote"]["name"]+"hogwarts"
        data["data"]["items"][2]["quote"]["name"] = data["data"]["items"][2]["quote"]["name"]+"hogwarts"
        data["data"]["items"][3]["quote"]["name"] = data["data"]["items"][3]["quote"]["name"]+"hogwarts"
        ## 修改返回信息的字段
        print("*******************修改后的信息************************")
        pprint(data)
        flow.response.text = json.dumps(data)

实现定制化的等价类

  • 注意: 这步比较难,如果没听懂的话,可以等下一章节结课,再来复习
import json
from pprint import pprint

from mitmproxy import http

def response(flow: http.HTTPFlow):
    # redirect to different host
    if "quote.json" in flow.request.url and "x=" in flow.request.url:
        ## 先接收到返回信息
        data = json.loads(flow.response.content)
        ## 对数据进行批量修改
        new_data = json_travel(data , num=100, text=1)
        ## 这步是为了方便打印
        data_mess = json.dumps(new_data, indent=2, ensure_ascii=False)
        print("=====================修改后的信息=======================================")
        print(data_mess)
        ## 改变返回信息
        flow.response.text = data_mess


def json_travel(data, array=None, text=1, num=1):
    """
    {
        "data":
        {"name":{
        "nickname": "xxxxx"
        }

        }
    }
    """
    # 如果是字典,则对字典进行遍历
    if isinstance(data, dict):
        data_new = dict()
        for k, v in data.items():
            data_new[k] = json_travel(v, array, text, num)
            if k == "name":
                data_new[k] = json_travel(v, array, text=2, num=1)

    # 如果是列表,那么对列表的每一项进行遍历
    elif isinstance(data, list):
        data_new = list()
        for item in data:
            item_new = json_travel(item, array, text, num)
            if array is None:
                data_new.append(item_new)
            else:
                pass
    # 如果是字符串,则和传入的text参数相乘、实现对字符串的修改
    elif isinstance(data, str):
        data_new = data*text
    # 如果是int或float 的数字类型,那么会对数字做一个乘积
    elif isinstance(data, int) or isinstance(data, float):
        data_new = data*num
    # 传入什么返回什么
    else:
        data_new = data
    return data_new