ronin-fuzzer 0.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,109 @@
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
@@ -0,0 +1,24 @@
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
@@ -0,0 +1,112 @@
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
@@ -0,0 +1,57 @@
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
@@ -0,0 +1,4 @@
1
+ require 'rspec'
2
+ require 'simplecov'
3
+
4
+ SimpleCov.start
@@ -0,0 +1,54 @@
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
metadata ADDED
@@ -0,0 +1,149 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ronin-fuzzer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.beta1
5
+ platform: ruby
6
+ authors:
7
+ - Postmodern
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-01-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: combinatorics
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: ronin-support
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.0.beta1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.0.0.beta1
41
+ - !ruby/object:Gem::Dependency
42
+ name: ronin-core
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.1.0.beta1
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.1.0.beta1
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.0'
69
+ description: 'A Ruby library for generating, mutating, and fuzzing data.
70
+
71
+ '
72
+ email: postmodern.mod3@gmail.com
73
+ executables:
74
+ - ronin-fuzzer
75
+ extensions: []
76
+ extra_rdoc_files:
77
+ - COPYING.txt
78
+ - ChangeLog.md
79
+ - README.md
80
+ files:
81
+ - ".document"
82
+ - ".github/workflows/ruby.yml"
83
+ - ".gitignore"
84
+ - ".rspec"
85
+ - ".ruby-version"
86
+ - ".yardopts"
87
+ - COPYING.txt
88
+ - ChangeLog.md
89
+ - Gemfile
90
+ - README.md
91
+ - Rakefile
92
+ - bin/ronin-fuzzer
93
+ - gemspec.yml
94
+ - lib/ronin/fuzzer/cli.rb
95
+ - lib/ronin/fuzzer/cli/command.rb
96
+ - lib/ronin/fuzzer/cli/commands/fuzz.rb
97
+ - lib/ronin/fuzzer/root.rb
98
+ - lib/ronin/fuzzer/version.rb
99
+ - lib/ronin/fuzzing.rb
100
+ - lib/ronin/fuzzing/core_ext.rb
101
+ - lib/ronin/fuzzing/core_ext/string.rb
102
+ - lib/ronin/fuzzing/fuzzer.rb
103
+ - lib/ronin/fuzzing/mutator.rb
104
+ - lib/ronin/fuzzing/repeater.rb
105
+ - lib/ronin/fuzzing/template.rb
106
+ - man/ronin-fuzzer-fuzz.1
107
+ - man/ronin-fuzzer-fuzz.1.md
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
+ homepage: https://ronin-rb.dev/
117
+ licenses:
118
+ - LGPL-3.0
119
+ metadata:
120
+ documentation_uri: https://rubydoc.info/gems/ronin-fuzzer
121
+ source_code_uri: https://github.com/ronin-rb/ronin-fuzzer
122
+ bug_tracker_uri: https://github.com/ronin-rb/ronin-fuzzer/issues
123
+ changelog_uri: https://github.com/ronin-rb/ronin-fuzzer/blob/master/ChangeLog.md
124
+ post_install_message:
125
+ rdoc_options: []
126
+ require_paths:
127
+ - lib
128
+ required_ruby_version: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: 3.0.0
133
+ required_rubygems_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ requirements: []
139
+ rubygems_version: 3.3.26
140
+ signing_key:
141
+ specification_version: 4
142
+ summary: generate, mutate, and fuzz data
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