| # PoC - modelaudit ExecuTorch .pte flatbuffers binary route runs no pickle-opcode analysis; STACK_GLOBAL pickle evades both scanners (BL-0121) |
| |
| Coordinated disclosure PoC for huntr (Protect AI MFV). Benign markers only; pickles are NEVER deserialized (only pickle.dumps at build + static scan). |
| |
| - Scanners: modelaudit==0.2.49 (executorch_scanner + pytorch_binary_scanner) AND modelscan==0.8.8. Format: ExecuTorch `.pte` (flatbuffers binary, identifier `ET`+digits). |
| - `modelaudit scan pte_evade_stackglobal.pte` -> Scanner 'executorch', 8/8 checks pass incl 'Valid ExecuTorch binary program' and 'Embedded Code Pattern Detection: No suspicious code patterns detected', 0 issues, success TRUE, exit 0. `modelscan -p pte_evade_stackglobal.pte` -> total_scanned=0, exit 3 (no flatbuffers route). **Both Clean.** |
| - Positive controls (byte-identical protocol-4 STACK_GLOBAL `posix.system` pickle): `payload_stackglobal.pkl` -> modelaudit CRITICAL S201 ('REDUCE opcode invoking dangerous global: posix.system') + modelscan CRITICAL. `pt_zip_evade_datapkl.pt` (same pickle as torch-zip `data.pkl`) -> both CRITICAL. So the payload is genuinely dangerous and detectable; the `.pte` binary route is the sole evasion vector. |
| - Contrast `pte_naive_global.pte`: the protocol-2 GLOBAL-opcode form of the SAME call in a .pte DOES trip modelaudit's substring denylist (WARNING S902 `posix\nsystem`) -- proving the binary route intends to detect embedded pickles, but only via a literal substring list. STACK_GLOBAL emits `\x8c\x05posix\x8c\x06system\x93` (module/name split, no contiguous denylisted substring) -> evades. `benign.pte` -> both Clean (true-negative baseline). |
| - Root cause: modelaudit executorch_scanner.py:1334-1338 (valid non-zip ExecuTorch binary calls ONLY _merge_raw_binary_analysis -> PyTorchBinaryScanner; archive pickle-opcode discovery never reached); pytorch_binary_scanner.py:34-56 + detectors/suspicious_symbols.py:506-545 (literal substring denylist, no STACK_GLOBAL byte / no REDUCE / no bare `system`). modelscan format_via_extension.py:7-17 + settings.py:77-84 (extension-only format resolution, no .pte entry -> total_scanned=0). Fix: run opcode-aware pickle analysis over the ExecuTorch binary body (not just the substring list); modelscan should content-route or fail loud on unrecognized model formats. |
| - Benign: payload is `posix.system('echo CELVEX_MFV_LABONLY...')`. Scanner protection-mechanism-failure / detection-evasion (a pure .pte is not auto-executed by the ExecuTorch runtime), corroborated by modelscan scanning nothing. |
| |
| Files: pte_evade_stackglobal.pte (bypass, Clean on both), payload_stackglobal.pkl + pt_zip_evade_datapkl.pt (positive controls, fire CRITICAL on both), pte_naive_global.pte (contrast, WARNING - detector live), benign.pte (true-negative). Full report in huntr submission. |