1 Ruby For Penetration Testers - Black Hat

Transcription

1RUBY FOR PENETRATION TESTERSruby for penetr at ion testersWhen you're down deep reversing a protocolor picking apart a binary, getting up to speedquickly can be challenging in the best ofcircumstances. Over the past few years, we'vefigured out a tool that we can rely on everytime: the Ruby programming language. We'dlike to highlight our use of Ruby to solve thesecurity testing problems we're faced withevery day.We use Ruby because it’s easy, flexible, andpowerful. It works for everything from reverseengineering firmware bus protocols to fuzzingfile formats to static and dynamic binaryanalysis. We've used it to beat up web apps,and we've stuck with it all the way to attackingexotic proprietary hardware applications.Having a great set of tools available to meetyour needs might be the difference between asuccessful result for your customer andupdating your resume with the details of yourformer employer.Not familiar with Ruby? None of us wereeither on that fateful day when Dino Dai Zovideclared Python “the language of over the hillhackers”. But we were surprised at how easyRuby was to pick up. So we'll lead off byillustrating why Ruby is so powerful, making acase for rapidly prototyping everything fromreversing tools to hacked up network clientsusing our not-so-patented “bag-o-tricks”approach.Then we dive into our real-world experiencesusing Ruby to quickly get up and running on awide range of tasks, including: Ripping apart static binaries and bendingthem to your will Getting up close and personal withproprietary file formats Becoming the puppet-master of both nativeand Java applications atruntime Exposing the most intimate parts of exoticnetwork services like JRMI and Web services Trimming the time you spend decodingproprietary protocols and cutting directly tofuzzing themAs if all that wasn’t enough, we'll show youhow to make Ruby mash-ups of the stuff youalready love. Make the tools you already relyon new again by getting them to worktogether, harder and smarter. When you'reasked to get twice as much done in half thetime, smile confidently knowing you have asecret weapon and the job will get done.WHY WE LIKE RUBYYou wouldn’t be reading this white paper orattending our talk unless you already knewsome kind of scripting language. So theeasiest way to help you “get” Ruby is tocompare it to other languages.The language everyone compares Ruby to isPython. You can Bing “Ruby vs. Python” andfind 1,000 good shootouts. Most of them aregoing to point out the most important fact:Ruby and Python are remarkably similarlanguages, to the point where you can readilyport code between them. If you're apentester, here are some of the bigdifferences you'll care about: Ruby has “blocks”, which are a notation fordefining functions on the fly without naming

2DOCUMENT TITLEthem; you can stuff them into variables andpass them around. This is huge: it allowsyou to define domain-specific languagesand new control structures, and it’sabsolutely killer for writing asynchronousnetwork code. Python is faster than Ruby. Not a little bitfaster. A lot faster. But Ruby has first-class regular expressions,using the /regex/ syntax borrowed fromPerl. This means regexes are insanely easyto use in Ruby. You don’t have to “import”them from a library or instantiate classes. Python has a huge, sprawling standardlibrary. Ruby has a smaller, tighter standardlibrary.Yes, Ruby has some syntax borrowed fromPerl. Yes, this is a scary idea. But you don’tcare: the regex syntax is good, and the rest ofit you can pretend doesn’t exist. Nobodywrites Ruby code that looks like Perl.Mike Tracy, god help him, came to Matasanofrom Tcl. Tcl and Ruby are surprisingly similar:you can call Ruby “Japanese Tcl” and defendthat name long enough to upset a Railsprogrammer. Go ahead, try it! Rubyprogrammers use blocks for a lot of the samethings that Tcl programmers use “uplevel” for,and the Ruby object model is very similar to[incr Tcl].All these dynamic languages are flexible. Rubyallows us to rapidly prototype tools forvulnerability exploitation, protocol fuzzing,reverse engineering and everything inbetween. Many of the tools we develop inRuby are easily hooked into one anotherwhich can further speed up tool developmentand promotes code reuse.Ruby has an answer to almost every situationwhere we would want to develop customcode to solve a problem: We can redefine portions of the library with“monkey patches”, for instance to allow allNumeric types to render as bignums. We can call low-level C libraries with Ruby/DL, FFI, or Win32ole. Or we can wrap thelibrary directly by extending the Rubyinterpreter. We can even add Ruby into existing toolswritten in languages like C. Ruby allows us to easily create DSL (DomainSpecific Language) frameworks like Ruckus,where defining complex structures is donein code, not complex configuration files.WHO ELSE IS USING RUBY?Ever hear of Metasploit? Metasploit may beone of the largest Ruby projects in existenceand arguably in the most popular list of Rubyframeworks. Metasploit makes advancedexploitation of vulnerabilities possible througheasy to use interfaces, payloads and tools. Allof this great stuff is also supported onmultiple platforms thanks to Ruby.Metasm is another powerful Ruby frameworkfor compiling, disassembling and debuggingnative code from Ruby. Metasm is includedwith the Metasploit framework as well.Ronin is another Ruby framework written withsecurity and data exploration in mind. Roninprovides convienence methods for an array ofdifferent protocols that penetration testersmight find useful.

3SCRIPTED PENETRATION TESTINGDOCUMENT TITLEYour first question about whether a languageis good for pentesting is, “how does it handleweb work”. Our answer: WWMD.WWMD is a console for breaking webapplications. It’s like “pentesting Expect”: it’ssomething in between a programmingenvironment and a console.WWMD isn’t intended to be just another ofthe myriad tools used to conduct webapplication security assessments. Its goal is toprovide an easily accessible scriptingframework that includes the basic elements ofa web testing tool (transport and parsing) andcombine them with convenience methods thatmake manual and automated testing taskseasier. Working either in IRB or from scripts,it’s a snap to create powerful tools that takecare of the time consuming and repetitivestuff and help you with the more subtle andadvanced things you need to get done.WWMD relies on Ruby and some greatlibraries for its base. Even if you're not goingto use WWMD, you should know about: Curb, which provides libcurl bindings forRuby, which we use for our raw HTTPtransport. Nokogiri, for parsing HTML documents.Curb and Nokogiri are extremely excellentlibraries, each of them reason enough tospend some time learning Ruby.To this, WWMD adds methods for everythingfrom manipulating headers and applicationinputs to encodings. It also includes a patchto Curb to allow sending requests usingarbitrary methods (OPTIONS, TRACE,RANDOM). All of the behaviors of the basePage object can be easily modified on a per-application basis using mixins and monkeypatches that are specific to your engagement.It also includes a ViewState (de)serializerthat outputs to and reads in from XML. Ifyou've never fuzzed ViewState before(working on one of the 4% of webapplications out there that don’t haveEnableViewStateMac true?) then this is yourhuckleberry. Another interesting use for theViewState deserializer is to programaticallybase64 decode BinarySerialized() (customserializations of objects like Telerik controls)that you'll find in many web applications.Before WWMD, I had to do all that work byhand.A simple login example:wwmd(main):003:0 page Page.new();nil nilwwmd(main):004:0 page.baseurl “http://www.example.com” “http://www.example.com”wwmd(main):005:0 page.get “http://www.example.com/example/” [200, 663]wwmd(main):006:0 page.text “Login:\nPassword:\n”wwmd(main):007:0 form page.getform [[“username”, nil], [“password”,nil]]wwmd(main):008:0 form[‘username’] “jqpublic” “jqpublic”wwmd(main):011:0 form[‘password’] “password” “password”wwmd(main):012:0 page.submit form [200, 2117]wwmd(main):013:0 page.bodydata.match(/you are loggedin.*/)[0].striphtml “you are logged in as jqpublic[logout]”wwmd(main):014:0

4DOCUMENT TITLEEver see a web form that takes an argumentlike:args key value;key value;key valueInstead of just fuzzing the form variable, youcan simply create a copy of the FormArrayclass that uses and ; as delimiters and fuzzeverything:wwmd(main):006:0 form FormArray.new [] wwmd(main):007:0 cust FormArray.new []wwmd(main):008:0 cust.delimiter “;” “;”wwmd(main):009:0 cust.equals “ ” “ ”wwmd(main):010:0 �,“val2”],[“key3”,“val3”]]) [[“key1”, “val1”], [“key2”,“val2”], [“key3”, “val3”]]wwmd(main):011:0 cust.topost “key1 val1;key2 val2;key3 val3”wwmd(main):012:0 form[‘args’] cust.topost “key1 val1;key2 val2;key3 val3”wwmd(main):013:0 form[‘test’] “value” “test”wwmd(main):014:0 form.topost “args key1 val1;key2 val2;key3 val3&test value”WWMD is available on github (http://github.com/miketracy/wwmd/tree/master)and remember, swiss army knives don’t killpeople but 15 different sharp things can’thurt.REVERSINGReverse engineering has taken a front seat invulnerability research and penetration testingover the last few years. Often a penetrationtester may be tasked with reversingproprietary network protocols or closedsource binaries in a relatively short amount oftime.Ruby enables this kind of rapid tooldevelopment whether the goal is breakingopen a custom network protocols headerstructure and de-obfuscating its payload orfinding that backdoor in a compiledexecutable. We have developed tools to doboth these kinds of things.NETWORK PROTOCOLSBeing able to transparently intercept andmodify network traffic is a great advantage toa penetration tester tasked with finding bugsin a proprietary network protocol. Not alloperating systems have well defined supportfor this type of behavior. We have developeda few OS-indepedent inline proxy tools tohelp ease the process of attacking protocolsin this way.These tools are available in our ‘RubyBlackBag (rbkb)’ distribution and are named‘blit’, ‘telson’, ‘plugsrv’ and ‘feed’. They worktogether to allow for inline network trafficmodification and inspection. blit: a simple OOB (Out Of Band) IPC (InterProcess Communication)mechanism for sending messages to blitenabled tools. telson: is responsible for setting up networkconnections andlistening for commands from blit enabledclients

5DOCUMENT TITLE plugsrv: is a reverse TCP/UDP proxybetween one or more connectionsquick and easy String class monkey patch toxor bytes against a ‘key’ may look like this: feed: a blit capable tool that feeds files toblit enabled servers1 def xor(k)2s self3out StringIO.new ; i 0;4s.each byte do x 5out.write((x (k[i] k[i 0]) ).chr)6i 17end8out.string9 endPacket captures can be modified and replayedwith ease by using a combination of blit andtelson. Simply save your saved session,modify the desired bytes, setup a connectionwith telson and send the packets to blitmanually or use feed to send all of themodified packets one at a time to telson.Using these tools seems a bit manual at first,but Ruby allows for their usage to be scriptedeasily and they often come in use for fuzzingnetwork sessions inline or reversing trickyprotocols.BINARIESRuby is also effective in the area of staticbinary analysis.Often when reverse engineering a closedsource binary the penetration tester will bepresented with embedded compressedimages or obfuscated data segments. We cancombine the usefulness of Ruckus with ourmany monkey patches to help de-obfuscateand extract these portions of applications.deezee is a tool included in Matasano’soriginal black bag C implementation. It worksby traversing a binary blob for compressedzlib images. Ruby has support for the Zlibclibrary by default so porting this tool to Rubyis trivial. This tool is often successful inextracting embedded file system blobs fromfirmware images or compressed datasegments within an executable.There are times when custom obfuscation isused to hide data segments of a binary ondisk. Often this comes in the form of a simplexor or base64 encoding. This is when we useRuby monkey patches to extract this data. AExtracting strings is often the first step to takewhen analyzing a foreign binary blob. Wewrote a better ‘strings’ utility in Ruby calledrstrings. rstrings has support for optional startand end offsets and different encoding typesascii and unicode and the ability to print atwhat offset in the blob the string was found. rstrings -t ascii -l 10 /bin/ls00001024:0000102f:a:" PAGEZERO"000012d8:000012e3:a:" pointers"0000131c:00001329:a:" jump table"00001368:00001373:a:" LINKEDIT"Grabbing the strings from a binary can onlytake you so far, at some point its file formatstructure and code segments must beexamined in detail. For this we use Ruckusand in the case of x86 executable, Frasm.Frasm is a Ruby extension to the Distorm64disassembly library. Disassembling x86 codein Ruby has never been easier:require 'frasm'd PQRSTUVWXYZ").each do l puts "#{l.mnem} #{l.size}#{l.offset} #{l.raw}"endINC ECX 1 0 41

6DOCUMENT 11111123456742434445464748RUNTIME ANALYSISFor debugging native code we havedeveloped a debugger named Ragweed.Ragweed uses Ruby/DL to wrap the nativedebug API on Win32, OS X and Linux.Ragweed is basically a scriptable debuggerwhich allows us to automate every task fromhit tracing to extracting data duringexecution.FUZZINGFuzzing is how you find bugs in binary attacksurfaces. You take a message, jumble it up,and throw it at the target. Again and again.Eventually the target crashes. You find outwhy. The answer is a security advisory.Every major language has a fuzzingframework. Probably the best-known is Peach,which is Python’s fuzzer du jour. We have aRuby fuzzing framework. It’s called Ruckus.Ruckus will take the Pepsi Challenge againstPeach any time.The first thing you want from a fuzzer is theability to define messages. So, you've gotyour DHCP header:0.78.1516.23 24.31opcode typeaddr lenhopcounttransaction idnum seconds flagsclient IPyour IPserver IPgateway IPclient hardware address(cont’d) hostname(cont’d).(cont’d) bootfileAnd here it is in Ruckus:class DHCPHeader Ruckus::Structurebyte :opcode, :value 1byte :hwtype, :value 6byte :hw address len, :value 6byte :hopcountn32 :trans idn16 :num secsn16 :flagsipv4 :client ip,:value "0.0.0.0"ipv4 :your ipipv4 :server ip,:value "0.0.0.0"ipv4 :gateway ipnum :client hw, :width 48string :server hostname,:size 64,:value ""string :boot file,:size 128,:value "generic"endSome things to notice here: Ruckus messages types are Ruby classes,but we give you a DSL-style interface fordefining the fields. We've got field types for everything you'regoing to see in a normal message. Byte-

7DOCUMENT TITLEsized fields. 32 bit network byte order fields.IP addresses. Strings. We do arbitrary numeric types. Got a 27 bitinteger field? Done! Got a flag word? Definethe flags bit by bit! Want a new field type? Every Ruckusmessage type is automatically a field type(lowercase the class name). It's turtles all theway down. Of course fields can take default values.But wait! There’s more!Every field in a Ruckus message can relate toanother field. For instance:class Foo Ruckus::Structurebyte :lenstr :stringrelate size :string,:to :lenrelate value :len,:to :string,:through :sizeendThis is something that comes up in networkprotocols all the time: length delimitedstrings. The field “len” records the 8 bitlength of the field “string”. Ruckus takes careof this for you.Ruckus works in both directions: in and out.If you define a working message type forsending messages, that same message typecan parse raw byte strings back intomessages. Why is this cool? Because it allowsus to do template-based fuzzing; for instance,we can write a proxy for a network protocol,capture messages, and then replay them withsubtle (or not-subtle) variations.Here’s where things with Ruckus start to gocrazy-go-nuts. Ruckus is actually modeled inpart after the HTML DOM.Like we said earlier, “turtles all the waydown”? Every field is itself a class. An integeris a Ruckus::Number. A string is a Ruckus::Str.If you want to wrap a DHCP header in a TCPmessage, you can do that with one fielddeclaration.Every field of every message is identified intwo important ways: its class; Ruby is introspective: you can takeany variable and gets its type with a singlecall. its optional “tag”, which is the moralequivalent of an HTML DOM “id”.All the fields of a message, nested arbitrarilydeep, form a tree. Just like in the HTMLDOM. And you can ask that tree for, say, allthe nodes that are of class “string”. Or thenode with the id “smbheaderbase”. Or allstrings in message components descendedfrom the node marked “smbheaderbase”.See where we're going with this? Cascadingfuzz sheets!Take an arbitrary message modeled withRuckus, and you can mutate it using CSS styleselectors. You can pick out all the stringsunder just a portion of the message, modifythem in some evil way, and render themessage back out, with all the associatedlength fields and doohickeys valid.To actually mutate the fields, we use someDino Dai Zovi code that leverages anotherRuby feature: generators. A generator takes aloop and turns it into a vending machine thatdispenses the loop results one at a time.

8DOCUMENT TITLEFor instance, here’s a loop that never ends,which generates random 10-character strings:comraider – iDefenseDranzer – certLoop { str ""; 10.times { str "A"[0] rand(26) } }While the available tools have impressive trackrecords for finding vulnerabilities in ActiveXcontrols, they can be of limited use for testingcontrols which have unique peculiarities suchas specific initialization requirements or nonstandard interfaces. In these cases, being ableto quickly prototype and build custom COMor browser-based ActiveX tools tospecification can be of immeasurable value.This loop isn’t very useful, because if youinvoke it, your program freezes. But usingRuby Generators, we can make it useful:g Generator.new { g Loop {str "";10.times {str "A"[0] rand(26)}g.yield(str)}}This is the same loop, but now each time wegenerate a string, we yield it to the Generatorobject. We can get each successive stringusing “g.next”, any time we want a randomstring.Ruckus uses DFuzz, which is Dino’s Generatordriven fuzzer library. DFuzz::String willgenerate a long sequence of progressivelylonger, weirder strings. DFuzz::Int willgenerate integers.ACTIVEXActiveX is an active area of vulnerabilityresearch and testing. A handful of generalpurpose ActiveX security testing tools alreadyexist, each with their own strengths. Theavailable ActiveX testing tools fall, generally,into two categories:Browser-based Testing. Examples Include:axman – by H.D. MooreDranzer – certDirect COM-based Interface Testing.Examples Include:Ruby lends itself well to the task of ActiveXresearch and vulnerability testing and bringsbenefits of rapid prototyping and testing. Thewindows version of Ruby ships with ‘win32ole’as part of its standard library. The ‘win32ole’library is designed to expose COM objects toRuby in a manner not unlike VBScript. Thelibrary is implemented a native extensionwritten in C/C and exposed to the rubyruntime.The ‘win32ole’ library makes dynamicenumeration, testing, and fuzzing of ActiveX(or even other COM interfaces) a snap.COM ENUMERATIONThe code below demonstrates quicklyidentifying all the installed and registered OLEtype libraries on the system including theirname, GUID, description, and registered filelocation:

9DOCUMENT TITLE1 require ‘win32ole’2 WIN32OLETYPELIB.typelibs.each do lib 3 begin4 puts “Name: #{lib.libraryname}”,5 “GUID: #{lib.guid}”,6 “Path: #{lib.path}”,7 “Desc: #{lib.name}\n\n”89 rescue WIN32OLERuntimeError10 # skip mis-registered TLB’s11 next12 end13 endBelow is an example of a standalone Rubyprogram which will produce a list of visiblemethods for any COM interface installed onthe system, accompanied by invocation type,return value, and typed arguments. This canbe used to quickly identify the exposedmethods for an ActiveX control:1 require ‘win32ole’2 obj WIN32OLE.new( ARGV.shift )rescue(exit(1))3 obj.olemethods.select { m m.visible? }. each do m 4 puts “#{m.invokekind}:#{m.returntypedetail.join(‘ ’)}#{m.name}(” 5 m.params.map { p “#{p.ole type}#{p.name}”}.join(‘, ’) “)”6 endACTIVEX FUZZINGUsing the same interfaces for enumeration, wecan easily begin producing test cases basedon the method interfaces. The example belowis an extremely trivial test case which simplygenerates several html files, one for eachargument per each method. The test-casechecks for unexpected errors when a 10kstring is supplied for each argumentindividually with null for all other arguments.7 obj.olemethods.each do m 8 psz m.sizeparams9 pary Array.new(psz, “null”)10 0.upto(psz-1) do idx 11 args pary.dup1213 tc “testcase10kstrargument#{m.name}#{idx}”14 args[idx] ‘“’ "A”*10000 ‘“’ # really lame testcase1516 File.open(”#{tc}.html" % idx, “w”)do f 17 f.write EOF1819202122 EOF23 end24 end25 endWe built a tool named ‘AxRub’ which takes ina CLSID as its argument and sets up a genericfake HTTP server in order to fuzz an ActiveXcontrol in the browser automatically. AxRub ishooked into the DFuzz generator to fuzz thecontrols methods with a variety of strings andnumeric values.INTEGRATING RUBYMost dynamic languages lend themselves toeasy integration with existing platforms andtoolsets, Ruby is no exception. Ruby can beextended using native C library, existing toolswritten in C or even bridged to otherlanguages like Java.WRAPPING LIBRARIESWrapping native libraries using Ruby issupported in two different ways. A nativeRuby extension can be written in C which linkswith the library it is intended to expose toRuby. This is a straight forward method that

10DOCUMENT TITLEdoesn’t require any additional third party codeto achieve, only what is absolutely necessary,only a C compiler, Ruby libraries, and thenative library you intend to wrap.Another, and increasingly more popular, wayto wrap native libraries is the use of Rubyextensions such as DL and FFI . Theseextensions allow you to wrap a native librarywith nothing more then Ruby code. Ruby/DLacts as a basic extension of the dynamic linker,as such you must provide it with the locationof your linker and it takes care of the rest. Theadvantage here is that no native code must bewritten and compiled. Our portable nativecode debugger, Ragweed, is written usingRuby/DL. It wraps the linker on Win32, OSXand Linux.FRASMOne native library we wrapped recently isdistorm64 , an x86 32 and 64 bit disassemblylibrary written in C. Distorm already containsPython bindings and we wanted the ability touse it from Ruby. We wrapped the underlyingdistorm C library in 104 lines of C and nowRuby scripts can be written to disassemblex86 instructions.1require 'frasm'23d NOPQRSTUVWXYZ").each do l 6puts "#{l.mnem} #{l.size}#{l.offset} #{l.raw}"7endINC ECX 1INC EDXINC EBXINC ESPINC EBP01111411 422 433 444 45INC ESI 1 5 46INC EDI 1 6 47DEC EAX 1 7 48.The ‘decode’ method takes in a string ofcharacters and passes them the distormlibrary for disassembly. An array of objects isreturned which hold four class variables‘mnem’, ‘size’, ‘offset’ and ‘raw’.EMBEDDING THE RUBY INTERPRETERWhile wrapping native libraries seems like themost ideal situation for extending existingtools, it is not always an option. Anotheroption for integrating Ruby into an existingtool is embedding the Ruby interpreter itself.The original Ruby interpreter is written in Cand provides a convenient API for callingRuby code from C. In certain cases we hadolder tools written in C that worked perfectlyyet lacked the dynamic programmability thatRuby provides. Rewriting these tools in Rubyis an enormous task that goes against ourphilosophy of not reinventing the wheel. Thebasic steps for embedding an interpreter andsharing a string with a ruby script are below:example.c1#include stdio.h 2#include ruby.h 34int main(int argc, char *argv[])5{6ruby init();/*Initialize Ruby */78VALUE str;/*Declare the string in C */910str rb str new2("SomeString");/* Assign the string avalue */1112rb load file("simple.rb");/*Load the Ruby script we want to run */

11DOCUMENT TITLE1314rb define variable("glbl",&str);/* Expose our string to ourscript */1516ruby exec();/*Run the interpreter */1718rb eval string("modify str");/*Call the method 'modify str' in ourscript */1920printf("%s\n",STR2CSTR(str));/* Print thestring our Ruby script modified */2122ruby finalize();/*We are now done with Ruby */2324return 0;25 }example.rb1234def modify strputs glbl glbl "Hello from Ruby!"endWe can compile our example.c program usinggcc, provided we have the right Rubydevelopment libraries in place: gcc -I/usr/lib/ruby/1.8/i486-linux/-lruby1.8 -o example example.cRunning our program: ./exampleHello from Ruby!Our Ruby script, example.rb, was called andthe ‘modify str’ method modified the globalstring ‘ glbl’. Our C program, example.c,printed out the modified string using theSTR2CSTR macro provided by ruby.hAlthough somewhat cruder then wrapping anative library, embedding the Ruby interpreteris a viable way to add scripting capabilities toexisting code bases where you don’t wish torewrite the project from scratch in Ruby.QUERUBAn older existing project named QueFuzzuses the libnetfilterqueue libraries on Linux tocreate an inline network packet fuzzer. Writingscalable fuzzing code in C is a lot moredifficult then writing it in Ruby. Despite itslimitations QueFuzz works as intended, therewas no reason to throw it out and start over.Instead we removed the C fuzzing code infavor of embedding the Ruby interpreter andpassing the packet to be fuzzed to a Rubyscript. This allows us to use all the built inmethods Ruby provides when reversing orfuzzing the packets contents. While a Rubywrapper around the libnetfilterqueue librarieswould be ideal, this is an involved softwaredevelopment process that requires all aspectsof the libraries functionality be taken intoconsideration. QueRub serves a specificpurpose, to fuzz network packets inline usingthe dynamic nature of Ruby while utilizing anexisting code base.LEAFRUBLeaf is another existing tool that was lacking ascripting component but was not eligible tobe wrapped as an existing library. Leaf is anextendable ELF analysis and disassemblyplatform that has support for plugins writtenin C. A plugin called LeafRub was written toembed the Ruby interpreter and expose Leaf’sinternal API and data to Ruby scripts thatmirror the design of a native C plugin.LeafRub works by creating constants for eachx86 instruction type, plugin functionarguments, and helpful functions in the LeafAPI. As each plugin hook is called in C, itsRuby counter part is called. Just like QueRub,this allows Ruby based Leaf plugins to utilize

12DOCUMENT TITLEall Ruby has to offer when disassembling ELFobjects.The following LeafRub Ruby script prints outeach instruction and looks up each opcodeagainst a list of known cross references andthe ELF symbol table.class Leafdef initializeputs "\n(LeafRub.rbinitialized)"enddef leaf code outputprint sprintf("%s %x [%16s](%s) (%x %x %x)\n", state.segment name, state.offset, instr.hex string, instr.inst string, instr.op one value, instr.op two value, instr.op three value, instr.op one value)self.match xref( state.offset, state.offset).each do x puts"\t#{x}" endself.match xref( instr.op one value, state.offset).each do x puts"\t#{x}" endself.match xref( instr.op two value, state.offset).each do x puts"\t#{x}" endself.match xref( instr.op three value, state.offset).each do x puts"\t#{x}" endself.match symbols( instr.op one value).each do x puts "\t#{x}" endself.match symbols( instr.op two value).each do x puts "\t#{x}" endself.match symbols( instr.op three value).each do x puts "\t#{x}" endendendleaf Leaf.newThe output of this script is shownbelow: leaf -f /bin/ls[ LEAF - Leaf ELF Analysis Framework ][ Loading LEAF Plugins . ]- LeafRub [Version: 0.1](LeafRub.rb initialized).rel.plt 8049508 [55 ](push %ebp) (0 0 0)(.rel.plt 0x8049508) @ [0x805aec4call 0x8049508]0x8049508 init@GLIBC.init 8049509 [89e5 ] (mov%esp, %ebp) (0 0 0).init 804950b [53 ] (push%ebx) (0 0 0).init 804950c [83ec04 ] (sub 0x4, %esp) (0 4 0).init 804950f [e800000000 ] (call0x8049514) (8049514 0 0)(.init 0x8049514) @ [0x804950fcall 0x8049514].init 8049514 [5b ] (pop%ebx) (0 0 0)(.init 0x8049514) @ [0x804950fcall 0x8049514].OTHER LANGUAGESWe use JRuby extensively to bridge the gapbetween Java and Ruby. This is particularlyuseful to a pentester who runs into a lot ofenterprise Java applications such as JRMI.In particular we have created Buby, a Jrubywrap of the Burp Java API.

time: the Ruby programming language. We'd like to highlight our use of Ruby to solve the security testing problems we're faced with every day. We use Ruby because it's easy, flexible, and powerful. It works for everything from reverse engineering firmware bus protocols to fuzzing file formats to static and dynamic binary analysis.