|
Пример построения простого antimalware сканера с собственными базами |
Наверх Назад | |
|
Администраторы сетей нередко задают вопросы по поводу того, нет ли возможности выполнять зачистку от нежилательного ПО, троянов или запрещенных к применению на ПК пользователей программ на базе AVZ. Возможность такая существует, и реализуется на основе скрипт-языка. Рассмотрим типовой пример:
var SignDB : TStrings; // Сигнатурная база MalwareCnt : integer; // Счетчик найденных зловредов DelMalwareCnt : integer; // Счетчик удаленных зловредов DeleteMalware : boolean; // Признак того, что делать с найденными Malware
// Обработка найденного файла Procedure ScanFile(AFileName : string); var FMD5 : string; begin SetStatusBarText(AFileName); // Вычисление MD5 суммы FMD5 := CalkFileMD5(AFileName); // Поиск MD5 в базе if (FMD5 <> '') and (SignDB.IndexOf(FMD5) >= 0) then begin AddToLog('Найден malware, файл = '+AFileName); inc(MalwareCnt); if DeleteMalware then begin DeleteFile(AFileName); inc(DelMalwareCnt); end; end; end;
// Сканирование каталога Procedure ScanDir(ADirName : string; AScanSubDir : boolean); var FS : TFileSearch; begin ADirName := NormalDir(ADirName); FS := TFileSearch.Create(nil); FS.FindFirst(ADirName + '*.*'); while FS.Found do begin // В зависимости от типа - или сканируем подкаталог, или изучаем файл if (FS.FileName <> '.') and (FS.FileName <> '..') then if FS.IsDir and AScanSubDir then ScanDir(ADirName + FS.FileName, AScanSubDir) else ScanFile(ADirName + FS.FileName); FS.FindNext; end; FS.Free; end;
begin // Режим сканирования DeleteMalware := false; // Обнуляем счетчик зловредов MalwareCnt := 0; DelMalwareCnt := 0; // Загружаем сигнатурную базу SignDB := TStringList.Create; SignDB.LoadFromFile('my_sign_db.txt'); AddToLog('Баз загружена, количество сигнатур = '+inttostr(SignDB.Count)); // Задействуем антируткит SearchRootkit(true, true); // Проверка дисков и (или) папок ScanDir('c:\', true); ScanDir('d:\MyFolder\', false); // Зачистка следов зловредов, если таковые были найдены if DelMalwareCnt > 0 then begin SaveLog('scan_result.txt'); // Включение AVZGuard - он помешает зловредам восстановиться SetAVZGuardStatus(true); // Активация BootCleaner BC_ImportALL; BC_Activate; // Эвристическая чистка ExecuteSysClean; // Перезагрузка RebootWindows(true); end; end.
для работы данного примера необходима сигнатурная база. В нашем случае роли сигнатуры выступает MD5 сумма файла - ее крайне неудобно применять в реальных ситуациях (так как изменение хотя-бы одного байта в файле приведет к изменению его MD5), однако для простейшего сканера такой подход удобен, так как расчитать MD5 любого файла очень просто, например в AVZ меню "Сервис/Вычислить MD5 сумму файла". Записи базы просты - по одной MD5 сумме в каждой строке, без пробелов до или после суммы
44D88612FEA8A8F36DE82E1278ABB02F
Это MD5 сумма файла EICAR - тестового "вируса", который можно взять где угодно, например вот тут: http://support.kaspersky.ru/downloads/eicar/eicar.zip (только нужно не забыть распаковать его - так как наш пример архивы не проверяет). // Эвристическая чистка ExecuteSysClean; end;
Процедура ScanFile выполняет самое интересное - изучение файла. Она выполняет следующие операции: 1. Выводит в строке статуса имя сканируемого файла через SetStatusBarText. Это чисто "косметическая" операция, которая замедляет работу скрипта, зато можно наблюдать за тем, как идет сканирование. Из реального скрипта ее можно исключить 2. При помощи CalkFileMD5 вычисляется MD5 сумма файла 3. Если MD5 вычислен успешно (в этом случае CalkFileMD5 возвращает строку с MD5 суммой) и такая MD5 сумма найдена в базе, то выполняются действия над найденным файлом - делается отметка в протоколе, а файл удаляется при условии, что DeleteMalware = true. В данном случае если DeleteMalware = true, то получаем "режим лечилки", если False - то "режим сканера" (данный параметр задается в начале скрипта).
Может возникнуть резонный вопрос - а как быть, если скажем имеется коллекция malware, насчитывающая сотни файлов. Не получать же вручную их MD5 для данной базы ... в данной ситуации мы можем построить несложный скрипт, который создаст базу сигнатур:
var SignDB : TStrings; // Сигнатурная база
// Обработка найденного файла Procedure ScanFile(AFileName : string); var FMD5 : string; begin SetStatusBarText(AFileName); // Вычисление MD5 суммы FMD5 := CalkFileMD5(AFileName); // Добавление в базу без повторов if (FMD5 <> '') and (SignDB.IndexOf(FMD5) < 0) then SignDB.Add(Trim(FMD5)); end;
// Сканирование каталога Procedure ScanDir(ADirName : string; AScanSubDir : boolean); var FS : TFileSearch; begin ADirName := NormalDir(ADirName); FS := TFileSearch.Create(nil); FS.FindFirst(ADirName + '*.*'); while FS.Found do begin // В зависимости от типа - или сканируем подкаталог, или изучаем файл if (FS.FileName <> '.') and (FS.FileName <> '..') then if FS.IsDir and AScanSubDir and then ScanDir(ADirName + FS.FileName, AScanSubDir) else ScanFile(ADirName + FS.FileName); FS.FindNext; end; FS.Free; end;
begin // Инициализируем сигнатурную базу SignDB := TStringList.Create; SignDB.LoadFromFile('my_sign_db.txt'); AddToLog('Баз загружена, количество сигнатур = '+inttostr(SignDB.Count)); // Сканирование папки с образцами Malware ScanDir('c:\MalwareSamplesDir\', true); // Сохранение базы AddToLog('Баз пополнена, количество сигнатур = '+inttostr(SignDB.Count)); SignDB.SaveToFile('my_sign_db.txt'); SignDB.Free; end.
Как несложно заметить, данный скрипт похож на предыдущий - выполняется рекурсивное сканирование папок с коллекцией Malware, однако вместо поиска по базе ведется ее пополнение. После заполнения база сохраняется. При добавлении новых MD5 в базу производится контроль повторов, поэтому выполнять его можно многократно - он загружает текущую базу и в случае надобности пополняет ее новыми сигнатурами.
|