Add mitmproxy to HAR conversion tools

- scripts/mitmproxy-to-har.py: Конвертер mitm → HAR
- MITMPROXY.md: Инструкция по записи и конвертации
- Два способа: mitmweb (GUI) и mitmdump + скрипт
This commit is contained in:
Claw 2026-03-22 22:36:34 +00:00
parent 90f465eedb
commit 7b01544802
2 changed files with 253 additions and 0 deletions

156
MITMPROXY.md Normal file
View File

@ -0,0 +1,156 @@
# Mitmproxy → HAR
## Быстрый старт
### Вариант 1: mitmweb (проще всего)
```bash
# 1. Запустить mitmweb
mitmweb --mode regular
# 2. Открыть в браузере
http://127.0.0.1:8081
# 3. Настроить прокси в браузере
# localhost:8081
# 4. Выполнить действия на Kwork
# 5. Экспорт: File → Export → HAR
```
### Вариант 2: mitmdump + конвертация
```bash
# 1. Записать трафик
mitmdump -w kwork-dump.mitm
# 2. Конвертировать в HAR
python3 scripts/mitmproxy-to-har.py kwork-dump.mitm kwork-dump.har
# 3. Анализировать
jq '.log.entries | length' kwork-dump.har
```
## Настройка прокси
### Системный прокси (Linux)
```bash
export http_proxy=http://127.0.0.1:8081
export https_proxy=http://127.0.0.1:8081
```
### Firefox
1. Настройки → Прокси
2. Manual proxy configuration
3. HTTP Proxy: 127.0.0.1:8081
4. ☑ Also use for HTTPS
### Chrome
```bash
# Запустить с прокси
google-chrome --proxy-server="127.0.0.1:8081"
```
## Установка сертификата
```bash
# 1. Открыть в браузере
http://mitm.it
# 2. Скачать сертификат для вашей ОС
# 3. Установить в доверенные
# Linux:
sudo cp mitmproxy-ca-cert.pem /usr/local/share/ca-certificates/
sudo update-ca-certificates
# 4. Перезапустить браузер
```
## Фильтрация трафика
```bash
# Только Kwork
mitmdump -w kwork.mitm --set 'filter=~u kwork\.ru'
# Только API
mitmdump -w kwork-api.mitm --set 'filter=~u /api/'
# Исключить статику
mitmdump -w kwork.mitm --set 'filter=!~u \.(css|js|png|jpg|gif|svg)'
```
## Скрипт для записи Kwork
```bash
#!/bin/bash
# record-kwork.sh
echo "Starting mitmproxy recording for Kwork..."
echo "Configure your browser to use proxy: localhost:8081"
echo "Press Ctrl+C when done"
mitmdump \
-w kwork-session.mitm \
--set 'filter=~u kwork\.ru' \
--set 'ignore_hosts=~u (cdn|counter|yandex|google)' \
--set 'keep_host_headers=true'
echo "Converting to HAR..."
python3 scripts/mitmproxy-to-har.py kwork-session.mitm kwork-session.har
echo "Done! File: kwork-session.har"
echo "Analyze with: jq '.log.entries | length' kwork-session.har"
```
## Анализ записанного HAR
```bash
# Количество запросов
jq '.log.entries | length' kwork-session.har
# JSON эндпоинты
jq '[.log.entries[] | select(.response.content.mimeType | test("json"; "i")) | .request.url | split("?")[0]] | unique' kwork-session.har
# Самые большие ответы
jq '[.log.entries[] | {url: .request.url, size: .response.bodySize}] | sort_by(.size) | reverse | .[0:10]' kwork-session.har
# Авторизация
jq '[.log.entries[].request.headers[] | select(.name | ascii_downcase | test("authorization|cookie"; "i"))] | unique' kwork-session.har
```
## Типичные проблемы
### SSL ошибки
```bash
# Игнорировать SSL ошибки
mitmdump --set 'ignore_hosts=.*'
# Или отключить проверку
mitmdump --set 'ssl_insecure=true'
```
### WebSocket
```bash
# WebSocket не экспортируется в HAR
# Используйте --show-websocket для отладки
mitmdump --show-websocket
```
### Сжатый трафик
```bash
# mitmproxy автоматически распаковывает
# Если нужно сырое:
mitmdump --set 'rawtcp=true'
```
---
_Updated: 2026-03-22_

View File

@ -0,0 +1,97 @@
#!/usr/bin/env python3
"""
Convert mitmproxy flow dump to HAR format
Usage: mitmproxy-to-har.py <input.mitm> <output.har>
"""
import json
import sys
from datetime import datetime
from mitmproxy import io
from mitmproxy.http import HTTPFlow
def flow_to_har_entry(flow: HTTPFlow) -> dict:
"""Convert single flow to HAR entry."""
if not flow.request or not flow.response:
return None
entry = {
"startedDateTime": datetime.fromtimestamp(flow.request.timestamp_start).isoformat() + "Z",
"time": int((flow.response.timestamp_end - flow.request.timestamp_start) * 1000) if flow.response.timestamp_end else 0,
"request": {
"method": flow.request.method,
"url": flow.request.url,
"httpVersion": flow.request.http_version,
"headers": [{"name": k, "value": v} for k, v in flow.request.headers.items()],
"queryString": [{"name": k, "value": v} for k, v in flow.request.query.items()],
"cookies": [{"name": k, "value": v} for k, v in flow.request.cookies.items()],
"headersSize": -1,
"bodySize": len(flow.request.content) if flow.request.content else 0,
},
"response": {
"status": flow.response.status_code,
"statusText": flow.response.reason,
"httpVersion": flow.response.http_version,
"headers": [{"name": k, "value": v} for k, v in flow.response.headers.items()],
"cookies": [{"name": k, "value": v} for k, v in flow.response.cookies.items()],
"content": {
"size": len(flow.response.content) if flow.response.content else 0,
"mimeType": flow.response.headers.get("Content-Type", "unknown").split(";")[0],
"text": flow.response.get_text() if flow.response.content else ""
},
"redirectURL": flow.response.headers.get("Location", ""),
"headersSize": -1,
"bodySize": len(flow.response.content) if flow.response.content else 0,
},
"cache": {},
"timings": {
"send": 0,
"wait": int((flow.response.timestamp_start - flow.request.timestamp_end) * 1000) if flow.response.timestamp_start and flow.request.timestamp_end else 0,
"receive": int((flow.response.timestamp_end - flow.response.timestamp_start) * 1000) if flow.response.timestamp_end and flow.response.timestamp_start else 0,
}
}
# Add POST data if present
if flow.request.method == "POST" and flow.request.content:
entry["request"]["postData"] = {
"mimeType": flow.request.headers.get("Content-Type", "application/octet-stream"),
"text": flow.request.get_text() if flow.request.content else ""
}
return entry
def convert_mitm_to_har(input_file: str, output_file: str):
"""Convert mitmproxy dump to HAR."""
har = {
"log": {
"version": "1.2",
"creator": {
"name": "mitmproxy-to-har",
"version": "1.0"
},
"entries": []
}
}
with open(input_file, 'rb') as f:
reader = io.FlowReader(f)
for flow in reader.read():
if isinstance(flow, HTTPFlow):
entry = flow_to_har_entry(flow)
if entry:
har["log"]["entries"].append(entry)
with open(output_file, 'w', encoding='utf-8') as f:
json.dump(har, f, indent=2, ensure_ascii=False)
print(f"Converted {len(har['log']['entries'])} flows to {output_file}")
if __name__ == "__main__":
if len(sys.argv) != 3:
print("Usage: mitmproxy-to-har.py <input.mitm> <output.har>")
sys.exit(1)
convert_mitm_to_har(sys.argv[1], sys.argv[2])