Fickling, Security Bypass, CVE-2024-3159 (Critical)

Listen to this Post

Two independent bugs in Fickling’s AST-based static analysis combine to allow a malicious pickle file to execute arbitrary stdlib function calls – including reading sensitive files – while `check_safety()` returns `Severity.LIKELY_SAFE` and `fickling.load()` completes without raising `UnsafeFileError` . The first bug exists in Interpreter.unused_assignments(), where the loop breaks immediately upon reaching result = _varN, preventing the right-hand side from being scanned for variable references. Any variable whose only reference is inside the result expression is never added to the used set. The second bug is in `TupleThree.run()` and siblings, where `ast.Tuple` is created with `elts` as a Python tuple instead of a list, causing `ast.walk()` to never descend into its elements . The BUILD opcode generates a non-assignment statement (_var4.__setstate__(_var2)) that makes `_var2` appear in the used set. Combined with `linecache` and `difflib` missing from UNSAFE_IMPORTS, an attacker can read arbitrary files: `getlines(‘/etc/passwd’)` reads the file, the result is transformed through `enumerate` and dict, then passed to Differ().__setstate__(), and finally returned as result = _var3. Since `check_safety()` returns LIKELY_SAFE, `fickling.load()` proceeds to deserialize the payload and returns file contents to the caller .
Platform: Fickling
Version: Prior to fix
Vulnerability: Security Bypass
Severity: Critical
date: 2024-04-30

Prediction: Patched 2024-04-30

What Undercode Say:

Install vulnerable version
pip install fickling
PoC execution
python3 poc.py
Check safety verdict bypass
python3 -c "import fickling; print(fickling.check_safety('payload.pkl').severity)"
Core bypass mechanism
from linecache import getlines
_var0 = getlines('/etc/passwd')
_var1 = enumerate(_var0)
_var2 = dict(_var1)
from difflib import Differ
_var3 = Differ()
_var4 = _var3
_var4.<strong>setstate</strong>(_var2)
result = _var3 RHS never scanned

How Exploit:

BUILD opcode creates `__setstate__` call making malicious variable appear “used”, bypassing UnusedVariables detection. Tuple typing bug hides references from AST walk .

Protection from this CVE

Update to commit `7f39d97` which adds unsafe modules to blocklist . Patch prevents `linecache` and `difflib` from being used in bypass.

Impact

Arbitrary file read via `fickling.load()` security gate bypass. File contents returned directly in deserialized object attributes. Same technique applicable to any stdlib module absent from `UNSAFE_IMPORTS` including gc.get_objects(), inspect.stack(), `netrc.netrc()` .

🎯Let’s Practice Exploiting & Learn Patching For Free:

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top