この問題について、情報集積および攻撃を遮断するようなスクリプトを作ってみました。
添付のファイルを${document_root}/xxxx.php 等の適当な名前にして設置し、index.phpの<?phpの冒頭付近で require_once xxxx.php; を追記すれば使えると思います。
com_jceを使ったクラッキングのパターンとして、wawalo.gifという名前のphpスクリプトをポストし、/images/stories/wawalo.gif にアクセスする事で、追加のバックドア用スクリプトを設置できるようにしたり、ディレクトリ等の情報を取ってきたりする仕組みのようです。
また、index.phpが存在していると決めつけて攻撃を仕掛けて来ているようにも見えますね…。
そうしますと、以下のようにするのもいくらか効果があるかもしれません。
index.phpをyyyy.php等の別名に変更し、そのスクリプトに繋がるように.htaccessの設定を切り替え、httpd.confの<Directory ${document_root}>内にある
DirectoryIndex index.html index.php
等の設定を以下のように変更
DirectoryIndex index.html yyyy.php
※気休め程度にしかならないかもしれませんが…。
<?php
class AttackRecorder {
// 情報集積用のpath (書き込み権限が必要になります)
// ウィンドウズ環境では、'C:\tmp\attacked_jce'等とするのが良いかもしれません
const logDir = '/tmp/attacked_jce';
final public static function check() {
// option=com_jce, com_jnews のアクセスを遮断 (実際に活用されている場合は、検出方法をもう少し厳密にする必要があるかもしれません)
if(array_key_exists('option', $_GET) && preg_match('"\bcom_(?:jce|jnews)\b"i',$_GET['option'])) {
// option=com_jnewsのアクセスを遮断 (こちらも実際に活用されている場合は、検出方法をもう少し厳密にする必要があるかもしれません)
} elseif(array_key_exists('REQUEST_URI', $_SERVER) && preg_match('"/components/com_jnews/"',$_SERVER['REQUEST_URI'])) {
} elseif(!empty($_FILES)) { // check eval php file
foreach($_FILES as $fSet) {
$data = file_get_contents($fSet['tmp_name']);
// 悪意のあるソースはevalを使っているようです
if(false === strpos($data,'<?') || !preg_match('"\beval\b(?=\s*\()"i', $data)) return;
}
} else {
return;
}
self::record();
exit;
}
final public static function record() {
if(!file_exists(self::logDir)) mkdir(self::logDir);
$tim = new DateTime();
$pBase = sprintf('%s/%s', self::logDir, $tim->format('Ymd-His'));
if(!empty($_FILES)) {
$idx = 0;
if(!empty($_FILES)) {
foreach($_FILES as $fSet) {
$path = sprintf('%s_%d.txt', $pBase, $idx++);
move_uploaded_file($fSet['tmp_name'], $path);
// eval無効化
$data = preg_replace('"\beval\b(?=\s*\()"i', '/*$0*/print', file_get_contents($path));
$fh = fopen($path, 'w');
fwrite($fh, $data);
fclose($fh);
}
}
}
if(isSet($_SERVER)) {
$ps = !empty($_POST);
$nm = sprintf('%s_%s', $pBase, $ps ? 'post' : 'get');
if(array_key_exists('REQUEST_URI', $_SERVER) && preg_match('"(?<=/components/com_)\w+(?=/)"', $_SERVER['REQUEST_URI'], $mt)) {
$nm .= sprintf('-%s', $mt[0]);
} elseif(array_key_exists('option', $_GET) && preg_match('"(?<=\bcom_)\w+\b"i',$_GET['option'], $mt)) {
$nm .= sprintf('-%s', $mt[0]);
}
$fh = fopen(sprintf('%s.txt', $nm), 'a');
flock($fh, LOCK_EX);
fwrite($fh, "########## _SERVER ##########\n");
foreach($_SERVER as $h => $v) {
// ログ取りする情報を調整
if(preg_match('"^(?:DOCUMENT_ROOT|GATEWAY_INTERFACE|HTTP_(?:HOST|ACCEPT)|PATH|SERVER_\w+|SCRIPT_(?:FILE)?NAME|PHP_SELF)$"i',$h)) continue;
fwrite($fh, sprintf("%s : %s\n", $h, $v));
}
if(!empty($_POST)) {
fwrite($fh, "########## _POST ##########\n");
foreach($_POST as $h => $v) {
fwrite($fh, sprintf("%s : %s\n", $h, $v));
}
}
if(!empty($_FILES)) {
fwrite($fh, "########## _FILE ##########\n");
foreach($_FILES as $fSet) {
fwrite($fh, sprintf("Name : %s\n", $fSet['name']));
}
}
fclose($fh);
}
}
}
AttackRecorder::check(); // ここでチェック!
?>
なお、php.iniを編集し、以下の記述の箇所を見つけ、disable_functionsを登録する事でかなりの攻撃が防げるのではないかと思われます。
↓
disable_functions = eval, phpinfo, system, shell_exec, exec, passthru, popen