mscgo77's picture
Upload README.md with huggingface_hub
1eb56ef verified
|
Raw
History Blame Contribute Delete
2.46 kB
---
license: mit
tags:
- security
- poc
---
# torch.package (PyTorch Package MFV) β€” picklescan/modelscan bypass PoC
Proof-of-concept model files for a huntr Model File Vulnerability (MFV) report against
the **PyTorch Package (.pt)** format (`torch.package`).
## Files
- `malicious_interned.pt` β€” the actual vulnerability PoC. Runs `os.system("touch /tmp/torch_package_interned_pwned")`
on load via `torch.package.PackageImporter(...).load_pickle(...)`. Both `picklescan` (1.0.4) and
`modelscan` (0.8.8, made by Protect AI, huntr's parent org) report this file as **clean**
("Infected files: 0" / "No issues found"). `modelscan --show-skipped` explicitly lists the payload
file (`archive/evilmodule.py`) as skipped: *"Model Scan did not scan file"*.
- `naive_detected_by_scanners.pt` β€” control/comparison file. Same RCE effect, but the pickle directly
references `subprocess.Popen`. Both scanners correctly flag this one as dangerous. Included to isolate
exactly which part of the technique causes the bypass (embedding the payload in the package's own
*interned* Python source module instead of referencing a known-dangerous stdlib global from the pickle
opcodes).
## Why the scanners miss it
`torch.package` archives are zip files that can bundle "interned" `.py` source modules alongside the
pickle data. When such a module is imported (which routinely happens as part of unpickling a package
object), `torch/package/package_importer.py`'s `PackageImporter._make_module()` runs
`exec(code, ns)` on that source directly. The pickle opcode stream itself never references anything
scanners treat as dangerous (`os.system`, `subprocess.Popen`, `eval`, etc.) β€” it just references
a custom, package-local class. Opcode-level scanners (picklescan, modelscan) have no model of this
second execution path, so they see nothing to flag.
## Reproduce
```bash
pip install torch picklescan modelscan
python3 -c "
import torch.package
picklescan_result = __import__('subprocess').run(['picklescan', '-p', 'malicious_interned.pt'])
"
picklescan -p malicious_interned.pt # Infected files: 0
modelscan -p malicious_interned.pt # No issues found! πŸŽ‰
python3 -c "
import torch.package
importer = torch.package.PackageImporter('malicious_interned.pt')
importer.load_pickle('archive', 'data.pkl')
"
ls -la /tmp/torch_package_interned_pwned # created by the RCE
```
Full report: huntr.com MFV submission (PyTorch Package format).