MOPB-15-2007:PHP shmop Functions Resource Verification Vulnerability

(Last Updated On: 2018年8月16日)

Stefanさんの承諾を得て日本語訳を公開しています。このブログの「the Month of PHP Bugs」カテゴリでMOPBの翻訳ページを一覧できます。分かりやすいように意訳できる部分は意訳します。厳密に原文の通り訳していないので正確性を重視される方は原文をご覧ください。

■クレジット
発見者:Stefan Esser
攻撃コード:Stefan Esser

■影響するバージョン
PHP 4.4.5以下、PHP 5.2.1以下

■PoCまたは攻撃コード
MOPB-15-2007.php
http://www.php-security.org/MOPB/code/MOPB-15-2007.php
MOPB-15-2007-RSA.php
http://www.php-security.org/MOPB/code/MOPB-15-2007-RSA.php

■リファレンス
なし

■サマリ
共有メモリ関数(shmop)はPHPから呼ばれる際に利用されるリソースタイプの確認に失敗しています。この為、ユーザが設定したデータを含む間違ったリソースで利用できます。例えば、特別に作成したGDモジュールのイメージリソースで任意のメモリアドレスを読み取る事が可能です。

■影響するバージョン
PHP 4.4.5未満、PHP 5.2.1未満

■詳細情報
PHPスクリプトは完全に実メモリから分離されていなければなりません。したがって、リクエストを超えて永続的に利用するDB接続やメモリなどを利用するPHP関数は、メモリ構造へのポインタを利用するのではなく、Zendエンジンのリソースとして登録され利用されなければなりません。

shmopモジュールの関数は共有メモリ情報、例えばマップされたメモリのベースアドレスやオフセット、に対してZendエンジンリソースを使用しています。PHPスクリプトがshmopモジュールの関数を利用して共有メモリにアクセスする場合、最初にリソースの仕組みによってパラメータが確認されます。

残念ながら、shmopモジュールの関数は利用されたリソースが本当にshmopのリソースかチェックに失敗しています。これにより、shmop関数は他の方法で作成されたリソースを使って呼び出されると任意のメモリアドレスへのアクセスを許してしまいます。最も簡単な攻撃方法はGDのイメージリソースを利用する方法です。GDイメージのリソースを利用する場合、イメージパレットを操作してshmopリソースの共有メモリセグメントへのベースアドレスへのポインタを操作できます。もちろんこれは任意コード実行攻撃に利用できます。

■PoC、攻撃コードまたは再現方法
二つの攻撃コードを添付しました。最初の攻撃コードはどのように任意アドレスを読み書きし、任意コードを実行するかデモンストレーションしています。二つ目の攻撃コードはmod_phpとmod_sslをロードしているApache上で利用します。Apache上で攻撃コードが呼び出された場合、ApacheのメモリからプライベートRSA鍵とSSL証明書をスキャンし、ダウンロード可能なファイルとして提供します。(x86上のApache 1, Linuxでテスト済み)

■備考
この脆弱性はローカル攻撃が可能な脆弱性が危険である事を示す非常によい例です。メモリをスキャンしてApacheのRSA鍵を探す、などはPHPで行えてはならない行為です。

たとえPHPのプロセスが別プロセスと別ユーザであっても、攻撃者は(PHPの脆弱性を利用して)マシン語を使用した方が、PHPコードだけで可能な攻撃より多くの攻撃を行えます。

投稿者: yohgaki