richö
‣ rich-oh!
‣ Computer Jerk at Stripe
‣ Duck Enthusiast
‣ Co-owner of plausibly the world's most ridiculous CVE
‣ WrongIslandCon jerk
‣ paraTROOPER
‣ github.com/richo
‣ twitter.com/rich0H
Slide 3
Slide 3 text
Please hold while
richo takes a selfie
Slide 4
Slide 4 text
What this talk is
‣ Neat tricks with bytecode vms
‣ Some hilarity inside of the Rubby's VM
‣ Some reversing fu for people who don't like
reversing
‣ Maybe a little opaque- please ask me questions
Slide 5
Slide 5 text
What this talk isn't
‣ Dropping 0day or bugs per se
Slide 6
Slide 6 text
The Problem
‣ Someone wants to give you a black box that does
computer
‣ They don't want you to know how it computers
Slide 7
Slide 7 text
Some terminology
‣ VM: Virtual machine
‣ Opcode/Instruction: Used interchangably to
refer to operations in the VM
‣ Bytecode: Internal representation of programs
expressed as a series of opcodes
Slide 8
Slide 8 text
Their Solution
‣ Obfuscation!
Slide 9
Slide 9 text
Their Solution
‣ Obfuscation!
‣ Not novel:
‣ Malware authors are on this case
‣ Native code has been doing this for years
‣ Obfuscating bytecode isn't new
Slide 10
Slide 10 text
This kinda sucks in a bytecode VM
‣ Your options for detecting fuckery are pretty
limited
‣ No performance counters
‣ Very limited sidechannels
‣ No weird instructions to poke
Slide 11
Slide 11 text
This *really* sucks in a dynamic VM
‣ Dynamic dispatch means you can't mangle
classes and methods
‣ Lack of a JIT means you can't do anything
egregious to method bodies
Slide 12
Slide 12 text
Code obfuscation
‣ Typically packs up either source or a build product
‣ Loaders tend to be really complex
‣ Messing with RE's is seemingly fun to these people
Slide 13
Slide 13 text
Some more terminology
‣ Rubby: An interpreted, dynamic language
‣ YARV: Yet Another Rubby VM
‣ MRI: Matz Rubby Interpreter
Slide 14
Slide 14 text
What if you're really lazy
Slide 15
Slide 15 text
The Rubby VM
source_file.rb READ CODEGEN
Slide 16
Slide 16 text
The Rubby VM
Slide 17
Slide 17 text
The Rubby VM
Slide 18
Slide 18 text
inside an InstructionSequence
Slide 19
Slide 19 text
The Rubby VM
source_file.rb READ CODEGEN
EVAL
Slide 20
Slide 20 text
The Obfuscated Rubby VM
source_file.rb READ CODEGEN
OBFUSCATION
obfuscated_source_file.rb
obfuscated_source_file.rb UNPACK EVAL
Slide 21
Slide 21 text
Packed code
Slide 22
Slide 22 text
Dynamic VM is Dynamic
‣ We can trivially insert instrumentation
‣ This.. sort of works.
‣ Tack binding.pry calls everywhere
‣ Attach a debugger, do a lot of `call rb_f_eval`
‣ Defeats for this are fairly plausible and costly to
bypass
‣ Dynamism is a double edged sword
Slide 23
Slide 23 text
Rubby
‣ Open Source!
‣ We can just slam our own debug interfaces in
‣ Worked entirely with the reference
implementation
‣ All mainstream loaders target it anyway
‣ Typically see a loader for each of the more recent
rubbies
Slide 24
Slide 24 text
The Rubby VM
‣ Interesting symbols to start with:
‣ rb_eval_iseq
Slide 25
Slide 25 text
The Rubby VM
‣ Interesting symbols to start with:
‣ rb_eval_iseq
‣ rb_define_method
‣ vm_define_method
Slide 26
Slide 26 text
The Rubby VM
‣ Interesting symbols to start with:
‣ rb_eval_iseq
‣ rb_define_method
‣ vm_define_method
‣ rb_f_eval (lol)
Slide 27
Slide 27 text
Ok so we have bytecode right
‣ Now what?
Slide 28
Slide 28 text
A stack of Rubbies
‣ Rubby's VM is a stack machine
‣ Opcodes consume operands from the stack and
leave values on it
‣ A few simple registers for storing branch
conditions, pc, etc
Slide 29
Slide 29 text
Deeper into the YARV
Slide 30
Slide 30 text
Expressive IR is nice
‣ YARV bytecode is pretty easy to read
‣ Auditing by hand isn't too bad
‣ Happily it's also sufficiently expressive that
decompilation is pretty tenable
Slide 31
Slide 31 text
Reversal
‣ Research project from Michael Edgar @
dartmouth
‣ Similar in operation to pyRETic by Rich Smith
Slide 32
Slide 32 text
Reversal
‣ Over the course of this research I found several
versions of rubby that simply won't compile
‣ Several debug flags that cause rubby simply not
to build
‣ The VM has gained more instructions since 2010
Slide 33
Slide 33 text
Aside: instructions
‣ bitblt:
Slide 34
Slide 34 text
Aside: Docs
‣ Rubby is an english language (now)
‣ This is.. not super true for large chunks of the
codebase
Slide 35
Slide 35 text
Reviving Reversal
‣ Patched reversal until it started working again
‣ Added support for rubby 1.9.3
‣ And it's delightful new instructions
Slide 36
Slide 36 text
Presenting: unrubby
‣ Hacked up rubby VM
‣ Lots and lots of hooks into internal behaviour
‣ Reaches out to reversal for decompilation
‣ Gives you back source!
Slide 37
Slide 37 text
Why not just reversal
‣ Reversal's mode of operation is a bit fragile
‣ Unrubby hooks the behaviour of the VM, not the
format of the bytecode
‣ Attempts to defeat unrubby would in turn be
fragile
Slide 38
Slide 38 text
Digging further in
‣ Reversal suggests it can take the whole program
and turn it back into source.
‣ This is largely untrue in my experience.
Slide 39
Slide 39 text
Obfuscation at many layers
‣ Problem space includes two layers:
‣ Obfuscation of the bytecode itself
‣ Difficult to read bytecode
Slide 40
Slide 40 text
Obfuscation at many layers
Slide 41
Slide 41 text
Obfuscation at many layers
Slide 42
Slide 42 text
Digging further in
‣ We can keep abusing the runtime behaviour of the VM
‣ hook more stuff!
‣ rb_mod_include
‣ rb_obj_extend
‣ rb_define_class
‣ rb_define_method
Slide 43
Slide 43 text
Patchy patchy
Slide 44
Slide 44 text
Patchy patchy
Slide 45
Slide 45 text
Bonus
‣ This also gives us a more flexible intermediate
state
‣ Write your own hooks in rubby!
Slide 46
Slide 46 text
More bonus
‣ This has the impact of "unfurling"
metaprogramming
‣ We get dynamically generated methods as well
Slide 47
Slide 47 text
Aside: Classes
‣ Rubby classes are weird
‣ If you think that hooking rb_define_class is
enough you would be sadly mistaken
‣ Luckily our hook function is idempotent
‣ Skim class.c and hook *everything*
Slide 48
Slide 48 text
Demo time!
Slide 49
Slide 49 text
Making it go
‣ Rubby's insanity is super useful to us
‣ We can preload our library, then hijack execution
flow during the eval step
‣ An atexit(3) hook will just dump the code to
stdout
Slide 50
Slide 50 text
Real world breaking
‣ Things have dependencies
‣ Things want to talk to databases
‣ Rubby to the rescue again!
Slide 51
Slide 51 text
Naively
‣ Reimplement rails without any bodies
Slide 52
Slide 52 text
Rubby: richo has feels
‣ Rubby lets you do a bunch of things it ought not to:
‣ method_missing
‣ const_missing
‣ reopening classes
‣ monkey patching
‣ etc
Slide 53
Slide 53 text
Or!
Slide 54
Slide 54 text
Stealth
‣ Reversing things is kinda noisy
‣ Do this in an unroutable vm
‣ Unroutable vm's are miserable to work with
Slide 55
Slide 55 text
Stealth
‣ Reversing things is kinda noisy
‣ Do this in an unroutable vm
‣ Unroutable vm's are misrable to work with
‣ Compromises end up getting made
Slide 56
Slide 56 text
What's in the box?
‣ Rubby source tree
‣ Patched version of reversal
‣ A rails shim that ought to appease many
applications
‣ Please play with it!
‣ Please report bugs!
‣ I'll drop some tips in the readme for how to report
bugs without coughing up privileged code
‣ UNRUBBY_REPORT_BUG
Slide 57
Slide 57 text
More goodies
‣ Lots of environment variables to control what
gets emitted
‣ UNRUBBY_FULL_ISEQ
‣ UNRUBBY_METHODS
‣ YOLO
‣ Abusing the autoloader can yield results
Slide 58
Slide 58 text
Care and Feeding
‣ unrubby currently targets rubby 2.1
‣ Vendors typically ship shims for their rubby
‣ Upstream vendors make loader bundles available
‣ Autoloaded packages can make you sad
‣ Implement your own entrypoint
‣ Overwrite their bundled rubby
Slide 59
Slide 59 text
How would I defeat it?
‣ No super obvious way
‣ Unfortunately Rubby is just a really obtuse VM to
target
‣ Cat and mouse games abound:
‣ Checksum argv[0]
‣ Recalculate internal offsets
‣ Best I came up with was to shove everything into
.rodata and statically link a binary
Slide 60
Slide 60 text
Go forth!
‣ No obvious way to defeat the attack!
‣ Cost of attack:defense way in favour of attacker
‣ Novel technique that can be applied to other VMs
easily
‣ Go reverse stuff
Slide 61
Slide 61 text
Gr33tz and shit
‣ Rich Smith - pyRETic
‣ Michael Edgar - Reversal
‣ TROOPERS for having me
‣ Whoever I'm missing
Slide 62
Slide 62 text
Resources
‣ https://github.com/richo/unrubby
‣ https://github.com/michaeledgar/reversal
‣ I'll toot the link to these slides - @rich0H
Questions?