ronin-support 0.5.0.rc1 → 0.5.0.rc2

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.
@@ -20,6 +20,6 @@
20
20
  module Ronin
21
21
  module Support
22
22
  # ronin-support version
23
- VERSION = '0.5.0.rc1'
23
+ VERSION = '0.5.0.rc2'
24
24
  end
25
25
  end
@@ -17,8 +17,9 @@
17
17
  # along with Ronin Support. If not, see <http://www.gnu.org/licenses/>.
18
18
  #
19
19
 
20
+ require 'ronin/fuzzing/template'
21
+ require 'ronin/fuzzing/mutator'
20
22
  require 'ronin/extensions/regexp'
21
- require 'ronin/fuzzing/extensions'
22
23
 
23
24
  require 'set'
24
25
 
@@ -224,12 +225,16 @@ module Ronin
224
225
  def each(&block)
225
226
  return enum_for(:each) unless block
226
227
 
228
+ mutator = unless @mutations.empty?
229
+ Fuzzing::Mutator.new(@mutations)
230
+ end
231
+
227
232
  each_word do |word|
228
233
  yield word
229
234
 
230
- unless @mutations.empty?
235
+ if mutator
231
236
  # perform additional mutations
232
- word.mutate(@mutations,&block)
237
+ mutator.each(word,&block)
233
238
  end
234
239
  end
235
240
  end
@@ -252,7 +257,7 @@ module Ronin
252
257
  # @api public
253
258
  #
254
259
  def each_n_words(n,&block)
255
- String.generate([each, n],&block)
260
+ Fuzzing::Template[[each, n]].each(&block)
256
261
  end
257
262
 
258
263
  #
@@ -0,0 +1,87 @@
1
+ require 'spec_helper'
2
+ require 'ronin/fuzzing/extensions/string'
3
+
4
+ describe String do
5
+ it "should provide String.generate" do
6
+ described_class.should respond_to(:generate)
7
+ end
8
+
9
+ it "should provide String#repeating" do
10
+ subject.should respond_to(:repeating)
11
+ end
12
+
13
+ it "should provide String#fuzz" do
14
+ subject.should respond_to(:fuzz)
15
+ end
16
+
17
+ it "should provide String#mutate" do
18
+ subject.should 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
+ strings.grep(/^[0-9]{2}$/).should == 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
+ subject.repeating(n).should == (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
+ strings.should == 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
+ strings.should =~ [
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
+ strings.should =~ [
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
@@ -0,0 +1,109 @@
1
+ require 'spec_helper'
2
+ require 'ronin/fuzzing/fuzzer'
3
+
4
+ describe 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
+ fuzzer.rules.should 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
+ subject.rules.should 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 Regexp constant" do
31
+ subject.rules.should have_key(Regexp::WORD)
32
+ end
33
+ end
34
+
35
+ context "otherwise" do
36
+ it "should raise a TypeError" do
37
+ lambda {
38
+ subject.new(Object.new => substitutions)
39
+ }.should 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
+ fuzzer.rules[pattern].should == ['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
+ subject.rules[pattern].should be_kind_of(Enumerable)
58
+ end
59
+ end
60
+
61
+ context "otherwise" do
62
+ it "should raise a TypeError" do
63
+ lambda {
64
+ subject.new(pattern => Object.new)
65
+ }.should 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
+ subject.each(string).to_a.should =~ [
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
+ subject.each(string).to_a.should =~ [
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
+ subject.each(string).to_a.should =~ [
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/fuzzing'
3
+
4
+ describe Fuzzing do
5
+ describe "[]" do
6
+ let(:method) { :bad_strings }
7
+
8
+ it "should return Enumerators for fuzzing methods" do
9
+ subject[method].should be_kind_of(Enumerable)
10
+ end
11
+
12
+ it "should raise NoMethodError for unknown methods" do
13
+ lambda {
14
+ subject[:foo]
15
+ }.should raise_error(NoMethodError)
16
+ end
17
+
18
+ it "should not allow accessing inherited methods" do
19
+ lambda {
20
+ subject[:instance_eval]
21
+ }.should 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 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
+ fuzzer.rules.should 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
+ subject.rules.should 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 Regexp constant" do
31
+ subject.rules.should have_key(Regexp::WORD)
32
+ end
33
+ end
34
+
35
+ context "otherwise" do
36
+ it "should raise a TypeError" do
37
+ lambda {
38
+ subject.new(Object.new => substitutions)
39
+ }.should 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
+ fuzzer.rules[pattern].should == ['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
+ subject.rules[pattern].should be_kind_of(Enumerable)
58
+ end
59
+ end
60
+
61
+ context "otherwise" do
62
+ it "should raise a TypeError" do
63
+ lambda {
64
+ subject.new(pattern => Object.new)
65
+ }.should 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
+ subject.each(string).to_a.should =~ [
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
+ subject.each(string).to_a.should =~ [
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
+ subject.each(string).to_a.should =~ [
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 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
+ repeator.lengths.should 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
+ lambda {
19
+ subject.new(Object.new)
20
+ }.should 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
+ values.should == [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.should
47
+
48
+ values.should == [
49
+ repeatable * 1,
50
+ repeatable * 2,
51
+ repeatable * 3,
52
+ repeatable * 4
53
+ ]
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+ require 'ronin/fuzzing/template'
3
+
4
+ describe 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
+ strings.grep(/^[0-9a-f][0-9]$/).should == strings
11
+ end
12
+
13
+ it "should generate Strings from lengths of CharSets" do
14
+ strings = subject.new([[:numeric, 2]]).to_a
15
+
16
+ strings.grep(/^[0-9]{2}$/).should == 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
+ strings.grep(/^[0-9]{1,2}$/).should == 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
+ strings.grep(/^[abc]{2}$/).should == 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
+ strings.grep(/^foo[abc]{2}$/).should == strings
35
+ end
36
+
37
+ it "should raise a TypeError for non String, Symbol, Enumerable CharSets" do
38
+ lambda {
39
+ subject.new([[Object.new, 2]]).to_a
40
+ }.should raise_error(TypeError)
41
+ end
42
+
43
+ it "should raise an ArgumentError for unknown CharSets" do
44
+ lambda {
45
+ subject.new([[:foo_bar, 2]]).to_a
46
+ }.should raise_error(ArgumentError)
47
+ end
48
+
49
+ it "should raise a TypeError for non Integer,Array,Range lengths" do
50
+ lambda {
51
+ subject.new([[:numeric, 'foo']]).to_a
52
+ }.should raise_error(TypeError)
53
+ end
54
+ end