Table of Contents
- Setting Up
- Enumeration
- Network Scanning with Nmap
- Enumerating Unknown TCP Port 8881 (Galaxy4d)
- Fingerprinting the OS Using SSH Client Tool
- Web Enumeration
- Login Credentials Retrieval through Bruteforcing
- Comprehensive Web Path Enumeration in Laravel Application
- Foothold
- Exploitation
- Privilege Escalation
Hello everyone! Welcome all of my viewers, to this brand-new VulnHub Walkthrough Article. In today's Article, we will be dealing with a vulnerable machine,
categorized as "Medium" in terms of difficulty.
The subject of our exploration is a machine named " Flick I ," which is a component of the “ Flick ” series. To begin with, you'll need to download the vulnerable image from the VulnHub website.
If you're not familiar with VulnHub yet, feel free to check out This Link:
Vulhub - Vulnerable By Design
Vulhub is a collection of pre-built vulnerable docker environments that are designed for learning and practicing security testing. It provides various intentionally vulnerable web applications and services for hands-on security training.
Setting Up
After successfully obtaining the image, the next step
involves setting up the server within VirtualBox, which is a fairly straightforward
procedure.
Before getting started, you need to extract the downloaded file, as it isn't in the " .ova " format. You can accomplish this using the WinRAR application.
Upon extraction, you'll have a " .ova " file that can be easily imported into VirtualBox.
First, Launch VirtualBox , and then go to the "File" menu, and select "Import Appliance".
Import the downloaded OVA file by browsing your computer to locate the download file and click "Next."
Review the appliance details and settings. You can keep the default settings or make adjustments based on your needs.
Click " Finish " to begin importing.
Once the import is complete, you'll find the "Flick I" vulnerable machine listed in the VirtualBox Manager.
Select the
virtual machine, click on "
Settings
," and change the network adapter
to "
Host-only adapter
."
Make sure that both your Kali Linux Machine, which is used for performing attacks, and your vulnerable machine must be connected to the same network.
Once the setup is done, it's time to start the Virtual Machines.
You'll notice that our Vulnerable Machine is all set, and we now have a login prompt waiting for us.
Let's dive into the fun!
Enumeration
Enumeration is the first process of our attack, aimed at identifying the IP Address of our Target Machine using Net Discover.
To do this, open a terminal, and run the following command:
From the scan result, we have obtained our target IP
address, which is, "192.168.95.117".
Next, we perform a network scan to detect what ports are open.
Network Scanning with Nmap
Scanning the Network is an essential part of the enumeration process. This allows us to understand the attack surface and plan targeted attacks. For this purpose, we'll use the popular Nmap tool. Use the following command on the terminal:
Where,
- -sC is used to perform a script scan using the default set of scripts, and
- -sV is used to enable version detection, which will detect, what versions are running on what port.
After conducting the network scan, we spotted the presence of one open port, specifically,
- The Port 22/TCP , running an SSH service, indicates that, if we possess valid credentials, gaining access to the server will be a straightforward process.
However, since we lack both a username and password, our next step involves revisiting the network scan. We'll perform an extensive scan covering all open ports.
Where,
- -A determines the target's OS, identifies service versions on open ports, and runs predefined scripts for advanced scanning tasks.
Enumerating Unknown TCP Port 8881 (Galaxy4d)
Upon revisiting the network scan, we've uncovered another open port, specifically,
- Port 8881/TCP. This port is hosting an unfamiliar service named "Galaxy4d?" This discovery has the potential to provide us with access to the vulnerable server's network.
Upon further examination of the Nmap script, it appears that this service might involve an admin server that prompts for a password.
Our
strategy involves attempting to access this service, and we can make use of
tools like
Netcat
to make this connection easier.
On a new terminal, type the following command:
As we already guessed, it prompts us to input a password to access the new world of "flick". Let’s try to guess some common passwords, but unfortunately, they don't work.
Now, let's focus on retrieving the password. After analyzing the network scan results, we discovered another unidentified piece of data.
This suggests that when we exploit Port 8881 , it might reveal the unrecognized service .
Fingerprinting the OS Using SSH Client Tool
Now, The only option left is using SSH. To proceed, our remaining option is to utilize SSH. On the terminal, run the following command:
The system will automatically consider your Kali Linux username as a user and initiate an attempt to connect to the vulnerable service:
Upon a successful connection attempt, a block of hexadecimal data will be provided. This block appears to contain additional information about the server's fingerprint.
Extracting OS Fingerprint with CyberChef
We can simplify the complex hexadecimal data using a tool like CyberChef to decode and understand its content.
CyberChef - The Cyber Swiss Army Knife
CyberChef is a powerful web application for encrypting, decrypting, and analyzing data. It provides a wide range of cryptographic, encoding, and data manipulation tools, making it a valuable asset for cybersecurity professionals and enthusiasts.
To do this, visit CyberChef, and follow these steps:
- Paste the Hexadecimal value into the input section.
- Search for "Hex" on the search bar in the operations section, and then drag and drop the "From hex" operation into the recipe section.
- This will automatically decode the hexadecimal value.
After decoding, I realized that the result was in the form of base64 encoding .
Let’s decode it.
- To decode it, copy the output and paste it into the input section again.
- Search for the "base64" operation in CyberChef, then drag the "From base64" operation into the recipe section.
- This will decode the base64-encoded data.
However, upon analyzing the output, I noticed that the decoded data is still in base64 format.
It appears that the creator of this vulnerable machine might have purposely confused us by repeatedly encoding the text.
Let's copy the output and paste it into the input section again, repeating the process until we find the correct text.
After attempting multiple times, I believe I've finally
identified the accurate data on my
17th attempt
.
Or, You can also generate a Python code to do the same thing. In a new terminal, create a new Python file named, " base64decoder.py " using the " nano " text editor.
Copy and paste the provided lines of code on my blog into this " base64decoder.py " file.
This code is like a set of instructions for your computer. This Python program is designed to uncover hidden content from base64 encoded text. It does this by repeatedly decoding the text.
Change the data with base64 encoded data and Paste it to the nano text editor.
Now, save your changes by
pressing "CTRL + X" and confirming.
To make the program work, type python3, mention the program name in the terminal, and hit Enter.
The program will start decoding the text step by step, like opening nested envelopes. After a number of iterations, the program will reveal the original hidden message in the 17th position.
Copy the hidden message and paste it on the admin server which we previously tried to access using Netcat.
Upon attempting, we find out that the password is accepted, and the
door is now open.
The concept of a " door " here is similar to a new accessible pathway or entry point.
Now, We should perform another network scan to observe any changes.
Web Enumeration
After scanning the network again, we have identified a fresh
accessible port.
- The port 80/TCP is active, indicating an HTTP service is operational. This suggests that a website with potential vulnerabilities is being hosted.
Now, let's explore the website content on
Port 80
. To do
this, you can use a web browser of your preference and enter the target's IP
address in the URL bar at the top of the browser window.
Upon visiting the website, we discover a collection of cat pictures. Let’s examine one of the cat images.
If you pay attention to the URL structure, you'll notice the image's location after the IP address.
Let's explore if we can access different paths using the URL.
I'll remove the image ID from the URL segments.
Oh no! Something didn't work as expected.
Let's try removing the "view" segment instead, and we find ourselves encountering an "Index of /image".
Regrettably, we're unable to access any of the directories. After investigating the website, I discovered a "Login" button that seems to offer access to the server.
Let me click on "Login to add a photo," which brought up a form requesting, a username and password.
Notably, a hint was provided on the side. This implies that the username, " demo " and the password are assigned to the first user.
Let’s try it.
However, my attempt to log in using these credentials was
unsuccessful, resulting, in "
The combination of username and password is
incorrect
."
Login Credentials Retrieval through Bruteforcing
Let’s try to brute-force the login form using Hydra.
Before that, I needed to intercept the data exchanged during a login attempt made with the " demo " username and password. I utilized BurpSuite for this purpose.
Launch BurpSuite, and Turn on the Proxy through Foxy Proxy :
Enable interception within the Proxy tab of the BurpSuite program:
This enabled me to capture and analyze the login data.
To perform a brute-force attack on the login form, we require specific login data: the cookie , username , and password data obtained through the interception process in Burp Suite.
Let's refresh the URL, causing it to trigger Burp Suite. Subsequently, the data should be sent to interception mode.
This information is crucial for
carrying out the attack effectively.
Now, Open a new terminal and run the following command:
However, I encountered an issue during this process. Hydra
was successfully following the 302 redirects, but it wasn't keeping the session
cookie. Consequently, every login attempt was falsely recognized as successful
since the failure message wasn't present on the redirected page.
To solve this issue, I created a Python program.
- This program utilizes the "requests" library, allowing it to send HTTP requests to web servers.
- Then, the program reads through a wordlist line by line and constructs a POST request to the URL.
- It supplies form data containing a username ("demo") and combines "demo" with the current word from the list to form the password.
- The parameter "allow_redirects" is set to False to prevent automatic redirection after the request.
- The server communication method is set to POST.
- The program then examines the "location" header in the HTTP response.
- This header usually contains the URL to which the server is directing.
- If the "location" header isn't the same, it signifies that the login attempt was successful.
- The program prints the guessed password, (which is "demo" followed by the current word from the list), and concludes the loop using the break statement.
After saving the program, it can be executed using the "python3" command.
Upon execution, the program systematically goes through the wordlist, attempting logins, until it successfully finds the correct password.
We have successfully obtained the password using the Python
program. Now, let's attempt to log in again.
Once logged in, I noticed that each image has a ' Download ' link. Upon clicking on a link, initiates the download of the image.
If you closely examine the URL format for downloading, you might realize that it appears susceptible to Local File Inclusion (LFI).
To explore this, I copied the download link and opened it in a new browser tab.
I decided to test LFI by inserting an arbitrary path into the ' filename ' parameter.
However, this resulted in an error, indicating that the file to download was invalid. I then attempted directory traversal.
All these requests yielded the same response: Oops! Looks
like you requested an invalid file to download!
/etc/passwd is not valid.
It became clear that the system was removing instances of the string ' ../ ' from the ' filename ' parameter. Instead of attempting to navigate to higher directories, I decided to retrieve the source code for files in the current directory.
For this purpose, I used Burp Suite to intercept the content and analyze the changes that occurred during the LFI testing.
Let's refresh the URL, causing it to trigger Burp Suite. Subsequently, the data should be sent to interception mode and from here send that data to the repeater.
Let me add " ./index.php " in Burpsuite Repeater to look at the changes.
This approach provided me with the source code for the '
index.php
'
file in the web root, confirming that the framework in use is
Laravel
.
Comprehensive Web Path Enumeration in Laravel Application
If you have read this article, then you will know the basic directories in the Laravel web framework, if you have not yet read it, kindly read it before proceeding further.
Mastering Web Paths in Laravel
This guide explores how to effectively manage and use web paths in Laravel, a popular PHP framework. Understanding web paths is essential for building clean, maintainable, and efficient web applications using Laravel.
Given my familiarity with Laravel's directory structure from
the article, I recalled that the web root for Laravel applications is within a
directory called '/public'. All application logic exists in directories above
this one.
With the URL path now altered, the next step is sending the data.
However, upon inspecting the response, it becomes evident that the
requested data is deemed invalid.
After a bit of thinking, I realized that if the system was simply replacing the '../' string, I could potentially exploit this behavior. I aimed to include '../' in the output by crafting a string with '..././'. This way, when the '../' was replaced, it would leave '../' within the string. Depending on how the replacement was implemented, this could enable directory traversal and arbitrary file inclusion.
To test this, I requested the following URL on Burpsuite.
I confirmed that the content matched what I had previously retrieved when using ' ./index.php ' as the filename.
This successful test verified my assumption, and I achieved the same file inclusion result.
/composer.json
In the Laravel project, there's a vital file named "/composer.json" situated in the same directory as the public directory.
This file contains essential information regarding the project's dependencies and configurations needed for Composer to work effectively.
Upon quick examination, I determined that the running version of the Laravel Framework is 4.1 .
Focusing on the " autoload " section, this part guides Laravel on how to automatically load classes within your application. You don't need to manually include these classes using "require" statements.
Under the " classmap ," you'll find classes related to various components of the application. When you use any of these classes in your code, Laravel's autoloader will include the necessary files without you having to explicitly state "require" statements.
As we're aware, the "/app" directory is the heart of the Laravel application.
It contains core application elements like Controllers, Models, and Services.
In Laravel, the "/routes.php" file serves to define your application's URL routes and link them to specific controller methods.
This organization aids in structuring the application's functions and logic neatly, facilitating easier management and development.
It's important to note that in Laravel 5 or higher, route definitions are shifted to the "/routes" directory.
/app/controllers/SessionController.php
Let’s try to attempt to access the controllers, which reside in the "/app/controllers" directory. Alter the URL path to lead to " SessionController.php " located within the controllers' directory.
The standout detail is the fake SQL injection (SQLI) error . However, due to a type-safe comparison against FALSE, it appears challenging to exploit.
/app/controllers/UploadController.php
We're aiming to retrieve the contents of the " UploadController.php " initially.
Interestingly, there seems to be no restriction on the type of file uploaded.
To test our assumption, Our test revolves around trying to upload a php-reverse-shell directly, bypassing the ' image/download ' route.
Start by clicking on " Upload a photo ."
Our goal here is to upload a PHP file that contains a reverse shell.
So, open a new terminal to perform these steps.
First, locate the reverse-shell PHP file. Once located, copy it to your Home directory.
Let me modify the PHP file to include my listening IP address.
If you're unsure about your Listening IP address, you can use the " ifconfig " command to confirm it. Next, we have to set up a listener on our machine to listen on Port 1234 .
Now, let me Upload the modified PHP file through the website's upload functionality.
Upon uploading, the website will automatically redirect you to the Home page. After uploading the PHP file, you can directly access it by browsing its path within the ' images ' directory on the website. I notice an unfamiliar file on the second page, be aware that I can't directly open it.
So my only option is to download it. Proceed to download the file.
Upon inspection, I realize that the downloaded file appears to be a JPEG image, but it doesn't display any image content.
However, this file is likely the one I uploaded, as the website automatically saved it in JPEG format. To confirm its true format, you can open a terminal from here, and run the following command on the terminal:
This reveals that the file is in ASCII text format and identified as a PHP script. It means I can use a text editor like "nano" to open and explore its content.
The process surprisingly turns out to be relatively
straightforward.
/app/controllers/ViewController.php
Let's check out the logic in ViewController.php .
After analyzing the logic in the " ViewController ," we confirm the replacement of the ' ../ ' string in the target filename. Unfortunately, the file is read using " file_get_contents " instead of being included. This means we can't exploit it to execute arbitrary PHP code.
/app/controllers/HomeController.php
For a more comprehensive perspective, we delve into the " HomeController.php " component.
Nothing noteworthy is found in these sections.
/app/config/database.php
Lastly, I explore the database configuration file.
The '/config' files define settings and options for different aspects of the web application. Please note that these details can vary based on the version. In Laravel 5, configuration files are stored in a separate directory, while in Laravel 4.1, the configuration file is within the "/app" directory.
Let’s visit it.
Examining the database configuration file reveals
credentials, including an
OLD SQLITE
database definition.
/app/database/production.sqlite
Given the obsolescence of SQLite 2 and below on modern systems, downloading it is futile. Instead, I attempt to acquire the database credentials online, and extract the username and password from Burp Suite, directly from the response side.
Efforts to copy a shorter portion of the data have also met with limited success. Although we can't directly copy the complete text, we do have the option to copy them individually, one at a time.
After copying each credential, I gather three sets of credentials. Now that we have the username and password, we can use them to access the server through the SSH service .
Foothold
Now that we have three sets of usernames and passwords,
let's try to attempt to log in to the server one by one.
Open a terminal and use the SSH command with the first username associated with the server's IP address.
Then, provide the password.
Unfortunately, the first username-password combination didn't grant us access. Moving on to the second one.
But this one also didn't work. Let's proceed with the third set.
Success! We've gained access to the server using the third set of credentials. Now, let's try to locate the user flag.
Upon checking the files and directories, I noticed that there isn't a flag file present. However, there is a message file that seems to contain our flag. Let’s view its contents using the " cat " command.
This message seems to be like a Hint, where there is a “
.dockerfile
”,
which is present in the same directory. This “
.dockerfile
” seems to provide access
permissions to the directories owned by the user Robin. The message even
includes an example of a directory path.
Taking this hint into consideration, let's attempt to access the mentioned file.
Successfully, we've been able to view the content within the file. Now, let's try listing the files and directories within the user robin using the "ls" command.
Unfortunately, we lack the necessary permissions to access the files directly. Our only option is to use the “ ./read_docker ”.
It appears that the user "
Robin
" might possess elevated
privileges. Our next step is to discover a method to escalate our privileges
and switch to the user, Robin.
Exploitation
As we lack the necessary password for the user, Robin, an
alternative route is to obtain the SSH keys.
Exploiting SSH Keys for Unauthorized Acces
Within the "/.ssh" directory, there are two most important files are present, they are:
- authorized_keys
- id_rsa
Let’s find a way to take a look at these contents. To inspect their contents, we will establish symbolic links to these files owned by the user, Robin. This is accomplished using the " ln " command.
Let's start by linking the "authorized_keys" file to a new file named, Dockerfile .
Where,
- -s is used for symbolic links.
You can verify this, using the ls -al command.
Now, let me read the file content using the " ./read_docker " command.
However, it's possible that the authorized key might not be effective. Let's also examine the contents of " id_rsa " using the same approach.
This file contains the private key necessary for accessing the user, Robin. To proceed, we will copy these contents into the " id_rsa " file in the same directory and then restrict its permissions using " chmod +600 ".
With the setup complete, we can use the SSH command to log in as the user Robin.
By doing so, we've successfully gained access to the
Robin user account. Our next objective is to acquire root access to
fulfill the
CTF challenge
.
Privilege Escalation
During the process of privilege escalation, the primary goal is to gather information about the system and pinpoint any potential vulnerabilities or misconfigurations that might grant us higher privileges, ultimately leading to accessing the root level.
To start, let's perform a User Permissions Enumeration to analyze the user's rights and privileges on the system. This can be achieved by executing commands like " sudo -l " or " uname -a " to determine which commands the current user can run with elevated privileges.
Let me run the “ uname -a ” command, to identify various details about the machine, such as its kernel version, hostname, architecture, processor, and operating system.
Additionally, I'll examine the privileges associated with the current user by running " sudo -l ."
Docker Container Escape Privilege Escalation
After executing this
command, I've discovered that the user "
robin
" possesses specific
permissions for “
/opt/start_apache/reset.sh
”. Unfortunately, this doesn't seem
to be a helpful route for obtaining a root shell.
Given the presence of Docker on the target machine, I'll use the " docker ps " command to list the currently active containers.
This
will provide an overview of the containers that are currently operational.
However, it appears that there are no other active containers at the moment. To gain further insight, I'll inspect the available Docker images that reside within the container repository.
Notably, there are several Ubuntu images accessible within Docker. Leveraging this discovery, I'll exploit the opportunity to attain a root shell.
When we run this command, a fresh Docker container will be established using the Ubuntu image. The container will start an interactive Bash shell session, allowing us to work within the container as if you were working in a regular Linux terminal. The /root directory on the host system will be accessible within the container, allowing you to manipulate files and perform tasks within that directory.
Following these steps, I've successfully gained root access. I'll confirm this by using the " whoami " command to verify the current user as, "root."
Next, I'll navigate to the root directory using the "cd" command and confirm the presence of the root flag with the "ls" command.
To view the content of the root flag, the "cat" command can be employed.
This is not the flag, which originally contained the flag. But, upon analyzing I find out that there is a directory on /root path, which may contain the rot flag.
To view the content of the root flag, the "cat" command can be employed.
With these actions, the CTF challenge has been successfully completed. If you have any questions or uncertainties, feel free to leave a comment in the designated section.