module Msf ### # # This module provides methods useful for developing fuzzers # ### module Auxiliary::Fuzzer # # Creates an instance of a fuzzer module # def initialize(info = {}) super register_advanced_options([ OptString.new('FuzzTracer', [ true, 'Sets the magic string to embed into fuzzer string inputs', 'MSFROCKS']), OptString.new('FuzzChar', [ true, 'Sets the character to use for generating long strings', 'X']) ], Msf::Auxiliary::Fuzzer) end # # Self-reflective iterators # def fuzz_numbers res = [] self.methods.sort.grep(/^fuzzer_number/).each do |m| @last_fuzzer_input = m block_given? ? self.send(m) {|x| yield(x) } : (res << self.send(m)) end res end def fuzz_strings res = [] self.methods.sort.grep(/^fuzzer_string/).each do |m| @last_fuzzer_input = m block_given? ? self.send(m) {|x| yield(x) } : (res << self.send(m)) end res end # # General input mangling routines # # Modify each byte of the string moving forward def fuzz_string_corrupt_byte(str,max=nil) res = [] 0.upto(max ? [max,str.length-1].min : (str.length - 1)) do |offset| 0.upto(255) do |val| @last_fuzzer_input = "fuzz_string_corrupt_byte offset:#{offset}/#{str.length} byte:#{val}" buf = str.dup buf[offset,1] = [val].pack('C') block_given? ? yield(buf) : (res << buf) end end res end # Modify each byte of the string moving backward def fuzz_string_corrupt_byte_reverse(str,max=nil) res = [] (max ? [max,str.length-1].min : (str.length - 1)).downto(0) do |offset| 0.upto(255) do |val| @last_fuzzer_input = "fuzz_string_corrupt_byte_reverse offset:#{offset}/#{str.length} byte:#{val}" buf = str.dup buf[offset,1] = [val].pack('C') block_given? ? yield(buf) : (res << buf) end end res end # # Useful generators (many derived from AxMan) # def fuzzer_string_format res = %W{ %s %p %n %x %@ %.257d %.65537d %.2147483648d %.257f %.65537f %.2147483648f} block_given? ? res.each { |n| yield(n) } : res end def fuzzer_string_filepath_dos res = %W{ aux con nul com1 com2 com3 com4 lpt1 lpt2 lp3 lpt4 prn } block_given? ? res.each { |n| yield(n) } : res end def fuzzer_number_power2 res = [ 0x100000000, 0x80000000, 0x40000000, 0x20000000, 0x10000000, 0x01000000, 0x00100000, 0x00010000, 0x00001000, 0x00000100, 0x00000010, 0x00000001 ] block_given? ? res.each { |n| yield(n) } : res end def fuzzer_number_power2_plus res = [] fuzzer_number_power2 do |num| res << num + 1 res << num + 2 res << num - 1 res << num - 2 res << num * -1 res << (num + 1) * -1 res << (num + 2) * -1 end block_given? ? res.each { |n| yield(n) } : res end def fuzzer_gen_string(len) @gen_string_block ||= datastore['FuzzChar'][0,1] * (1024 * 512) res = '' while (res.length < len) res += @gen_string_block end res[0,len] end def fuzzer_string_small res = [] 16.step(512,16) do |len| buf = fuzzer_gen_string(len) block_given? ? yield(buf) : (res << buf) end res end def fuzzer_string_long res = [] 64.step(8192,64) do |len| buf = fuzzer_gen_string(len) buf[len / 2, datastore['FuzzTracer'].length] = datastore['FuzzTracer'] block_given? ? yield(buf) : (res << buf) end res end def fuzzer_string_giant res = [] 512.step(65532 * 2, 512) do |len| buf = fuzzer_gen_string(len) buf[len / 2, datastore['FuzzTracer'].length] = datastore['FuzzTracer'] block_given? ? yield(buf) : (res << buf) end res end def fuzzer_string_uri_types res = %W{ aaa aaas about acap adiumxtra afp aim apt aw bolo callto cap chrome cid content crid cvs data dav designates dict disk dns doi ed2k example examples fax feed file finger fish ftp gg gizmoproject go gopher h323 hcp http https iax2 icap im imap info ipp irc ircs iris iris.beep iris.lws iris.xpc iris.xpcs itms jar javascript keyparc lastfm ldap ldaps lsid magnet mailto mid mms modem ms-help msnim msrp msrps mtqp mupdate mvn news nfs nntp notes opaquelocktoken over pop pres prospero psyc res rlogin rmi rsync rtsp secondlife service sftp sgn shell shttp sip sips skype smb sms snews snmp soap.beep soap.beeps soldat ssh steam svn tag teamspeak tel telephone telnet tftp thismessage tip tv unreal urn ut2004 vbscript vemmi ventrilo view-source wais webcal worldwind wtai wyciwyg wysiwyg xfire xmlrpc.beep xmpp xri ymsgr z39.50r z39.50s } block_given? ? res.each { |n| yield(n) } : res end def fuzzer_string_uri_dividers res = %W{ : :// } block_given? ? res.each { |n| yield(n) } : res end def fuzzer_string_path_prefixes res = %W{ C:\\ \\\\localhost\\ / } block_given? ? res.each { |n| yield(n) } : res end def fuzzer_string_uris_small res = [] fuzzer_string_uri_types do |proto| fuzzer_string_uri_dividers do |div| fuzzer_string_small do |str| buf = proto + div + str block_given? ? yield(buf) : (res << buf) end end end res end def fuzzer_string_uris_long res = [] fuzzer_string_uri_types do |proto| fuzzer_string_uri_dividers do |div| fuzzer_string_long do |str| buf = proto + div + str block_given? ? yield(buf) : (res << buf) end end end res end def fuzzer_string_uris_giant res = [] fuzzer_string_uri_types do |proto| fuzzer_string_uri_dividers do |div| fuzzer_string_giant do |str| buf = proto + div + str block_given? ? yield(buf) : (res << buf) end end end res end def fuzzer_string_uris_format res = [] fuzzer_string_uri_types do |proto| fuzzer_string_uri_dividers do |div| fuzzer_string_format do |str| buf = proto + div + str block_given? ? yield(buf) : (res << buf) end end end res end def fuzzer_string_uris_dos res = [] fuzzer_string_uri_types do |proto| fuzzer_string_uri_dividers do |div| fuzzer_string_filepath_dos do |str| buf = proto + div + str block_given? ? yield(buf) : (res << buf) end end end res end def fuzzer_string_paths_small res = [] fuzzer_string_path_prefixes do |pre| fuzzer_string_small do |str| buf = pre + str block_given? ? yield(buf) : (res << buf) end end res end def fuzzer_string_paths_long res = [] fuzzer_string_path_prefixes do |pre| fuzzer_string_long do |str| buf = pre + str block_given? ? yield(buf) : (res << buf) end end res end def fuzzer_string_paths_giant res = [] fuzzer_string_path_prefixes do |pre| fuzzer_string_giant do |str| buf = pre + str block_given? ? yield(buf) : (res << buf) end end res end def fuzzer_string_paths_format res = [] fuzzer_string_path_prefixes do |pre| fuzzer_string_format do |str| buf = pre + str block_given? ? yield(buf) : (res << buf) end end res end def fuzzer_string_paths_dos res = [] fuzzer_string_path_prefixes do |pre| fuzzer_string_filepath_dos do |str| buf = pre + str block_given? ? yield(buf) : (res << buf) end end res end end end