# # Copyright (c) 2006-2012 Hal Brodigan (postmodern.mod3 at gmail.com) # # This file is part of Ronin Support. # # Ronin Support is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published # by the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Ronin Support is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with Ronin Support. If not, see . # require 'ronin/fuzzing/template' require 'ronin/fuzzing/repeater' require 'ronin/fuzzing/fuzzer' require 'ronin/fuzzing/mutator' require 'ronin/fuzzing/fuzzing' require 'ronin/extensions/regexp' class String # # Generate permutations of Strings from a format template. # # @param [Array(, )] fields # The fields which defines the string or character sets which will # make up parts of the String. # # @yield [string] # The given block will be passed each unique String. # # @yieldparam [String] string # A newly generated String. # # @return [Enumerator] # If no block is given, an Enumerator will be returned. # # @raise [ArgumentError] # A given character set name was unknown. # # @raise [TypeError] # A given string set was not a String, Symbol or Enumerable. # A given string set length was not an Integer or Enumerable. # # @example Generate Strings with ranges of repeating sub-strings: # # @example Generate Strings with three alpha chars and one numeric chars: # String.generate([:alpha, 3], :numeric) do |password| # puts password # end # # @example Generate Strings with two to four alpha chars: # String.generate([:alpha, 2..4]) do |password| # puts password # end # # @example Generate Strings using alpha and punctuation chars: # String.generate([Chars.alpha + Chars.punctuation, 4]) do |password| # puts password # end # # @example Generate Strings from a custom char set: # String.generate([['a', 'b', 'c'], 3], [['1', '2', '3'], 3]) do |password| # puts password # end # # @example Generate Strings containing known Strings: # String.generate("rock", [:numeric, 4]) do |password| # puts password # end # # @example Generate Strings with ranges of repeating sub-strings: # String.generate(['/AA', (1..100).step(5)]) do |path| # puts path # end # # @since 0.3.0 # # @api public # def self.generate(*fields,&block) Ronin::Fuzzing::Template.new(fields).each(&block) end # # Repeats the String. # # @param [Enumerable, Integer] lengths # The number of times to repeat the String. # # @yield [repeated] # The given block will be passed every repeated String. # # @yieldparam [String] repeated # A repeated version of the String. # # @return [Enumerator] # If no block is given, an Enumerator will be returned. # # @raise [TypeError] # `n` must either be Enumerable or an Integer. # # @example # 'A'.repeating(100) # # => "AAAAAAAAAAAAA..." # # @example Generates 100 upto 700 `A`s, increasing by 100 at a time: # 'A'.repeating((100..700).step(100)) do |str| # # ... # end # # @example Generates 128, 1024, 65536 `A`s: # 'A'.repeating([128, 1024, 65536]) do |str| # # ... # end # # @api public # # @since 0.4.0 # def repeating(lengths,&block) case lengths when Integer # if lengths is an Integer, simply multiply the String and return repeated = (self * lengths) yield repeated if block_given? return repeated else return Ronin::Fuzzing::Repeater.new(lengths).each(self,&block) end end # # Incrementally fuzzes the String. # # @param [Hash{Regexp,String => #each}] substitutions # Patterns and their substitutions. # # @yield [fuzz] # The given block will be passed every fuzzed String. # # @yieldparam [String] fuzz # A fuzzed String. # # @return [Enumerator] # If no block is given, an Enumerator will be returned. # # @example Replace every `e`, `i`, `o`, `u` with `(`, 100 `A`s and a `\0`: # "the quick brown fox".fuzz(/[eiou]/ => ['(', ('A' * 100), "\0"]) do |str| # p str # end # # @example {String.generate} with {String#fuzz}: # "GET /".fuzz('/' => String.generate(['A', 1..100])) do |str| # p str # end # # @since 0.3.0 # # @api public # def fuzz(substitutions={},&block) Ronin::Fuzzing::Fuzzer.new(substitutions).each(self,&block) end # # Permutes over every possible mutation of the String. # # @param [Hash{Regexp,String,Symbol => Symbol,Enumerable}] mutations # The patterns and substitutions to mutate the String with. # # @yield [mutant] # The given block will be yielded every possible mutant String. # # @yieldparam [String] mutant # A mutated String. # # @return [Enumerator] # If no block is given, an Enumerator will be returned. # # @raise [TypeError] # A mutation pattern was not a Regexp, String or Symbol. # A mutation substitution was not a Symbol or Enumerable. # # @example # "hello old dog".mutate('e' => ['3'], 'l' => ['1'], 'o' => ['0']) do |str| # puts str # end # # @since 0.4.0 # # @api public # def mutate(mutations={},&block) Ronin::Fuzzing::Mutator.new(mutations).each(self,&block) end end