CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/msf/core/auxiliary/fuzzer.rb
Views: 11784
1
# -*- coding: binary -*-
2
module Msf
3
4
###
5
#
6
# This module provides methods useful for developing fuzzers
7
#
8
###
9
module Auxiliary::Fuzzer
10
11
12
def initialize(info = {})
13
super
14
register_advanced_options([
15
OptString.new('FuzzTracer', [ true, 'Sets the magic string to embed into fuzzer string inputs', 'MSFROCKS']),
16
OptString.new('FuzzChar', [ true, 'Sets the character to use for generating long strings', 'X'])
17
], Msf::Auxiliary::Fuzzer)
18
end
19
20
21
# Will return or yield numbers based on the presence of a block.
22
#
23
# @return [Array<Array>] Returns an array of arrays of numbers if there is no block given
24
# @yield [Array<Integer>] Yields an array of numbers if there is a block given
25
# @see #fuzzer_number_power2
26
27
def fuzz_numbers
28
res = []
29
self.methods.sort.grep(/^fuzzer_number/).each do |m|
30
@last_fuzzer_input = m
31
block_given? ? self.send(m) {|x| yield(x) } : (res << self.send(m))
32
end
33
res
34
end
35
36
37
# Will return or yield a string based on the presence of a block
38
#
39
# @return [Array] Returns and array of arrays of strings if there is no block given
40
# @yield [Array] Yields array of strings if there is a block given
41
42
def fuzz_strings
43
res = []
44
self.methods.sort.grep(/^fuzzer_string/).each do |m|
45
@last_fuzzer_input = m
46
block_given? ? self.send(m) {|x| yield(x) } : (res << self.send(m))
47
end
48
res
49
end
50
51
# Modifies each byte of the string from beginning to end, packing each element as an 8 bit character.
52
#
53
# @param str [String] The string the mutation will be based on.
54
# @param max [Integer, NilClass] Max string size.
55
# @return [Array] Returns an array of an array of strings
56
# @see #fuzzer_string_format
57
58
def fuzz_string_corrupt_byte(str,max=nil)
59
res = []
60
0.upto(max ? [max,str.length-1].min : (str.length - 1)) do |offset|
61
0.upto(255) do |val|
62
@last_fuzzer_input = "fuzz_string_corrupt_byte offset:#{offset}/#{str.length} byte:#{val}"
63
buf = str.dup
64
buf[offset,1] = [val].pack('C')
65
block_given? ? yield(buf) : (res << buf)
66
end
67
end
68
res
69
end
70
71
# Modifies each byte of the string from beginning to end, packing each element as an 8 bit character.
72
#
73
# @param str [String] The string the mutation will be based on.
74
# @param max [Integer, NilClass] Max string size.
75
# @return [Array] Returns an array of an array of strings
76
# @see fuzzer_string_format
77
78
def fuzz_string_corrupt_byte_reverse(str,max=nil)
79
res = []
80
(max ? [max,str.length-1].min : (str.length - 1)).downto(0) do |offset|
81
0.upto(255) do |val|
82
@last_fuzzer_input = "fuzz_string_corrupt_byte_reverse offset:#{offset}/#{str.length} byte:#{val}"
83
buf = str.dup
84
buf[offset,1] = [val].pack('C')
85
block_given? ? yield(buf) : (res << buf)
86
end
87
end
88
res
89
end
90
91
# Useful generators (many derived from AxMan)
92
#
93
# @return [Array] Returns and array of strings.
94
95
def fuzzer_string_format
96
res = %W{ %s %p %n %x %@ %.257d %.65537d %.2147483648d %.257f %.65537f %.2147483648f}
97
block_given? ? res.each { |n| yield(n) } : res
98
end
99
100
# Reserved filename array
101
# Useful generators (many derived from AxMan)
102
#
103
# @return [Array] Returns and array of reserved filenames in Windows.
104
105
def fuzzer_string_filepath_dos
106
res = %W{ aux con nul com1 com2 com3 com4 lpt1 lpt2 lp3 lpt4 prn }
107
block_given? ? res.each { |n| yield(n) } : res
108
end
109
110
# Fuzzer Numbers by Powers of Two
111
#
112
# @return [Array] Returns an array with pre-set values
113
114
def fuzzer_number_power2
115
res = [
116
0x100000000,
117
0x80000000,
118
0x40000000,
119
0x20000000,
120
0x10000000,
121
0x01000000,
122
0x00100000,
123
0x00010000,
124
0x00001000,
125
0x00000100,
126
0x00000010,
127
0x00000001
128
]
129
block_given? ? res.each { |n| yield(n) } : res
130
end
131
132
# Powers of two by some fuzzing factor.
133
#
134
# @return [Array] Returns and array of integers.
135
136
def fuzzer_number_power2_plus
137
res = []
138
fuzzer_number_power2 do |num|
139
res << num + 1
140
res << num + 2
141
res << num - 1
142
res << num - 2
143
res << num * -1
144
res << (num + 1) * -1
145
res << (num + 2) * -1
146
end
147
block_given? ? res.each { |n| yield(n) } : res
148
end
149
150
# Generates a fuzz string If no block is set, it will retrieve characters from the
151
# FuzzChar datastore option.
152
#
153
# @param len [Integer] String size.
154
# @return [String] Returns a string of size 1024 * 512 specified by the user
155
156
def fuzzer_gen_string(len)
157
@gen_string_block ||= datastore['FuzzChar'][0,1] * (1024 * 512)
158
res = ''
159
while (res.length < len)
160
res += @gen_string_block
161
end
162
res[0,len]
163
end
164
165
# Creates a smaller fuzz string starting from length 16 -> 512 bytes long
166
#
167
# @return [Array] Returns an array of characters
168
def fuzzer_string_small
169
res = []
170
16.step(512,16) do |len|
171
buf = fuzzer_gen_string(len)
172
block_given? ? yield(buf) : (res << buf)
173
end
174
res
175
end
176
177
# Creates a longer fuzz string from length 64 -> 8192 bytes long
178
#
179
# @return [Array] Returns an array of characters
180
def fuzzer_string_long
181
res = []
182
64.step(8192,64) do |len|
183
buf = fuzzer_gen_string(len)
184
buf[len / 2, datastore['FuzzTracer'].length] = datastore['FuzzTracer']
185
block_given? ? yield(buf) : (res << buf)
186
end
187
res
188
end
189
190
# Creates a giant fuzz string from length 512 -> 131,064 bytes long
191
#
192
# @return [Array] Returns an array of characters
193
def fuzzer_string_giant
194
res = []
195
512.step(65532 * 2, 512) do |len|
196
buf = fuzzer_gen_string(len)
197
buf[len / 2, datastore['FuzzTracer'].length] = datastore['FuzzTracer']
198
block_given? ? yield(buf) : (res << buf)
199
end
200
res
201
end
202
203
# Various URI types
204
#
205
# @return [Array] Returns an array of strings
206
def fuzzer_string_uri_types
207
res = %W{
208
aaa aaas about acap adiumxtra afp aim apt aw bolo callto cap chrome cid
209
content crid cvs data dav designates dict disk dns doi ed2k example examples
210
fax feed file finger fish ftp gg gizmoproject go gopher h323 hcp http https
211
iax2 icap im imap info ipp irc ircs iris iris.beep iris.lws iris.xpc iris.xpcs
212
itms jar javascript keyparc lastfm ldap ldaps lsid magnet mailto mid mms modem
213
ms-help msnim msrp msrps mtqp mupdate mvn news nfs nntp notes opaquelocktoken
214
over pop pres prospero psyc res rlogin rmi rsync rtsp secondlife service sftp
215
sgn shell shttp sip sips skype smb sms snews snmp soap.beep soap.beeps soldat
216
ssh steam svn tag teamspeak tel telephone telnet tftp thismessage tip tv unreal
217
urn ut2004 vbscript vemmi ventrilo view-source wais webcal worldwind wtai wyciwyg
218
wysiwyg xfire xmlrpc.beep xmpp xri ymsgr z39.50r z39.50s
219
}
220
block_given? ? res.each { |n| yield(n) } : res
221
end
222
223
# Generator for common URI dividers
224
#
225
# @return [Array] Returns an array of strings
226
227
def fuzzer_string_uri_dividers
228
res = %W{ : :// }
229
block_given? ? res.each { |n| yield(n) } : res
230
end
231
232
# Generator for common path prefixes
233
#
234
# @return [Array] Returns an array of strings
235
236
def fuzzer_string_path_prefixes
237
res = %W{ C:\\ \\\\localhost\\ / }
238
block_given? ? res.each { |n| yield(n) } : res
239
end
240
241
# Generates various small URI string types
242
#
243
# @return [Array] Returns an array of strings
244
245
def fuzzer_string_uris_small
246
res = []
247
fuzzer_string_uri_types do |proto|
248
fuzzer_string_uri_dividers do |div|
249
fuzzer_string_small do |str|
250
buf = proto + div + str
251
block_given? ? yield(buf) : (res << buf)
252
end
253
end
254
end
255
res
256
end
257
258
# Generates various long URI string types
259
#
260
# @return [Array] Returns an array of strings
261
262
def fuzzer_string_uris_long
263
res = []
264
fuzzer_string_uri_types do |proto|
265
fuzzer_string_uri_dividers do |div|
266
fuzzer_string_long do |str|
267
buf = proto + div + str
268
block_given? ? yield(buf) : (res << buf)
269
end
270
end
271
end
272
res
273
end
274
275
# Generates various giant URI string types
276
#
277
# @return [Array] Returns an array of strings
278
279
def fuzzer_string_uris_giant
280
res = []
281
fuzzer_string_uri_types do |proto|
282
fuzzer_string_uri_dividers do |div|
283
fuzzer_string_giant do |str|
284
buf = proto + div + str
285
block_given? ? yield(buf) : (res << buf)
286
end
287
end
288
end
289
res
290
end
291
292
# Format for the URI string generator
293
#
294
# @return [Array] Returns an array of strings
295
296
def fuzzer_string_uris_format
297
res = []
298
fuzzer_string_uri_types do |proto|
299
fuzzer_string_uri_dividers do |div|
300
fuzzer_string_format do |str|
301
buf = proto + div + str
302
block_given? ? yield(buf) : (res << buf)
303
end
304
end
305
end
306
res
307
end
308
309
310
# Generates various small strings
311
#
312
# @return [Array] Returns an array of strings
313
314
def fuzzer_string_uris_dos
315
res = []
316
fuzzer_string_uri_types do |proto|
317
fuzzer_string_uri_dividers do |div|
318
fuzzer_string_filepath_dos do |str|
319
buf = proto + div + str
320
block_given? ? yield(buf) : (res << buf)
321
end
322
end
323
end
324
res
325
end
326
327
328
# Generates various small strings
329
#
330
# @return [Array] Returns an array of strings
331
332
def fuzzer_string_paths_small
333
res = []
334
fuzzer_string_path_prefixes do |pre|
335
fuzzer_string_small do |str|
336
buf = pre + str
337
block_given? ? yield(buf) : (res << buf)
338
end
339
end
340
res
341
end
342
343
344
# Generates various small strings
345
#
346
# @return [Array] Returns an array of strings
347
348
def fuzzer_string_paths_long
349
res = []
350
fuzzer_string_path_prefixes do |pre|
351
fuzzer_string_long do |str|
352
buf = pre + str
353
block_given? ? yield(buf) : (res << buf)
354
end
355
end
356
res
357
end
358
359
360
# Generates various giant strings
361
#
362
# @return [Array] Returns an array of strings
363
364
def fuzzer_string_paths_giant
365
res = []
366
fuzzer_string_path_prefixes do |pre|
367
fuzzer_string_giant do |str|
368
buf = pre + str
369
block_given? ? yield(buf) : (res << buf)
370
end
371
end
372
res
373
end
374
375
376
# Format for the path generator
377
#
378
# @return [Array] Returns an array of strings
379
380
def fuzzer_string_paths_format
381
res = []
382
fuzzer_string_path_prefixes do |pre|
383
fuzzer_string_format do |str|
384
buf = pre + str
385
block_given? ? yield(buf) : (res << buf)
386
end
387
end
388
res
389
end
390
391
392
# Generates fuzzer strings using path prefixes
393
#
394
# @return [Array] Returns an array of strings
395
396
def fuzzer_string_paths_dos
397
res = []
398
fuzzer_string_path_prefixes do |pre|
399
fuzzer_string_filepath_dos do |str|
400
buf = pre + str
401
block_given? ? yield(buf) : (res << buf)
402
end
403
end
404
res
405
end
406
407
end
408
end
409
410