Shellshock, cómo se podría explotar en remoto
Shellshock
’(){ echo "hola"; };’
O incluso una función vacía y además anónima.
’(){ :; };’
Por otro, podemos definir variables de entorno en Bash, con env o cualquier otro método. E incluso, variables de entorno que son funciones. Por ejemplo.
env VARDENTORNO=’(){ :; };’
El fallo es que bash, al interpretar esto, no se detiene en el último punto y coma, sino que sigue. Por ejemplo:
env VARDENTORNO=’(){ :; }; echo "Se ha ejecutado el echo... y lo que queramos"’
lo ejecutaría cuando sea exportado o definida la función. Ya tenemos lo básico. En esta captura se resume el funcionamiento.

¿En remoto?
Imaginemos un CGI en Bash colgado en una página. Si se le envía al script una cabecera con una función definida y un comando a continuación... ejecutará ese comando a continuación. Este ejercicio está inspirado en esta prueba de concepto. Para empezar, definimos un script cualquiera que haga de CGI.

Ahora veamos paso a paso. Queremos pasarle una función cualquiera a una variable de entorno y a continuación un comando. Para eso, podemos aprovechar que Apache toma las cabeceras como (o las transforma en) variables de entorno. Por ejemplo, el User-Agent se introducirá como valor de la variable de entorno HTTP_USER_AGENT de Apache. Si se le envía una función definida y cuando termine un comando... interpretará el comando y ya tenemos la ejecución de código.
¿Cómo cambiar el User Agent? Muchas formas. ¿Qué comandos usarán si quieren hacer daño? Lo más sencillo (y de lo que habrá gusanos en cuestión de horas) sería descargar una shell php. Veamos cómo, por ejemplo con Curl.

Con el comando -H se le define la cabecera User-Agent (o cualquier otra). Se usa una función vacía (es irrelevante su contenido para este fin) y luego el comando interesante (wget). En este caso, se baja una shell pública en c99txt.net y se almacena en /var/www/upload/d.php en el servidor. Estos son los logs de Apache una vez lanzado....

Devuelve un 500 porque la función no termina limpiamente, pero el comando se ha ejecutado. ¿La prueba?
Obviamente, el atacante "solo" dispone de los permisos y privilegios de Apache, y esto limita dónde escribir y qué hacer. También es importante recordar que los comandos deben ir con sus rutas absolutas.
El ataque es posible con cualquier sistema que permita cambiar el user-agent, por ejemplo el plugin para Firefox

En resumen, algo muy apetecible para crear gusanos que busquen indiscriminadamente CGIs y una vez con permisos de ejecución, busquen nuevas víctimas ellos mismos. El problema es que no solo con Apache, sino con decenas de sistemas o programas que usen Bash en algún momento del proceso, se puede ser vulnerable. Durante los siguientes días, se seguirán encontrando fórmulas ingeniosas para explotar el fallo.