細工されたJPEGはPHPのメモリバグを悪用のトリガーとなる可能性がある

最も広く使用されているWebプログラミング言語の1つであるPHPは、コアレベルでの直接的な攻撃対象としてはめったに見なされません。セキュリティのフォーカスは通常、フレームワークとサードパーティライブラリーに向かいます。

しかし、新しい研究によると、PHPの組み込み機能、特にext/standard拡張機能は、画像ファイルなどの信頼されていない入力を処理する場合、重大なリスクをもたらす可能性があることが示されています。

これらの欠陥は、信頼できるコア関数でさえ特定の条件下では悪用可能になる可能性があることを示しています。

PHPの中核にはZendエンジンがあり、PHPスクリプトをコンパイルして実行します。これには、Zend VM(実行エンジン)、コンパイラー、メモリマネージャー、パフォーマンス最適化用のOPcacheなどのコンポーネントが含まれています。

このプロセス中に、画像処理用の関数などの組み込み関数はCコードを介してシステムメモリと直接相互作用します。これにより、メモリ処理バグに特に敏感になります。

ext/standard拡張機能はここで重要な役割を果たします。ファイル処理や画像メタデータ解析を含む数百のコア関数を提供します。

これらの関数はユーザーが制御できる入力(アップロードされた画像など)を処理するため、このレイヤーの脆弱性は広い影響を持つ可能性があります。

PT SwarmのリサーチャーたちはPHPの標準拡張機能を背後にあるCコードを分析し、ネイティブ画像処理関数に影響を与える2つのメモリセーフティ問題を発見しました:getimagesize()のヒープメモリ開示とiptcembed()のヒープバッファオーバーフロー。

最初の脆弱性はCVE-2025-14177(CVSS 6.3)として追跡され、EXIFメタデータなどのJPEG APPセグメントを解析するときのgetimagesize()関数に影響します。

PHPスクリプトが実行される場合、トークン化、抽象構文木への解析、オペコードへのコンパイル、最終的には実行というパイプラインに従います。

Image

問題は、チャンク読み込みの不適切な処理から生じます。PHPが大きなJPEGメタデータを複数のチャンクで読み込むとき、各チャンクを順序立てて追記するのではなく同じメモリロケーションに誤って書き込みます。その結果:

  • バッファの先頭が上書きされます。
  • バッファのテールは初期化されません。
  • 機密のヒープデータがユーザーに漏らされる可能性があります。

たとえば、細工されたJPEGファイルに大きなAPP1(EXIF)セグメントがあると、マルチチャンク読み込みをトリガーできます。攻撃者がデフォルトのチャンクサイズ(通常は8192バイト)を理解している場合、ファイルを構成してサーバープロセスから残りのメモリフラグメントをリークさせることができます。

リサーチャーたちは、メモリに識別可能なマーカーを埋め込み、脆弱な関数経由でそれらを取得することで、これを実証し、実データのリークを確認しました。

細工されたJPEGはPHPメモリをトリガーします

2番目の問題はiptcembed()関数に影響し、JPEGイメージにIPTCメタデータを挿入します。最初のバグとは異なり、このバグはヒープバッファオーバーフロー(より深刻な脆弱性のクラス)につながる可能性があります。

Image

根本的な原因はPHPがメモリを割り当てる方法にあります。この関数はfstat()を使用してファイルサイズを決定し、それに応じてバッファを割り当てます。ただし、バッファリミットを検証せずにEOFまで入力を読み込み続けます。

パイプ(FIFO)などの非標準ファイルを処理する場合、これは危険になります。ファイルサイズはゼロとして報告されます。そのような場合:

  • PHPは非常に小さなバッファを割り当てます。
  • 入力ストリームはデータの提供を続けます。
  • メモリ書き込みはバッファ境界を超過し、オーバーフローが発生します。

シンプルなデモンストレーションでは、リサーチャーたちはFIFOパイプを使用して大きなペイロードを持つ細工されたJPEGをストリーミングしました。その結果は、AddressSanitizer によって検出された確認済みのヒープバッファオーバーフロー であり、確実な悪用を証明しています。

PHP開発者は、ターゲットとなった修正で両方の問題に対処しました:

  • getimagesize()の場合、バッファポインタは各チャンク読み込み後に正しく進むようになり、上書きと初期化されていないメモリリークを防ぎます。
  • iptcembed()の場合、厳密なバウンドチェックが導入され、割り当てられたメモリを超える書き込みを停止し、リミットに達した場合は処理を安全に終了します。

関数iptcembed(php-src/ext/standard/iptc.c)はJPEGを再パッケージします:入力ストリームを読み込み、マーカー(APP、SOSなど)を解析し、同時にバイトを新しいバッファ(spoolbuf)にコピーします。

Image

これらの脆弱性は、重要な教訓を強調します:成熟し、広く信頼されているランタイムコンポーネントでさえ、微妙であるが危険な欠陥を含む可能性があります。特にCなどの低レベル言語で記述されている場合。

開発者とセキュリティチームにとって、教訓は明確です。ファイル、特に画像を処理する関数は盲目的に信頼すべきではありません。入力の検証、ファイルサイズの制限、PHPの最新化は、エクスポーチャーを減らすための必須の手順です。

攻撃者が画像メタデータなどの非従来型エントリーポイントの探索を続けるに従い、これらの調査結果は、アプリケーションスタックのすべてのレイヤー(長い間安全と考えられてきたものを含む)を精査することの重要性を強化します。

翻訳元: https://gbhackers.com/crafted-jpegs-trigger-php-memory/

ソース: gbhackers.com