Skip to content

Instantly share code, notes, and snippets.

@postmodern
Created May 12, 2009 21:33
Show Gist options
  • Save postmodern/110746 to your computer and use it in GitHub Desktop.
Save postmodern/110746 to your computer and use it in GitHub Desktop.
A simple example showing that it's not hard to write fuzzers in Ruby.
require 'benchmark'
require 'block_fuzzer'
fuzz = SophSec::BlockFuzzer.new('_' * 86, 'EVIL', 4)
puts Benchmark.measure { fuzz.each { |mutant| } }
module SophSec
class BlockFuzzer
include Enumerable
# Data to fuzz
attr_accessor :data
# Evil data to inject
attr_accessor :evil
# Padding between injected data
attr_accessor :padding
#
# Creates a new BlockFuzzer object using the specified _data_,
# _evil_ data to inject and option _padding_ between injected
# _evil_ data. If a _block_ is given, it will be passed the
# newly created fuzzer.
#
# fuzzer = BlockFuzzer.new('_' * 48, 'EVIL', 4)
#
def initialize(data,evil,padding=0,&block)
@data = data.to_s
@evil = evil.to_s
@padding = padding
block.call(self) if block
end
#
# Calculates all possible indices for injecting evil data, with
# specified padding between injected blocks, within the original data.
#
# require 'pp'
#
# all_indices do |indices|
# pp indices
# end
#
def all_indices(&block)
l = @data.length # length of data
b = @evil.length # length of evil data
p = @padding # padding between injected data blocks
build_indices = lambda { |n,i,indices|
# n = number of blocks to use
# i = starting index
# indices = previous indices
unless n == 0
(i..(l-(((b+p)*n)-p))).each do |j|
build_indices.call(n-1,j+b+p,indices + [j])
end
else
block.call(indices)
end
}
(1..((l / (b+p))+1)).each do |n| # n = number of blocks
build_indices.call(n,0,[])
end
return nil
end
#
# Mutates the original data, injecting the evil data while maintaining
# padding between the injected blocks of evil data. Each mutation
# of the original data will be passed to the given _block_.
#
# each |mutant|
# puts mutant
# end
#
def each(&block)
all_indices do |indices|
mutant = @data.dup
indices.each { |i| mutant[i,@evil.length] = @evil }
block.call(mutant)
end
end
#
# Prints out each mutation of the original data.
#
def print_mutations
each { |mutant| puts mutant }
end
#
# Saves each mutation of the original data to the specified _path_.
#
def save_mutations(path)
File.open(path,'w') do |file|
each { |mutant| file.puts mutant }
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment