Задача найти все файлы которые задаем по маске , и удалить последнюю строку.

Тема в разделе "Как сделать...", создана пользователем funman, 8 мар 2012.

  1. funman

    funman

    Регистр.:
    28 дек 2007
    Сообщения:
    155
    Симпатии:
    25
    Добрый день!

    У меня проблема, есть сайт на joomla, троян зарозил все JS файлы на сервере. пробовал удалять вручную , но файлов оч много.

    Решением проблемы вижу написать на PHP скрипт который бы рекурсивно нашел все JS файлы на сервере, потом удалил последнюю строчку с вредоносным кодом. Код везде разный (переменные сформированы из случайных символов, но общая структура одинаковая и главное он находится в конце)

    Из проблем по которым мне нужна ваша помощь вижу.
    1) Как мне перебрать все файлы во всех директориях начиная с определенной заданной + нужно из этого списка исключить файлы которые к примеру были отредактированы какого числа (к примеру те что я чистил сегодня в ручную . так как у них последняя строчка уже явно будет не вирусная)

    2) Как собственно наиболее быстрым способом удалять последнюю строчку , чтобы скрипт не вылетел по тайм-ауту и не сожрал всю память (файлы есть оч не маленькие)

    Могу сюда прикрепить образец зараженного файла из которого нужно удалять код, если это поможет. Заранее всем спасибо за любую помощь.
     
  2. funman

    funman

    Регистр.:
    28 дек 2007
    Сообщения:
    155
    Симпатии:
    25
    Вот ,что получилось , все вроде работает, только проблема в том что у файлов права должны быть минимум 666, как сделать чтобы строчки удалялись у файлов с правами 644

    PHP:
    <?php
     
    function scan_dir($dirname)
      {
        
    // Открываем текущую директорию
        
    $dir opendir($dirname);
        
    // Читаем в цикле директорию
        
    while (($file readdir($dir)) !== false)
        {
          
    // Если файл обрабатываем его содержимое
          
    if($file != "." && $file != "..")
          {
            
    // Если имеем дело с файлом - производим в нём замену
            
    if(is_file($dirname."/".$file))
            {
    //устанавливаем маску файла     
            
    if (preg_match("/.*?\.js/""$file"))
              {
    //устанавливаем фильтр на дату файла       
    if (date ("dmy",filemtime($dirname."/".$file))=="080312"){
    // - удаляем первую строку.
    $lines file($dirname."/".$file);
    $last sizeof($lines) - ;
    unset(
    $lines[$last]);
    $fp fopen($dirname."/".$file'w');
    fwrite($fpimplode(''$lines));
    fclose($fp);
    echo 
    "файл $file " date ("dmy",filemtime($dirname."/".$file)). "\n <br>";
    }}
            }
            
    // Если перед нами директория, вызываем рекурсивно
            // функцию scan_dir
            
    if(is_dir($dirname."/".$file))
            {     
              
    scan_dir($dirname."/".$file);
            }
          }
        }
        
    // Закрываем директорию
        
    closedir($dir);
      }
    $dirname ".";
      
    scan_dir($dirname);  // Вызов рекурсивной функции
    ?>
     
  3. KillDead

    KillDead

    Регистр.:
    11 авг 2006
    Сообщения:
    884
    Симпатии:
    540
    что то вроде
    Код:
    function ReadFolderDirectory($dir, $why='file', $shotPath=false, $root_dir='', $listDir = array()) {
        # static $listDir;
        if ($shotPath)
            $root_dir = $dir;
     
        if ($handler = opendir($dir)) {
            while (($sub = readdir($handler)) !== FALSE) {
                if ($sub != "." && $sub != ".." && $sub != "Thumb.db") {
                    if (is_file($dir . "/" . $sub) && $why == 'file') {
     
                        $listDir[] = str_replace($root_dir, '', $dir . "/" . $sub);
                    } elseif (is_dir($dir . "/" . $sub)) {
     
                        if ($why == 'dir')
                            $listDir[] = str_replace($root_dir, '', $dir . "/" . $sub);
     
     
     
                        $listDir = ReadFolderDirectory($dir . "/" . $sub, $why, 0, $root_dir, $listDir);
                    }
                }
            }
            closedir($handler);
        }
        return $listDir;
    }
     
    $ALL_DIRS = array();
    $allFiles = ReadFolderDirectory(SCAN_DIR, 'file' );
    echo "files: ".count($allFiles)."\n";
    echo "<pre>";
    //print_r($allFiles);
    //exit;
    foreach ($allFiles as $path) {
        // проверяем только js
        if(!preg_match('~\.js$~', $path )){
            continue; 
        }
       
        clearstatcache();
        // test file
        $file = file_get_contents(  $path);
        if (strpos($file, 'eval(base64_decode("="))')) {
     
            echo "$path Fix\n";
            $file_new = preg_replace('~eval\(base64_decode\(.*?\)\);~i', '', $file);
            file_put_contents($path, $file_new);
        } 
     
    }
    
    Примерно следующее, единственное -
    переписываем 2 строки
    if (strpos($file, 'eval(base64_decode("="))')) {
    надо указать проверку, чтобы обнаружил вредоносный код в файле.
    и
    $file_new = preg_replace('~eval\(base64_decode\(.*?\)\);~i', '', $file);
    это удаление в принципе, если только последнюю строку надо удалить- то заменяем на
    $e = explode("\n", $file);
    unset ($e[sizeof($e)-1]);
    $file_new = implode("\n", $e);
    ------------
    Память должен не жрать, Хотя может отвалится по времени. И вначале советовал бы отбекапить.
     
  4. funman

    funman

    Регистр.:
    28 дек 2007
    Сообщения:
    155
    Симпатии:
    25
    там нету Base64 вообще, код который сделал выше в принципе работает, только проблема что все JS имеют права 644, а для удаления строки нужно чтобы файлы имели права 666.

    Как вариант думаю можно всем JS сменить владельца на "apache", или может есть какое то другое решение?

    p.s. кому интересно прикладываю в архиве пример вредоносного кода, щас уже палится Каспером.

     

    Вложения: