Hack The Box – Breadcrumbs Walkthrough
Introduction
This was a hard Windows machine that involved exploiting a directory traversal vulnerability to forge session cookies and hijack an admin user’s session, a file upload functionality through which remote command execution can be obtained, and a SQL injection vulnerability to escalate privileges to Administrator
Enumeration
The first thing to do is to run a TCP Nmap scan against the 1000 most common ports, and using the following flags:
- -sC to run default scripts
- -sV to enumerate applications versions
The scan has identified a number of open ports: 22 (SSH), 135 (MSRPC), 139 (NetBios), 80 (HTTP), 445 (SMB), and 3306 (MySQL). The next step will be to start enumerating HTTP.
Enumerating HTTP
When accessing the site on port 80, the following page is displayed:
When clicking on the “Check Books” button the site takes to the page below, which allows to search books by title and author:
Capturing the request used by the web application when clicking on the “Book” button:
It appears to contain a “book” parameter with the name of the HTML page linked to the book. When attempting directory traversal against the book parameter, although it failed the site revealed the directoryto the web application root folder, which may be useful later on:
The next step is to run a scan to find hidden files or directories using Gobuster, with the following flags:
- dir to specify the scan should be done against directories and files
- -u to specify the target URL
- -w to specify the word list to use
- -x to specify the extensions to enumerate
- -t to specify the number of concurrent threads
The scan has found a few interesting entries, such as /portal and /db. When performing a subsequent scan against the /db entry, a db.php file is found. This could be the file used to perform the database connection and it might contain credentials:
Using the directory traversal vulnerability to obtain the contents of the db.php file, which seems to contain database credentials:
These won’t be useful at this point in time, so decided to go to the /portal entry, which presents a login page:
The “helper” page can be accessed without authentication, which lists available administrator users:
The site allows users to self-register to access additional functionality:
Authenticating with the account created above:
Self-registered users are presented with the page below upon authentication:
The “User management” button takes to the page below which lists all existing users and their position:
It appears an “Admin” position user would be required to proceed further.
The “Check tasks” button takes to the following page, which lists a number of issues, one of which mentions an issue with the duration of the PHPSESSID cookie:
This may be a hint as to what is required to exploit the web application. The site has generated a JWT token upon authentication, when encoding it on jwt.io it seems to contain the username:
Ideally by changing the username parameter further access may be unlocked, although unfortunately it cannot be changed as it uses SHA-256 encryption and a key is required to do so..
When clicking on the “File management” button, it simply redirects to the home page, meaning there is probably some rule on the backend checking for the current user’s access. When using directory traversal to view the contents of file.php (which is what the file management feature links back to), there indeed appears to be a rule that redirects users back to the home page if the username within their JWT token is no “paul”:
This confirms the paul user needs to be able to access further functionality.
Hijacking Paul User
When viewing the contents of the login.php page, it appears to be using an AuthController.php script to authenticate user:
Upon inspecting the contents of the AuthController.php file, it appears to use the db.php and cookie.php files (respectively to communicate with the database end establish sessions through cookies):
The file appears to contains a “secret_key” variable, which might be what is used to generate the JWT tokens:
When accessing the cookie.php file, the code used to generate sessions cookies is revealed:
Inspecting the code used to generate the session cookie and adding comments to it:
<?php
/** * @param string $username Username requesting session cookie
*
* @return string $session_cookie Returns the generated cookie
*
* @devteam
* Please DO NOT use default PHPSESSID; our security team says they are
predictable.
* CHANGE SECOND PART OF MD5 KEY EVERY WEEK
* */
function makesession($username){
//store the length of the username - 1
$max = strlen($username) - 1;
//pick a random letter from the name
$seed = rand(0, $max);
//definining hashing key, using a salt and a random letter from the username
$key = \"s4lTy_stR1nG_\".$username[$seed].\"(!528.\/9890\";
//creating session coookie by generating a md5 hash of the username with the
key above, and concatenating it to the username
$session_cookie = $username.md5($key);
return $session_cookie;
}
Running the code locally to create a valid session cookie, trying one for each letter of the paul username:
Both a JWT token and a PHPSESSID are required to impersonate Paul.
Using the key found earlier to generate the JWT token replacing the username with paul:
Replacing the cookies with the ones generated above, trying one PHPSESSID at a time:
Upon refreshing the page, the user has now changed to Paul:
The file management functionality is now available, which allows to upload files. It mentions only ZIP files are allowed:
Exploiting File Upload
The first step is to generate a PHP reverse shell using MSFvenom with the following flags:
- -p to specify the payload type, in this case, the PHP reverse shell
- LHOST to specify the localhost IP address to connect to
- LPORT to specify the local port to connect to
- -o to specify the output file, in this case shell.php
Renaming the file extension to .zip and uploading it:
Intercepting the request with Burp and changing the extension with .zip
The file was successfully uploaded
The next step is to set up a Netcat listener, which will catch the reverse shell when it is executed by the victim host, using the following flags:
- -l to listen for incoming connections
- -v for verbose output
- -n to skip the DNS lookup
- -p to specify the port to listen on
The fileController.php file reveals how files are uploaded on the /portal/uploads folder:
Accessing the file from the browser, therefore triggering the reverse shell:
A callback on the Netcat listener was received, granting a shell as the www-data user:
Local Enumeration
There appears to be a “juliette” user present on the machine:
When navigating to the web server root folder – there seems to be an interesting “pizzaDeliveryUserData” folder:
It seems to contain user information, a file for the “juliette” is present, and it contains information in JSON format, including a password:
Using SSH to authenticate as Juliette with the password found above:
Privilege Escalation
When consulting the “Looting for Passwords” Windows section of PayloadAllTheThings, it mentions that contents of the Sticky Notes in Windows are stored in a SQLite database, and it indicates the directory to the database file:
When navigating to the directory, the file appears to be there:
Downloading the files remotely using SCP and opening the .sqlite file using SQLiteBrowser:
It looks like there are a few tables available:
The “Note” table contains a clear-text password for the “development” user:
Authenticating as the Development user via SSH:
There appears to be an interesting “Krypter_Linux” file under C:\Development
Downloading the file via SCP – it seems to be a Linux binary:
Using the strings command against the binary to understand what it does- it appears that it performs a GET request on
port 1234 with the following parameters:
method=select&username=administrator&table=passwords
Since port 1234 is only open locally, a SSH tunnel needs to be setup to be able to access it from the Kali host:
SSH -N -f -L 1234:127.0.0.11:1234 development@10.10.10.228
Now all connections to port 1234 on the Kali host will be forwarded to port 1234 on the target machine.
Performing the same GET request mentioned in the binary using Curl returns an AES key. When adding quotes to one of the parameters if returns an error from MySQL, meaning the application may be vulnerable to SQL injection:
Running SQLMap against the application, providing the vulnerable URL and the –dump option to dump the contents of the database:
A base-64 encoded AES encrypted password for the administrator user (and its AES Key, which was also found above) was found:
Using an online AES decrypter to decrypt the string, providing the AES key:
Base64-decoding the decrypted string to obtain the clear-text password:
Authenticating as the Administrator user via SSH:
At this point, full access to the remote host has been obtained.
Conclusion
This was a very challenging box and one of my first hard boxes on Hack The Box. As the name suggest, it required to collect a lot of “breadcrumbs”, and slowly gain information about the web application in order to hijack Paul’s session The sticky note vector was very unusual and definitely not something I had used before, whereas the SQL injection part was not too complicated.