cmpndry's picture
Upload 3 files
4cbb7df verified
|
Raw
History Blame Contribute Delete
2.19 kB
---
license: mit
tags:
- security-poc
- coordinated-disclosure
---
# PoC: modelscan 0.8.8 multi-pickle legacy scan bypass (scanner evasion)
> Coordinated-disclosure proof-of-concept submitted to huntr. The model file in this
> repository is a **benign test artifact**: its payload only runs `touch MP_legacy_pwn`
> (creates an empty marker file in the working directory). No network access, no
> destructive action. Do not load untrusted model files.
## What this demonstrates
`modelscan` 0.8.8 reports `evil_legacy.pt` as clean ("No issues found! πŸŽ‰", exit 0), yet
`torch.load("evil_legacy.pt", weights_only=False)` executes the payload. The identical
`os.system` operator in a single-stream pickle **is** flagged β€” so this is a scan-coverage
correctness defect, not a denylist gap.
This is a **scanner-evasion** finding (huntr "unique methods to bypass our automated
scanners"), not a report of pickle deserialization itself. Root cause: `scan_pytorch()`
(`modelscan/tools/picklescanner.py`) calls `scan_pickle_bytes(..., multiple_pickles=False)`,
so `_list_globals()` breaks after the first of the file's sequential pickle streams and
never inspects the model object graph.
## How the PoC model was created
A well-formed 5-stream PyTorch legacy file: magic number, protocol, sys_info, the
`os.system` payload object, and an empty storage-keys list (so `torch.load` returns
without error β€” a valid file, not malformed). See `poc.py`.
## Files
- `evil_legacy.pt` β€” the malicious-but-benign model file (modelscan-clean, executes on load).
- `poc.py` β€” self-contained: builds the file, scans it (clean), loads it (executes), and runs a single-stream control (flagged). One command.
## Reproduce
```
pip install "modelscan==0.8.8" torch
modelscan -p evil_legacy.pt # -> No issues found! πŸŽ‰ (exit 0)
python -c "import torch; torch.load('evil_legacy.pt', weights_only=False)" # -> creates MP_legacy_pwn
python poc.py # full differential, prints: RESULT: PASS
```
## Affected / fix
modelscan 0.8.8 (latest at disclosure). Fix: pass `multiple_pickles=True` in the PyTorch
legacy scan path (`scan_pytorch`), matching the non-legacy behaviour.