@@ -20,20 +20,35 @@ class MsfVenom
20
20
class MsfVenomError < StandardError ; end
21
21
class UsageError < MsfVenomError ; end
22
22
class NoTemplateError < MsfVenomError ; end
23
+ class IncompatibleError < MsfVenomError ; end
23
24
24
25
Status = "[*] "
25
26
Error = "[-] "
26
27
27
28
require 'optparse'
28
29
30
+ def initialize ( in_stream = $stdin, out_stream = $stdout, err_stream = $stderr, framework = nil )
31
+ @in = in_stream
32
+ @out = out_stream
33
+ @err = err_stream
34
+ @framework = framework
35
+ end
36
+
29
37
def init_framework ( create_opts = { } )
30
- return @framework if @framework
31
38
create_opts [ :module_types ] ||= [
32
39
::Msf ::MODULE_PAYLOAD , ::Msf ::MODULE_ENCODER , ::Msf ::MODULE_NOP
33
40
]
34
41
@framework = ::Msf ::Simple ::Framework . create ( create_opts . merge ( 'DisableDatabase' => true ) )
35
42
end
36
43
44
+ def framework
45
+ return @framework if @framework
46
+
47
+ init_framework
48
+
49
+ @framework
50
+ end
51
+
37
52
def parse_args ( args )
38
53
@opts = { }
39
54
@datastore = { }
@@ -42,7 +57,7 @@ class MsfVenom
42
57
opt . separator ( '' )
43
58
opt . separator ( 'Options:' )
44
59
45
- opt . on ( '-p' , '--payload [ payload] ' , String , 'Payload to use. Specify a \'-\' or stdin to use custom payloads' ) do |p |
60
+ opt . on ( '-p' , '--payload < payload> ' , String , 'Payload to use. Specify a \'-\' or stdin to use custom payloads' ) do |p |
46
61
if p == '-'
47
62
@opts [ :payload ] = 'stdin'
48
63
else
@@ -57,11 +72,11 @@ class MsfVenom
57
72
@opts [ :list ] = l
58
73
end
59
74
60
- opt . on ( '-n' , '--nopsled [ length] ' , Integer , 'Prepend a nopsled of [length] size on to the payload' ) do |n |
75
+ opt . on ( '-n' , '--nopsled < length> ' , Integer , 'Prepend a nopsled of [length] size on to the payload' ) do |n |
61
76
@opts [ :nopsled ] = n . to_i
62
77
end
63
78
64
- opt . on ( '-f' , '--format [ format] ' , String , "Output format (use --help-formats for a list)" ) do |f |
79
+ opt . on ( '-f' , '--format < format> ' , String , "Output format (use --help-formats for a list)" ) do |f |
65
80
@opts [ :format ] = f
66
81
end
67
82
@@ -70,31 +85,31 @@ class MsfVenom
70
85
@opts [ :encoder ] = e
71
86
end
72
87
73
- opt . on ( '-a' , '--arch [ architecture] ' , String , 'The architecture to use' ) do |a |
88
+ opt . on ( '-a' , '--arch < architecture> ' , String , 'The architecture to use' ) do |a |
74
89
@opts [ :arch ] = a
75
90
end
76
91
77
- opt . on ( '--platform [ platform] ' , String , 'The platform of the payload' ) do |l |
92
+ opt . on ( '--platform < platform> ' , String , 'The platform of the payload' ) do |l |
78
93
@opts [ :platform ] = l
79
94
end
80
95
81
- opt . on ( '-s' , '--space [ length] ' , Integer , 'The maximum size of the resulting payload' ) do |s |
96
+ opt . on ( '-s' , '--space < length> ' , Integer , 'The maximum size of the resulting payload' ) do |s |
82
97
@opts [ :space ] = s
83
98
end
84
99
85
- opt . on ( '-b' , '--bad-chars [ list] ' , String , 'The list of characters to avoid example: \'\x00\xff\'' ) do |b |
100
+ opt . on ( '-b' , '--bad-chars < list> ' , String , 'The list of characters to avoid example: \'\x00\xff\'' ) do |b |
86
101
@opts [ :badchars ] = b
87
102
end
88
103
89
- opt . on ( '-i' , '--iterations [ count] ' , Integer , 'The number of times to encode the payload' ) do |i |
104
+ opt . on ( '-i' , '--iterations < count> ' , Integer , 'The number of times to encode the payload' ) do |i |
90
105
@opts [ :iterations ] = i
91
106
end
92
107
93
- opt . on ( '-c' , '--add-code [ path] ' , String , 'Specify an additional win32 shellcode file to include' ) do |x |
108
+ opt . on ( '-c' , '--add-code < path> ' , String , 'Specify an additional win32 shellcode file to include' ) do |x |
94
109
@opts [ :addshellcode ] = x
95
110
end
96
111
97
- opt . on ( '-x' , '--template [ path] ' , String , 'Specify a custom executable file to use as a template' ) do |x |
112
+ opt . on ( '-x' , '--template < path> ' , String , 'Specify a custom executable file to use as a template' ) do |x |
98
113
@opts [ :template ] = x
99
114
end
100
115
@@ -120,12 +135,11 @@ class MsfVenom
120
135
end
121
136
122
137
begin
123
- opt . parse!
138
+ opt . parse! ( args )
124
139
rescue OptionParser ::InvalidOption => e
125
- p e
126
140
raise UsageError , "Invalid option\n #{ opt } "
127
141
rescue OptionParser ::MissingArgument => e
128
- p e
142
+ raise UsageError , "Missing required argument for option \n #{ opt } "
129
143
end
130
144
131
145
if @opts . empty?
@@ -145,20 +159,20 @@ class MsfVenom
145
159
end
146
160
147
161
def print_status ( msg )
148
- $stderr . puts ( Status + msg )
162
+ @err . puts ( Status + msg )
149
163
end
150
164
151
165
def print_error ( msg )
152
- $stderr . puts ( Error + msg )
166
+ @err . puts ( Error + msg )
153
167
end
154
168
155
169
def get_encoders ( arch , encoder )
156
170
encoders = [ ]
157
171
158
172
if ( encoder )
159
- encoders << @ framework. encoders . create ( encoder )
173
+ encoders << framework . encoders . create ( encoder )
160
174
else
161
- @ framework. encoders . each_module_ranked (
175
+ framework . encoders . each_module_ranked (
162
176
'Arch' => arch ? arch . split ( ',' ) : nil ) { |name , mod |
163
177
encoders << mod . new
164
178
}
@@ -168,8 +182,8 @@ class MsfVenom
168
182
end
169
183
170
184
def payload_stdin
171
- $stdin . binmode
172
- payload = $stdin . read
185
+ @in . binmode
186
+ payload = @in . read
173
187
payload
174
188
end
175
189
@@ -178,14 +192,14 @@ class MsfVenom
178
192
nop_jpts [ 'SaveRegisters' ] ||= [ 'esp' , 'ebp' , 'esi' , 'edi' ]
179
193
180
194
if nop_mod
181
- nop = @ framework. nops . create ( nop_mod )
195
+ nop = framework . nops . create ( nop_mod )
182
196
raw = nop . generate_sled ( len , nop_opts )
183
197
return raw if raw
184
198
end
185
199
186
- @ framework. nops . each_module_ranked ( 'Arch' => arch ) do |name , mod |
200
+ framework . nops . each_module_ranked ( 'Arch' => arch ) do |name , mod |
187
201
begin
188
- nop = @ framework. nops . create ( name )
202
+ nop = framework . nops . create ( name )
189
203
raw = nop . generate_sled ( len , nop_opts )
190
204
return raw if raw
191
205
rescue
@@ -198,14 +212,14 @@ class MsfVenom
198
212
init_framework ( :module_types => [ ::Msf ::MODULE_PAYLOAD ] )
199
213
tbl = Rex ::Ui ::Text ::Table . new (
200
214
'Indent' => 4 ,
201
- 'Header' => "Framework Payloads (#{ @ framework. stats . num_payloads } total)" ,
215
+ 'Header' => "Framework Payloads (#{ framework . stats . num_payloads } total)" ,
202
216
'Columns' =>
203
217
[
204
218
"Name" ,
205
219
"Description"
206
220
] )
207
221
208
- @ framework. payloads . each_module { |name , mod |
222
+ framework . payloads . each_module { |name , mod |
209
223
tbl << [ name , mod . new . description ]
210
224
}
211
225
@@ -225,7 +239,7 @@ class MsfVenom
225
239
] )
226
240
cnt = 0
227
241
228
- @ framework. encoders . each_module (
242
+ framework . encoders . each_module (
229
243
'Arch' => arch ? arch . split ( ',' ) : nil ) { |name , mod |
230
244
tbl << [ name , mod . rank_to_s , mod . new . name ]
231
245
@@ -239,14 +253,14 @@ class MsfVenom
239
253
init_framework ( :module_types => [ ::Msf ::MODULE_NOP ] )
240
254
tbl = Rex ::Ui ::Text ::Table . new (
241
255
'Indent' => 4 ,
242
- 'Header' => "Framework NOPs (#{ @ framework. stats . num_nops } total)" ,
256
+ 'Header' => "Framework NOPs (#{ framework . stats . num_nops } total)" ,
243
257
'Columns' =>
244
258
[
245
259
"Name" ,
246
260
"Description"
247
261
] )
248
262
249
- @ framework. nops . each_module { |name , mod |
263
+ framework . nops . each_module { |name , mod |
250
264
tbl << [ name , mod . new . description ]
251
265
}
252
266
@@ -270,15 +284,14 @@ class MsfVenom
270
284
@opts [ :platform ] = ::Msf ::Module ::PlatformList . transform ( "Windows" )
271
285
end
272
286
else
273
- payload = @ framework. payloads . create ( @opts [ :payload ] )
287
+ payload = framework . payloads . create ( @opts [ :payload ] )
274
288
if payload . nil?
275
- print_error ( "Invalid payload: #{ @opts [ :payload ] } " )
276
- exit
289
+ raise UsageError , "Invalid payload: #{ @opts [ :payload ] } "
277
290
end
278
291
if @opts [ :list_options ]
279
292
print_status ( "Options for #{ payload . fullname } \n \n " +
280
293
::Msf ::Serializer ::ReadableText . dump_module ( payload , ' ' ) )
281
- exit
294
+ return
282
295
end
283
296
@opts [ :arch ] ||= payload . arch [ 0 ]
284
297
# If it's not stdin, we'll already have a PlatformList
@@ -299,23 +312,23 @@ class MsfVenom
299
312
@opts [ :list ] . each do |mod |
300
313
case mod . downcase
301
314
when "payloads"
302
- $stderr . puts dump_payloads
315
+ @err . puts dump_payloads
303
316
when "encoders"
304
- $stderr . puts dump_encoders ( @opts [ :arch ] )
317
+ @err . puts dump_encoders ( @opts [ :arch ] )
305
318
when "nops"
306
- $stderr . puts dump_nops
319
+ @err . puts dump_nops
307
320
when "all"
308
321
# Init here so #dump_payloads doesn't create a framework with
309
322
# only payloads, etc.
310
323
init_framework
311
- $stderr . puts dump_payloads
312
- $stderr . puts dump_encoders
313
- $stderr . puts dump_nops
324
+ @err . puts dump_payloads
325
+ @err . puts dump_encoders
326
+ @err . puts dump_nops
314
327
else
315
328
print_error ( "Invalid module type" )
316
329
end
317
330
end
318
- exit
331
+ return
319
332
end
320
333
321
334
# Normalize the options
@@ -326,7 +339,6 @@ class MsfVenom
326
339
@opts [ :encode ] ||= !( @opts [ :badchars ] . nil? or @opts [ :badchars ] . empty? )
327
340
328
341
329
- init_framework
330
342
payload_raw = generate_raw_payload
331
343
332
344
if @opts [ :template ]
@@ -391,69 +403,66 @@ class MsfVenom
391
403
rescue => e
392
404
print_error ( "#{ enc . refname } failed: #{ e . class } #{ e } " )
393
405
e . backtrace . each { |el |
394
- $stderr . puts ( el . to_s )
406
+ @err . puts ( el . to_s )
395
407
}
396
408
end
397
409
end
398
410
end
399
411
400
412
if @opts [ :nopsled ]
401
- #puts @opts[:arch].class
402
413
nopts = { 'BadChars' => @opts [ :badchars ] }
403
414
nops = generate_nops ( [ @opts [ :arch ] ] , @opts [ :nopsled ] , nil , nopts )
404
415
payload_raw = nops + payload_raw
405
416
end
406
417
407
- $stdout . binmode
418
+ @out . binmode
408
419
409
420
case @opts [ :format ] . downcase
410
421
# Special-case this to check endianness
411
422
when "js_be"
412
423
413
424
if Rex ::Arch . endian ( payload . arch ) != ENDIAN_BIG
414
- print_error ( "Big endian format selected for a non big endian payload" )
415
- exit
425
+ raise IncompatibleError , "Big endian format selected for a non big endian payload"
416
426
end
417
- $stdout . write ::Msf ::Simple ::Buffer . transform ( payload_raw , @opts [ :format ] )
427
+ @out . write ::Msf ::Simple ::Buffer . transform ( payload_raw , @opts [ :format ] )
418
428
419
429
# Special-case this so we can build a war directly from the payload if
420
430
# possible
421
431
when "war"
422
- exe = ::Msf ::Util ::EXE . to_executable_fmt ( @ framework, @opts [ :arch ] , @opts [ :platform ] , payload_raw , @opts [ :format ] , exeopts )
432
+ exe = ::Msf ::Util ::EXE . to_executable_fmt ( framework , @opts [ :arch ] , @opts [ :platform ] , payload_raw , @opts [ :format ] , exeopts )
423
433
if ( !exe and payload . platform . platforms . index ( ::Msf ::Module ::Platform ::Java ) )
424
434
exe = payload . generate_war . pack
425
435
else
426
436
exe = ::Msf ::Util ::EXE . to_jsp_war ( exe )
427
437
end
428
- $stdout . write exe
438
+ @out . write exe
429
439
430
440
# Same as war, special-case this so we can build a jar directly from the
431
441
# payload if possible
432
442
when "java"
433
- exe = ::Msf ::Util ::EXE . to_executable_fmt ( @ framework, @opts [ :arch ] , @opts [ :platform ] , payload_raw , @opts [ :format ] , exeopts )
443
+ exe = ::Msf ::Util ::EXE . to_executable_fmt ( framework , @opts [ :arch ] , @opts [ :platform ] , payload_raw , @opts [ :format ] , exeopts )
434
444
if ( !exe and payload . platform . platforms . index ( ::Msf ::Module ::Platform ::Java ) )
435
445
exe = payload . generate_jar . pack
436
446
end
437
447
if exe
438
- $stdout . write exe
448
+ @out . write exe
439
449
else
440
450
print_error ( "Could not generate payload format" )
441
451
end
442
452
443
453
when *::Msf ::Simple ::Buffer . transform_formats
444
- $stdout . write ::Msf ::Simple ::Buffer . transform ( payload_raw , @opts [ :format ] )
454
+ @out . write ::Msf ::Simple ::Buffer . transform ( payload_raw , @opts [ :format ] )
445
455
446
456
when *::Msf ::Util ::EXE . to_executable_fmt_formats
447
- exe = ::Msf ::Util ::EXE . to_executable_fmt ( @ framework, @opts [ :arch ] , @opts [ :platform ] , payload_raw , @opts [ :format ] , exeopts )
457
+ exe = ::Msf ::Util ::EXE . to_executable_fmt ( framework , @opts [ :arch ] , @opts [ :platform ] , payload_raw , @opts [ :format ] , exeopts )
448
458
if exe . nil?
449
- print_error ( "This format does not support that platform/architecture" )
450
- exit
459
+ raise IncompatibleError , "This format does not support that platform/architecture"
451
460
end
452
- $stdout . write exe
461
+ @out . write exe
453
462
454
463
else
455
- print_error ( "Unsupported format" )
456
- exit
464
+ raise IncompatibleError , "Unsupported format"
465
+ return
457
466
end
458
467
end
459
468
end
0 commit comments