Escalación de Privilegios en entornos Linux
Escalación de Privilegios
Herramientas de enumeración:
Exploits de kernel
El kernel es el núcleo de cualquier sistema operativo, debido que, es la interfaz fundamental entre el hardware y sus procesos.
Los exploits a nivel de kernel aprovechan las vulnerabilidades que estos tienen para poder ejecutar código como root.
Estos exploits son específicos a cada versión vulnerable, y cuando se usan, pueden causar inestabilidad del sistema, o causar inoperabilidad del sistema completo.
El escalar privilegios usando un exploit de kernel es tan fácil como: descargar el exploit, compilarlo y ejecutarlo (estas pueden funcionar de forma inmediata, o pueden requerir modificaciones).
Lo mejor para encontrar un exploit, es buscar en google, github o exploit-db.
Herramienta Linux Exploit Suggester 2.
uname -a
cat /etc/lsb-release
searchsploit linux kernel <kernel_version> priv esc
./linux-exploit-suggester-2.pl -k <kernel_version>Validar la versión del OS y el kernel:
uname -a
cat /etc/lsb-release
Buscamos exploit asociados la versión del kernel:
Usamos el siguiente código en la máquina víctima, y lo compilamos:
Eliminar la línea que contiene
# 0day.today [2018-03-28] #para que no de error al momento de compilar.
Lo ejecutamos para obtener acceso como root:

Ejecutamos Linux Exploit Suggester 2 con la versión del kernel para buscar exploits:

Cargamos el exploit en la máquina víctima, lo compilamos y lo ejecutamos:

Nos conectamos usando el usuario
firefart:password:

Rollback

Servicios vulnerables
Los servicios son programas que corren en segundo plano, los cuales, pueden aceptar entradas o realizando tareas de forma periódicas.
Al igual que con los exploits de kernel, podemos usar Searchsploit, Google o Github para encontrar exploits para estos servicios.
Buscamos los servicios instalados:

Validamos la versión del servicio
scree:

Buscamos exploits asociados al servicio
screen:

Descargamos el exploit para poder subirlo a la máquina víctima:

Ya en la máquina víctima, le damos permisos de ejecución y corremos el exploit:

Usando
Linux Smart Enumeration, enumeramos la máquina víctima:


Validamos la versión de MySQL:

Buscando en Exploit-DB, se encuentra el siguiente exploit:

Descargamos el exploit en la máquina víctima, lo compilamos y ejecutamos el ataque:
Dentro de MySQL, ejecutamos los siguientes comandos:

Revisamos la carpeta
tmpy ejecutamos el binariorootbash:

En algunos casos, los procesos de root pueden estar vinculados a un puerto interno, con el cual se comunica.
Si por alguna razón el exploit no puede ejecutarse de forma local en la máquina, podemos hacer realizar un reenvío del puerto mendiante SSH a nuestra máquina atacante:
Ahora el exploit puede ejecutarse en la máquina del atacante apuntando al puerto indicado en la conexión SSH.
Por ejemplo, imaginemos que la PoC - Explotación del Servicio MySQL no se puede realizar en la máquina víctima, lo primero que tenemos que ver es el puerto a la escucha del servicio MySQL:

Ahora ejecutamos el Port Forwarding en la máquina víctima para poder acceder al servicio:
Ahora en la máquina atacante, usamos el siguiente comando para conectarnos al servicio remoto:
Podemos comprobar que estamos en el servicio correcto usando el siguiente comando de mysql:
Archivos con permisos débiles
Nos podemos aprovechar de algunos archivos del sistema para escalar privilegios si el permiso en uno de ellos es muy débil.
Si estos archivos pueden ser leídos, podrían contener información sobre cuentas locales, como la de root. En caso de que podamos escribir en el, podríamos modificar la forma en que el OS funciona y así, poder tener acceso como root.
Archivo /etc/shadow: uno de los archivos en que nos tenemos que fijar es en el archivo
/etc/shadow, el cual, contiene los hashes de las contraseñas de los usuarios, y que por defecto puede ser leído solo por root. si podemos leer este archivo, obtendremos el hash del usuario root, el cual, podría ser crackeado. En caso de que podamos escribir este archivo, podríamos reemplazar el hash de la contraseña de root.Archivo /etc/passwd: en versiones anteriores, el archivo
/etc/passwdcontenía los hashes de los usuarios. Por este motivo, si en la segunda columna de un usuario se tiene un hash, este se toma en cuenta antes de que se valide en el archivo/etc/shadow. Entonces, si podemos escribir en este archivo, podríamos incorporar un hash en el usuario root. En caso de que solo podamos agregar información a este, podríamos crear un nuevo usuario, al cual, le asignaremos le UID de root (0).
Archivo shadow con permisos de lectura
Enumeración de archivos que podemos leer:

Lo crackeamos usando JTR:

Archivo shadow con permisos de escritura
Enumeración de archivos con permisos de lectura:

Respaldamos el archivo:

En la máquina atacante, generamos un nuevo hash, donde, la contraseña será
newpassword:

Reemplazamos nuestro hash por el que tiene root:

Nos conectamos usando el comando
suen ingresando la nueva contraseña:

Si queremos hacer el rollback, debemos restaurar el archivo copiado en el segundo punto.
Modificación de parámetros del usuario root
Enumeración de permisos:

Generamos la contraseña
passwordusandoopenssl:

Modificamos la columna con la contraseña generada y escalamos privilegios:

Agregar un nuevo usuario root
Podemos agregar un nuevo usuario con la estructura del usuario root y un hash de contraseña al archivo
/etc/passwd:

Abusando de los permisos de sudo
Sudo es un programa que le permite a los usuario ejecutar otros programas con privilegios de otros usuarios.
Los privilegios de sudo pueden ser asignados a un usuario permitiendole correr ciertos comandos como root, sin la necesidad de cambiar de usuario o ganar un privilegio excesivo.
Por lo tanto, cuando se usa el comando sudo, el sistema valida si el usuario tiene los permisos correctos para ejecutar dicho comando (se encuentra configurado en /etc/sudoers).
Para correr un programa usando sudo, se debe hacer de la siguiente forma:
Si queremos correr un programa como otro usuario, debemos usar el siguiente comando:
Como atacantes, podemos usar el siguiente comando: sudo -l. Con este comando podemos identificar si el usuario posee privilegios de sudo en ciertos comandos, y ver si algunos de ellos no solicita el ingreso de la contraseña para su ejecución (aparecerá NOPASSWD).
Si podemos usar cualquier comando, y sabemos la contraseña del usuario, podemos usar sudo su para obtener una shell como root.
En caso de que no podamos usar su, existen otras alternativas para escalar privilegios:
Incluso, podríamos usar una secuencia de escape de la shell.
Secuencia de escape de la shell
Incluso si estamos restringidos a usar ciertos programas con sudo, podríamos escapar del programa para obtener una shell.
Las secuencia de escape de la shell las podemos encontrar en GTFOBins.
Abusando de las Intended Functionality
Si un programa no tiene una secuencia de escape, aún es posible escalar privilegios.
Podemos leer archivos como root, y con esto extraer información (como contraseñas, hashes, llaves, etc.).
Si podemos escribir archivos como root, podemos insertar o modificar información.
Variables de entorno
Los programas que se ejecutan con sudo pueden heredar las variables de entorno desde el entorno del usuario.
Si en el archivo /etc/sudoers encontramos la opción env_reset, sudo ejecutará el programa en un nuevo entorno mínimo.
La opción env_keep puede ser usada para mantener las variables de entorno del entorno de un usuario.
Estas opciones se pueden encontrar con el comando sudo -l.
LD_PRELOAD
Es una variable de entorno que puede ser configurada para la ruta de un archivo shared object (.so).
Cuando se encuentra habilitado, el shared object puede ser cargado antes de cualquier otra cosa.
Podemos crear un shared object con una función init(), donde ejecutaremos nuestro código cuando este sea cargado.
Este no funcionará si el ID del usuario real es diferente del ID del usuario efectivo.
Sudo debe estar configurado para mantener la variable de entorno LD_PRELOAD usando la opción env_keep.
LD_LIBRARY_PATH
Esta variable de entorno contiene una lista de directorios, donde, las librerías compartidas son buscadas primero.
El comando ldd puede ser usado para imprimir las librerías compartidas usado por un programa:
Si creamos una librería compartida con el mismo nombre de que usa uno de los programas, y establecer LD_LIBRARY_PATH en su directorio principal, el programa cargará nuestra librería compartida en su lugar.
Explotación
Generamos un script que usaremos para obtener una shell reversa con privilegios de root:
Nos ponemos a la escucha en el puerto indicado:
Ejecutamos el script con
tcpdump:
Enumeramos los permisos de
sudo:

Le damos permisos de
sudoersal usuario local:

Enumeramos los permisos de
sudo:

Usamos la secuencia de escape indicado en GTFOBins, el cual, nos permite escalar privilegios:


Al buscar apache2 en GTFOBins, vemos que no existen sencuencias de escape:

Si vemos la información del manual de apache2, podemos usar la opción -f para indicar un archivo de configuración:

Podemos indicar el archivo /etc/shadow, donde, nos dará un error mostrando información del archivo, del cual, obtenemos los hashes que posteriormente podríamos crackear:


Ahora con esto ingresamos como root al sistema:

Vemos que tenemos la opción env_keep+=LD_PRELOAD habilitada:

Por lo tanto, creamos el siguiente archivo C:
Compilamos y lo ejecutamos usando la variable de entorno con un comando que tengamos permitido usar con sudo:

Vemos que tenemos la opción env_keep+=LD_LIBRARY_PATH habilitada:

Ejecutamos el comando ldd en el servicio apache2:

Vemo que posee múltiples librerías compartidas.
Con esta información, creamos una librería llamada library_path.c:
Compilamos con el nombre de una de las librías que apache2 y lo ejecutamos usando la variable de entorno:

Abusando de los cron jobs
Los cron jobs son tareas programadas con la finalidad de ejecutar procesos periodicamente, como realizar respaldos, limpiar directorios, entre otros.
Los cron jobs se ejecutan con el mismo nivel de seguridad del usuario que los creó.
Por defecto, estos son ejecutados usando la shell /bin/sh, con variables de entorno limitados.
Con el comando crontab se crean los cron table files, los cuales, contendrán las tareas que necesitamos ejecutar.
Los archivos cron poseen 6 campos: minutos, horas, días, mes, semana y comando, por ejemplo: 0 */12 * * * /home/admin/backup.sh.
Los contrabs de los usuarios son alojados en /var/spool/cron/ o en /var/spool/cron/crontabs/, miestras que, los crontab del sistema se encuentran en /etc/crontab.
A veces, los archivos asociados a los cron jobs pueden tener fallas de configuración, como los permisos de estos. Por lo tanto, si podemos escribir el programa o el script que se encuentra en el cron job, podríamos reemplazarlo por nuestro código para escalar privilegios.
Como atacantes, es necesario buscar los archivos cron del usuario root, donde, se tengan permisos de escritura.
Descargamos
pspypara detectar scripts que se ejecutan de forma periodica:


Buscamos por archivos que podamos escribir:

Dejamos a la escucha el puerto 443:
Agregamos lo siguiente al script
backup.sh:

Usamos
lse.shpara enumerar loscron jobs:

Podemos revalidar usando enumeración manual:

Detectamos que tenemos permisos de escritura en el script:

Agregamos lo siguiente al script para obtener una shell con permisos de root:

Nos ponemos a la escucha:
Esperamos a que se genere la conexión:

Usando
lse.shenumeramos si podemos escribir un ejecutable en el path del cron job y podemos encontrar un archivo ejecutable dentro del archivo contrab:


Como el script
overwrite.shno especifica su ruta absoluta, podemos crear un script con el mismo nombre en la ruta/home/user:
Le damos permisos de ejecución al script nuevo:
Ejecutamos el nuevo binario creado en
/tmp:

Revisamos la configuración del archivo contrab, el cual, contiene un script que posee una wildcard en uno de los comandos que ejecuta:

Buscamos como obtener una shell con el comando
taren GTFOBins:

Creamos un archivo
elfconmsfvenompara obtener una shell reversa:
Subimos la shell, le damos permisos de ejecución y creamos los archivos con los nombres necesarios para ejecutar dicho binario:

Ponemos a la escucha el puerto indicado en msfvenom:

Permisos especiales
SetUID Bit
El permiso SetUID (conocido también como SUID o Set User ID Upon Execution) puede permitir a un usuario a ejecutar un programa con permisos de otro usuario.
Para detectar este permiso, debe aparecer una s, y podemos usar el siguiente comando para encontrar binarios con dicho permiso:
SetGID
El permiso SetGID (conocido también como SGID o Set Group ID) es otro permiso especial, el cual, permite correr el binario como si fueramos parte del grupo que lo creo. Al igual que en SUID, se debe tener una s en los permisos, y se puede detectar con el siguiente comando:
Para mayor información, visitar el siguiente enlace.
Explotación
Buscamos binarios con permisos SUID:

En GTFOBins validamos como ejecutar SUID del binario sed para leer el archivo
shadow, y con así, poder crackear el hash del usuario root:


Podríamos escribir en el archivo passwd, para agregar un nuevo usuario con permisos de root.
Enumeramos usando
lse.sh:

Buscamos exploits para la versión del binario exim:

Subimos el script, le damos permisos de ejecución y lo ejecutamos:
Si da error con interpretando
^M, usar el siguiente comando:sed -i -e "s/^M//" 39535.sh

La variable de entorno PATH contiene la lista de directorios donde la shell debería encontrar los programas.
Si un programa intenta ejecutar otro programa, pero este no especifica el la ruta absoluta de este, buscará en los directorios del PATH hasta encontrarlo.
Por lo tanto, si tenemos control sobre la variable PATH, podemos decirle que busque nuestro programa en un directorio donde podamos escribir.
Si un programa intenta ejecutar otro, el nombre de este aparecerá como string en el ejecutable. Por este motivo, podemos usar el comando stringspara buscar en el programa.
También, podemos usar strace para que programas se encuentra ejecutando.
Una tercera forma de obtener esta información, es es usando ltrace.
Si buscamos los SUID, podemos encontrar el binario suid-env:
Buscamos archivos con permisos SUID:

Al ejecutarlo, vemos que utiliza
apache2:

Usando
strings, vemos que inicia el servicioapache2, donde, no se especifica la ruta absoluta de este:

Usando
straceyltracecomprobamos que ejecuta dicho servicio:


Archivo C llamado
service.c:

Compilamos el binario:

Modificamos el PATH y ejecutamos el binario con el SUID:

En algunas shell (como en bash inferior a 4.2-048) es posible definir funciones con un nombre de rutas absolutas.
Estas funciones pueden ser exportadas para que subprocesos tengan acceso a ellas, y las funciones puedan tener prioridad sobre el ejecutable real que se llama.
Para este caso, se usará el binario suid-env2:
Enumeramos usando el siguiente comando:

Validamos el funcionamiento y los strings del binario:

Vemos que se ejecuta con el binario
sh:

Obtenemos la versión de
sh:

Creamos una función asociada al binario, donde, se ejecutar
/bin/bash -p, para luego poder usarlo:

Bash posee un modo debugging que puede ser habilitado con la opción -x, o modificando la variable de entorno SHELLOPTS para incluirlo en xtrace.
Por defecto, SHELLOPTS es solo lectura, sin embargo, el comando env permite configurar SHELLOPTS.
Cuando estamos en el modo debugging, bash usa la variable de entorno PS4 para mostrar un prompt extra para los estados de debug. Esta variable puede incluir un comando embebido, el cual, se ejecutará cada tiempo que es mostrado.
Si el archivo SUID corre otro programa a través de bash (usando system()), estas variables de entorno pueden ser heredadas.
Si el archivo SUID está siendo ejecutado, este comando se ejecutará con el privilegio del propietario.
En las versiones 4.4 y superiores, la variable de entorno PS4 no es heradada cuando la shell se ejecuta como root.
Usando el comando
env, validamos que podemos inyectar comandos en la variablePS4:

Ejecutamos el siguiente comando para copiar un binario de
bashcon permisosSUID:

Escalamos privilegios uando el binario con permisos SUID:

Encontrando credenciales
Cuando hacemos una evaluación de seguridad, podemos encontrar almacenamientos débiles de contraseñas, o que las contraseñas estan siendo reutilizadas, lo cual, podría ser una forma fácil de escalar privilegios.
Muchas de estas contraseñas se encuentran archivos de configuración (.conf, .config, .xml, .bak, entre otros).
A diferencia de otras contraseñas que podrían ser encontradas almacenadas en texto plano, la de root se encuentra de forma segura en formato de hash en /etc/shadow. Pero, si el usuario de root reutiliza su contraseña para los servicios, estas pueden ser usadas para obtener privilegios de root.
Los comandos utilizados por un usuario son registrados en el archivo history, el cual, podría contener contraseñas ingresadas por el usuario.
Si hacemos un ls -la en el directorio home del usuario, podemos ver que tenemos varios archivos history:

Si leemos dichos archivos, podemos encontrar la contraseña de root:

Podemos usar el siguiente comando para encontrar archivos de configuración, basados en el nombre de este:
También, podriamos buscar en directorios como el home, para ver si tenemos otros archivos de configuración que no contengan la palabra config o .conf:

Las llaves SSH pueden ser usadas para la autenticación en caso de que no tengamos la contraseña del usuario.
Estas se encuentran en pares: una privada y una pública. Si se obtiene la llave privada, podríamos conectarnos a la máquina local, o a una remota.
Para saber los equipos remotos, podemos buscar en el archivo
known_hosts.
Estas llaves por lo general son almacenadas en directios llamados .ssh, por lo tanto, si buscamos por ellos, podemos encontrar las llaves que necesitamos:

Copiamos la llave en el directorio temporal, le cambiamos los permisos y la usamos para conectarnos como root:

Privilegios de grupos
LXD es similar a Docker y es el administrador de contenedores de Ubuntu. Cuando se instala, todos los usuarios se agregan al grupo LXD, el cual, puede ser utilizado para aumentar privilegios creando un contenedor, haciendolo privilegiado, donde, podemos acceder al sistema de archivos del host en /mnt/root:

Descomprimimos la imagen Alpine:

Ejecutamos el proceso de inicialización de LXD (elegimos los valores por defecto):
Para mayor información, referirse al siguiente post.

Importamos la imagen local:

Iniciamos un contenedor con privilegios con la opción security.privileged configurado en true, para poder correr un contenedor sin mapeo UID, haciendo al usuario root del contenedor igual como el root del host:

Montamos el sistema de archivos del host:

Finalmente, obtenemos una shell dentro de la instacia del contenedor. Ahora podemos navegar por el sistema de archivos del host montado como root. Por lo tanto, si queremos ir al directorio home de root, podemos hacerlo con el comando cd /mnt/root/root:

Colocar un usuario en el grupo docker es esencialmente equivalente al acceso de nivel de root al sistema de archivos sin necesidad de una contraseña.
Los miembros del grupo docker pueden generar nuevos contenedores docker.
Por ejemplo, con el siguiente comando, creamos una nueva instacia de Docker con el directorio /root en el sistema de archivos del host montado como un volumen:
Con esto, podríamos encontrar llaves SSH u otra información que nos permita escalar privilegios. Por lo tanto, se podría montar cualquier directorio.
Los usuarios dentro del grupo de disk tienen acceso total a cualquier dispositivo contenido en /dev, como /dev/sda1, que suele ser el dispositivo principal utilizado por el sistema operativo.
Un atacante con estos privilegios puede usar debugfs para acceder a todo el sistema de archivos con privilegios de nivel root. Al igual que con el ejemplo del grupo Docker, esto podría aprovecharse para recuperar claves SSH, credenciales o para agregar un usuario.
Los miembros del grupo adm pueden leer todos los registros almacenados en /var/log. Esto no otorga acceso como root, pero podría aprovecharse para recopilar datos confidenciales almacenados en archivos de registro o enumerar las acciones del usuario y ejecutar cron jobs:

Técnicas misceláneas
Si tenemos instalado tcpdump, usuarios privilegiados pueden capturar tráfico de la red, donde, se pueden encontrar intercambio de credenciales en texto plano.
Existen múltiples herramientas (como net-creds y PCredz) que nos pueden ayudar a analizar el tráfico capturado en busqueda de credenciales. Se pueden detectar:
Números de tarjetas de crédito
Credenciales o hashes de los siguientes protocolos:
SNMP
NTLMv2
SMBv2
Kerberos
HTTP
FTP
POP
IMAP
Telnet
SMTP
NFS permite a los usuarios acceder a archivos y directorios compartidos a través de la red alojados en sistemas Linux. Este trabaja con el puerto TCP/UDP 2049, y cualquier montaje accesible puede ser listado usando los siguientes comandos:

Cuando los volumenes NFS son creados, se pueden configurar las siguientes opciones:
root_squash: si el usuario root es usado para acceder a los recursos compartidos por NFS, será cambiado por el usuarionfsnobody, el cual, es una cuenta sin privilegiosno_root_squash: los usuarios remotos que se conectan a los recursos compartidos usando el usuario root, podrán crear archivos en el servidor NFS como el usuario root. Esto permitiría la creación de scripts/programas con el bits SUID configurado
Si al revisar el archivo /etc/exports vemos que tiene los directorios con la opción no_root_squash, podemos hacer lo siguiente:

Crear el siguiente archivo C:
Compilamos nuestro archivo:
Montamos el directorio
/tmp:
Copiamos el binario y le damos permisos de SUID:

Ejecutamos el binarioL

Tmux es una herramienta que permite acceder a múltiples sesiones de terminal simultáneamente en una sola ventana.
Cuando estamos trabajando en tmux podemos salir de la sesión (sin cerrarla), en la cual, podemos dejar procesos ejecutandose (como por ejemplo, un escaneo de nmap).
Por muchas razones, un usuario puede dejar un proceso tmux ejecutándose como un usuario privilegiado, como root, al que le podemos hacer un hijacking. Esto se puede hacer con los siguientes comandos para crear una nueva sesión compartida y modificar la propiedad.
Si podemos comprometer el grupo dev, podríamos conectarnos a la sesión y ganar acceso como root.
Lo primero es validar el proceso tmux corriendo:

Confirmamos los permisos:

Revisamos nuestros permisos:

Ingresamos a la sesión de tmux y validamos los permisos del usuario con el cual quedamos conectado:

Last updated





