@@ -31,7 +31,7 @@ def commands
31
31
{
32
32
'python_reset' => 'Resets/restarts the Python interpreter' ,
33
33
'python_execute' => 'Execute a python command string' ,
34
- 'python_import' => 'Import/run a python run '
34
+ 'python_import' => 'Import/run a python file or module '
35
35
}
36
36
end
37
37
@@ -42,15 +42,18 @@ def cmd_python_reset(*args)
42
42
43
43
@@python_import_opts = Rex ::Parser ::Arguments . new (
44
44
'-h' => [ false , 'Help banner' ] ,
45
- '-f' => [ true , 'Path to the file (.py, .pyc) to import' ] ,
46
- '-m ' => [ true , 'Name of the module (optional)' ] ,
47
- '-r' => [ true , 'Name of the variable containing the result (optional)' ]
45
+ '-f' => [ true , 'Path to the file (.py, .pyc), or module directory to import' ] ,
46
+ '-n ' => [ true , 'Name of the module (optional, for single files only )' ] ,
47
+ '-r' => [ true , 'Name of the variable containing the result (optional, single files only )' ]
48
48
)
49
49
50
50
def python_import_usage
51
- print_line ( 'Usage: python_imoprt <-f file path> [-m mod name] [-r result var name]' )
51
+ print_line ( 'Usage: python_imoprt <-f file path> [-n mod name] [-r result var name]' )
52
52
print_line
53
- print_line ( 'Loads a python code file from disk into memory on the target.' )
53
+ print_line ( 'Loads a python code file or module from disk into memory on the target.' )
54
+ print_line ( 'The module loader requires a path to a folder that contains the module,' )
55
+ print_line ( 'and the folder name will be used as the module name. Only .py files will' )
56
+ print_line ( 'work with modules.' )
54
57
print_line ( @@python_import_opts . usage )
55
58
end
56
59
@@ -64,28 +67,59 @@ def cmd_python_import(*args)
64
67
end
65
68
66
69
result_var = nil
67
- file = nil
70
+ source = nil
68
71
mod_name = nil
69
72
70
73
@@python_import_opts . parse ( args ) { |opt , idx , val |
71
74
case opt
72
75
when '-f'
73
- file = val
74
- when '-m '
76
+ source = val
77
+ when '-n '
75
78
mod_name = val
76
79
when '-r'
77
80
result_var = val
78
81
end
79
82
}
80
83
81
- unless file
82
- print_error ( "File path must be specified" )
84
+ unless source
85
+ print_error ( "The -f parameter must be specified" )
83
86
return false
84
87
end
85
88
86
- result = client . python . import ( file , mod_name , result_var )
89
+ if ::File . directory? ( source )
90
+ files = ::Find . find ( source ) . select { |p | /.*\. py$/ =~ p }
91
+ if files . length == 0
92
+ fail_with ( "No .py files found in #{ source } " )
93
+ end
94
+
95
+ base_name = ::File . basename ( source )
96
+ unless source . end_with? ( '/' )
97
+ source << '/'
98
+ end
99
+
100
+ print_status ( "Importing #{ source } with base module name #{ base_name } ..." )
101
+
102
+ files . each do |file |
103
+ rel_path = file [ source . length , file . length - source . length ]
104
+ parts = rel_path . split ( '/' )
105
+
106
+ mod_parts = [ base_name ] + parts [ 0 , parts . length - 1 ]
107
+
108
+ if parts [ -1 ] != '__init__.py'
109
+ mod_parts << ::File . basename ( parts [ -1 ] , '.*' )
110
+ end
111
+
112
+ mod_name = mod_parts . join ( '.' )
113
+ print_status ( "Importing #{ file } as #{ mod_name } ..." )
114
+ result = client . python . import ( file , mod_name , nil )
115
+ handle_exec_result ( result , nil )
116
+ end
117
+ else
118
+ print_status ( "Importing #{ source } ..." )
119
+ result = client . python . import ( source , mod_name , result_var )
120
+ handle_exec_result ( result , result_var )
121
+ end
87
122
88
- handle_exec_result ( result , result_var )
89
123
end
90
124
91
125
@@python_execute_opts = Rex ::Parser ::Arguments . new (
0 commit comments