TESTforge42's picture
Upload folder using huggingface_hub
f7bd30a verified
|
Raw
History Blame Contribute Delete
1.58 kB
---
license: apache-2.0
tags: [security-research, huntr, model-file-security, scanner-bypass, pytorch]
---
# picklescan & ModelScan bypass: LEGACY (non-zip) PyTorch .bin — 5-iteration-loop exhaustion
Benign PoC for the huntr Model File Format program. Payload writes only a nonce marker — no real harm.
## Vulnerability
The legacy torch serialization (torch.save(..., _use_new_zipfile_serialization=False)) is the format most pre-safetensors HF `pytorch_model.bin` checkpoints ship in: a flat concatenation of pickles (magic, protocol, sys_info, then the main object pickle). ModelScan's scan_pytorch calls scan_pickle_bytes(multiple_pickles=False) — it scans ONLY the protocol pickle and NEVER the main object pickle, so a plain malicious legacy .bin already evades it. picklescan's legacy branch loops `for _ in range(5): scan_pickle_bytes(...)` and RESUMES after a genops error; prepending 6 int-opcode-desync pickles (`I0x10\n`) exhausts all 5 iterations so the real main pickle falls beyond the scan window and its GLOBAL is never seen (picklescan exit 0). torch._legacy_load reads the whole stream with the C unpickler: leading junk ints are discarded and the main object's __reduce__ fires -> arbitrary code execution at load. Distinct scanner code path (flat 5-pickle loop) + distinct loader (_legacy_load) from the .pt-ZIP variant.
## Measured (2026-07-24): picklescan 1.0.5 exit 0; ModelScan 0.8.8 exit 0; torch.load fires the benign marker.
## Reproduce
```python
import torch
torch.load("pytorch_model.bin", weights_only=False) # fires the benign marker
```