apache http server
SophosLabs Uncut

Vulnerabilidad día cero del servidor web Apache fácil de explotar ¡parchea ya!

El prestigioso servidor web Apache acaba de ser actualizado para corregir una peligrosa vulnerabilidad de ejecución remota de código (RCE).

Este fallo es ya ampliamente conocido y fácil de explotar, con ejemplos que ahora circulan libremente en Twitter, y una sola solicitud web de aspecto inocente dirigida a tu servidor podría ser suficiente para que un atacante lo tome por completo.

Las estimaciones sobre la prevalencia varían, pero una buena estimación es que entre una cuarta y una tercera parte de los servicios web que se prestan en Internet acaban siendo gestionados por una instancia de Apache.

Recuerda que incluso si los servidores web públicos de tu organización no son Apache (quizás utilices el popular producto nginx en Unix, o Microsoft IIS en Windows), es posible que tengas Apache ejecutándose en algún lugar de tu red.

De hecho, cualquier producto de software que tenga su propia interfaz HTTP, como un sistema de gestión de documentos o un sistema de tickets de soporte, podría estar usando Apache como su servidor web integrado.

Por lo tanto, debes revisar tu red no sólo por los servidores web tradicionales hechos para los visitantes externos, sino también para los servidores HTTP dentro de tu red que los ciberdelincuentes, como las bandas de ransomware, podrían utilizar para ampliar o expandir un ataque que ya está en marcha.

Curiosamente, dada la naturaleza del fallo, esta vulnerabilidad, llamada CVE-2021-41773, se introdujo hace menos de un mes, en Apache 2.4.49.

Irónicamente, esto significa que los usuarios de Apache que fueron descuidados al actualizar la última vez, y todavía están en la versión 2.4.48 o anterior, se saltarán esta vulnerabilidad por completo.

Para parchear el fallo, actualiza inmediatamente a Apache 2.4.50.

Explicación del salto de directorio

Cuando escuchamos por primera vez sobre CVE-2021-41773, documentado como una “vulnerabilidad de divulgación de archivos y salto de directorio”, asumimos que el problema había pasado desapercibido en el código de Apache durante años.

Esto se debe a que los errores de salto de directorio son del siglo pasado, y muchas fallas de validación de ruta en el código contemporáneo resultan ser artefactos de programación que quedaron de una época menos cuidadosa.

En pocas palabras, un error de salto de directorio ocurre cuando un usuario intenta acceder a un archivo en el servidor que debería estar bloqueado, pero falla la verificación de seguridad del nombre del archivo.

Este error de programación es fácil de cometer porque hay muchas formas diferentes de referirse a un mismo archivo y hay que tenerlas todas en cuenta.

Por ejemplo, supongamos que se encuentra actualmente en un directorio llamado /home/duck (el equivalente de C:\ Users\duck en Windows), donde ha colocado un archivo llamado findme.txt.

Canónicamente, que es el término de la jerga para “la única forma verdadera de hacerlo”, se referiría a este archivo como:

/home/duck/findme.txt

Si quisieras asegurarte de que este archivo realmente se encuentra en el directorio /home/duck, la forma programática obvia de hacerlo sería simplemente verificar que el nombre completo del archivo comience con /home/duck/, por ejemplo, así:

Pero esto no es suficiente, porque todos los sistemas de archivo principales en todos los sistemas operativos principales permiten tener nombres de archivo que “saltan” dentro del árbol de directorios, por ejemplo, como este:

/home/duck/subdir1/subdir2/../../findme.txt
/home/duck/../../etc/passwd

En los nombres de directorio, punto-punto es la abreviatura de “subir un directorio”, de modo que en el primer nombre de archivo anterior, subdir1/subdir2/ desciende dos niveles más en el árbol de directorios, mientras que ../../ remonta de nuevo dos niveles.

En otras palabras, cada instancia de ../ en un nombre de archivo esencialmente cancela el nombre del directorio que lo precede inmediatamente en la ruta.

Nuestra función simplista isfilewithinpath() concluiría que los archivos findme.txt y passwd anteriores estaban contenidos de forma segura debajo de la “ruta raíz” de /home/duck/, porque ambas rutas comienzan exactamente con esa cadena de texto.

Pero solo el primer archivo está en /home/duck/, porque esos nombres se simplifican a:

/home/duck/subdir1/../findme.txt
/home/../etc/passwd

Que a su vez simplifican, o canonizan, a:

/home/duck/findme.txt
/etc/passwd

Uno de ellos es nuestro propio archivo findme.txt, guardado de forma segura en nuestro propio árbol de directorios, mientras que el otro es el archivo central de contraseñas de Unix / Linux del directorio del sistema /etc.

(En los sistemas modernos, el archivo passwd es un nombre poco apropiado: contiene nombres de usuario, pero por razones de seguridad no ha contenido contraseñas o incluso hashes de contraseñas durante muchas décadas, en caso de que te lo preguntes).

De hecho, incluso puede usar punto-punto como una especie de mecanismo de escape-completamente-desde-cualquier-lugar, porque cuando llega al directorio raíz del propio sistema, típicamente / en Unix o C:\ en Windows, cada punto-punto se ignora, así:

/home/duck/findme.txt -> /home/duck/findme.txt
/home/duck/../findme.txt -> /home/findme.txt
/home/duck/../../findme.txt -> /findme.txt
/home/duck/../../../../findme.txt -> /findme.txt <- hemos llegado al techo y ahora simplemente nos quedamos allí (sin errores)
/home/duck/../../../../../findme.txt -> /findme.txt

En otras palabras, no es necesario que conozca su lugar exacto en la jerarquía de directorios para escapar a cualquier otro subdirectorio específico, siempre que coloques muchas entradas de puntos-puntos y barras en el nombre del archivo.

En particular, no provocarás un error si accidentalmente tiene más puntos de los estrictamente necesarios.

Prueba el siguiente comando en un ordenador con Windows desde casi cualquier lugar de la unidad C:, e imprimirás el archivo de hosts (una lista de anulaciones de números de IP para nombres de servidores específicos, que a menudo usan usuarios legítimos para bloquear redes publicitarias molestas y malware para bloquear sitios web útiles de ciberseguridad).

Ten en cuenta que este nombre de archivo es un nombre de archivo relativo de apariencia inocente (porque no denota explícitamente una ruta cableada que quieras usar), pero gracias al truco punto-punto-barra, actúa efectivamente como un nombre de ruta absoluto.

Los puntos te lanzan hacia arriba hasta llegar a C:\, donde simplemente rebotas repetidamente en el techo y permaneces en C:\ hasta que el camino comienza a descender nuevamente hasta el punto final deseado:

-- I went three levels down in my own home directory:

C:\Users\duck\test\subdir1\subdir2> type ..\..\..\..\..\..\..\..\..\..\Windows\System32\drivers\etc\hosts

-- But even using a non-absolute path I traversed predictably to the Windows directory:

# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
[. . .]
# For example:
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host

# localhost name resolution is handled within DNS itself.
#       127.0.0.1       localhost
#       ::1             localhost

Todo el software preocupado de la seguridad, especialmente los servidores web, debe estar atento a este tipo de trucos de punto-punto.

El truco de salto de directorio puede permitir a los atacantes especificar nombres de archivos que parecen estar en una ubicación inofensiva y que, por lo tanto, los atacantes pueden leer, o incluso escribir o ejecutar, cuando se supone que no deben verlos archivos en absoluto.

Si quisiéramos buscar el truco de los puntos en una URL, tendríamos que buscar puntos dobles y reaccionar en consecuencia, por ejemplo, de esta manera, donde recorremos la cadena de ruta para ver si la subcadena no confiable …/ aparece en cualquier momento:

Pero esta no es una prueba lo suficientemente estricta para un servidor web, porque las URL que incluyen nombres de archivo y ruta se pueden codificar utilizando lo que se conoce como secuencias de escape de URL.

Los escapes de URL representan caracteres ASCII que de otro modo serían ilegales en las URL convirtiéndolos en un signo de porcentaje seguido de dos dígitos hexadecimales para representar el código ASCII.

No puedes tener espacios en una URL, por ejemplo, por lo que si desea utilizar un nombre de archivo o directorio que incluya un espacio como parte de una URL, debes transmitir cada espacio como %20, abreviatura de “reemplace esto con Código hexadecimal ASCII 0x20 (decimal 32)”, que denota un carácter de espacio.

Códigos de escape URL de los 128 caracteres ASCII.
%2E (punto) resaltado en rojo.

Incluso si un carácter en una URL no necesita escapar, generalmente puedes hacerlo escapar de todos modos en tu solicitud web, y el servidor en el otro extremo lo decodificará y lo usará correctamente, como comprobarás si pruebas uno o ambos de estos comandos:

 $ curl -D - https://nakedsecurity.sophos.com/podcast/
 $ curl -D - https://nakedsecurity.sophos.com/%70%6F%64%63%61%73%74/

La ruta de la URL en el segundo comando anterior es solo la palabra podcast convertida en códigos de escape de URL utilizando la tabla anterior.

Por lo tanto, para detectar la aparición de la secuencia de puntos en una ruta de URL, realmente necesitas buscar alguna o todas las siguientes formas diferentes de codificarla:

   . . <- ambos puntos se pueden representar literalmente como ellos mismos

   %2E. <- o el primer punto solo se puede escapar
   %2e. <- y ten en cuenta que los escapes de URL pueden usar dígitos hexadecimales en mayúsculas o minúsculas

   . %2E <- o el segundo punto solo puede escaparse
   . %2e

   %2E %2E <- o ambos pueden escaparse
   %2e %2E
   %2e %2E
   %2e %2e

El error CVE-2021-41733 introducido en Apache 2.4.49 fue un nuevo código agregado para normalizar o canonizar las rutas de URL para eliminar partes inconsistentes, innecesarias o peligrosas del nombre de ruta pero (por lo que podemos ver) el código solo detectó correctamente los primeros tres casos anteriores, donde ambos puntos se enviaron sin escape, o solo se escapó el primer punto.

Al codificar el segundo punto como %2E, podría omitir la verificación de punto y punto y, por lo tanto, explotar esta vulnerabilidad de salto de directorio con un nombre adecuado.

Los informes iniciales implicaban correctamente, que este error se podía aprovechar para leer archivos que estaban fuera de los límites, incluido el acceso a archivos fuera del árbol de directorios del servidor web, así como la descarga de secuencias de comandos y otros archivos de código fuente dentro del árbol del servidor que se suponía que no debían ser directamente accesibles para los visitantes del sitio web.

Eso es bastante malo, pero resulta que al solicitar un archivo no autorizado, por ejemplo, al intentar acceder al intérprete de shell del sistema y, al mismo tiempo, proporcionar un encabezado HTTP no autorizado en su solicitud, es posible que no solo pueda ejecutar arbitrariamente programas en el servidor, sino también para pasar parámetros arbitrarios (opciones de línea de comando) a esos programas.

Cuando tienes acceso remoto no autenticado a un shell de comandos como bash, y puedes enviarle los comandos que desees a través de una simple solicitud HTTP, prácticamente tienes una “puerta trasera” de servidor genérico, y tienes acceso al sistema por completo.

El error se ha corregido de forma algo torpe al comprobar explícitamente una secuencia de puntos en la que el primer carácter ya aparece como un punto, ya sea porque se envió literalmente o ya se ha convertido, mientras que el segundo carácter puede aparecer como un punto literal o como una secuencia %2E que aún no se ha eliminado.

¿Qué hacer?

  • Si tienes Apache 2.4.49, debe actualizar de inmediato a Apache 2.4.50 si aún no lo has hecho. Este error es ampliamente conocido y el código de muestra para abusar de él está ampliamente disponible online.
  • Si tienes una versión anterior de Apache, este error no te afecta. Irónicamente, quizás, si tardaste en actualizar la última vez (la versión 2.4.49 salió el 15 de septiembre de 2021), esta lentitud te ha protegido esta vez.
  • No te limites a reparar este fallo en los servidores web conectados a Internet. Primero, hazlo en los expuestos públicamente, porque ahí es donde radica el peligro inmediato. Pero espera que los ciberdelincuentes adopten este exploit como un truco de “movimiento lateral” una vez que ya tienen una cabeza de playa dentro de una red, porque es muy fácil de abusar.
  • Si tiene dudas sobre si algún software habilitado para la web que utilizas incluye Apache, pregunta a su proveedor. Si tienes herramientas de escaneo de red como Nmap disponibles, puedes buscar servidores HTTP o HTTPS en tu propia red y verificar sus encabezados de respuesta, que a menudo revelan el código del servidor en uso, especialmente en el Server: header.

EJEMPLOS DE COMANDOS CURL PARA BUSCAR APACHE

Si conoces el nombre del servidor (o la IP) y el número de puerto de los servicios HTTP o HTTPS en tu red, puedes ver los encabezados que regresan cuando envías una solicitud web básica, como puedes ver aquí:

$ curl --http-1.1 --head https://nakedsecurity.sophos.com/
HTTP/1.1 200 OK
Server: nginx                   <-- We're using Nginx
Date: Wed, 06 Oct 2021 17:19:46 GMT
Content-Type: text/html; charset=UTF-8
[. . . ]


$  curl --http1.1 --head https://www.apache.org
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 73991
Server: Apache                  <-- As you would expect!
[. . .]


$ curl --http1.1 --head https://127.0.0.1:8888
HTTP/1.1 501 Not implmemented
Server: Lua-TLS-Generic         <-- Local test server I use for articles
Connection: close
Content-Type: text/plain
[. . .]

Algunos resultados pueden no ser concluyentes porque no devuelven un encabezado Server:, como la excelente herramienta gratuita de administración de código fuente de Fossil que usamos para nuestro código de muestra.

Este producto tiene un servidor web que no usa Apache, pero no tiene una etiqueta de servidor propia:

$ fossil ui
Listening for HTTP requests on TCP port 8080
[. . .]


$ curl --http1.1 --head http://127.0.0.1:8080
HTTP/1.0 302 Moved Temporarily
Date: Wed, 6 Oct 2021 17:23:52 +0000
Connection: close
X-Frame-Options: SAMEORIGIN
[. . .]

Del mismo modo, algunos servidores pueden elegir deliberadamente identificarse a sí mismos como algo diferente de lo que realmente son, ya sea como un señuelo para engañar a los escáneres de red poco avanzados que les lanzan rutinariamente “pruebas” de exploits no deseados, o por razones de compatibilidad con aplicaciones de cliente que esperan un proveedor específico en el otro extremo.

Dejar un comentario

Your email address will not be published.