※ 本ブログは、2023年9月28日にHP WOLF SECURITY BLOGにポストされた Picture this Exploit: Exploring the WebP Image Vulnerability CVE-2023-4863の日本語訳です。
2023年9月のPatch Tuseday(パッチの火曜日:品質更新プログラムリリース日)は、攻撃者によって悪用されているいくつかの脆弱性に焦点を当てました。なかでも深刻なバグの1つは、WebPにおける重大なヒープバッファオーバーフローのゼロデイ脆弱性(CVE-2023-4863)の公開です。この脆弱性はWebP画像をレンダリングするソフトウェアライブラリに存在し、このライブラリを使用するすべてのアプリケーションに影響します。影響を受けるアプリケーションの例としては、Google ChromeやMicrosoft EdgeのようなWebブラウザだけでなく、WebP画像を扱うデスクトップアプリケーションも含まれます。注目すべき点は、悪意のあるWebP画像をレンダリングすることでエクスプロイトが発動することです。Web閲覧中に画像が読み込まれた場合や、ローカルで画像を開いた場合など、多くの攻撃シナリオではユーザーによる操作がほとんど必要ありません。ブラウザーやエクスプロイトを内包するオフィスドキュメントを隔離するアプリケーション封じ込めソリューション(HP Sure Click Enterprise - Secure Browser など)よってまだ保護されていないエンドユーザーにとっては、エクスプロイトのリスクとパッチシステムを理解することが特に重要です。このブログ記事では、脆弱性と攻撃ベクトルについて詳しく説明します。
Webページで画像を使用するときは、必ずエンコードして圧縮します。その目的は、画像のファイルサイズを小さくして、画質を保ちながらできるだけ早く読み込めるようにすることです。画像を圧縮する場合、非可逆圧縮と可逆圧縮という2つの異なるアプローチがあります。非可逆圧縮では、解凍時に復元できない元のファイルの一部が削除されます。圧縮レベルが高いほど、不可逆的に削除される情報が多くなり、画質の低下が顕著になります。一方、可逆圧縮では、解凍時に品質を損なうことなく、常に元のファイルを復元できます。この特性のため、可逆圧縮を使用した画像は、非可逆圧縮のものより大きくなります。
CVE-2023-4863はWebP画像を可逆圧縮方式でデコードする手法で発見されたため、解凍方法について知ることは重要です。複雑な圧縮技術の実装でこのような脆弱性が見つかるのは珍しいことではありません。デコーダーの脆弱性には、長く不名誉な歴史があります。長年にわたり、画像、アーカイブ、オーディオ、ビデオなど多様なフォーマットを扱うあらゆる種類のデコーダーの実装で、重大な脆弱性が見つかってきました。最新のファジング技術は確かにそのような脆弱性を発見するのに役立ちますが、まだまだ発見されるべき脆弱性はたくさん存在すると考えて良いでしょう。
WebPは、画像をエンコードおよびデコードするためのコーデックライブラリです。WebPの可逆圧縮を、同じく可逆圧縮を使用するPNGフォーマットと比較すると、その画像は平均26%小さくなります。このため、WebPは読み込み時間が短縮され、Webアプリケーションにとって魅力的なものとなっています。WebPコーデックはオープンソースであるため、脆弱性を修正したソースコードを見ることができます。修正は主にハフマン符号化の実装に焦点を当てています。
ハフマン符号化は、可逆圧縮における一般的な技術です。ルックアップテーブルを作成し、シンボルにコードを割り当てるというものです。画像の場合、シンボルはピクセルの強度に対応します。発生頻度の高いシンボルには短いコードが割り当てられ、発生頻度の低いシンボルには長いコードが割り当てられます。しかし、この符号化の実装はそれほど単純ではありません。なぜなら、各コードは正しいシンボルに一義的にデコードされなければならないからです。可変長符号が使用されるため、正しくデコードするためには、それぞれに固有の接頭辞が必要です。そのため、ハフマン符号は接頭符号とも呼ばれます。
ハフマン符号化の結果は、復号に使われるルックアップテーブルと、ハフマン符号の列を持つビット列で表わされます。
ハフマン符号をデコードする際には、決められた数のビットが段階的に読み込まれます。通常、ビット数は最長のハフマン符号の長さに対応します。この例では3ビットで、最初のシーケンスとして "000 "が得られます。
このシーケンスをルックアップテーブルで検索し、対応するシンボルをデコードします。しかし最初のテーブルを見ても、このハフマン符号は見つかりません。したがって、正しいシンボルをデコードするためにテーブルを拡張しなければなりません。各コードの接頭辞は一意なので、拡張は問題なく行えます。こうしてできた表は図4のようになります。
このテーブルから、シーケンス "000 "が見つかり、最初のシンボル "H "のデコードに成功します。テーブルの接頭辞の長さを用いて、探索されたハフマン符号の有効長を求めます。これは次のビット列を正しくデコードするために重要です。この例では、ハフマン符号 "000 "の接頭辞長は2です。
つまり、最初のシーケンスの3番目のビットは、次のシーケンスで再利用されなければなりません。従って、次のステップでは追加の2ビットだけを読み取る必要があります。これで2番目のビット列 "011 "が得られます。
再び、このハフマン符号をテーブルから探し、シンボル "P "を復号します。このような手順で、符号全体を段階的にデコードしていきます。
デコード効率を向上させるため、生成された符号はテーブルのインデックスとして使用され、正しいシンボルを指します。こうすることで、ハフマン符号のために表全体を検索する必要はなく、そのインデックスを介して正しいエントリに直接アクセスできます。初期テーブルを拡張してエントリーを増やすと、性能は最適化されますが、テーブルが非常に大きくなる可能性があります。出現するシンボルが増えれば増えるほど、割り当てられたコードは長くなります。また、それらはテーブルのインデックスとして使用されるため、テーブルの長さは符号の長さの2のべき乗で大きくなります。
この問題を解決するために、通常は第2レベルのテーブルが使われます。最大符号長が定義され、この長さまでのシンボルはすべて第一のテーブルに直接エンコードされます。より長い符号に割り当てられたシンボルはすべて第二のテーブルにエンコードされ、ポインタを使用してリンクされます。しかし、これらの符号は周波数割当のためにそれほど頻繁にアクセスされないので、性能の低下はわずかである。
第2レベルのテーブルを使ってハフマン符号表を再構築し、最初のインデックス長を2ビットに減らすと、次のような表になります。ご覧のように、テーブルのサイズは大幅に縮小され、異なるシンボルが多数存在する場合にはさらに大きな効果があります。
要約すると、周波数の高い順にコードに割り当てられたシンボルのセットがあります。これらは対応するコードをインデックスとするルックアップテーブルに格納され、デコード時に照会できます。コードがある長さを超えると、単一のテーブルには格納されなくなり、第2レベルのテーブルで拡張されます。ハフマン符号化について詳しくは、こちらの記事をご覧ください。
パッチを当てたWebPコーデックのコードの変更点をよく見てみると、主に第2レベルテーブルの割り当てと充填方法の実装が変更されていることがわかります。
生成されたテーブルを保存するには、画像ファイルをレンダリングするプロセスでメモリを確保する必要があります。理想的には、割り当てられたメモリはテーブルのサイズと正確に一致します。しかし、生成されたテーブルのサイズを計算するのは非常に時間がかかるため、代わりに固定量のメモリが割り当てられます。この定義されたサイズは、生成されたテーブルを格納するのに十分な大きさであり、それを超えることはないと仮定されています。
しかし、ハフマンテーブルの入力は攻撃者によって制御され、その結果信頼できないソースから来るため、結果として得られるテーブルは異常に大きくなることになります。この脆弱性を悪用するために、テーブルの一部が割り当てられたメモリ領域を超えて書き込まれ、メモリ内の他の値を上書きします。これはヒープバッファオーバーフローと呼ばれ、非常に一般的なバッファオーバーフロー脆弱性のサブクラスです。攻撃者は、悪意のある WebP 画像を細工して、アクセスできないはずのメモリを上書きし、プロセスの制御フローに影響を与えることができます。最終的には、攻撃者がプロセス内でコードを実行し、データの流出やマルウェアのインストールなど、悪意のある目的を達成することが可能になります。
9月7日にリリースされたパッチは、割り当てられた領域外のメモリーの上書きを防ぐことで脆弱性を修正します。パフォーマンス上の理由から、固定サイズのメモリが割り当てられます。しかし、ハフマンテーブルを作成する際には、割り当てられたメモリセクションに実際のデータを書き込むことなく、最初のステップでテーブルのサイズが計算されます。テーブルがこのサイズを超えると、作成は中止され、画像はレンダリングできません。これにより、境界外書き込みが防止され、脆弱性が緩和されます。
多くの開発者は、アプリケーションでWebPをサポートするために、独自のコーデックを開発するのではなく、libwepbライブラリに依存しています。これは開発者にとっては便利ですが、人気のあるライブラリに脆弱性が存在する場合、多くのデバイスが危険にさらされることになります。このようにして、脆弱性は1つの特定のプログラムだけでなく、多くの異なるアプリケーションに影響を及ぼします。
この脆弱性を悪用する方法の一つは、オンライン広告を利用することです。攻撃者は、この脆弱性を悪用するために特別に細工したWebP画像をオンライン広告に掲載します。被害者は、そのWebサイトにアクセスするだけで、画像が読み込まれ、脆弱性が悪用されます。最近のWebブラウザのアーキテクチャにより、エクスプロイトコードはブラウザ内蔵のサンドボックス内で実行されます。しかし、攻撃者はエクスプロイトを連鎖させてサンドボックスを抜け出し、被害者のホストシステムに感染させることに非常に長けています。
現在、多くの一般的なWebブラウザ、画像ビューアやエディタ、その他のデスクトップアプリケーションがCVE-2023-4863の影響を受けています。要するに、脆弱なバージョンのライブラリを使って WebP 画像をレンダリングするアプリケーションはすべて、CVE-2023-4863 の影響を受けます。
影響を受けるアプリケーションの数が多いため、攻撃者は多くのベクターを使ってこの脆弱性を悪用する機会を得ており、脆弱性のウィンドウは大幅に広がっています。この脆弱性に関連するすべてのソフトウェアコンポーネントとそのパッチレベルをドキュメント化することは、どんなに優れたセキュリティチームにとっても困難なことでしょう。
脆弱なWebP実装を使用しているすべてのアプリケーションにパッチを当てるには、かなりの時間がかかるでしょう。この脆弱性がすでに攻撃者によって悪用されているという事実も安心できるものではありません。しかし、パッチが存在する前であっても、このような脆弱性を緩和するのに役立つアプリケーション分離のような予防技術があります。
しかし、どのようなタイプのアプリケーション隔離でもこの脆弱性を防げるわけではないことに注意することは重要です。例えば、ある種のリモートブラウザによる隔離アプローチではこのような攻撃を防ぐことはできません。
リモートブラウザ隔離技術では、Webサイトはローカルではなく、サーバ上でリモートレンダリングされます。その後、Webページの「無害化」されたバージョンがクライアントに渡され、ローカルブラウザで再度レンダリングされます。この方法により、マルウェアのダウンロードやエクスプロイトキットの実行は防ぐことができます。しかし、画像がリモートのブラウザからローカルのブラウザにそのままの形で渡される場合、今回の脆弱性からの保護にはならず、依然として侵害につながる可能性があります。
HP Sure Click Enterprise は、Web ブラウジングセッションをセキュアな micro-VM 内に隔離するため、ユーザーはこの脆弱性から保護されます。ユーザーがブラウジング中に悪意のある WebP 画像に遭遇した場合、エクスプロイトはホスト PC から隔離されたハードウェア実装されたコンテナ内で実行されます。これにより、ホストシステムが侵害され、機密データが流出するのを防ぐことができます。さらに、このアプローチは他のデスクトップアプリケーションにも拡張することができます。Web などの危険な場所からダウンロードされた悪意のある WebP イメージファイルから保護するために、HP Sure Click Enterprise のお客様はポリシーをカスタマイズして保護を強化することができます。詳しいガイダンスと設定例は、こちらのナレッジベース記事を参照してください:Protect against malicious WebP image files (hp.com)
デコーダーに影響を与える脆弱性は長年にわたって数多く存在してきました。ファジングの進歩にもかかわらず、このような新しいバグは定期的に表面化しています。影響を受けるWebPライブラリの人気を考えると、影響を受けるすべてのアプリケーションにパッチが適用されるまでには、しばらく時間がかかりそうです。HP Wolf Securityのアプリケーション隔離テクノロジーは、CVE-2023-4863のようなゼロデイ脆弱性から、たとえパッチが存在する前であっても、Web閲覧、Eメールの添付ファイルを開く、リンクをクリックする、ファイルをダウンロードするといった危険なアクティビティや攻撃ベクトルを隔離することで保護します。
Author : Patrick Schläpfer
監訳:日本HP