chore: initial commit — recon artifacts + design spec + Phase 1 plan
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
"""Read mitmproxy flow file, print unique endpoints by host/method/path."""
|
||||
import sys, collections
|
||||
from mitmproxy import io as miio
|
||||
from mitmproxy.exceptions import FlowReadException
|
||||
|
||||
flow_file = sys.argv[1]
|
||||
filter_host = sys.argv[2] if len(sys.argv) > 2 else None
|
||||
|
||||
stats = collections.Counter()
|
||||
endpoints = collections.defaultdict(set)
|
||||
hosts = collections.Counter()
|
||||
status_codes = collections.Counter()
|
||||
|
||||
with open(flow_file, "rb") as f:
|
||||
reader = miio.FlowReader(f)
|
||||
try:
|
||||
for flow in reader.stream():
|
||||
if not hasattr(flow, "request"):
|
||||
continue
|
||||
req = flow.request
|
||||
host = req.pretty_host
|
||||
if filter_host and filter_host not in host:
|
||||
continue
|
||||
hosts[host] += 1
|
||||
key = (req.method, req.path.split("?")[0])
|
||||
endpoints[host].add(key)
|
||||
stats[(req.method, host, req.path.split("?")[0])] += 1
|
||||
if flow.response:
|
||||
status_codes[flow.response.status_code] += 1
|
||||
except FlowReadException as e:
|
||||
print(f"[warn] flow truncated: {e}", file=sys.stderr)
|
||||
|
||||
print("=== Hosts ===")
|
||||
for h, c in hosts.most_common():
|
||||
print(f" {c:5d} {h}")
|
||||
print()
|
||||
print("=== Endpoints grouped by host ===")
|
||||
for h in sorted(endpoints.keys()):
|
||||
print(f"\n--- {h} ---")
|
||||
for method, path in sorted(endpoints[h]):
|
||||
count = stats[(method, h, path)]
|
||||
print(f" [{count:3d}x] {method:6s} {path}")
|
||||
print()
|
||||
print("=== Status codes ===")
|
||||
for code, c in status_codes.most_common():
|
||||
print(f" {code}: {c}")
|
||||
Reference in New Issue
Block a user