第32回 PHPセキュリティ月間
前回もArthur Gerkis氏が投稿したPHPにおけるコード実行を解説した文書を紹介しました。今回はその続きです。
- MOPS Submission 07: Our Dynamic PHP - Obvious and not so obvious PHP code injection and evaluation
- http://
www. php-security. org/ 2010/ 05/ 20/ mops-submission-07-our-dynamic-php/ index. html
動的コード
動的コードでのコード実行には
動的変数
ブラウザからの入力をグローバル変数として初期化するregister_
register_
<?php
foreach ($_GET as $key => $value) {
$$key = $value;
}
// ... some code
if (logged_in() || $authenticated) {
// ... administration area
}
?>
このコードに対して
http://www.example.com/index.php?authenticated=true
とアクセスすると,
PHP 4.
動的な関数
PHPには変数の中に保存された文字列を関数名として呼び出す,
可変関数の利用
<?php
$dyn_func = $_GET['dyn_func'];
$argument = $_GET['argument'];
$dyn_func($argument);
?>
このスクリプトに次のURLでアクセスすると,
http://www.example.com/index.php?dyn_func=system&argument=uname
次はcreate_
<?php
$foobar = "system('ls')";
$dyn_func = create_function('$foobar', "echo $foobar;");
$dyn_func('');
?>
このコードを実行するとsystem関数でlsコマンドが実行されます。create_
<?php
eval("function lambda_n() { echo system('ls'); }");
lambda_n();
?>
このように動作することはPHPマニュアルのcreate_
例1 create_
<?php
$newfunc = create_function('$a,$b', 'return "ln($a) + ln($b) = " . log($a * $b);');
echo "新しい匿名関数: $newfunc\n";
echo $newfunc(2, M_E) . "\n";
// 出力
// 新しい匿名関数: lambda_1
// ln(2) + ln(2.718281828459) = 1.6931471805599
?>
{}構文
PHPは変数とテキストを分けるための{$var_
<?php
$var_name = '変数';
echo "これは日本語のテキストに{$var_name}を埋め込んでいます";
?>
日本語のように単語の区切りが無いテキストに変数を埋め込むためには必須の構文です。この構文を利用すると変わったコード実行が可能になります。
<?php
$var = "I was innocent until ${`ls`} appeared here";
?>
このコードを実行すると`ls`をPHPスクリプト中で実行したようにlsコマンドを実行します。PHPがこのような動作するのは${}の中に入っている文字列をPHPのコードとして評価しているからです。${`ls`}はlsを実行した結果を変数名として利用しようとします。
これを利用すると,
<?php
$foobar = 'phpinfo';
${'foobar'}();
?>
この脆弱性だけではセキュリティ上の脅威となりませんが,