It seems this file will cat /root/root.txt when read, which is what we want.
sudo -l reveals:
sudo -l
Matching Defaults entries for henry on precious:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User henry may run the following commands on precious:
(root) NOPASSWD: /usr/bin/ruby /opt/update_dependencies.rb
# 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
update_dependencies.rb grabs dependencies.yml, but does so relatively. We can run this script as root and use the dependencies.yml in henry's home directory instead of the one in /opt/sample. This will print out the root.txt flag.
henry@precious:~$ sudo /usr/bin/ruby /opt/update_dependencies.rb
sh: 1: reading: not found
[ROOT FLAG HERE]
Traceback (most recent call last):
... (irrelevant traceback)
/usr/lib/ruby/2.7.0/net/protocol.rb:458:in `system': no implicit conversion of nil into String (TypeError)
That's the box completed!
Messing around with the website in Burp Suite reveals the PDFs are being generated with pdfkit 0.8.6, which is vulnerable. Using lets us inject commands into the website, giving us a reverse shell in Ruby.