ronin-support 0.3.0 → 0.4.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog.md +77 -7
- data/README.md +19 -3
- data/gemspec.yml +2 -2
- data/lib/ronin/extensions/regexp.rb +50 -2
- data/lib/ronin/extensions/string.rb +1 -0
- data/lib/ronin/formatting.rb +1 -0
- data/lib/ronin/formatting/extensions.rb +1 -0
- data/lib/ronin/formatting/extensions/binary/string.rb +56 -5
- data/lib/ronin/formatting/extensions/html/string.rb +6 -7
- data/lib/ronin/formatting/extensions/sql/string.rb +34 -0
- data/lib/ronin/formatting/extensions/text/string.rb +0 -180
- data/lib/ronin/fuzzing.rb +21 -0
- data/lib/ronin/fuzzing/extensions.rb +20 -0
- data/lib/ronin/fuzzing/extensions/string.rb +380 -0
- data/lib/ronin/fuzzing/fuzzing.rb +191 -0
- data/lib/ronin/network/esmtp.rb +94 -1
- data/lib/ronin/network/extensions/esmtp/net.rb +2 -82
- data/lib/ronin/network/extensions/http/net.rb +1 -736
- data/lib/ronin/network/extensions/imap/net.rb +1 -103
- data/lib/ronin/network/extensions/pop3/net.rb +1 -71
- data/lib/ronin/network/extensions/smtp/net.rb +2 -157
- data/lib/ronin/network/extensions/ssl/net.rb +1 -132
- data/lib/ronin/network/extensions/tcp/net.rb +2 -296
- data/lib/ronin/network/extensions/telnet/net.rb +1 -135
- data/lib/ronin/network/extensions/udp/net.rb +2 -214
- data/lib/ronin/network/http/http.rb +750 -5
- data/lib/ronin/network/imap.rb +105 -2
- data/lib/ronin/network/mixins.rb +1 -1
- data/lib/ronin/network/mixins/esmtp.rb +49 -52
- data/lib/ronin/network/mixins/http.rb +49 -53
- data/lib/ronin/network/mixins/imap.rb +47 -44
- data/lib/ronin/network/mixins/mixin.rb +58 -0
- data/lib/ronin/network/mixins/pop3.rb +44 -38
- data/lib/ronin/network/mixins/smtp.rb +49 -51
- data/lib/ronin/network/mixins/tcp.rb +56 -69
- data/lib/ronin/network/mixins/telnet.rb +57 -50
- data/lib/ronin/network/mixins/udp.rb +48 -52
- data/lib/ronin/network/network.rb +1 -0
- data/lib/ronin/network/pop3.rb +72 -2
- data/lib/ronin/network/smtp/email.rb +1 -0
- data/lib/ronin/network/smtp/smtp.rb +159 -3
- data/lib/ronin/network/ssl.rb +131 -2
- data/lib/ronin/network/tcp.rb +306 -1
- data/lib/ronin/network/telnet.rb +136 -2
- data/lib/ronin/network/udp.rb +229 -1
- data/lib/ronin/support.rb +2 -3
- data/lib/ronin/support/support.rb +38 -0
- data/lib/ronin/support/version.rb +1 -1
- data/lib/ronin/templates/erb.rb +2 -1
- data/lib/ronin/ui/output/helpers.rb +35 -1
- data/lib/ronin/ui/shell.rb +12 -2
- data/lib/ronin/wordlist.rb +157 -0
- data/spec/extensions/regexp_spec.rb +38 -0
- data/spec/formatting/html/string_spec.rb +1 -1
- data/spec/formatting/sql/string_spec.rb +23 -3
- data/spec/formatting/text/string_spec.rb +0 -110
- data/spec/fuzzing/string_spec.rb +158 -0
- data/spec/wordlist_spec.rb +65 -0
- metadata +35 -27
@@ -0,0 +1,21 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2006-2011 Hal Brodigan (postmodern.mod3 at gmail.com)
|
3
|
+
#
|
4
|
+
# This file is part of Ronin Support.
|
5
|
+
#
|
6
|
+
# Ronin Support is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Lesser General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# Ronin Support is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Lesser General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Lesser General Public License
|
17
|
+
# along with Ronin Support. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#
|
19
|
+
|
20
|
+
require 'ronin/fuzzing/extensions'
|
21
|
+
require 'ronin/fuzzing/fuzzing'
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2006-2011 Hal Brodigan (postmodern.mod3 at gmail.com)
|
3
|
+
#
|
4
|
+
# This file is part of Ronin Support.
|
5
|
+
#
|
6
|
+
# Ronin Support is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Lesser General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# Ronin Support is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Lesser General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Lesser General Public License
|
17
|
+
# along with Ronin Support. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#
|
19
|
+
|
20
|
+
require 'ronin/fuzzing/extensions/string'
|
@@ -0,0 +1,380 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2006-2011 Hal Brodigan (postmodern.mod3 at gmail.com)
|
3
|
+
#
|
4
|
+
# This file is part of Ronin Support.
|
5
|
+
#
|
6
|
+
# Ronin Support is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Lesser General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# Ronin Support is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Lesser General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Lesser General Public License
|
17
|
+
# along with Ronin Support. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#
|
19
|
+
|
20
|
+
require 'ronin/extensions/regexp'
|
21
|
+
require 'ronin/fuzzing/fuzzing'
|
22
|
+
|
23
|
+
require 'combinatorics/generator'
|
24
|
+
require 'combinatorics/list_comprehension'
|
25
|
+
require 'combinatorics/power_set'
|
26
|
+
require 'chars'
|
27
|
+
|
28
|
+
class String
|
29
|
+
|
30
|
+
#
|
31
|
+
# Generate permutations of Strings from a format template.
|
32
|
+
#
|
33
|
+
# @param [Array(<String,Symbol,Enumerable>, <Integer,Array,Range>)] template
|
34
|
+
# The template which defines the string or character sets which will
|
35
|
+
# make up parts of the String.
|
36
|
+
#
|
37
|
+
# @yield [string]
|
38
|
+
# The given block will be passed each unique String.
|
39
|
+
#
|
40
|
+
# @yieldparam [String] string
|
41
|
+
# A newly generated String.
|
42
|
+
#
|
43
|
+
# @return [Enumerator]
|
44
|
+
# If no block is given, an Enumerator will be returned.
|
45
|
+
#
|
46
|
+
# @raise [ArgumentError]
|
47
|
+
# A given character set name was unknown.
|
48
|
+
#
|
49
|
+
# @raise [TypeError]
|
50
|
+
# A given string set was not a String, Symbol or Enumerable.
|
51
|
+
# A given string set length was not an Integer or Enumerable.
|
52
|
+
#
|
53
|
+
# @example Generate Strings with ranges of repeating sub-strings.
|
54
|
+
#
|
55
|
+
# @example Generate Strings with three alpha chars and one numeric chars.
|
56
|
+
# String.generate([:alpha, 3], :numeric) do |password|
|
57
|
+
# puts password
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# @example Generate Strings with two to four alpha chars.
|
61
|
+
# String.generate([:alpha, 2..4]) do |password|
|
62
|
+
# puts password
|
63
|
+
# end
|
64
|
+
#
|
65
|
+
# @example Generate Strings using alpha and punctuation chars.
|
66
|
+
# String.generate([Chars.alpha + Chars.punctuation, 4]) do |password|
|
67
|
+
# puts password
|
68
|
+
# end
|
69
|
+
#
|
70
|
+
# @example Generate Strings from a custom char set.
|
71
|
+
# String.generate([['a', 'b', 'c'], 3], [['1', '2', '3'], 3]) do |password|
|
72
|
+
# puts password
|
73
|
+
# end
|
74
|
+
#
|
75
|
+
# @example Generate Strings containing known Strings.
|
76
|
+
# String.generate("rock", [:numeric, 4]) do |password|
|
77
|
+
# puts password
|
78
|
+
# end
|
79
|
+
#
|
80
|
+
# @example Generate Strings with ranges of repeating sub-strings.
|
81
|
+
# String.generate(['/AA', (1..100).step(5)]) do |path|
|
82
|
+
# puts path
|
83
|
+
# end
|
84
|
+
#
|
85
|
+
# @since 0.3.0
|
86
|
+
#
|
87
|
+
# @api public
|
88
|
+
#
|
89
|
+
def self.generate(*template)
|
90
|
+
return enum_for(:generate,*template) unless block_given?
|
91
|
+
|
92
|
+
sets = []
|
93
|
+
|
94
|
+
template.each do |pattern|
|
95
|
+
set, length = pattern
|
96
|
+
set = case set
|
97
|
+
when String
|
98
|
+
[set].each
|
99
|
+
when Symbol
|
100
|
+
name = set.to_s.upcase
|
101
|
+
|
102
|
+
unless Chars.const_defined?(name)
|
103
|
+
raise(ArgumentError,"unknown charset #{set.inspect}")
|
104
|
+
end
|
105
|
+
|
106
|
+
Chars.const_get(name).each_char
|
107
|
+
when Enumerable
|
108
|
+
set
|
109
|
+
else
|
110
|
+
raise(TypeError,"set must be a String, Symbol or Enumerable")
|
111
|
+
end
|
112
|
+
|
113
|
+
case length
|
114
|
+
when Integer
|
115
|
+
length.times { sets << set.dup }
|
116
|
+
when Array, Range
|
117
|
+
sets << Combinatorics::Generator.new do |g|
|
118
|
+
length.each do |sublength|
|
119
|
+
superset = Array.new(sublength) { set.dup }
|
120
|
+
|
121
|
+
superset.comprehension { |strings| g.yield strings.join }
|
122
|
+
end
|
123
|
+
end
|
124
|
+
when nil
|
125
|
+
sets << set
|
126
|
+
else
|
127
|
+
raise(TypeError,"length must be an Integer, Range or Array")
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
sets.comprehension do |strings|
|
132
|
+
new_string = ''
|
133
|
+
|
134
|
+
strings.each do |string|
|
135
|
+
new_string << case string
|
136
|
+
when Integer
|
137
|
+
string.chr
|
138
|
+
else
|
139
|
+
string.to_s
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
yield new_string
|
144
|
+
end
|
145
|
+
return nil
|
146
|
+
end
|
147
|
+
|
148
|
+
#
|
149
|
+
# Repeats the String.
|
150
|
+
#
|
151
|
+
# @param [Enumerable, Integer] n
|
152
|
+
# The number of times to repeat the String.
|
153
|
+
#
|
154
|
+
# @yield [repeated]
|
155
|
+
# The given block will be passed every repeated String.
|
156
|
+
#
|
157
|
+
# @yieldparam [String] repeated
|
158
|
+
# A repeated version of the String.
|
159
|
+
#
|
160
|
+
# @return [Enumerator]
|
161
|
+
# If no block is given, an Enumerator will be returned.
|
162
|
+
#
|
163
|
+
# @raise [TypeError]
|
164
|
+
# `n` must either be Enumerable or an Integer.
|
165
|
+
#
|
166
|
+
# @example
|
167
|
+
# 'A'.repeating(100)
|
168
|
+
# # => "AAAAAAAAAAAAA..."
|
169
|
+
#
|
170
|
+
# @example Generates 100 upto 700 `A`s, increasing by 100 at a time:
|
171
|
+
# 'A'.repeating((100..700).step(100)) do |str|
|
172
|
+
# # ...
|
173
|
+
# end
|
174
|
+
#
|
175
|
+
# @example Generates 128, 1024, 65536 `A`s:
|
176
|
+
# 'A'.repeating([128, 1024, 65536]) do |str|
|
177
|
+
# # ...
|
178
|
+
# end
|
179
|
+
#
|
180
|
+
# @api public
|
181
|
+
#
|
182
|
+
# @since 0.4.0
|
183
|
+
#
|
184
|
+
def repeating(n)
|
185
|
+
if n.kind_of?(Integer)
|
186
|
+
# if n is an Integer, simply multiply the String and return
|
187
|
+
repeated = (self * n)
|
188
|
+
|
189
|
+
yield repeated if block_given?
|
190
|
+
return repeated
|
191
|
+
end
|
192
|
+
|
193
|
+
return enum_for(:repeating,n) unless block_given?
|
194
|
+
|
195
|
+
unless n.kind_of?(Enumerable)
|
196
|
+
raise(TypeError,"argument must be Enumerable or an Integer")
|
197
|
+
end
|
198
|
+
|
199
|
+
n.each do |length|
|
200
|
+
yield(self * length)
|
201
|
+
end
|
202
|
+
|
203
|
+
return self
|
204
|
+
end
|
205
|
+
|
206
|
+
#
|
207
|
+
# Incrementally fuzzes the String.
|
208
|
+
#
|
209
|
+
# @param [Hash{Regexp,String => #each}] substitutions
|
210
|
+
# Patterns and their substitutions.
|
211
|
+
#
|
212
|
+
# @yield [fuzz]
|
213
|
+
# The given block will be passed every fuzzed String.
|
214
|
+
#
|
215
|
+
# @yieldparam [String] fuzz
|
216
|
+
# A fuzzed String.
|
217
|
+
#
|
218
|
+
# @return [Enumerator]
|
219
|
+
# If no block is given, an Enumerator will be returned.
|
220
|
+
#
|
221
|
+
# @example Replace every `e`, `i`, `o`, `u` with `(`, 100 `A`s and a `\0`:
|
222
|
+
# "the quick brown fox".fuzz(/[eiou]/ => ['(', ('A' * 100), "\0"]) do |str|
|
223
|
+
# p str
|
224
|
+
# end
|
225
|
+
#
|
226
|
+
# @example {String.generate} with {String#fuzz}:
|
227
|
+
# "GET /".fuzz('/' => String.generate(['A', 1..100])) do |str|
|
228
|
+
# p str
|
229
|
+
# end
|
230
|
+
#
|
231
|
+
# @since 0.3.0
|
232
|
+
#
|
233
|
+
# @api public
|
234
|
+
#
|
235
|
+
def fuzz(substitutions={})
|
236
|
+
return enum_for(:fuzz,substitutions) unless block_given?
|
237
|
+
|
238
|
+
substitutions.each do |pattern,substitution|
|
239
|
+
pattern = case pattern
|
240
|
+
when Regexp
|
241
|
+
pattern
|
242
|
+
when String
|
243
|
+
Regexp.new(Regexp.escape(pattern))
|
244
|
+
when Symbol
|
245
|
+
Regexp.const_get(pattern.to_s.upcase)
|
246
|
+
else
|
247
|
+
raise(TypeError,"cannot convert #{pattern.inspect} to a Regexp")
|
248
|
+
end
|
249
|
+
|
250
|
+
substitution = case substitution
|
251
|
+
when Enumerable
|
252
|
+
substitution
|
253
|
+
when Symbol
|
254
|
+
Ronin::Fuzzing[substitution]
|
255
|
+
else
|
256
|
+
raise(TypeError,"substitutions must be Enumerable or a Symbol")
|
257
|
+
end
|
258
|
+
|
259
|
+
scanner = StringScanner.new(self)
|
260
|
+
indices = []
|
261
|
+
|
262
|
+
while scanner.scan_until(pattern)
|
263
|
+
indices << [scanner.pos - scanner.matched_size, scanner.matched_size]
|
264
|
+
end
|
265
|
+
|
266
|
+
indices.each do |index,length|
|
267
|
+
substitution.each do |substitute|
|
268
|
+
substitute = case substitute
|
269
|
+
when Proc
|
270
|
+
substitute.call(self[index,length])
|
271
|
+
when Integer
|
272
|
+
substitute.chr
|
273
|
+
else
|
274
|
+
substitute.to_s
|
275
|
+
end
|
276
|
+
|
277
|
+
fuzzed = dup
|
278
|
+
fuzzed[index,length] = substitute
|
279
|
+
yield fuzzed
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
#
|
286
|
+
# Permutes over every possible mutation of the String.
|
287
|
+
#
|
288
|
+
# @param [Hash{Regexp,String,Symbol => Symbol,#each}] mutations
|
289
|
+
# The patterns and substitutions to mutate the String with.
|
290
|
+
#
|
291
|
+
# @yield [mutant]
|
292
|
+
# The given block will be yielded every possible mutant String.
|
293
|
+
#
|
294
|
+
# @yieldparam [String] mutant
|
295
|
+
# A mutated String.
|
296
|
+
#
|
297
|
+
# @return [Enumerator]
|
298
|
+
# If no block is given, an Enumerator will be returned.
|
299
|
+
#
|
300
|
+
# @example
|
301
|
+
# "hello old dog".mutate('e' => ['3'], 'l' => ['1'], 'o' => ['0']) do |str|
|
302
|
+
# puts str
|
303
|
+
# end
|
304
|
+
#
|
305
|
+
# @since 0.4.0
|
306
|
+
#
|
307
|
+
# @api public
|
308
|
+
#
|
309
|
+
def mutate(mutations={})
|
310
|
+
return enum_for(:mutate,mutations) unless block_given?
|
311
|
+
|
312
|
+
matches = Set[]
|
313
|
+
|
314
|
+
mutations.each do |pattern,mutation|
|
315
|
+
pattern = case pattern
|
316
|
+
when Regexp
|
317
|
+
pattern
|
318
|
+
when String
|
319
|
+
Regexp.new(Regexp.escape(pattern))
|
320
|
+
when Symbol
|
321
|
+
Regexp.const_get(pattern.to_s.upcase)
|
322
|
+
else
|
323
|
+
raise(TypeError,"cannot convert #{pattern.inspect} to a Regexp")
|
324
|
+
end
|
325
|
+
|
326
|
+
scanner = StringScanner.new(self)
|
327
|
+
|
328
|
+
while scanner.scan_until(pattern)
|
329
|
+
length = scanner.matched_size
|
330
|
+
index = scanner.pos - length
|
331
|
+
original = scanner.matched
|
332
|
+
|
333
|
+
mutator = Combinatorics::Generator.new do |g|
|
334
|
+
mutation.each do |mutate|
|
335
|
+
g.yield case mutate
|
336
|
+
when Proc
|
337
|
+
mutate.call(original)
|
338
|
+
when Integer
|
339
|
+
mutate.chr
|
340
|
+
else
|
341
|
+
mutate.to_s
|
342
|
+
end
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
matches << [index, length, mutator]
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
matches.powerset do |submatches|
|
351
|
+
# ignore the empty Set
|
352
|
+
next if submatches.empty?
|
353
|
+
|
354
|
+
# sort the submatches by index
|
355
|
+
submatches = submatches.sort_by { |index,length,mutator| index }
|
356
|
+
sets = []
|
357
|
+
prev_index = 0
|
358
|
+
|
359
|
+
submatches.each do |index,length,mutator|
|
360
|
+
# add the previous substring to the set of Strings
|
361
|
+
if index > prev_index
|
362
|
+
sets << [self[prev_index,index - prev_index]]
|
363
|
+
end
|
364
|
+
|
365
|
+
# add the mutator to the set of Strings
|
366
|
+
sets << mutator
|
367
|
+
|
368
|
+
prev_index = index + length
|
369
|
+
end
|
370
|
+
|
371
|
+
# add the remaining substring to the set of Strings
|
372
|
+
if prev_index < self.length
|
373
|
+
sets << [self[prev_index..-1]]
|
374
|
+
end
|
375
|
+
|
376
|
+
sets.comprehension { |strings| yield strings.join }
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2006-2011 Hal Brodigan (postmodern.mod3 at gmail.com)
|
3
|
+
#
|
4
|
+
# This file is part of Ronin Support.
|
5
|
+
#
|
6
|
+
# Ronin Support is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Lesser General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# Ronin Support is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Lesser General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Lesser General Public License
|
17
|
+
# along with Ronin Support. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#
|
19
|
+
|
20
|
+
require 'set'
|
21
|
+
|
22
|
+
module Ronin
|
23
|
+
module Fuzzing
|
24
|
+
SHORT_LENGTHS = SortedSet[1, 100, 500, 1_000, 10_000]
|
25
|
+
|
26
|
+
LONG_LENGTHS = SortedSet[
|
27
|
+
128, 255, 256, 257, 511, 512, 513, 1023, 1024, 2048, 2049, 4095,
|
28
|
+
4096, 4097, 5_000, 10_000, 20_000, 32762, 32763, 32764, 32765, 32766,
|
29
|
+
32767, 32768, 32769,
|
30
|
+
0xffff-2, 0xffff-1, 0xffff, 0xffff+1, 0xffff+2,
|
31
|
+
99_999, 100_000, 500_000, 1_000_000
|
32
|
+
]
|
33
|
+
|
34
|
+
# Null bytes in various encodings
|
35
|
+
NULL_BYTES = ['%00', '%u0000', "\x00"]
|
36
|
+
|
37
|
+
# Newline characters
|
38
|
+
NEW_LINES = ["\n", "\r", "\n\r"]
|
39
|
+
|
40
|
+
# Format String flags
|
41
|
+
FORMAT_STRINGS = ['%p', '%s', '%n']
|
42
|
+
|
43
|
+
#
|
44
|
+
# Returns a fuzzer method.
|
45
|
+
#
|
46
|
+
# @param [Symbol] name
|
47
|
+
# The name of the fuzzer to return.
|
48
|
+
#
|
49
|
+
# @return [Enumerator]
|
50
|
+
# An Enumerator for the fuzzer method.
|
51
|
+
#
|
52
|
+
# @api semipublic
|
53
|
+
#
|
54
|
+
# @since 0.4.0
|
55
|
+
#
|
56
|
+
def self.[](name)
|
57
|
+
if (!Object.respond_to?(name) && respond_to?(name))
|
58
|
+
enum_for(name)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.bad_strings(&block)
|
63
|
+
yield ''
|
64
|
+
|
65
|
+
chars = [
|
66
|
+
'A', 'a', '1', '<', '>', '"', "'", '/', "\\", '?', '=', 'a=', '&',
|
67
|
+
'.', ',', '(', ')', ']', '[', '%', '*', '-', '+', '{', '}',
|
68
|
+
"\x14", "\xfe", "\xff"
|
69
|
+
]
|
70
|
+
|
71
|
+
chars.each do |c|
|
72
|
+
LONG_LENGTHS.each { |length| yield c * length }
|
73
|
+
end
|
74
|
+
|
75
|
+
yield '!@#$%%^#$%#$@#$%$$@#$%^^**(()'
|
76
|
+
yield '%01%02%03%04%0a%0d%0aADSF'
|
77
|
+
yield '%01%02%03@%04%0a%0d%0aADSF'
|
78
|
+
|
79
|
+
NULL_BYTES.each do |c|
|
80
|
+
SHORT_LENGTHS.each { |length| yield c * length }
|
81
|
+
end
|
82
|
+
|
83
|
+
yield "%\xfe\xf0%\x00\xff"
|
84
|
+
yield "%\xfe\xf0%\x00\xff" * 20
|
85
|
+
|
86
|
+
SHORT_LENGTHS.each do |length|
|
87
|
+
yield "\xde\xad\xbe\xef" * length
|
88
|
+
end
|
89
|
+
|
90
|
+
yield "\n\r" * 100
|
91
|
+
yield "<>" * 500
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.format_strings(&block)
|
95
|
+
FORMAT_STRINGS.each do |fmt|
|
96
|
+
yield fmt
|
97
|
+
yield fmt * 100
|
98
|
+
yield fmt * 500
|
99
|
+
yield "\"#{fmt}\"" * 500
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.bad_paths(&block)
|
104
|
+
padding = 'A' * 5_000
|
105
|
+
|
106
|
+
yield "/.:/#{padding}\x00\x00"
|
107
|
+
yield "/.../#{padding}\x00\x00"
|
108
|
+
|
109
|
+
yield "\\\\*"
|
110
|
+
yield "\\\\?\\"
|
111
|
+
|
112
|
+
yield "/\\" * 5_000
|
113
|
+
yield '/.' * 5_000
|
114
|
+
|
115
|
+
NULL_BYTES.each do |c|
|
116
|
+
if c.start_with?('%')
|
117
|
+
yield "#{c}/"
|
118
|
+
yield "/#{c}"
|
119
|
+
yield "/#{c}/"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.bit_fields(&block)
|
125
|
+
("\x00".."\xff").each do |c|
|
126
|
+
yield c
|
127
|
+
yield c << c # x2
|
128
|
+
yield c << c # x4
|
129
|
+
yield c << c # x8
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def self.signed_bit_fields(&block)
|
134
|
+
("\x80".."\xff").each do |c|
|
135
|
+
yield c
|
136
|
+
yield c << c # x2
|
137
|
+
yield c << c # x4
|
138
|
+
yield c << c # x8
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def self.uint8(&block)
|
143
|
+
("\x00".."\xff").each(&block)
|
144
|
+
end
|
145
|
+
|
146
|
+
def self.uint16
|
147
|
+
uint8 { |c| yield c * 2 }
|
148
|
+
end
|
149
|
+
|
150
|
+
def self.uint32
|
151
|
+
uint8 { |c| yield c * 4 }
|
152
|
+
end
|
153
|
+
|
154
|
+
def self.uint64
|
155
|
+
uint8 { |c| yield c * 8 }
|
156
|
+
end
|
157
|
+
|
158
|
+
def self.int8(&block)
|
159
|
+
("\x00".."\x70").each(&block)
|
160
|
+
end
|
161
|
+
|
162
|
+
def self.int16
|
163
|
+
int8 { |c| yield c * 2 }
|
164
|
+
end
|
165
|
+
|
166
|
+
def self.int32
|
167
|
+
int8 { |c| yield c * 4 }
|
168
|
+
end
|
169
|
+
|
170
|
+
def self.int64
|
171
|
+
int8 { |c| yield c * 8 }
|
172
|
+
end
|
173
|
+
|
174
|
+
def self.sint8(&block)
|
175
|
+
("\x80".."\xff").each(&block)
|
176
|
+
end
|
177
|
+
|
178
|
+
def self.sint16
|
179
|
+
sint8 { |c| yield c * 2 }
|
180
|
+
end
|
181
|
+
|
182
|
+
def self.sint32
|
183
|
+
sint8 { |c| yield c * 4 }
|
184
|
+
end
|
185
|
+
|
186
|
+
def self.sint64
|
187
|
+
sint8 { |c| yield c * 8 }
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
end
|