2011年 4月 20日
NULL文字無効化
PHP 5.3.4で導入されたNULL文字の無効化は,サンプルコードのような脆弱なスクリプトの問題の主要な部分を解決します。分かりやすくするためにファイル名はスクリプト中に記述します。
<?php
$filename = "/etc/passwd\0.png";
if (preg_match('|\.png$|', $filename)) {
echo readfile($filename);
}
?>
このコードをPHP 5.3.4以前で実行すると
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
[省略]
のようにパスワードファイルをダンプしてしまいます。PHP 5.3.4以降で実行するとreadfile関数がFALSEを返すため何も表示されません。
なぜPHPアプリにセキュリティホールが多いのか?:第41回 PHP 5.3.4におけるセキュリティ上重要な仕様変更|gihyo.jp … 技術評論社
PHP本体はC言語で記述されているため,ファイルを開く場合,最終的にはC言語のライブラリにファイル名が渡されます。C言語の文字列はバイナリセーフではなく,NULL文字(\0)は文字列の終端を表す文字になっています。一方,PHPの文字列はバイナリセーフであるためNULL文字は特別な意味を持ちません。
このPHP言語とC言語の文字列型変数の仕様の違いにより,脆弱なスクリプトが存在するとNULL文字を利用した強制ブラウズが行えるようになっていました。
サンプルコード1
if (preg_match(‘|.png$|’, $_GET[‘png_file’])) {
echo readfile($_GET[‘png_file’]);
}
?>
1年前 |
固定リンク | 2011年 4月 20日 |
