El venerable servidor web Apache se acaba de actualizar para corregir un error peligroso en la ejecución remota de código (RCE).
Este error ya es bien conocido y trivial de explotar, con ejemplos que ahora circulan libremente en Twitter, y una sola solicitud web de apariencia inocente a su servidor podría ser suficiente para que un atacante lo controle por completo.
Las estimaciones de la prevalencia de Apache varían, pero una buena estimación es que entre un cuarto y un tercio de los servicios web conectados a Internet terminarán siendo procesados por una instancia de Apache.
Tenga en cuenta que incluso si no ejecuta los servidores web de acceso público de su empresa en Apache (es posible que esté utilizando el popular nginx Producto bajo Unix, o Microsoft IIS en Windows), aún puede ejecutar Apache en cualquier lugar de su 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, utiliza Apache como un servidor web integrado.
Por lo tanto, no solo debe verificar en su red los servidores web tradicionales para visitantes externos, sino también los servidores HTTP dentro de su red que los ciberdelincuentes, como las bandas de ransomware, podrían usar para extender o expandir un ataque que ya está en progreso.
Dada la naturaleza del error, este error se llama fascinante. CVE-2021-41773, se introdujo en Apache 2.4.49 hace menos de un mes.
Irónicamente, esto significa que los usuarios de Apache que fueron descuidados con la actualización la última vez y todavía están volviendo a la versión 2.4.48 o anterior se saltearán esta vulnerabilidad por completo.
Para parchear contra el error, actualizar inmediatamente a Apache 2.4.50.
Cruce de camino explicado
Cuando escuchamos por primera vez sobre CVE-2021-41773, documentado como «Vulnerabilidad de divulgación de archivos y cruce de rutas», asumimos que el error había estado en el código de Apache sin ser detectado durante años.
Esto se debe a que los errores de recorrido de ruta solo aparecieron en el último siglo, y muchos errores 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 términos simples, un error de recorrido de ruta ocurre cuando un usuario intenta acceder a un archivo en el servidor que debería haber sido 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 hacer referencia al mismo archivo y debe considerarlas todas.
Por ejemplo, digamos que se encuentra actualmente en un directorio llamado /home/duck (el equivalente de C:Usersduck en Windows) donde encontrará un archivo llamado. he dejado caer findme.txt.
Canonical, ese es el término técnico para «La única forma verdadera», nombrarías este archivo así:
/home/duck/findme.txt
Si desea asegurarse de que este archivo esté realmente en el /home/duck Directory, la forma programática obvia de hacer esto sería simplemente verificar que el nombre de archivo completo comience con /home/duck/, por ejemplo así:
Sin embargo, esto no es lo suficientemente bueno, ya que todos los sistemas de archivos principales en todos los sistemas operativos principales permiten nombres de archivos que «saltan» dentro del árbol de directorios, por ejemplo, de la siguiente manera:
/home/duck/subdir1/subdir2/../../findme.txt /home/duck/../../etc/passwd
En nombres de directorio, dot-dot es la abreviatura de «subir un directorio», por lo que en el primer nombre de archivo anterior, subdir1/subdir2/ va dos niveles más profundo en el árbol de directorios, mientras que el ../../ lo siguiente sube de nuevo dos niveles.
En otras palabras, cualquier instancia de ../ en un nombre de archivo esencialmente anula el nombre del directorio que lo precede inmediatamente en la ruta.
Nuestro simplificado isfilewithinpath() La función concluiría que los archivos findme.txt y passwd por encima de ambos estaban a salvo bajo la «ruta raíz» de /home/duck/porque ambas rutas comienzan con esta cadena de texto exacta.
Pero solo el primer archivo está realmente debajo /home/duck/porque estos nombres se simplifican a …
/home/duck/subdir1/../findme.txt /home/../etc/passwd
… que a su vez simplifica, ¿verdad? canonizar, para:
/home/duck/findme.txt /etc/passwd
Uno de ellos es el nuestro. findme.txt Archivo que se almacena de forma segura en nuestro propio árbol de directorios, mientras que el otro es el archivo de contraseña central de Unix / Linux del directorio del sistema /etc.
(En los sistemas modernos, el passwd El archivo está un poco mal: tiene nombres de usuario, pero por razones de seguridad no ha tenido contraseñas o incluso hashes de contraseña en él durante muchas décadas, en caso de que se lo pregunte.)
De hecho, incluso puede usar dot-dot como una especie de mecanismo de escape-completo-desde-cualquier lugar, porque cuando llega a la raíz del sistema usted mismo, normalmente / bajo Unix o C: En Windows, cualquier punto posterior se ignora de la siguiente manera:
/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 <-- we've hit the ceiling and now we simply stay there (no errors)/home/duck/../../../../../findme.txt --> /findme.txt
En otras palabras, no necesita saber su posición exacta en la jerarquía de directorios para acceder a cualquier otro subdirectorio en particular, siempre que incluya muchas entradas de puntos, puntos y barras en el nombre del archivo.
En particular, no provocará un error si accidentalmente tiene más puntos de los estrictamente necesarios.
Pruebe el siguiente comando en una computadora con Windows desde casi cualquier lugar del C: conduce e imprime el hosts Archivo (una lista de anulaciones de números de IP para nombres de servidores específicos, comúnmente utilizada por usuarios legítimos para bloquear redes publicitarias molestas y malware para bloquear sitios web de ciberseguridad útiles).
Tenga en cuenta que este nombre de archivo parece inocente relativo Nombre de archivo (porque no nombra explícitamente una ruta cableada que quiere usar), pero gracias a los trucos de punto, punto y barra, actúa efectivamente como un absolutamente Nombre de ruta.
Los puntos te llevan hasta que llegas C:donde sigues rebotando en el techo y te quedas dentro C: hasta que el camino comience de nuevo hasta el punto final deseado:
-- I went three levels down in my own home directory:C:Usersducktestsubdir1subdir2> type ....................WindowsSystem32driversetchosts-- 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
Cualquier software consciente de la seguridad, especialmente los servidores web, debe estar atento a este tipo de trucos puntuales.
La traición del recorrido de la ruta puede permitir a los atacantes especificar nombres de archivos que parecen estar en un lugar inofensivo y que, por lo tanto, los atacantes pueden leer, tal vez incluso escribir, o ejecutar si se supone que no deben ver los archivos en absoluto.
Si quisiéramos buscar punto-punto-traición en una URL, tendríamos que buscar puntos dobles y reaccionar en consecuencia, por ejemplo, donde recorremos la cadena de ruta para ver si la subcadena no confiable ../ aparece en cada punto:
Sin embargo, esto no es lo suficientemente estricto para un servidor web, ya que las URL que contienen nombres de archivo y ruta se pueden codificar con los llamados Secuencias de escape de URL.
Los escapes de URL representan caracteres ASCII que de otro modo no estarían permitidos en las URL convirtiéndolos en un signo de porcentaje seguido de dos dígitos hexadecimales para representar el código ASCII.
Por ejemplo, no puede incluir espacios en una URL. Por lo tanto, si desea usar un nombre de archivo o directorio que incluya un espacio como parte de una URL, debe usar cada espacio como un. transferir %20, abreviatura de «reemplace esto con el código hexadecimal ASCII 0x20 (decimal 32)», que denota un espacio.
Aunque no hay necesidad de escapar de un carácter en una URL, generalmente puede escapar de él en su solicitud web, y el servidor en el otro extremo lo decodificará y usará correctamente, como encontrará si lo intenta uno o ambos. 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 convertido a códigos de escape de URL utilizando la tabla anterior.
Entonces, para detectar la ocurrencia de la secuencia de puntos en una ruta de URL, realmente necesita buscar cualquiera o todos los siguientes tipos diferentes de codificación:
. . <-- both dots can be represented literally as themselves %2E . <-- or the first dot alone can be escaped %2e . <-- and note that URL escapes can use upper or lower case hex digits . %2E <-- or the second dot alone can be escaped . %2e %2E %2E <-- or they can both be escaped %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 canonicalizar 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 reconoció correctamente los primeros tres casos anteriores, donde ambos puntos se enviaron sin escapar o solo se escapó el primer punto.
Codificando el segundo Señalar como %2E, puede omitir la verificación punto a punto y así aprovechar esta vulnerabilidad denominada de recorrido de ruta.
Los informes iniciales indicaron correctamente que este error podría aprovecharse para leer archivos que estaban prohibidos, incluido el acceso a archivos fuera del árbol de directorios del servidor web y la descarga de secuencias de comandos y otros archivos de código fuente dentro del árbol del servidor que no estaban destinados a ser accesibles directamente para los visitantes del sitio web. .
Eso es bastante malo, pero resulta que cuando solicita un archivo fraudulento, por ejemplo, al intentar acceder al intérprete de shell del sistema, y al mismo tiempo incluir un encabezado HTTP fraudulento en su solicitud, es posible que no solo pueda ejecutar cualquier programas en el servidor, pero también pasan cualquier parámetro (opciones de línea de comando) a esos programas.
Si tiene acceso remoto no autenticado a un shell de comandos como bash, y puede enviarle los comandos que desee con una simple solicitud HTTP, tiene prácticamente una «puerta trasera» de servidor genérico y ha configurado el sistema por completo.
¿Qué tengo que hacer?
- Si tiene Apache 2.4.49, debe actualizar inmediatamente a Apache 2.4.50 si aún no lo ha hecho. Este error es bien conocido y el código de muestra para abusar de él está muy extendido en Internet.
- Si tiene una versión anterior de Apache, este error no le afectará. Irónicamente, su indolencia puede haberlo salvado esta vez si la última vez tardó en actualizar (2.4.49 se lanzó el 15 de septiembre de 2021).
- No se limite a cerrar esta brecha en los servidores web con acceso a Internet. Haga primero lo expuesto públicamente, porque ahí es donde reside su peligro inmediato. Sin embargo, espere que los ciberdelincuentes adopten este exploit como una táctica de «movimiento lateral» una vez que ya tengan una cabeza de playa en una red porque es muy fácil abusar de ella.
- Si tiene alguna duda sobre si alguno de los software habilitados para la web que está utilizando incluye Apache, comuníquese con su proveedor. Si tiene herramientas de escaneo de red como Nmap, puede buscar servidores HTTP o HTTPS en su propia red y verificar sus encabezados de respuesta, que a menudo revelan el código del servidor que se está utilizando, especialmente en el Server: Encabezamiento.
EJEMPLO DE COMANDOS DE CURL PARA BUSCAR APACHE
Si conoce el nombre del servidor (o número de IP) y el número de puerto de cualquier servicio HTTP o HTTPS en su red, puede ver los encabezados que regresan cuando envía una simple solicitud web a la red, como puede ver aquí:
$ curl --http-1.1 --head https://nakedsecurity.sophos.com/HTTP/1.1 200 OKServer: nginx <-- We're using NginxDate: Wed, 06 Oct 2021 17:19:46 GMTContent-Type: text/html; charset=UTF-8[. . . ]$ curl --http1.1 --head https://www.apache.orgHTTP/1.1 200 OKConnection: keep-aliveContent-Length: 73991Server: Apache <-- As you would expect![. . .]$ curl --http1.1 --head https://127.0.0.1:8888HTTP/1.1 501 Not implmementedServer: Lua-TLS-Generic <-- Local test server I use for articlesConnection: closeContent-Type: text/plain[. . .]
Es posible que algunos resultados no sean concluyentes porque no son un. devolver Server: Encabezados, 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 su propia etiqueta de servidor:
$ fossil uiListening for HTTP requests on TCP port 8080[. . .]$ curl --http1.1 --head http://127.0.0.1:8080HTTP/1.0 302 Moved TemporarilyDate: Wed, 6 Oct 2021 17:23:52 +0000Connection: closeX-Frame-Options: SAMEORIGIN[. . .]
Del mismo modo, algunos servidores pueden elegir intencionalmente identificarse a sí mismos como algo diferente de lo que realmente son, ya sea para engañar a los escáneres de red ingenuos que rutinariamente les lanzan «pruebas» de exploits no deseados, o por compatibilidad con aplicaciones cliente, aquellos que esperan un producto de un proveedor en particular. el otro extremo.