【拉勾4期】雪球 app 抓包与 mock实战 2

标题

雪球 app 抓包与 mock实战 2

课程价值

  • 了解 mitmproxy 工具
  • 掌握 mitmdump 做 mock 测试

大纲

  • mitmproxy 介绍
  • mitmproxy 工具
  • mitmdump 实战

时长

90分钟

PPT

https://pdf.ceshiren.com/lg4/雪球app抓包与mock实战2

实战内容

参考资料

mitmproxy 安装

推荐使用 python 安装方式:python 版本需要高于 3.6

pip install pipx
pipx install mitmproxy

环境验证

mitmdump --version

mitmproxy 工具

3个工具

  • mitmproxy → 命令行工具
  • mitmdump → 加载python脚本
  • mitmweb → web界面工具

常用参数

  • -h 帮助信息
  • -p 指定监听的端口
  • -s 加载 python 脚本

整数安装方式

  1. 设置好代理,启动工具
  2. 在浏览器访问 mitm.it
  3. 选择对应的系统下载证书进行安装

mitmdump 实战

录制与回放

录制:mitmdump -w tmp
过滤:mitmdump -nr tmp -w tmp2 “~s hogwarts”
回放:mitmdump -nC tmp2

参数

  • -n 不启动代理
  • -r 读取文件内容
  • -w 写入文件
  • ~s 过滤响应数据

实现 maplocal

代码

from mitmproxy import http


# request 方法名不能修改
def request(flow: http.HTTPFlow):
    # 发起请求,判断 url 是不是预期的值
    if "quote.json" in flow.request.pretty_url:
        # 打开一个保存在本地的数据文件
        with open ("/Users/mac/Desktop/quote.json") as f:
            # 创造一个 response
            flow.response = http.HTTPResponse.make(
                200,  # (optional) status code
                # 读取文件中的数据作为返回内容
                f.read(),
                {"Content-Type": "application/json"}  # (optional) headers
            )

启动脚本

mitmdump -p xxxx -s python_path

实现 rewrite

代码

def response(flow: http.HTTPFlow):
    # 加上过滤条件
    if "quote.json" in flow.request.pretty_url and "x=" in flow.request.pretty_url:
        # 拿到响应数据,转化成为python对象
        data = json.loads(flow.response.content)
        # 修改对应的字段的值
        data['data']['items'][0]['quote']['name'] = "rewrite_hogwarts"
        # 把修改后的数据,转为字符串,赋值给原始响应数据
        flow.response.text = json.dumps(data)

启动命令

mitmdump -p xxxx -s python_path

课后作业

使用mitmproxy,贴出来脚本内容和效果截图

  • 对第一个股票保持原样
  • 对第二个股票名字加长一倍
  • 对第三个股票名字变成空

课后调查表


使用maplocal

# 使用maplocal
def response(flow: http.HTTPFlow):
    # 加上过滤条件
    if "quote.json" in flow.request.pretty_url and "x=" in flow.request.pretty_url:
        # 拿到响应数据,转化成为python对象
        data = json.loads(flow.response.content)
        # 修改对应的字段的值
        data['data']['items'][0]['quote']['current'] = "111"
        data['data']['items'][1]['quote']['name'] = data['data']['items'][1]['quote']['name'] * 2
        data['data']['items'][2]['quote']['name'] = ""

        # 把修改后的数据,转为字符串,赋值给原始响应数据
        flow.response.text = json.dumps(data)

# 使用rewrite
def request(flow: http.HTTPFlow):
    if "quote.json" in flow.request.pretty_url:
        with open ("E:\changename.json", encoding="utf-8") as f:
            flow.response = http.HTTPResponse.make(
                200,
                f.read(),
                {"Content-Type": "application/json"}  # (optional) headers
            )


第一种方法通过改maplocal修改json:

from mitmproxy import http

def request(flow: http.HTTPFlow):
    if "quote.json" in flow.request.pretty_url:
        with open ("./mock1.json", encoding="utf-8") as f:
            flow.response = http.HTTPResponse.make(
                200,
                f.read(),
                {"Content-Type": "application/json"}  # (optional) headers
            )

image
第二种方法就是通过rewrite:

import json

from mitmproxy import http


def response(flow: http.HTTPFlow):
    if "quote.json" in flow.request.pretty_url and "x=" in flow.request.pretty_url:
        data = json.loads(flow.response.content)
        data['data']['items'][1]['quote']['name'] =data['data']['items'][1]['quote']['name'] + data['data']['items'][1]['quote']['name']
        data['data']['items'][2]['quote']['name'] = " "
        flow.response.text = json.dumps(data)

import json
from mitmproxy import http


def response(flow: http.HTTPFlow):
    if 'quote.json' in flow.request.pretty_url and 'x=' in flow.request.pretty_url:
        data = json.loads(flow.response.content)
        # 如果股票列表长度>=3,才进行替换操作
        if len(data['data']['items']) >= 3:
            data['data']['items'][1]['quote']['name'] *= 2
            data['data']['items'][2]['quote']['name'] = ""
        flow.response.text = json.dumps(data)

image

1.读取本地json文件,返回客户端


2.直接修改响应字段

第一种方式MapLocal:
代码:

import json
from mitmproxy import http
def response(flow: http.HTTPFlow):
    if 'quote.json' in flow.request.pretty_url and 'x=' in flow.request.pretty_url:
        data=json.loads(flow.response.content)
        data['data']['items'][1]['quote']['name'] *= 2
        data['data']['items'][2]['quote']['name']=''
        flow.response.text=json.dumps(data)

结果:
image

第二种方式Rewrite:
代码:

from mitmproxy import http

def request(flow: http.HTTPFlow):
    if 'quote.json' in flow.request.pretty_url:
        with open('C:\\Users\\admin\\Desktop\\xueqiu1.json',encoding='utf-8') as f:
            flow.response=http.HTTPResponse.make(
                200,
                f.read(),
                {'Content-Type': 'application/json'}
            )

结果:
image

mock实战作业二——张涛

  • 对第一个股票保持原样
  • 对第二个股票名字加长一倍
  • 对第三个股票名字变成空

方法一:使用maplocal方法直接修改json文件

  • 代码
from mitmproxy import http
import os

# 使用maplocal进行mock
# 方法名必须死request
def request(flow: http.HTTPFlow):
    # 发起请求,判断 url 是不是预期的值
    if "quote.json" in flow.request.pretty_url:
        # 打开一个保存在本地的数据文件
        with open ("quote.json", encoding="utf-8") as f:
            # 创造一个 response
            flow.response = http.HTTPResponse.make(
                200,  # (optional) status code
                # 读取文件中的数据作为返回内容
                f.read(),
                {"Content-Type": "application/json"}  # (optional) headers
            )

if __name__ == '__main__':
    os.system(r"mitmdump -p 8999 -s 'D:\My_Files\HogwartsAPI\assignment\mock_practice\mitm_pra.py'")
  • 截图

image

方法二:使用rewrite方法

  • 代码
import json
from mitmproxy import http
import os

def response(flow: http.HTTPFlow):
    # 限制条件进行url过滤
    if 'quote.json' in flow.request.pretty_url and 'x=' in flow.request.pretty_url:
        # 获取响应信息,并使用json.loads转换为Python可编辑的json文件
            data = json.loads(flow.response.content)
            for i in range(len(data['data']['items'])):
                # 为了与第一种方法区别结果,这里将所有股票名改为InsaneLoafer
                data['data']['items'][i]['quote']['name'] = "Insane"
                # 修改第二只股票,名字加长一倍
                if i == 1:
                    data['data']['items'][i]['quote']['name'] *= 2
                # 修改第三只股票,将其名字置空
                elif i == 2:
                    data['data']['items'][i]['quote']['name'] = ''
            # 重新以二进制原格式返回响应信息
            flow.response.text = json.dumps(data)

if __name__ == '__main__':
    os.system(r"mitmdump -p 8999 -s 'D:\My_Files\HogwartsAPI\assignment\mock_practice\mitm_rewrite.py'")
  • 截图

image

from mitmproxy import http
import json


# 方法名不能修改
# def request(flow: http.HTTPFlow):
#     # 添加过滤条件
#     if "quote.json" in flow.request.pretty_url:
#         # 文件必须护绝对路径
#         with open("C:/Users/biao.du\Documents/lg_study\mitmproxy/xueqiu.json") as f:
#             flow.response = http.HTTPResponse.make(
#                 200,
#                 f.read(),
#                 {"Content-Type": "application/json"}  # (optional) headers
#             )
#             f.read()


def response(flow: http.HTTPFlow):
    print(flow.request.pretty_url)
    if "quote.json" in flow.request.pretty_url and "x=" in flow.request.pretty_url:
        data = json.loads(flow.response.content)
        data["data"]["items"][1]["quote"]["name"] =  data["data"]["items"][1]["quote"]["name"] * 2
        data["data"]["items"][2]["quote"]["name"] = ""

        # flow.response.text = json.dumps(data)
        # 同flow.response.text
        flow.response = http.HTTPResponse.make(
            200,
            json.dumps(data)
        )

image

image

import json
from pprint import pprint

from mitmproxy import http


def response(flow: http.HTTPFlow):
    if 'quote.json' in flow.request.pretty_url and 'x=' in flow.request.pretty_url:

        data = json.loads(flow.response.text)
        print(data, '-----------')
        # data['data']['items'][0]['quote']['name'] = 'zhuyuan'
        data['data']['items'][1]['quote']['name'] = data['data']['items'][1]['quote']['name'] * 2
        data['data']['items'][2]['quote']['name'] = ''
        flow.response.text = json.dumps(data)

import json
from mitmproxy import http


def response(flow: http.HTTPFlow):
    # 过滤条件
    if "quote.json" in flow.request.pretty_url and "x=" in flow.request.pretty_url:
        # 拿到响应数据, 转换为字典
        data = json.loads(flow.response.content)
        # 修改对应的字段的值
        data['data']['items'][0]['quote']['name'] = "rewrite_zsj"
        data['data']['items'][1]['quote']['name'] = "rewrite_zsjrewrite_zsj"
        data['data']['items'][2]['quote']['name'] = ""
        # 把修改后的数据, 转为字符串,赋值给原始响应数据
        flow.response.text = json.dumps(data)

作业:
一:使用rewrite方法:

from mitmproxy import http
import json


def response(flow:http.HTTPFlow):
    # 添加过滤条件,只修改这一个接口数据,否则的话其他接口找不到该字段会报错
    if "quote.json" in flow.request.pretty_url and "x=" in flow.request.pretty_url:
        # 拿到响应数据,转化成为Python对象
        data = json.loads(flow.response.content)
        # 修改对应的字段的值
        data["data"]["items"][1]["quote"]["name"] *= 2
        data["data"]["items"][2]["quote"]["name"] = ""
        # 把修改后的数据转为字符串,赋值给原始响应数据
        flow.response.text = json.dumps(data)

效果截图如下:
image
二:使用maplocal方法,只需要修改quote.json中的字段value即可

作业

作业:
使用mitmproxy,贴出来脚本内容和效果截图

  • 对第一个股票保持原样
  • 对第二个股票名字加长一倍
  • 对第三个股票名字变成空

实现代码与效果图如下: