MOPB-09-2007:PHP wddx_deserialize() String Append Buffer Overflow Vulnerability

(Last Updated On: )

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

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

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

■リファレンス
なし

■サマリ
Stefan EsserがPHPセキュリティレスポンスチームを去ってから、PHPのCVSリポジトリに擬似的なセキュリティフィックスが行われています。擬似的なセキュリティフィックスとは、危険と考えられている関数(strncpy, sprintfなど)をより安全と考えられている関数(strlcpy, spprinfなど)に書き換える事を意味しています。

残念ながらこれらの変更は非常にずさんであり、コードを壊し、ユーザから苦情があったため、いくつか場所でリバート(訳注:リポジトリに行った変更を元に戻すこと)しなければなりませんでした。そして、WDDX拡張モジュールを利用している場合、特殊に細工された(悪意のある)WDDXパケットによりバッファーオーバーフローが発生するコードが追加されました。この問題に対してユーザから苦情があることは考えづらく、アドバイザリが無い場合はおそらく次のPHPリリースに含まれていたと思われます。

■影響するバージョン
CVS版のPHPのみ

■詳細情報
先週、以下の問題のあるstrncpyからstrlcpyの変更が行われ、CVSリポジトリに追加されました。

--- wddx.c	2007/02/24 02:17:27	1.119.2.10.2.11
+++ wddx.c	2007/02/24 17:59:45	1.119.2.10.2.12
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: wddx.c,v 1.119.2.10.2.11 2007/02/24 02:17:27 helly Exp $ */
+/* $Id: wddx.c,v 1.119.2.10.2.12 2007/02/24 17:59:45 iliaa Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -1034,10 +1034,9 @@
    Z_STRVAL_P(ent->data) = estrndup(decoded, decoded_len);
    Z_STRLEN_P(ent->data) = decoded_len;
 } else {
-   Z_STRVAL_P(ent->data) = erealloc(Z_STRVAL_P(ent->data),
-   Z_STRLEN_P(ent->data) + decoded_len + 1);
-   strncpy(Z_STRVAL_P(ent->data)+Z_STRLEN_P(ent->data), decoded, decoded_len);
    Z_STRLEN_P(ent->data) += decoded_len;
+   Z_STRVAL_P(ent->data) = erealloc(Z_STRVAL_P(ent->data), Z_STRLEN_P(ent->data) + 1);
+   strlcpy(Z_STRVAL_P(ent->data) + Z_STRLEN_P(ent->data), decoded, Z_STRLEN_P(ent->data) + 1);
    Z_STRVAL_P(ent->data)[Z_STRLEN_P(ent->data)] = '\0';
 }

Cプログラマにとってはボールドの部分が間違っている事は明らかなはずです。正しい関数はstrlcpy()ではなく、strlcat()であり加算を行っている部分も誤りです。

このWDDXのアンシリアライズコードの小さな欠陥は、<string>等のタグが他のタグに解釈されるなどにより、バッファオーバーフローを引き起こします。この状態は悪意のある(攻撃者が送信した)WDDXパケットの場合にのみ発生します。

■PoC、攻撃コードまたは再現手順
この脆弱性はCVS版のPHPにのみ存在する事を発見したばかりで、任意コードを実行する攻撃コードは作成していません。しかしながら、任意コードを実行する攻撃が可能であること、それを月末までには証明できることを疑っていません。その時までは、添付のPOCコードでPHPがメモリマネージャで確認できます。

■備考
PHP開発者がPHPをより安全にするためにこのような変更を行う事は理解できます。しかし、コミットする前に複数回チェックする事をお勧めします。WDDXで行われたような変更は、悪意のあるパケットのみで脆弱性が現れるためこれらの問題はセキュリティ監査が明らかにするまで発見されないので、非常に危険です。

この様な変更によってのみ我々の主張が証明できます。
(訳注:「我々の主張」とは「安易により安全だとされている関数への書き換えを行う事は危険」とする主張と思われます)

投稿者: yohgaki