Created
May 12, 2009 21:33
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'benchmark' | |
require 'block_fuzzer' | |
fuzz = SophSec::BlockFuzzer.new('_' * 86, 'EVIL', 4) | |
puts Benchmark.measure { fuzz.each { |mutant| } } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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