Skip to content

Instantly share code, notes, and snippets.

@xeger
Created February 1, 2013 22:34
Show Gist options
  • Save xeger/4694642 to your computer and use it in GitHub Desktop.
Save xeger/4694642 to your computer and use it in GitHub Desktop.
---
- !seq:Victim
- one
- two
- !map:Victim
one: uno
two: due
- !ruby/array:Victim
- one
- two
- !ruby/hash:Victim
one: uno
two: due
- !ruby/object:Victim
attribute: value
#!/usr/bin/env ruby
# Vector: a self-contained test case to explore the recently-disclosed vulnerability in the
# Psych YAML parser.
#
# Instructions: run this script with various versions of the Ruby VM (and various YAML libraries).
# If it raises an exception, then YAML has been fooled into calling potentially unsafe methods on
# an object.
require 'yaml'
class OwnedByAnExploit < Exception; end
# Under Ruby 1.9.x, using Victim as our base class lets us explore which
# methods YAML might be calling that we didn't think about in the individual vulnerable classes.
# Under 1.8.x it can't do this job as well (methods inherited from Object will not Victim).
base = defined?(BasicObject) ? BasicObject : Object
class Victim < base
# Methods that YAML will ask us about, which we shouldn't claim to support
YAML_METHODS = [:yaml_initialize, :init_with]
# Methods that YAML is allowed to call on us
ALLOWED_METHODS = [:instance_variable_set]
def class
::Victim
end
def inspect
"<Victim>"
end
def respond_to?(m)
if YAML_METHODS.include?(m)
false
else
true
end
end
def method_missing(m, *args)
if ALLOWED_METHODS.include?(m)
::Kernel.puts "YAML called allowed method #{m}(#{args})"
true #do nothing
else
args = args.map { |a| a.inspect }.join(',')
::Kernel.raise ::OwnedByAnExploit, "YAML called disallowed method #{m}(#{args})"
end
end
end
result = YAML.load(File.read('exploit.yml'))
puts "Loaded exploit YAML without any exceptions; looks like I may be home free!"
(0..3).each do |i|
puts "Here's YAML element #{i}, an instance of #{result[i].class.name}:"
puts " " + result[i].inspect
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment