Created
February 1, 2013 22:34
-
-
Save xeger/4694642 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
- !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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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