| license: apache-2.0 | |
| tags: [security-research, huntr, model-file-security, scanner-bypass, numpy] | |
| # picklescan & ModelScan bypass: .npz ZIP-container with an object-dtype member carrying an INT-opcode desync | |
| Benign PoC for the huntr Model File Format program. Payload writes only a nonce marker — no real harm. | |
| ## Vulnerability | |
| A NumPy .npz is a ZIP of .npy members. Both scanners RECURSE into the .npz and scan each member (positive control: a plain malicious object-.npy inside the .npz is CAUGHT by BOTH). This PoC's object-dtype member carries the INT-opcode desync prefix "I0x10\n": genops parses base-10 and aborts before the payload, while np.load(..., allow_pickle=True)[member] parses "0x10" base-0 and executes the embedded __reduce__ payload. Distinct ZIP-recursion code path + real npz member-access loader ($1500 non-pickle tier). | |
| ## Measured (2026-07-24): picklescan 1.0.5 exit 0; ModelScan 0.8.8 no issue; np.load(...,allow_pickle=True) fires the benign marker. | |
| ## Reproduce | |
| ```python | |
| import numpy as np | |
| z = np.load("model.npz", allow_pickle=True); z[z.files[0]] # fires the benign marker | |
| ``` | |
| ```bash | |
| picklescan -p model.npz # exit 0 | |
| modelscan -p model.npz # no issue | |
| ``` | |