ronin-fuzzer 0.1.0.beta1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +1 -0
- data/README.md +5 -2
- data/bin/ronin-fuzzer +1 -1
- data/gemspec.yml +8 -6
- data/lib/ronin/fuzzer/cli/command.rb +1 -1
- data/lib/ronin/fuzzer/cli/commands/fuzz.rb +180 -63
- data/lib/ronin/fuzzer/cli.rb +1 -1
- data/lib/ronin/fuzzer/root.rb +1 -1
- data/lib/ronin/fuzzer/version.rb +2 -2
- data/lib/ronin/fuzzing/core_ext/string.rb +1 -1
- data/lib/ronin/fuzzing/core_ext.rb +1 -1
- data/lib/ronin/fuzzing/fuzzer.rb +1 -1
- data/lib/ronin/fuzzing/mutator.rb +1 -1
- data/lib/ronin/fuzzing/repeater.rb +1 -1
- data/lib/ronin/fuzzing/template.rb +1 -1
- data/lib/ronin/fuzzing.rb +1 -1
- data/man/ronin-fuzzer-fuzz.1 +2 -2
- data/man/ronin-fuzzer-fuzz.1.md +2 -2
- data/ronin-fuzzer.gemspec +2 -1
- metadata +14 -26
- data/spec/core_ext/string_spec.rb +0 -87
- data/spec/fuzzer_spec.rb +0 -109
- data/spec/fuzzing_spec.rb +0 -24
- data/spec/mutator_spec.rb +0 -112
- data/spec/repeater_spec.rb +0 -57
- data/spec/spec_helper.rb +0 -4
- data/spec/template_spec.rb +0 -54
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b75ddebfc52f82912471833f168b9e8813af985b9443cb1c6b88a27b1c730a3b
|
4
|
+
data.tar.gz: 7a0454d2ece994db0151eb7ed1df4ce0edf6ab2e05d48d12f13621930d66cd8d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 508b1ede3b5ec7e9be7d1a9bccfab1add955ce60f028559d444613f6e485195ef52f95f293acab505a9493222b2ba31337901df3038a8bd2fee0a3b8668c8a43
|
7
|
+
data.tar.gz: 65fdbda74f4b756e3378e1fbdc5ac533612a6aad873eff7b8b17bc0a0f1a94726bdb15525668f974f18b2a5d50feb2853077d8a8ba00040c64ed88b5a3352a3f
|
data/.github/workflows/ruby.yml
CHANGED
data/README.md
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
[![CI](https://github.com/ronin-rb/ronin-fuzzer/actions/workflows/ruby.yml/badge.svg)](https://github.com/ronin-rb/ronin-fuzzer/actions/workflows/ruby.yml)
|
4
4
|
[![Code Climate](https://codeclimate.com/github/ronin-rb/ronin-fuzzer.svg)](https://codeclimate.com/github/ronin-rb/ronin-fuzzer)
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/ronin-fuzzer.svg)](https://badge.fury.io/rb/ronin-fuzzer)
|
5
6
|
|
6
7
|
* [Website](https://ronin-rb.dev/)
|
7
8
|
* [Source](https://github.com/ronin-rb/ronin-fuzzer)
|
@@ -13,7 +14,9 @@
|
|
13
14
|
|
14
15
|
## Description
|
15
16
|
|
16
|
-
ronin-fuzzer is a Ruby library for generating, mutating, and fuzzing
|
17
|
+
ronin-fuzzer is a Ruby library and CLI for generating, mutating, and fuzzing
|
18
|
+
data. The goal of ronin-fuzzer is to be both easy to use and highly
|
19
|
+
customizable.
|
17
20
|
|
18
21
|
## Features
|
19
22
|
|
@@ -68,7 +71,7 @@ gem.add_dependency 'ronin-fuzzer', '~> 0.1'
|
|
68
71
|
|
69
72
|
## License
|
70
73
|
|
71
|
-
Copyright (c) 2006-
|
74
|
+
Copyright (c) 2006-2023 Hal Brodigan (postmodern.mod3@gmail.com)
|
72
75
|
|
73
76
|
This file is part of ronin-fuzzer.
|
74
77
|
|
data/bin/ronin-fuzzer
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# ronin-fuzzer - A Ruby library for generating, mutating, and fuzzing data.
|
4
4
|
#
|
5
|
-
# Copyright (c) 2006-
|
5
|
+
# Copyright (c) 2006-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
|
6
6
|
#
|
7
7
|
# This file is part of ronin-fuzzer.
|
8
8
|
#
|
data/gemspec.yml
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
name: ronin-fuzzer
|
2
|
-
summary:
|
2
|
+
summary: A highly configurable fuzzing library and CLI for Ruby.
|
3
3
|
description: |
|
4
|
-
A Ruby library for generating, mutating, and fuzzing data.
|
4
|
+
A Ruby library and CLI for generating, mutating, and fuzzing data.
|
5
|
+
The goal of ronin-fuzzer is to be both easy to use and highly customizable.
|
5
6
|
|
6
7
|
license: LGPL-3.0
|
7
8
|
authors: Postmodern
|
@@ -10,10 +11,11 @@ homepage: https://ronin-rb.dev/
|
|
10
11
|
has_yard: true
|
11
12
|
|
12
13
|
metadata:
|
13
|
-
documentation_uri: https://
|
14
|
+
documentation_uri: https://ronin-rb.dev/docs/ronin-fuzzer
|
14
15
|
source_code_uri: https://github.com/ronin-rb/ronin-fuzzer
|
15
16
|
bug_tracker_uri: https://github.com/ronin-rb/ronin-fuzzer/issues
|
16
|
-
changelog_uri: https://github.com/ronin-rb/ronin-fuzzer/blob/
|
17
|
+
changelog_uri: https://github.com/ronin-rb/ronin-fuzzer/blob/main/ChangeLog.md
|
18
|
+
rubygems_mfa_required: 'true'
|
17
19
|
|
18
20
|
generated_files:
|
19
21
|
- man/ronin-fuzzer-fuzz.1
|
@@ -23,8 +25,8 @@ required_ruby_version: ">= 3.0.0"
|
|
23
25
|
dependencies:
|
24
26
|
combinatorics: ~> 0.4
|
25
27
|
# Ronin dependencies:
|
26
|
-
ronin-support: ~> 1.0
|
27
|
-
ronin-core: ~> 0.1
|
28
|
+
ronin-support: ~> 1.0
|
29
|
+
ronin-core: ~> 0.1
|
28
30
|
|
29
31
|
development_dependencies:
|
30
32
|
bundler: ~> 2.0
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# ronin-fuzzer - A Ruby library for generating, mutating, and fuzzing data.
|
3
3
|
#
|
4
|
-
# Copyright (c) 2006-
|
4
|
+
# Copyright (c) 2006-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
|
5
5
|
#
|
6
6
|
# This file is part of ronin-fuzzer.
|
7
7
|
#
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# ronin-fuzzer - A Ruby library for generating, mutating, and fuzzing data.
|
3
3
|
#
|
4
|
-
# Copyright (c) 2006-
|
4
|
+
# Copyright (c) 2006-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
|
5
5
|
#
|
6
6
|
# This file is part of ronin-fuzzer.
|
7
7
|
#
|
@@ -20,8 +20,12 @@
|
|
20
20
|
#
|
21
21
|
|
22
22
|
require 'ronin/fuzzer/cli/command'
|
23
|
-
require 'ronin/
|
24
|
-
|
23
|
+
require 'ronin/core/cli/logging'
|
24
|
+
|
25
|
+
require 'ronin/support/text/patterns'
|
26
|
+
require 'ronin/fuzzing/repeater'
|
27
|
+
require 'ronin/fuzzing/fuzzer'
|
28
|
+
require 'ronin/fuzzing'
|
25
29
|
|
26
30
|
require 'shellwords'
|
27
31
|
require 'tempfile'
|
@@ -44,7 +48,7 @@ module Ronin
|
|
44
48
|
# -q, --[no-]quiet Disable verbose output.
|
45
49
|
# --[no-]silent Silence all output.
|
46
50
|
# -r [[PATTERN|/REGEXP/]:[METHOD|STRING*N[-M]]],
|
47
|
-
# --rule
|
51
|
+
# --rule Adds a fuzzing rule.
|
48
52
|
# -i, --input [FILE] Input file to fuzz.
|
49
53
|
# -o, --output [FILE] Output file path.
|
50
54
|
# -c [PROGRAM [OPTIONS|#string#|#path#] ...],
|
@@ -59,6 +63,8 @@ module Ronin
|
|
59
63
|
#
|
60
64
|
class Fuzz < Command
|
61
65
|
|
66
|
+
include Core::CLI::Logging
|
67
|
+
|
62
68
|
option :input, short: '-i',
|
63
69
|
value: {
|
64
70
|
type: String,
|
@@ -68,45 +74,66 @@ module Ronin
|
|
68
74
|
|
69
75
|
option :rules, short: '-r',
|
70
76
|
value: {
|
71
|
-
type:
|
77
|
+
type: String,
|
72
78
|
usage: '[PATTERN|/REGEXP/|STRING]:[METHOD|STRING*N[-M]]'
|
73
79
|
},
|
74
|
-
desc: '
|
80
|
+
desc: 'Adds a fuzzing rule' do |value|
|
81
|
+
@rules << parse_rule(value)
|
82
|
+
end
|
75
83
|
|
76
84
|
option :output, short: '-o',
|
77
85
|
value: {
|
78
86
|
type: String,
|
79
87
|
usage: 'PATH'
|
80
88
|
},
|
81
|
-
desc: 'Output file path'
|
89
|
+
desc: 'Output file path' do |value|
|
90
|
+
@mode = :output
|
91
|
+
|
92
|
+
@output = value
|
93
|
+
@output_ext = File.extname(@output)
|
94
|
+
@output_name = @output.chomp(@output_ext)
|
95
|
+
end
|
82
96
|
|
83
97
|
option :command, short: '-c',
|
84
98
|
value: {
|
85
99
|
type: String,
|
86
100
|
usage: '"PROGRAM [OPTIONS|#string#|#path#] ..."'
|
87
101
|
},
|
88
|
-
desc: 'Template command to run'
|
102
|
+
desc: 'Template command to run' do |value|
|
103
|
+
@mode = :command
|
104
|
+
@command = Shellwords.shellescape(value)
|
105
|
+
end
|
89
106
|
|
90
107
|
option :tcp, short: '-t',
|
91
108
|
value: {
|
92
109
|
type: String,
|
93
110
|
usage: 'HOST:PORT'
|
94
111
|
},
|
95
|
-
desc: 'TCP service to fuzz'
|
112
|
+
desc: 'TCP service to fuzz' do |value|
|
113
|
+
@mode = :tcp
|
114
|
+
|
115
|
+
@host, @port = parse_host_port(value)
|
116
|
+
end
|
96
117
|
|
97
118
|
option :udp, short: '-u',
|
98
119
|
value: {
|
99
120
|
type: String,
|
100
121
|
usage: 'HOST:PORT'
|
101
122
|
},
|
102
|
-
desc: 'UDP service to fuzz'
|
123
|
+
desc: 'UDP service to fuzz' do |value|
|
124
|
+
@mode = :udp
|
125
|
+
|
126
|
+
@host, @port = parse_host_port(value)
|
127
|
+
end
|
103
128
|
|
104
129
|
option :pause, short: '-p',
|
105
130
|
value: {
|
106
131
|
type: Float,
|
107
132
|
usage: 'SECONDS'
|
108
133
|
},
|
109
|
-
desc: 'Pause in between mutations'
|
134
|
+
desc: 'Pause in between mutations' do |value|
|
135
|
+
@pause = value
|
136
|
+
end
|
110
137
|
|
111
138
|
description 'Performs basic fuzzing of files'
|
112
139
|
|
@@ -116,58 +143,99 @@ module Ronin
|
|
116
143
|
|
117
144
|
man_page 'ronin-fuzzer-fuzz.1'
|
118
145
|
|
146
|
+
# The execution mode to run the fuzzer in.
|
147
|
+
#
|
148
|
+
# @return [:output, :command, :tcp, :udp]
|
149
|
+
attr_reader :mode
|
150
|
+
|
151
|
+
# The output file template.
|
119
152
|
#
|
120
|
-
#
|
153
|
+
# @return [String, nil]
|
154
|
+
attr_reader :output
|
155
|
+
|
156
|
+
# The output file extension.
|
157
|
+
#
|
158
|
+
# @return [String, nil]
|
159
|
+
attr_reader :output_ext
|
160
|
+
|
161
|
+
# The output file name.
|
162
|
+
#
|
163
|
+
# @return [String, nil]
|
164
|
+
attr_reader :output_name
|
165
|
+
|
166
|
+
# The command template to execute.
|
167
|
+
#
|
168
|
+
# @return [String, nil]
|
169
|
+
attr_reader :command
|
170
|
+
|
171
|
+
# The host name to send fuzzing data to.
|
172
|
+
#
|
173
|
+
# @return [String, nil]
|
174
|
+
attr_reader :host
|
175
|
+
|
176
|
+
# The port to send fuzzing data to.
|
177
|
+
#
|
178
|
+
# @return [Integer, nil]
|
179
|
+
attr_reader :port
|
180
|
+
|
181
|
+
# The fuzzing rules.
|
182
|
+
#
|
183
|
+
# @return [Array<(Regexp, Enumerator)>]
|
184
|
+
attr_reader :rules
|
185
|
+
|
186
|
+
#
|
187
|
+
# Initializes the `ronin-fuzzer fuzz` command.
|
188
|
+
#
|
189
|
+
# @param [Hash{Symbol => Object}] kwargs
|
190
|
+
# Additional keyword arguments.
|
191
|
+
#
|
192
|
+
def initialize(**kwargs)
|
193
|
+
super(**kwargs)
|
194
|
+
|
195
|
+
@rules = []
|
196
|
+
end
|
197
|
+
|
198
|
+
#
|
199
|
+
# Runs the `ronin-fuzzer fuzz` command.
|
121
200
|
#
|
122
201
|
def run
|
123
|
-
|
202
|
+
if @rules.empty?
|
124
203
|
print_error "Must specify at least one fuzzing rule"
|
125
|
-
exit
|
204
|
+
exit(-1)
|
126
205
|
end
|
127
206
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
if options[:output]
|
133
|
-
@file_ext = File.extname(options[:output])
|
134
|
-
@file_name = @output.chomp(@file_ext)
|
135
|
-
elsif options[:command]
|
136
|
-
@command = shellwords(options[:command])
|
137
|
-
elsif (options[:tcp] || options[:udp])
|
138
|
-
@socket_class = if options[:tcp] then TCPSocket
|
139
|
-
elsif options[:udp] then UDPSocket
|
140
|
-
end
|
141
|
-
|
142
|
-
@host, @port = (options[:tcp] || options[:udp]).split(':',2)
|
143
|
-
@port = @port.to_i
|
144
|
-
end
|
207
|
+
data = if options[:input] then File.read(options[:input])
|
208
|
+
else $stdin.read
|
209
|
+
end
|
145
210
|
|
146
|
-
|
147
|
-
|
211
|
+
method = case @mode
|
212
|
+
when :output then method(:fuzz_file)
|
213
|
+
when :command then method(:fuzz_command)
|
214
|
+
when :tcp, :udp then method(:fuzz_network)
|
215
|
+
else method(:print_fuzz)
|
148
216
|
end
|
149
217
|
|
150
|
-
|
151
|
-
method(:fuzz_file)
|
152
|
-
elsif options[:command]
|
153
|
-
method(:fuzz_command)
|
154
|
-
elsif (options[:tcp] || options[:udp])
|
155
|
-
method(:fuzz_network)
|
156
|
-
else
|
157
|
-
method(:print_fuzz)
|
158
|
-
end
|
218
|
+
fuzzer = Fuzzing::Fuzzer.new(@rules)
|
159
219
|
|
160
|
-
fuzzer = Fuzzer::Fuzzer.new(rules)
|
161
220
|
fuzzer.each(data).each_with_index do |string,index|
|
162
221
|
method.call(string,index + 1)
|
163
222
|
|
164
|
-
sleep(pause) if pause
|
223
|
+
sleep(@pause) if @pause
|
165
224
|
end
|
166
225
|
end
|
167
226
|
|
168
|
-
|
169
|
-
|
170
|
-
|
227
|
+
#
|
228
|
+
# Creates a new output path for the given index.
|
229
|
+
#
|
230
|
+
# @param [Integer] index
|
231
|
+
# The index number of the fuzzing iteration.
|
232
|
+
#
|
233
|
+
# @return [String]
|
234
|
+
# The new output path.
|
235
|
+
#
|
236
|
+
def output_path(index)
|
237
|
+
"#{@output_name}-#{index}#{@output_ext}"
|
238
|
+
end
|
171
239
|
|
172
240
|
#
|
173
241
|
# Writes the fuzzed string to a file.
|
@@ -176,12 +244,12 @@ module Ronin
|
|
176
244
|
# The fuzzed string.
|
177
245
|
#
|
178
246
|
# @param [Integer] index
|
179
|
-
# The iteration number.
|
247
|
+
# The fuzzing iteration number.
|
180
248
|
#
|
181
249
|
def fuzz_file(string,index)
|
182
|
-
path =
|
250
|
+
path = output_path(index)
|
183
251
|
|
184
|
-
|
252
|
+
log_info "Creating file ##{index}: #{path} ..."
|
185
253
|
|
186
254
|
File.open(path,'wb') do |file|
|
187
255
|
file.write string
|
@@ -212,7 +280,7 @@ module Ronin
|
|
212
280
|
end
|
213
281
|
end
|
214
282
|
|
215
|
-
|
283
|
+
log_info "Running command #{index}: #{arguments.join(' ')} ..."
|
216
284
|
|
217
285
|
# run the command as it's own process
|
218
286
|
unless system(*arguments)
|
@@ -220,10 +288,10 @@ module Ronin
|
|
220
288
|
|
221
289
|
if status.coredump?
|
222
290
|
# jack pot!
|
223
|
-
|
291
|
+
log_error "Process ##{status.pid} coredumped!"
|
224
292
|
else
|
225
293
|
# process errored out
|
226
|
-
|
294
|
+
log_warning "Process ##{status.pid} exited with status #{status.exitstatus}"
|
227
295
|
end
|
228
296
|
end
|
229
297
|
end
|
@@ -239,14 +307,18 @@ module Ronin
|
|
239
307
|
# The iteration number.
|
240
308
|
#
|
241
309
|
def fuzz_network(string,index)
|
242
|
-
|
243
|
-
socket = @socket_class.new(@host,@port)
|
310
|
+
log_debug "Connecting to #{@host}:#{@port} ..."
|
244
311
|
|
245
|
-
|
312
|
+
socket = case @mode
|
313
|
+
when :tcp then TCPSocket.new(@host,@port)
|
314
|
+
when :udp then UDPSocket.new(@host,@port)
|
315
|
+
end
|
316
|
+
|
317
|
+
log_info "Sending message ##{index}: #{string.inspect} ..."
|
246
318
|
socket.write(string)
|
247
319
|
socket.flush
|
248
320
|
|
249
|
-
|
321
|
+
log_debug "Disconnecting from #{@host}:#{@port} ..."
|
250
322
|
socket.close
|
251
323
|
end
|
252
324
|
|
@@ -260,11 +332,57 @@ module Ronin
|
|
260
332
|
# The iteration number.
|
261
333
|
#
|
262
334
|
def print_fuzz(string,index)
|
263
|
-
|
335
|
+
log_debug "String ##{index} ..."
|
264
336
|
|
265
337
|
puts string
|
266
338
|
end
|
267
339
|
|
340
|
+
#
|
341
|
+
# Parses the host and port from the value.
|
342
|
+
#
|
343
|
+
# @param [String] value
|
344
|
+
# The value to parse.
|
345
|
+
#
|
346
|
+
# @return [(String, Integer)]
|
347
|
+
# The parsed host and port.
|
348
|
+
#
|
349
|
+
def parse_host_port(value)
|
350
|
+
host, port = value.split(':',2)
|
351
|
+
|
352
|
+
return host, port.to_i
|
353
|
+
end
|
354
|
+
|
355
|
+
#
|
356
|
+
# Parses a fuzzing rule.
|
357
|
+
#
|
358
|
+
# @param [String] value
|
359
|
+
# The fuzzing rule.
|
360
|
+
#
|
361
|
+
# @return [(Regexp, Enumerator)]
|
362
|
+
# The fuzzing pattern and list of substitutions.
|
363
|
+
#
|
364
|
+
def parse_rule(value)
|
365
|
+
if value.start_with?('/')
|
366
|
+
unless (index = value.rindex('/:'))
|
367
|
+
raise(OptionParser::InvalidArgument,"argument must be of the form /REGEXP/:REPLACE, but was: #{value}")
|
368
|
+
end
|
369
|
+
|
370
|
+
regexp = parse_pattern(value[1...index])
|
371
|
+
substitution = parse_substitution(value[index+2..])
|
372
|
+
|
373
|
+
return [regexp, substitution]
|
374
|
+
else
|
375
|
+
unless (index = value.rindex(':'))
|
376
|
+
raise(OptionParser::InvalidArgument,"argument must be of the form STRING:STYLE but was: #{value}")
|
377
|
+
end
|
378
|
+
|
379
|
+
pattern = parse_pattern(value[0...index])
|
380
|
+
substitution = parse_substitution(value[index+1..])
|
381
|
+
|
382
|
+
return [pattern, substitution]
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
268
386
|
#
|
269
387
|
# Parses a fuzz pattern.
|
270
388
|
#
|
@@ -281,9 +399,8 @@ module Ronin
|
|
281
399
|
when /^[a-z][a-z_]+$/
|
282
400
|
const = string.upcase
|
283
401
|
|
284
|
-
if
|
285
|
-
|
286
|
-
Regexp.const_get(const)
|
402
|
+
if Support::Text::Patterns.const_defined?(const,false)
|
403
|
+
Support::Text::Patterns.const_get(const,false)
|
287
404
|
else
|
288
405
|
string
|
289
406
|
end
|
@@ -313,9 +430,9 @@ module Ronin
|
|
313
430
|
lengths.to_i
|
314
431
|
end
|
315
432
|
|
316
|
-
|
433
|
+
Fuzzing::Repeater.new(lengths).each(string)
|
317
434
|
else
|
318
|
-
|
435
|
+
Fuzzing[string]
|
319
436
|
end
|
320
437
|
end
|
321
438
|
|
data/lib/ronin/fuzzer/cli.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# ronin-fuzzer - A Ruby library for generating, mutating, and fuzzing data.
|
3
3
|
#
|
4
|
-
# Copyright (c) 2006-
|
4
|
+
# Copyright (c) 2006-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
|
5
5
|
#
|
6
6
|
# This file is part of ronin-fuzzer.
|
7
7
|
#
|
data/lib/ronin/fuzzer/root.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# ronin-fuzzer - A Ruby library for generating, mutating, and fuzzing data.
|
3
3
|
#
|
4
|
-
# Copyright (c) 2006-
|
4
|
+
# Copyright (c) 2006-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
|
5
5
|
#
|
6
6
|
# This file is part of ronin-fuzzer.
|
7
7
|
#
|
data/lib/ronin/fuzzer/version.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# ronin-fuzzer - A Ruby library for generating, mutating, and fuzzing data.
|
3
3
|
#
|
4
|
-
# Copyright (c) 2006-
|
4
|
+
# Copyright (c) 2006-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
|
5
5
|
#
|
6
6
|
# This file is part of ronin-fuzzer.
|
7
7
|
#
|
@@ -22,6 +22,6 @@
|
|
22
22
|
module Ronin
|
23
23
|
module Fuzzer
|
24
24
|
# ronin-fuzzer version
|
25
|
-
VERSION = '0.1.0
|
25
|
+
VERSION = '0.1.0'
|
26
26
|
end
|
27
27
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# ronin-fuzzer - A Ruby library for generating, mutating, and fuzzing data.
|
3
3
|
#
|
4
|
-
# Copyright (c) 2006-
|
4
|
+
# Copyright (c) 2006-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
|
5
5
|
#
|
6
6
|
# This file is part of ronin-fuzzer.
|
7
7
|
#
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# ronin-fuzzer - A Ruby library for generating, mutating, and fuzzing data.
|
3
3
|
#
|
4
|
-
# Copyright (c) 2006-
|
4
|
+
# Copyright (c) 2006-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
|
5
5
|
#
|
6
6
|
# This file is part of ronin-fuzzer.
|
7
7
|
#
|
data/lib/ronin/fuzzing/fuzzer.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# ronin-fuzzer - A Ruby library for generating, mutating, and fuzzing data.
|
3
3
|
#
|
4
|
-
# Copyright (c) 2006-
|
4
|
+
# Copyright (c) 2006-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
|
5
5
|
#
|
6
6
|
# This file is part of ronin-fuzzer.
|
7
7
|
#
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# ronin-fuzzer - A Ruby library for generating, mutating, and fuzzing data.
|
3
3
|
#
|
4
|
-
# Copyright (c) 2006-
|
4
|
+
# Copyright (c) 2006-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
|
5
5
|
#
|
6
6
|
# This file is part of ronin-fuzzer.
|
7
7
|
#
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# ronin-fuzzer - A Ruby library for generating, mutating, and fuzzing data.
|
3
3
|
#
|
4
|
-
# Copyright (c) 2006-
|
4
|
+
# Copyright (c) 2006-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
|
5
5
|
#
|
6
6
|
# This file is part of ronin-fuzzer.
|
7
7
|
#
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# ronin-fuzzer - A Ruby library for generating, mutating, and fuzzing data.
|
3
3
|
#
|
4
|
-
# Copyright (c) 2006-
|
4
|
+
# Copyright (c) 2006-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
|
5
5
|
#
|
6
6
|
# This file is part of ronin-fuzzer.
|
7
7
|
#
|
data/lib/ronin/fuzzing.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#
|
2
2
|
# ronin-fuzzer - A Ruby library for generating, mutating, and fuzzing data.
|
3
3
|
#
|
4
|
-
# Copyright (c) 2006-
|
4
|
+
# Copyright (c) 2006-2023 Hal Brodigan (postmodern.mod3 at gmail.com)
|
5
5
|
#
|
6
6
|
# This file is part of ronin-fuzzer.
|
7
7
|
#
|
data/man/ronin-fuzzer-fuzz.1
CHANGED
@@ -53,8 +53,8 @@ The output PATH to write the fuzzer to\.
|
|
53
53
|
.LP
|
54
54
|
.TP
|
55
55
|
\fB-c\fR, \fB--command\fR \fICOMMAND\fP
|
56
|
-
The command to run with the fuzzed data\. All
|
57
|
-
will be replaced with the fuzzed data, and
|
56
|
+
The command to run with the fuzzed data\. All occurrences of \fB#string#\fR
|
57
|
+
will be replaced with the fuzzed data, and occurrences of \fB#path#\fR will
|
58
58
|
be replaced with the path to the fuzzed data\.
|
59
59
|
.LP
|
60
60
|
.TP
|
data/man/ronin-fuzzer-fuzz.1.md
CHANGED
@@ -40,8 +40,8 @@ to output files, run in commands or sent to TCP/UDP services.
|
|
40
40
|
The output PATH to write the fuzzer to.
|
41
41
|
|
42
42
|
`-c`, `--command` *COMMAND*
|
43
|
-
The command to run with the fuzzed data. All
|
44
|
-
will be replaced with the fuzzed data, and
|
43
|
+
The command to run with the fuzzed data. All occurrences of `#string#`
|
44
|
+
will be replaced with the fuzzed data, and occurrences of `#path#` will
|
45
45
|
be replaced with the path to the fuzzed data.
|
46
46
|
|
47
47
|
`-t`, `--tcp` *HOST*:*PORT*
|
data/ronin-fuzzer.gemspec
CHANGED
@@ -27,13 +27,14 @@ Gem::Specification.new do |gem|
|
|
27
27
|
gem.files = `git ls-files`.split($/)
|
28
28
|
gem.files = glob[gemspec['files']] if gemspec['files']
|
29
29
|
gem.files += Array(gemspec['generated_files'])
|
30
|
+
# exclude test files from the packages gem
|
31
|
+
gem.files -= glob[gemspec['test_files'] || 'spec/{**/}*']
|
30
32
|
|
31
33
|
gem.executables = gemspec.fetch('executables') do
|
32
34
|
glob['bin/*'].map { |path| File.basename(path) }
|
33
35
|
end
|
34
36
|
|
35
37
|
gem.extensions = glob[gemspec['extensions'] || 'ext/**/extconf.rb']
|
36
|
-
gem.test_files = glob[gemspec['test_files'] || 'spec/{**/}*_spec.rb']
|
37
38
|
gem.extra_rdoc_files = glob[gemspec['extra_doc_files'] || '*.{txt,md}']
|
38
39
|
|
39
40
|
gem.require_paths = Array(gemspec.fetch('require_paths') {
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ronin-fuzzer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Postmodern
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: combinatorics
|
@@ -30,28 +30,28 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.0
|
33
|
+
version: '1.0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.0
|
40
|
+
version: '1.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: ronin-core
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0.1
|
47
|
+
version: '0.1'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.1
|
54
|
+
version: '0.1'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: bundler
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,9 +66,9 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '2.0'
|
69
|
-
description:
|
70
|
-
|
71
|
-
|
69
|
+
description: |
|
70
|
+
A Ruby library and CLI for generating, mutating, and fuzzing data.
|
71
|
+
The goal of ronin-fuzzer is to be both easy to use and highly customizable.
|
72
72
|
email: postmodern.mod3@gmail.com
|
73
73
|
executables:
|
74
74
|
- ronin-fuzzer
|
@@ -106,21 +106,15 @@ files:
|
|
106
106
|
- man/ronin-fuzzer-fuzz.1
|
107
107
|
- man/ronin-fuzzer-fuzz.1.md
|
108
108
|
- ronin-fuzzer.gemspec
|
109
|
-
- spec/core_ext/string_spec.rb
|
110
|
-
- spec/fuzzer_spec.rb
|
111
|
-
- spec/fuzzing_spec.rb
|
112
|
-
- spec/mutator_spec.rb
|
113
|
-
- spec/repeater_spec.rb
|
114
|
-
- spec/spec_helper.rb
|
115
|
-
- spec/template_spec.rb
|
116
109
|
homepage: https://ronin-rb.dev/
|
117
110
|
licenses:
|
118
111
|
- LGPL-3.0
|
119
112
|
metadata:
|
120
|
-
documentation_uri: https://
|
113
|
+
documentation_uri: https://ronin-rb.dev/docs/ronin-fuzzer
|
121
114
|
source_code_uri: https://github.com/ronin-rb/ronin-fuzzer
|
122
115
|
bug_tracker_uri: https://github.com/ronin-rb/ronin-fuzzer/issues
|
123
|
-
changelog_uri: https://github.com/ronin-rb/ronin-fuzzer/blob/
|
116
|
+
changelog_uri: https://github.com/ronin-rb/ronin-fuzzer/blob/main/ChangeLog.md
|
117
|
+
rubygems_mfa_required: 'true'
|
124
118
|
post_install_message:
|
125
119
|
rdoc_options: []
|
126
120
|
require_paths:
|
@@ -139,11 +133,5 @@ requirements: []
|
|
139
133
|
rubygems_version: 3.3.26
|
140
134
|
signing_key:
|
141
135
|
specification_version: 4
|
142
|
-
summary:
|
143
|
-
test_files:
|
144
|
-
- spec/core_ext/string_spec.rb
|
145
|
-
- spec/fuzzer_spec.rb
|
146
|
-
- spec/fuzzing_spec.rb
|
147
|
-
- spec/mutator_spec.rb
|
148
|
-
- spec/repeater_spec.rb
|
149
|
-
- spec/template_spec.rb
|
136
|
+
summary: A highly configurable fuzzing library and CLI for Ruby.
|
137
|
+
test_files: []
|
@@ -1,87 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'ronin/fuzzing/core_ext/string'
|
3
|
-
|
4
|
-
describe String do
|
5
|
-
it "should provide String.generate" do
|
6
|
-
expect(described_class).to respond_to(:generate)
|
7
|
-
end
|
8
|
-
|
9
|
-
it "should provide String#repeating" do
|
10
|
-
expect(subject).to respond_to(:repeating)
|
11
|
-
end
|
12
|
-
|
13
|
-
it "should provide String#fuzz" do
|
14
|
-
expect(subject).to respond_to(:fuzz)
|
15
|
-
end
|
16
|
-
|
17
|
-
it "should provide String#mutate" do
|
18
|
-
expect(subject).to respond_to(:mutate)
|
19
|
-
end
|
20
|
-
|
21
|
-
describe "generate" do
|
22
|
-
subject { described_class }
|
23
|
-
|
24
|
-
it "should generate Strings from a template" do
|
25
|
-
strings = subject.generate([:numeric, 2]).to_a
|
26
|
-
|
27
|
-
expect(strings.grep(/^[0-9]{2}$/)).to eq(strings)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
describe "#repeating" do
|
32
|
-
subject { 'A' }
|
33
|
-
|
34
|
-
context "when n is an Integer" do
|
35
|
-
let(:n) { 100 }
|
36
|
-
|
37
|
-
it "should multiply the String by n" do
|
38
|
-
expect(subject.repeating(n)).to eq(subject * n)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
context "when n is Enumerable" do
|
43
|
-
let(:n) { [128, 512, 1024] }
|
44
|
-
|
45
|
-
it "should repeat the String by each length" do
|
46
|
-
strings = subject.repeating(n).to_a
|
47
|
-
|
48
|
-
expect(strings).to eq(n.map { |length| subject * length })
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
describe "#fuzz" do
|
54
|
-
subject { "foo bar" }
|
55
|
-
|
56
|
-
it "should apply each fuzzing rule individually" do
|
57
|
-
strings = subject.fuzz(/o/ => ['O', '0'], /a/ => ['A', '@']).to_a
|
58
|
-
|
59
|
-
expect(strings).to match_array([
|
60
|
-
"fOo bar",
|
61
|
-
"f0o bar",
|
62
|
-
"foO bar",
|
63
|
-
"fo0 bar",
|
64
|
-
"foo bAr",
|
65
|
-
"foo b@r"
|
66
|
-
])
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
describe "#mutate" do
|
71
|
-
subject { "foo bar" }
|
72
|
-
|
73
|
-
it "should apply every combination of mutation rules" do
|
74
|
-
strings = subject.mutate(/o/ => ['0'], /a/ => ['@']).to_a
|
75
|
-
|
76
|
-
expect(strings).to match_array([
|
77
|
-
"f0o bar",
|
78
|
-
"fo0 bar",
|
79
|
-
"f00 bar",
|
80
|
-
"foo b@r",
|
81
|
-
"f0o b@r",
|
82
|
-
"fo0 b@r",
|
83
|
-
"f00 b@r"
|
84
|
-
])
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
data/spec/fuzzer_spec.rb
DELETED
@@ -1,109 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'ronin/fuzzing/fuzzer'
|
3
|
-
|
4
|
-
describe Ronin::Fuzzing::Fuzzer do
|
5
|
-
let(:string) { 'GET /one/two/three' }
|
6
|
-
|
7
|
-
describe "#initialize" do
|
8
|
-
subject { described_class }
|
9
|
-
|
10
|
-
context "patterns" do
|
11
|
-
let(:substitutions) { ['bar'] }
|
12
|
-
|
13
|
-
it "should accept Regexps" do
|
14
|
-
fuzzer = subject.new(/foo/ => substitutions)
|
15
|
-
|
16
|
-
expect(fuzzer.rules).to have_key(/foo/)
|
17
|
-
end
|
18
|
-
|
19
|
-
context "when given Strings" do
|
20
|
-
subject { described_class.new('foo' => substitutions) }
|
21
|
-
|
22
|
-
it "should convert to Regexp" do
|
23
|
-
expect(subject.rules).to have_key(/foo/)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
context "when given Symbols" do
|
28
|
-
subject { described_class.new(:word => substitutions) }
|
29
|
-
|
30
|
-
it "should lookup the Ronin::Support::Text::Patterns constant" do
|
31
|
-
expect(subject.rules).to have_key(Ronin::Support::Text::Patterns::WORD)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
context "otherwise" do
|
36
|
-
it "should raise a TypeError" do
|
37
|
-
expect {
|
38
|
-
subject.new(Object.new => substitutions)
|
39
|
-
}.to raise_error(TypeError)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
context "substitutions" do
|
45
|
-
let(:pattern) { /foo/ }
|
46
|
-
|
47
|
-
it "should accept Enumerable values" do
|
48
|
-
fuzzer = subject.new(pattern => ['bar'])
|
49
|
-
|
50
|
-
expect(fuzzer.rules[pattern]).to eq(['bar'])
|
51
|
-
end
|
52
|
-
|
53
|
-
context "when given Symbols" do
|
54
|
-
subject { described_class.new(pattern => :bad_strings) }
|
55
|
-
|
56
|
-
it "should map to an Enumerator for a Fuzzing method" do
|
57
|
-
expect(subject.rules[pattern]).to be_kind_of(Enumerable)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
context "otherwise" do
|
62
|
-
it "should raise a TypeError" do
|
63
|
-
expect {
|
64
|
-
subject.new(pattern => Object.new)
|
65
|
-
}.to raise_error(TypeError)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
describe "#each" do
|
72
|
-
let(:string) { "foo bar" }
|
73
|
-
|
74
|
-
subject { described_class.new(/o/ => ['O', '0'], /a/ => ['A', '@']) }
|
75
|
-
|
76
|
-
it "should apply each fuzzing rule individually" do
|
77
|
-
expect(subject.each(string).to_a).to match_array([
|
78
|
-
"fOo bar",
|
79
|
-
"f0o bar",
|
80
|
-
"foO bar",
|
81
|
-
"fo0 bar",
|
82
|
-
"foo bAr",
|
83
|
-
"foo b@r"
|
84
|
-
])
|
85
|
-
end
|
86
|
-
|
87
|
-
context "when mutations contain Integers" do
|
88
|
-
subject { described_class.new(/o/ => [48]) }
|
89
|
-
|
90
|
-
it "should convert them to characters" do
|
91
|
-
expect(subject.each(string).to_a).to match_array([
|
92
|
-
"f0o bar",
|
93
|
-
"fo0 bar"
|
94
|
-
])
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
context "when mutations contain Procs" do
|
99
|
-
subject { described_class.new(/o/ => [lambda { |str| str.upcase }]) }
|
100
|
-
|
101
|
-
it "should call them with the matched String" do
|
102
|
-
expect(subject.each(string).to_a).to match_array([
|
103
|
-
"fOo bar",
|
104
|
-
"foO bar"
|
105
|
-
])
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
data/spec/fuzzing_spec.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'ronin/fuzzing'
|
3
|
-
|
4
|
-
describe Ronin::Fuzzing do
|
5
|
-
describe "[]" do
|
6
|
-
let(:method) { :bad_strings }
|
7
|
-
|
8
|
-
it "should return Enumerators for fuzzing methods" do
|
9
|
-
expect(subject[method]).to be_kind_of(Enumerable)
|
10
|
-
end
|
11
|
-
|
12
|
-
it "should raise NoMethodError for unknown methods" do
|
13
|
-
expect {
|
14
|
-
subject[:foo]
|
15
|
-
}.to raise_error(NoMethodError)
|
16
|
-
end
|
17
|
-
|
18
|
-
it "should not allow accessing inherited methods" do
|
19
|
-
expect {
|
20
|
-
subject[:instance_eval]
|
21
|
-
}.to raise_error(NoMethodError)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
data/spec/mutator_spec.rb
DELETED
@@ -1,112 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'ronin/fuzzing/mutator'
|
3
|
-
|
4
|
-
describe Ronin::Fuzzing::Mutator do
|
5
|
-
let(:string) { 'GET /one/two/three' }
|
6
|
-
|
7
|
-
describe "#initialize" do
|
8
|
-
subject { described_class }
|
9
|
-
|
10
|
-
context "patterns" do
|
11
|
-
let(:substitutions) { ['bar'] }
|
12
|
-
|
13
|
-
it "should accept Regexps" do
|
14
|
-
fuzzer = subject.new(/foo/ => substitutions)
|
15
|
-
|
16
|
-
expect(fuzzer.rules).to have_key(/foo/)
|
17
|
-
end
|
18
|
-
|
19
|
-
context "when given Strings" do
|
20
|
-
subject { described_class.new('foo' => substitutions) }
|
21
|
-
|
22
|
-
it "should convert to Regexp" do
|
23
|
-
expect(subject.rules).to have_key(/foo/)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
context "when given Symbols" do
|
28
|
-
subject { described_class.new(:word => substitutions) }
|
29
|
-
|
30
|
-
it "should lookup the Ronin::Support::Text::Patterns constant" do
|
31
|
-
expect(subject.rules).to have_key(Ronin::Support::Text::Patterns::WORD)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
context "otherwise" do
|
36
|
-
it "should raise a TypeError" do
|
37
|
-
expect {
|
38
|
-
subject.new(Object.new => substitutions)
|
39
|
-
}.to raise_error(TypeError)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
context "mutations" do
|
45
|
-
let(:pattern) { /foo/ }
|
46
|
-
|
47
|
-
it "should accept Enumerable values" do
|
48
|
-
fuzzer = subject.new(pattern => ['bar'])
|
49
|
-
|
50
|
-
expect(fuzzer.rules[pattern]).to eq(['bar'])
|
51
|
-
end
|
52
|
-
|
53
|
-
context "when given Symbols" do
|
54
|
-
subject { described_class.new(pattern => :bad_strings) }
|
55
|
-
|
56
|
-
it "should map to an Enumerator for a Fuzzing method" do
|
57
|
-
expect(subject.rules[pattern]).to be_kind_of(Enumerable)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
context "otherwise" do
|
62
|
-
it "should raise a TypeError" do
|
63
|
-
expect {
|
64
|
-
subject.new(pattern => Object.new)
|
65
|
-
}.to raise_error(TypeError)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
describe "#each" do
|
72
|
-
let(:string) { "foo bar" }
|
73
|
-
|
74
|
-
subject { described_class.new(/o/ => ['0'], /a/ => ['@']) }
|
75
|
-
|
76
|
-
it "should apply every combination of mutation rules" do
|
77
|
-
expect(subject.each(string).to_a).to match_array([
|
78
|
-
"f0o bar",
|
79
|
-
"fo0 bar",
|
80
|
-
"f00 bar",
|
81
|
-
"foo b@r",
|
82
|
-
"f0o b@r",
|
83
|
-
"fo0 b@r",
|
84
|
-
"f00 b@r"
|
85
|
-
])
|
86
|
-
end
|
87
|
-
|
88
|
-
context "when mutations contain Integers" do
|
89
|
-
subject { described_class.new(/o/ => [48]) }
|
90
|
-
|
91
|
-
it "should convert them to characters" do
|
92
|
-
expect(subject.each(string).to_a).to match_array([
|
93
|
-
"f0o bar",
|
94
|
-
"fo0 bar",
|
95
|
-
"f00 bar"
|
96
|
-
])
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
context "when mutations contain Procs" do
|
101
|
-
subject { described_class.new(/o/ => [lambda { |str| str.upcase }]) }
|
102
|
-
|
103
|
-
it "should call them with the matched String" do
|
104
|
-
expect(subject.each(string).to_a).to match_array([
|
105
|
-
"fOo bar",
|
106
|
-
"foO bar",
|
107
|
-
"fOO bar"
|
108
|
-
])
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
data/spec/repeater_spec.rb
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'ronin/fuzzing/repeater'
|
3
|
-
|
4
|
-
describe Ronin::Fuzzing::Repeater do
|
5
|
-
describe "#initialize" do
|
6
|
-
subject { described_class }
|
7
|
-
|
8
|
-
context "when lengths is an Integer" do
|
9
|
-
it "should coerce lengths to an Enumerable" do
|
10
|
-
repeator = subject.new(10)
|
11
|
-
|
12
|
-
expect(repeator.lengths).to be_kind_of(Enumerable)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
context "when lengths is not Enumerable or an Integer" do
|
17
|
-
it "should raise a TypeError" do
|
18
|
-
expect {
|
19
|
-
subject.new(Object.new)
|
20
|
-
}.to raise_error(TypeError)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
describe "#each" do
|
26
|
-
let(:repeatable) { 'A' }
|
27
|
-
|
28
|
-
context "when lengths was an Integer" do
|
29
|
-
let(:length) { 10 }
|
30
|
-
|
31
|
-
subject { described_class.new(length) }
|
32
|
-
|
33
|
-
it "should yield one repeated value" do
|
34
|
-
values = subject.each(repeatable).to_a
|
35
|
-
|
36
|
-
expect(values).to eq([repeatable * length])
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
context "when lengths was Enumerable" do
|
41
|
-
let(:lengths) { (1..4) }
|
42
|
-
|
43
|
-
subject { described_class.new(lengths) }
|
44
|
-
|
45
|
-
it "should yield repeated values for each length" do
|
46
|
-
values = subject.each(repeatable).to_a
|
47
|
-
|
48
|
-
expect(values).to eq([
|
49
|
-
repeatable * 1,
|
50
|
-
repeatable * 2,
|
51
|
-
repeatable * 3,
|
52
|
-
repeatable * 4
|
53
|
-
])
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
data/spec/spec_helper.rb
DELETED
data/spec/template_spec.rb
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'ronin/fuzzing/template'
|
3
|
-
|
4
|
-
describe Ronin::Fuzzing::Template do
|
5
|
-
subject { described_class }
|
6
|
-
|
7
|
-
it "should generate Strings from CharSets" do
|
8
|
-
strings = subject.new([:lowercase_hexadecimal, :numeric]).to_a
|
9
|
-
|
10
|
-
expect(strings.grep(/^[0-9a-f][0-9]$/)).to eq(strings)
|
11
|
-
end
|
12
|
-
|
13
|
-
it "should generate Strings from lengths of CharSets" do
|
14
|
-
strings = subject.new([[:numeric, 2]]).to_a
|
15
|
-
|
16
|
-
expect(strings.grep(/^[0-9]{2}$/)).to eq(strings)
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should generate Strings from varying lengths of CharSets" do
|
20
|
-
strings = subject.new([[:numeric, 1..2]]).to_a
|
21
|
-
|
22
|
-
expect(strings.grep(/^[0-9]{1,2}$/)).to eq(strings)
|
23
|
-
end
|
24
|
-
|
25
|
-
it "should generate Strings from custom CharSets" do
|
26
|
-
strings = subject.new([[%w[a b c], 2]]).to_a
|
27
|
-
|
28
|
-
expect(strings.grep(/^[abc]{2}$/)).to eq(strings)
|
29
|
-
end
|
30
|
-
|
31
|
-
it "should generate Strings containing known Strings" do
|
32
|
-
strings = subject.new(['foo', [%w[a b c], 2]]).to_a
|
33
|
-
|
34
|
-
expect(strings.grep(/^foo[abc]{2}$/)).to eq(strings)
|
35
|
-
end
|
36
|
-
|
37
|
-
it "should raise a TypeError for non String, Symbol, Enumerable CharSets" do
|
38
|
-
expect {
|
39
|
-
subject.new([[Object.new, 2]]).to_a
|
40
|
-
}.to raise_error(TypeError)
|
41
|
-
end
|
42
|
-
|
43
|
-
it "should raise an ArgumentError for unknown CharSets" do
|
44
|
-
expect {
|
45
|
-
subject.new([[:foo_bar, 2]]).to_a
|
46
|
-
}.to raise_error(ArgumentError)
|
47
|
-
end
|
48
|
-
|
49
|
-
it "should raise a TypeError for non Integer,Array,Range lengths" do
|
50
|
-
expect {
|
51
|
-
subject.new([[:numeric, 'foo']]).to_a
|
52
|
-
}.to raise_error(TypeError)
|
53
|
-
end
|
54
|
-
end
|