Mitmproxy: tips, tricks and scripts
Useful links
- https://docs.mitmproxy.org/stable/concepts-certificates
- https://docs.mitmproxy.org/stable/api/mitmproxy/flow.html
Precondition
Let’s put this code at the top of our mitmproxy script file:
from mitmproxy import http
import json
import time
import os
server_folder = "mitmproxy_data"
def parse_json(content: bytes):
try:
return json.loads(content.decode("utf-8"))
except:
return None
Tips, tricks, scripts
Filter by host and endpoints
def request(flow: http.HTTPFlow) -> None:
content = flow.request.content
if any(url in flow.request.url for url in target_list()):
print(content)
def response(flow: http.HTTPFlow) -> None:
content = flow.response.content
if any(url in flow.request.url for url in target_list()):
print(content)
def target_list():
return ["foo.bar", "sample-website.com/test/endpoint"]
Catch all json requests and responses
def request(flow: http.HTTPFlow) -> None:
content = parse_json(flow.request.content)
if content is not None:
print(content)
def response(flow: http.HTTPFlow) -> None:
content = parse_json(flow.response.content)
if content is not None:
print(content)
Embed tracking beacon in jsons
def request(flow: http.HTTPFlow) -> None:
content = parse_json(flow.request.content)
if content is not None:
content = add_tracker(flow, content)
print(content)
def response(flow: http.HTTPFlow) -> None:
content = parse_json(flow.response.content)
if content is not None:
content = add_tracker(flow, content)
print(content)
def add_tracker(flow: http.HTTPFlow, content: json):
if isinstance(content, list):
content += [{"mitmproxy_tracker": flow.request.url}]
else:
content["mitmproxy_tracker"] = flow.request.url
return content
Write json data to a file
def request(flow: http.HTTPFlow) -> None:
content = parse_json(flow.request.content)
if content is not None:
file = open(file_path("request"), 'w')
file.write(beautify(content))
file.close()
def response(flow: http.HTTPFlow) -> None:
content = parse_json(flow.response.content)
if content is not None:
file = open(file_path("response"), 'w')
file.write(beautify(content))
file.close()
def file_path(type: str):
os.makedirs(server_folder, exist_ok=True)
return server_folder + "/" + type + "_%s.json" % int(time.time())
def beautify(content: json):
return json.dumps(content, indent=4, sort_keys=True)
Return all jsons combined into one
def request(flow: http.HTTPFlow) -> None:
if "mitmproxy/collect" in flow.request.url:
jsons = []
for file in os.listdir(server_folder):
file_path = os.path.join(server_folder, file)
content = ""
with open(file_path) as file:
for line in file:
content += line
jsons.append(content)
json = "[" + ",".join(jsons) + "]"
flow.response = http.Response.make(
200,
json,
{"Content-Type": "application/json"}
)
Clear all saved files
if "mitmproxy/clear" in flow.request.url:
for file in os.listdir(server_folder):
os.remove(os.path.join(server_folder, file))
flow.response = http.Response.make(200)
Kill request
def request(flow: http.HTTPFlow) -> None:
block_hosts = ["appldnld.apple.com", "mesu.apple.com"]
if any(host in flow.request.host for host in block_hosts):
flow.kill
Update headers and queries in requests and responses
def request(flow: http.HTTPFlow) -> None:
flow.request.query["mitm"] = "proxy"
flow.request.headers["newheader"] = "foo"
def response(flow: http.HTTPFlow) -> None:
flow.response.query["proxy"] = "mitm"
flow.response.headers["newheader"] = "bar"
Change response status code
def response(flow: http.HTTPFlow) -> None:
flow.response.status_code = 503
Emulate slow connection
def response(flow: http.HTTPFlow) -> None:
time.sleep(5.0)
Redirect requests
def request(flow: http.HTTPFlow) -> None:
flow.request.host = "127.0.0.1"
flow.request.scheme = "http"
flow.request.port = 4567
Anything else?
Stay in touch (: