Metafuzz: Building Boring Fuzzers Faster, Using Metadata

3,274 views

Published on

Metafuzz: Building Boring Fuzzers Faster, Using Metadata - Ben Nagy

Published in: Technology, Business
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,274
On SlideShare
0
From Embeds
0
Number of Embeds
59
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Metafuzz: Building Boring Fuzzers Faster, Using Metadata

  1. 1. Metafuzz 0.3 Building Boring Fuzzers, Faster Ben Nagy
  2. 2. This is not... <ul><li>A Fuzzer. It’s a framework for building fuzzers. </li></ul><ul><li>A Ruby port of Peach Fuzz. </li></ul><ul><li>Emergent, Genetic, Artificially Intelligent, Protocol Autoanalytic, Code Coverage Adaptive or Next Generation </li></ul><ul><li>100% done </li></ul><ul><li>(but it’s good enough for government work) </li></ul>
  3. 3. What’s included in 0.3 <ul><li>Four main components: </li></ul><ul><li>BinStruct </li></ul><ul><li>Define protocol data units (PDUs), also works as a half decent parser. Designed for packed binary structures, support hacked in at the last second for token separated text. </li></ul><ul><li>Generators </li></ul><ul><li>Some generator classes to help you create output streams that range from simple to as complex as you like. </li></ul><ul><li>Fuzzer </li></ul><ul><li>An example auto-fuzzer. It’s pretty simple, but has hooks for extension. If you don’t like it, keep the BinStruct class and write your own (and send me a copy). </li></ul><ul><li>FSA </li></ul><ul><li>A tool for creating finite state automata to automate and track state transitions for stateful protocols. </li></ul>
  4. 4. Generators <ul><li>Generators::Repeater </li></ul><ul><li>( Element, Start, Step, Limit, *Transforms ) </li></ul><ul><li># Example – Kickin’ It Old Skool </li></ul><ul><li>include Generators </li></ul><ul><li>g=Repeater.new(‘A’,0,256,10000,proc {|a| a.to_s}) </li></ul><ul><li>g.next => “AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...” </li></ul><ul><li># What’s with the proc {|a| a.to_s} ? </li></ul><ul><li># Proc object – a portable code block. In this </li></ul><ul><li># case,without it the output would be an Array at each </li></ul><ul><li># step. The framework uses these kinds of things a lot. </li></ul><ul><li># Equivalent: </li></ul><ul><li>g=Generators::Repeater.new(‘A’,0,256,10000) </li></ul><ul><li>g.next.to_s </li></ul>
  5. 5. Generators – Repeater <ul><li>Generators::Repeater </li></ul><ul><li>include Generators </li></ul><ul><li># Example - Dictionary </li></ul><ul><li>b33r=%w(asahi chang singha tiger kloster) </li></ul><ul><li>beerz=Repeater.new(b33r,1,1,1,proc {|a| a.to_s.capitalize}) </li></ul><ul><li>beerz.next => “Asahi” </li></ul><ul><li># Example – Incrementor </li></ul><ul><li>nums=Repeater.new((1..1000),1,1,1,proc {|a| a.first.succ * 8}) </li></ul><ul><li>nums.next => 16 </li></ul><ul><li># Example – Mutator </li></ul><ul><li>require ‘base64’ </li></ul><ul><li>g=Repeater.new(beerz,1,1,1,proc {|a| Base64.encode64 a.to_s}) </li></ul><ul><li>g.next => &quot;QXNhaGk= &quot; </li></ul>
  6. 6. Generators - Cartesian <ul><li>Generators::Cartesian </li></ul><ul><li># Example – Long Drinks </li></ul><ul><li>base=%w(black rum vodka gin whisky) </li></ul><ul><li>mix=%w(soda coke tonic lemonade beer) </li></ul><ul><li>drink=Generators::Cartesian.new(base, base, mix) </li></ul><ul><li>drink.next => [“black”, “black”, “soda”] </li></ul><ul><li># fuzzing bartenders </li></ul><ul><li>while drink.next? </li></ul><ul><li>order.base, order.extra, order.mixer = drink.next </li></ul><ul><li>bartender.send order.to_s </li></ul><ul><li>end </li></ul><ul><li># or </li></ul><ul><li>orderstring=“Give me a %s, %s and %s.” % drink.next </li></ul>
  7. 7. Generators - Cartesian <ul><li># Geek Moment – 3 line Ruby method for Cartesian Product </li></ul><ul><li>def cartprod(base, *others) </li></ul><ul><li>return base.map{|a|[a]} if others.empty? </li></ul><ul><li>others = cartprod(*others) </li></ul><ul><li>base.inject([]) { | r, a | </li></ul><ul><li>others.inject(r) { | r, b | </li></ul><ul><li>r << ([a, *b]) </li></ul><ul><li>} </li></ul><ul><li>} </li></ul><ul><li>end </li></ul><ul><li># (I didn’t write that, it was a guy called Brian Schr öder) </li></ul>
  8. 8. Generators - Other <ul><li>Some more useful Generators... </li></ul><ul><li>Generators::Chain(Generator, Generator, ...) </li></ul><ul><li>Generators::Static(Element, Limit, *Transforms) </li></ul><ul><li>md5salt=proc {|s| </li></ul><ul><li>OpenSSL::Digest::MD5.new( s + rand(256).chr ) </li></ul><ul><li>} </li></ul><ul><li>g=Generators::Static.new(“beer&quot;, 5, md5salt) </li></ul><ul><li>g.next => e2fc714c4727ee9395f324cd2e7f331f </li></ul><ul><li>g.next => dcc4a4d1992c0cd595454eb34b74e761 </li></ul><ul><li>Generators::BinaryCornerCases( Integer ) </li></ul><ul><li>BinaryCornerCases.new(16).to_a.map {|c| “%.16b” % c} </li></ul><ul><li>[&quot;1111111111111111&quot;, &quot;0000000000000000&quot;, &quot;1000000000000000&quot;, &quot;0000000000000001&quot;, </li></ul><ul><li>&quot;0111111111111111&quot;, &quot;1111111111111110&quot;, &quot;1100000000000000&quot;, &quot;0000000000000011&quot;, </li></ul><ul><li>&quot;0011111111111111&quot;, &quot;1111111111111100&quot;, &quot;1110000000000000&quot;, &quot;0000000000000111&quot;, </li></ul><ul><li>&quot;0001111111111111&quot;, &quot;1111111111111000&quot;, &quot;1010101010101010&quot;, &quot;0101010101010101&quot;] </li></ul>
  9. 9. “ Meta” <ul><li>What’s all this “meta” stuff? </li></ul><ul><li>Metadata – data about data. </li></ul><ul><li>The BinStruct field objects include metadata that lets us take a lot of the logic out of the output generator (fuzzer) so it can be made more generic </li></ul><ul><li>Metaprogramming – code that writes code. </li></ul><ul><li>When you inherit from the BinStruct class you can define your structure using a very abbreviated syntax </li></ul>
  10. 10. BinStruct - Definition <ul><li>class BeerReq < BinStruct </li></ul><ul><li>bitstring :flags, 8, &quot;Beer Flags&quot; </li></ul><ul><li>signed :temp, 8, &quot;Beer Temperature&quot; </li></ul><ul><li>unsigned :len, 8, &quot;Name Length&quot; </li></ul><ul><li>string :name, 'self.len * 8', &quot;Beer Name&quot; </li></ul><ul><li>string :extra, 32*8, &quot;Extra Beer Data&quot;, 'self.flags[0..0]==&quot;1&quot;' </li></ul><ul><li>end </li></ul>
  11. 11. BinStruct - Parsing <ul><li>class BeerReq < BinStruct </li></ul><ul><li>bitstring :flags, 8, &quot;Beer Flags&quot; </li></ul><ul><li>signed :temp, 8, &quot;Beer Temperature&quot; </li></ul><ul><li>unsigned :len, 8, &quot;Name Length&quot; </li></ul><ul><li>string :name, 'self.len * 8', &quot;Beer Name&quot; </li></ul><ul><li>string :extra, 32*8, &quot;Extra Beer Data&quot;, 'self.flags[0..0]==&quot;1&quot;' </li></ul><ul><li>end </li></ul><ul><li>data=&quot;20037705ASAHISuper Dry Beer From Japan but this is too long&quot; </li></ul><ul><li>BeerReq.new(data).inspect # data is shortened </li></ul><ul><li>Output: </li></ul><ul><li>Beer Flags: 10000000 </li></ul><ul><li>Beer Temperature: -1 </li></ul><ul><li>Name Length: 5 </li></ul><ul><li>Beer Name: ASAHI </li></ul><ul><li>Extra Beer Data: Super Dry Beer From Japan but th </li></ul>
  12. 12. BinStruct – Template PDUs <ul><li>class HTTPGet < BinStruct </li></ul><ul><li>string :op, 0, &quot;Operation&quot; </li></ul><ul><li>string :dir, 0, &quot;Directory&quot; </li></ul><ul><li>string :ver, 0, &quot;Version&quot; </li></ul><ul><li>separator ' ' </li></ul><ul><li>default_value :op, &quot;GET&quot; </li></ul><ul><li>default_value :dir, '/' </li></ul><ul><li>default_value :ver, &quot;HTTP/1.0 &quot; </li></ul><ul><li>end </li></ul><ul><li>req=HTTPGet.new </li></ul><ul><li>req.to_s ; req.op; req[:op] </li></ul><ul><li>“ GET / HTTP/1.0 ” </li></ul><ul><li>“ GET” </li></ul><ul><li>#<Fields::StringField:0x2754160 @desc=...> </li></ul>
  13. 13. BinStruct – Other Stuff <ul><li>Can create nested structures with add_child method, allows children to reference their parent object with self.parent </li></ul><ul><li>Can easily create new field classes with their own wrappers for packing / unpacking data </li></ul><ul><li>Can define new instance methods that only apply to objects of the new subclass. In other words, it’s not a config file, it’s normal Ruby code. </li></ul><ul><li>Can manually access and modify the internal array of Field objects, set the raw binary contents of fields to bypass sign checks etc. Feel free to shoot self.foot </li></ul>
  14. 14. Fuzzing time! <ul><li>class BeerReq < BinStruct </li></ul><ul><li>bitstring :flags, 8, &quot;Beer Flags&quot; </li></ul><ul><li>signed :temp, 8, &quot;Beer Temperature&quot; </li></ul><ul><li>unsigned :len, 8, &quot;Name Length&quot; </li></ul><ul><li>string :name, 'self.len * 8', &quot;Beer Name&quot; </li></ul><ul><li>string :extra, 32*8, &quot;Extra Beer Data&quot;, 'self.flags[0..0]==&quot;1&quot;' </li></ul><ul><li>end </li></ul><ul><li>require ‘fuzzer’ </li></ul><ul><li>beerfuzz=Fuzzer.new(BeerReq.new) </li></ul><ul><li>beerfuzz.basic_tests {|req| p req.to_s} </li></ul><ul><li>What will it do? </li></ul><ul><li>Enumerate numeric fields 8 bits or less, run corner cases on longer ones. Expand strings. </li></ul><ul><li>Delete each field </li></ul><ul><li>Insert overflow junk before each field, adapting to the field type </li></ul><ul><li>For text protocols, extend separators </li></ul>
  15. 15. Fuzzing - Fixups <ul><li>require ‘fuzzer’ </li></ul><ul><li>fixlen=proc {|req| req.len=req.name.length} </li></ul><ul><li>beerfuzz=Fuzzer.new(BeerReq.new, fixlen) </li></ul><ul><li>beerfuzz.basic_tests {|req| p req.to_s} </li></ul><ul><li>What will it do? </li></ul><ul><li>Fixups will be run, in order, on each new object before it is yielded to the block. </li></ul><ul><li>By default, the object will also be yielded unfixed, but you can tell it not to. </li></ul><ul><li>You can specify as many fixups as you want – eg to fix a length and then calculate a checksum afterwards </li></ul>
  16. 16. Fuzzing – Custom Fuzzing Code <ul><li>module Fields </li></ul><ul><li>class EmailField < StringField </li></ul><ul><li># no special behaviour </li></ul><ul><li>end </li></ul><ul><li>end </li></ul><ul><li>module Mutations </li></ul><ul><li># define a proc that creates a generator </li></ul><ul><li>Replacement_Generators[“email”]=proc {... </li></ul><ul><li>end </li></ul><ul><li>class Foo < BinStruct </li></ul><ul><li>email :eml, [...] </li></ul><ul><li>end </li></ul><ul><li>fuzz=Fuzzer.new(Foo) # All done. </li></ul>
  17. 17. Fuzzing – Custom Fuzzing Code <ul><li>Don’t forget: </li></ul><ul><li>Some protocols just need custom lovin’ </li></ul>
  18. 18. Finite State Automata
  19. 19. FSA – Building - Nodes <ul><li>require ‘fsa’ </li></ul><ul><li>class BeerOrder < FSA </li></ul><ul><li>node :init, root=true </li></ul><ul><li>node :ordered </li></ul><ul><li>node :accepted </li></ul><ul><li>node :paid </li></ul><ul><li>node :got_change </li></ul><ul><li>node :got_beer </li></ul><ul><li>end </li></ul><ul><li>Once the nodes are defined, we need to connect them with edges. </li></ul>
  20. 20. FSA – Building - Edges <ul><li>require ‘fsa’ </li></ul><ul><li>class BeerOrder < FSA </li></ul><ul><li>node :init, root=true </li></ul><ul><li>node :ordered </li></ul><ul><li>node :accepted </li></ul><ul><li>node :paid </li></ul><ul><li>node :got_change </li></ul><ul><li>node :got_beer </li></ul><ul><li>edge :init, :ordered, :send, proc {...} </li></ul><ul><li>edge :ordered, :accepted, :recv, proc, proc </li></ul><ul><li>... </li></ul><ul><li>Send edges have one block, which is an action block. Action blocks need to create or process the PDU, update state etc </li></ul><ul><li>Receive edges have a match block and an action block. Match blocks inspect data and say “is this data for me?” </li></ul>
  21. 21. FSA – Building - Blocks <ul><li>require ‘fsa’ </li></ul><ul><li>class BeerOrder < FSA </li></ul><ul><li>node :init, root=true </li></ul><ul><li>node :ordered </li></ul><ul><li>node :accepted </li></ul><ul><li>node :paid </li></ul><ul><li>node :got_change </li></ul><ul><li>node :got_beer </li></ul><ul><li>order=proc { </li></ul><ul><li>set_state( :ordered_beer, “Asahi” ) </li></ul><ul><li>BeerReq.new( &quot;000305Asahi” ) </li></ul><ul><li>} </li></ul><ul><li>beer_match=proc {|beer| </li></ul><ul><li>beer.name == get_state :ordered_beer </li></ul><ul><li>} </li></ul>
  22. 22. FSA - Using <ul><li>beer=BeerOrder.new </li></ul><ul><li>puts “At Node #{beer.current_node.name}&quot; </li></ul><ul><li>beer.navigate(beer.init, beer.ordered) </li></ul><ul><li>if beer.current_node.can_process? response </li></ul><ul><li>beer.deliver response </li></ul><ul><li>end </li></ul><ul><li>beer.state.inspect; beer.state[:ordered_beer] </li></ul><ul><li>beer.reset </li></ul><ul><li>You get the idea. </li></ul>
  23. 23. Not Done Yet <ul><li>Delivery – modular send and receive machinery that can be hooked up to the FSA for standard stuff like TCP, UDP, RAW etc </li></ul><ul><li>Automation – with an FSA and a set of BinStructs, traverse every node and fuzz every sendable packet. Not that hard, I just need to get around to remembering Djikstra’s Algorithm. </li></ul><ul><li>Linked Fields – allow user to link fields like Length, Value pairs so Fuzzer can test combinations. </li></ul><ul><li>Probably lots of other stuff I didn’t think of. </li></ul>
  24. 24. Questions? Feedback / Beer: bnagy@eeye.com

×