mimimitm.py (3150B)
1from io import BytesIO 2from logging import info, warn 3from typing_extensions import override 4from mitmproxy import ctx 5from os import listdir 6from os.path import basename 7from PIL import Image, ImageDraw 8from ultralytics import YOLO 9from ultralytics.yolo.utils import set_logging 10from urllib.parse import urlparse 11 12import pillow_avif 13import random 14 15set_logging("ultralytics", False) 16 17class MIMIMITM: 18 def __init__(self): 19 self.model = None 20 21 def load(self, loader): 22 loader.add_option("weights", str, "weights.pt", "weights path (.pt)") 23 loader.add_option("debug", bool, False, "enable debug") 24 loader.add_option("imgsize", int, 640, "inference img size") 25 loader.add_option("conf", float, 0.5, "confidence threshold") 26 loader.add_option("iou", float, 0.5, "IOU threshold") 27 loader.add_option("dev", str, "cpu", "inference device") 28 loader.add_option("augment", bool, True, "inference device") 29 30 def running(self): 31 try: 32 self.model = YOLO(ctx.options.weights) 33 self.overlays = [Image.open(f"overlays/{name}") \ 34 for name in listdir("overlays")] 35 info("MIMIMITM is running!") 36 except: 37 addons.clear() 38 raise 39 40 def response(self, flow): 41 content_type = flow.response.headers.get("content-type", "") 42 43 info(f"TYPE {content_type}") 44 45 if "image/" not in content_type: 46 return 47 48 if ctx.options.debug: 49 warn("RUNNING") 50 51 try: 52 io = BytesIO(flow.response.content) 53 io.name = basename(urlparse(flow.request.url).path) 54 img = Image.open(io, formats=None) 55 except: 56 raise Exception(f"load img of content type {content_type}") 57 58 results = self.model.predict(source=img, imgsz=ctx.options.imgsize, 59 conf=ctx.options.conf, iou=ctx.options.iou, 60 augment=ctx.options.augment, device=ctx.options.dev) 61 result = results[0].cpu().numpy() 62 63 draw = ImageDraw.Draw(img) 64 if ctx.options.debug: 65 warn(f"FOUND {len(result.boxes)}") 66 for box in result.boxes: 67 x1, y1, x2, y2 = [int(v + 0.5) for v in box.xyxy[0]] 68 if ctx.options.debug: 69 conf = box.conf[0] 70 info(f"BOX ({conf}) {x1} {y1} {x2} {y2}") 71 draw.line((x1, y1, x2, y1), fill=(255, 0, 0), width=2) 72 draw.line((x2, y1, x2, y2), fill=(255, 0, 0), width=2) 73 draw.line((x2, y2, x1, y2), fill=(255, 0, 0), width=2) 74 draw.line((x1, y2, x1, y1), fill=(255, 0, 0), width=2) 75 w, h = abs(x1 - x2), abs(y1 - y2) 76 if w < h / 2: # facing away approximator 77 continue 78 y1, y2 = (y1 - h / 2), (y2 - h / 2) 79 bx, by = (int(x1 - w / 2), int(y1 - h / 2)) 80 overlay = random.choice(self.overlays).resize((w * 2, h * 2)) 81 img.paste(overlay, box=(bx, by), mask=overlay.split()[-1]) 82 83 io = BytesIO() 84 img.save(io, format=img.format) 85 flow.response.content = io.getvalue() 86 87addons = [ 88 MIMIMITM() 89]