--- license: mit tags: - security-research - modelscan-bypass --- # Modelscan EOP Bypass PoC — STACK_GLOBAL Offset 0 Scanner Crash ## Vulnerability `picklescanner.py:87` uses `range(1, n)` to scan backward from STACK_GLOBAL opcode, which **skips index 0**. Placing a callable's module argument at position 0 causes the scanner to find only 1 argument instead of 2, raising `ValueError`. This `ValueError` propagates to `modelscan.py:175` where a broad `except Exception` handler converts it to a scanner **error** (not an **issue**). **Result:** `modelscan` reports **"No issues found!"** while the pickle contains `os.system` (a CRITICAL blocklisted callable) and executes arbitrary commands. ## Impact This bypasses the **entire** `unsafe_globals` blocklist. Any callable (`os.system`, `subprocess.Popen`, etc.) can be used because the scanner crashes before checking the blocklist. ## Reproduction ```bash modelscan scan -p eop_bypass_poc.pkl # Output: "No issues found! 🎉" python3 -c "import pickle; pickle.loads(open('eop_bypass_poc.pkl','rb').read())" # Output: PWNED_BY_MODELSCAN_EOP_BYPASS ``` ## Root Cause ```python # picklescanner.py:86-87 elif op_name == "STACK_GLOBAL": values: List[str] = [] for offset in range(1, n): # BUG: should be range(1, n+1) to include pos 0 ``` ## Fix Change `range(1, n)` to `range(1, n+1)` in `picklescanner.py:87`.