6
6
import os
7
7
import pathlib
8
8
import pickle
9
+ import pip
9
10
import py7zr
11
+ import pydoc
10
12
import pytest
11
13
import requests
12
14
import runpy
13
15
import socket
14
16
import subprocess
15
17
import sys
16
- from unittest import TestCase
18
+ import venv
17
19
import zipfile
18
- import pip
20
+ from functools import partial
21
+ from unittest import TestCase
19
22
20
23
from picklescan .cli import main
21
24
from picklescan .scanner import (
33
36
scan_numpy ,
34
37
scan_pytorch ,
35
38
)
36
- import torch
37
- import torch ._inductor .codecache as codecache
38
- import pydoc
39
- import venv
40
- from functools import partial
39
+
40
+ try :
41
+ import torch
42
+ import torch ._inductor .codecache as codecache
43
+ except ImportError :
44
+ # If PyTorch test files need to be regenerated, run 'pip install torch==2.6.0' first
45
+ torch = None
46
+ codecache = None
41
47
42
48
_root_path = os .path .dirname (__file__ )
43
49
@@ -105,20 +111,16 @@ def __reduce__(self):
105
111
'import os\n os.system("whoami")' ,
106
112
)
107
113
114
+
108
115
class Malicious17 :
109
116
def __reduce__ (self ):
110
- return codecache .compile_file , (
111
- '' , '' , [
112
- 'sh' ,
113
- '-c' ,'$(echo "pwned")'
114
- ]
115
- )
117
+ return codecache .compile_file , ("" , "" , ["sh" , "-c" , '$(echo "pwned")' ])
118
+
116
119
117
120
class Malicious18 :
118
121
def __reduce__ (self ):
119
- return pydoc .pipepager , (
120
- '' , 'echo "pwned"'
121
- )
122
+ return pydoc .pipepager , ("" , 'echo "pwned"' )
123
+
122
124
123
125
class Malicious19 :
124
126
def __init__ (self , path , ** kwargs ):
@@ -128,11 +130,10 @@ def __init__(self, path, **kwargs):
128
130
def __reduce__ (self ):
129
131
return partial (torch .load , self .path , ** self .kwargs ), ()
130
132
133
+
131
134
class Malicious20 :
132
135
def __reduce__ (self ):
133
- return venv .create , (
134
- 'venv' , False , False , True , False , "$(echo pwned)"
135
- )
136
+ return venv .create , ("venv" , False , False , True , False , "$(echo pwned)" )
136
137
137
138
138
139
class Malicious16 :
@@ -469,8 +470,13 @@ def initialize_pickle_files():
469
470
initialize_pickle_file (f"{ _root_path } /data/malicious18.pkl" , Malicious18 (), 4 )
470
471
471
472
# This exploit serializes kwargs and passes them into a torch.load call
472
- initialize_pickle_file (f"{ _root_path } /data/malicious19.pkl" ,
473
- Malicious19 ("some_other_model.bin" , pickle_file = 'config.json' , weights_only = False ), 4 )
473
+ initialize_pickle_file (
474
+ f"{ _root_path } /data/malicious19.pkl" ,
475
+ Malicious19 (
476
+ "some_other_model.bin" , pickle_file = "config.json" , weights_only = False
477
+ ),
478
+ 4 ,
479
+ )
474
480
475
481
initialize_pickle_file (f"{ _root_path } /data/malicious20.pkl" , Malicious20 (), 4 )
476
482
initialize_7z_file (
@@ -486,7 +492,7 @@ def initialize_pickle_files():
486
492
487
493
initialize_zip_file (
488
494
f"{ _root_path } /data/malicious1_wrong_ext.zip" ,
489
- "data.txt" , # Pickle file with a non-standard extension
495
+ "data.txt" , # Pickle file with a non-standard extension
490
496
pickle .dumps (Malicious1 (), protocol = 4 ),
491
497
)
492
498
@@ -640,9 +646,7 @@ def test_scan_file_path():
640
646
compare_scan_results (
641
647
scan_file_path (f"{ _root_path } /data/malicious1.zip" ), malicious1
642
648
)
643
- compare_scan_results (
644
- scan_file_path (f"{ _root_path } /data/malicious1.7z" ), malicious1
645
- )
649
+ compare_scan_results (scan_file_path (f"{ _root_path } /data/malicious1.7z" ), malicious1 )
646
650
compare_scan_results (
647
651
scan_file_path (f"{ _root_path } /data/malicious1_wrong_ext.zip" ), malicious1
648
652
)
@@ -830,10 +834,11 @@ def test_scan_directory_path():
830
834
Global ("torch.serialization" , "load" , SafetyLevel .Dangerous ),
831
835
Global ("functools" , "partial" , SafetyLevel .Dangerous ),
832
836
Global ("pip" , "main" , SafetyLevel .Dangerous ),
837
+ Global ("builtins" , "eval" , SafetyLevel .Dangerous ),
833
838
],
834
- scanned_files = 37 ,
835
- issues_count = 38 ,
836
- infected_files = 31 ,
839
+ scanned_files = 38 ,
840
+ issues_count = 39 ,
841
+ infected_files = 33 ,
837
842
scan_err = True ,
838
843
)
839
844
compare_scan_results (scan_directory_path (f"{ _root_path } /data/" ), sr )
0 commit comments