Пишем свою антивирусную утилиту. Часть 1 — Подготовка
Внимание, статья написана в 2012 году и практически устарела.
Скажите, а не хотелось бы вам написать свой собственный антивирус? Если да, то это статья для вас.
Компьютерные вирусы – бич современного айти общества. Еще с далекого 1983 года, когда Оуен продемонстрировал широкой публике вредоносный код, который прозвали вирусом, стало ясно, что компьютерные системы весьма уязвимы. С тех пор прошло почти 30 лет, за которые компьютерные вирусы постоянно эволюционировали. Нет смысла писать о том, сколько вреда нанесли эти вредоносные программы (малварь или зловред на компьютерном лексиконе) экономике. В СМИ то и дело появляется об этом очередная заметка.
Что же такое компьютерный вирус в широком смысле этого термина? Зловредом принят считать код, так или иначе вредящей нормальной работе компьютера. Наверняка вы и сами неоднократно сталкивались с подхваченным вирусом. Нормальный вирус должен уметь заражать обычные файлы, размножаться, иметь полиморфную структуру (чтобы его не детектили антивирусы) и т.д. К компьютерным вирусам также относят троянцев, червей и различные вредоносные скрипты. Также к ним в какой то мере можно отнести и руткиты, но это не совсем верно. Просто сам руткит даже по своему названию подразумевает уже не вирусную природу, хотя они и очень опасны, особенно для систем, пользователи которых пренебрегают обновлением (всегда обновляйте свою систему в целях повышения безопасности!).
Можно написать о структуре PE-файла или ELF, показать, как вирус заражает систему, но в рамках данной статьи это будет лишним. Возможно, что я коснусь более углубленно данной темы в других статьях.
Естественно, что для противоборства вирусам смекалистыми программистами были разработаты антивирусные системы. Например, Евгений Касперский, разработчик знаменитого антивируса Касперского, начинал с безобидного хобби по собиранию этих вирусов и их программной нейтрализации. Как видите, это хобби принесло ему в последствии славу и сотни миллионов долларов состояния. Заманчиво, не так ли?
Написать отличную антивирусную систему довольно-таки трудно. Такая система должна уметь делать эвристический анализ файла, иметь мощный сканер и работать с базой, в которой она будет хранить сигнатуры вирусов, также нужен будет собственный драйвер для слежения за состоянием системы. Это только минимум. Но мы будем отталкиваться от этого.
Мы напишем с вами сканер зловредов, которые являются относительно постоянными по своей структуре (не буду загружать вас умными словами, можете почитать о них в моей книге). В качестве языка разработки я буду использовать C++, как наиболее быстрый и умеющий работать на низком уровне. Как вариант, можно использовать Делфи, однако учтите, что программа будет сильно уступать в скорости сишной.
Учите, что я буду использовать также классы из MFC, так что вам понадобиться полноценная Visual Studio, а на VC++ Express.
Наш сканер будет использовать хэш файла для сравнения с базой данных. Так сканер может выявить червей и троянов. Вроде бы негусто, однако этот сканер можно будет наращивать дополнительным функционалом.
Не будем пока заморачиваться окошками и прочей ерундой – нам важна сама программа, поэтому сканер будет иметь консольный вид.
Итак, прежде чем приступить к кодированию, давайте пройдемся по небольшому ТЗ, что должен уметь делать наш сканер. А он должен выполнять:
Вот таков наш план. Как видите, наш простой сканер будет выполнять много того, что положено сканеру антивирусника. Тем не менее, не стоит забывать, что сейчас практически все вирусы криптуются и упаковываются различными пакерами или протекторами. Это сделано для того, чтобы антивирусная система не смогла проанализировать сигнатуру Pe файла. Однако наш сканер пока не умеет этого делать. Но ведь мы же будем его улучшать, не так ли?
Пишем свое вредоносное ПО. Часть 1: Учимся писать полностью «не обнаружимый» кейлогер
Хакерский мир можно условно разделить на три группы атакующих:
1) «Skids» (script kiddies) – малыши, начинающие хакеры, которые собирают известные куски кода и утилиты и используя их создают какое-то простое вредоносное ПО.
2) «Byuers» — не чистые на руку предприниматели, тинэйджеры и прочие любители острых ощущений. Покупают услуги по написанию такого ПО в интернете, собирают с ее помощью различную приватную информацию, и, возможно, перепродают ее.
3) «Black Hat Сoders» — гуру программирования и знатоки архитектур. Пишут код в блокноте и разрабатывают новые эксплоиты с нуля.
Может ли кто-то с хорошими навыками в программировании стать последним? Не думаю, что вы начнете создавать что-то, на подобии regin (ссылка) после посещения нескольких сессий DEFCON. С другой стороны, я считаю, что сотрудник ИБ должен освоить некоторые концепты, на которых строится вредоносное ПО.
Зачем ИБ-персоналу эти сомнительные навыки?
Знай своего врага. Как мы уже обсуждали в блоге Inside Out, нужно думать как нарушитель, чтобы его остановить. Я – специалист по информационной безопасности в Varonis и по моему опыту – вы будете сильнее в этом ремесле если будете понимать, какие ходы будет делать нарушитель. Поэтому я решил начать серию постов о деталях, которые лежат в основе вредоносного ПО и различных семействах хакерских утилит. После того, как вы поймете насколько просто создать не детектируемое ПО, вы, возможно, захотите пересмотреть политики безопасности на вашем предприятии. Теперь более подробно.
Для этого неформального класса «hacking 101» вам необходимы небольшие знания в программировании (С# и java) и базовое понимание архитектуры Windows. Имейте ввиду, что в реальности вредоносное ПО пишется на C/C++/Delphi, чтобы не зависеть от фреймфорков.
Кейлогер – это ПО или некое физическое устройство, которое может перехватывать и запоминать нажатия клавиш на скомпрометированной машине. Это можно представить как цифровую ловушку для каждого нажатия на клавиши клавиатуры.
Зачастую эту функцию внедряют в другое, более сложное ПО, например, троянов (Remote Access Trojans RATS), которые обеспечивают доставку перехваченных данных обратно, к атакующему. Также существуют аппаратные кейлогеры, но они менее распространены, т.к. требуют непосредственного физического доступа к машине.
Тем не менее создать базовые функции кейлогера достаточно легко запрограммировать. ПРЕДУПРЕЖДЕНИЕ. Если вы хотите попробовать что-то из ниже следующего, убедитесь, что у вас есть разрешения, и вы не несёте вреда существующей среде, а лучше всего делать это все на изолированной ВМ. Далее, данный код не будет оптимизирован, я всего лишь покажу вам строки кода, которые могут выполнить поставленную задачу, это не самый элегантный или оптимальный путь. Ну и наконец, я не буду рассказывать как сделать кейлогер стойким к перезагрузкам или пытаться сделать его абсолютно не обнаружимым благодаря особым техникам программирования, так же как и о защите от удаления, даже если его обнаружили.
Для подключения к клавиатуре вам всего лишь нужно использовать 2 строки на C#:
Вы можете изучить больше про фунцию GetAsyncKeyState на MSDN:
Для понимания: эта функция определяет нажата клавиш или отжата в момент вызова и была ли нажата после предыдущего вызова. Теперь постоянно вызываем эту функцию, чтобы получать данные с клавиатуры:
Что здесь происходит? Этот цикл будет опрашивать каждые 100 мс каждую из клавиш для определения ее состояния. Если одна из них нажата (или была нажата), сообщение об этом будет выведено на консоль. В реальной жизни эти данные буферизируются и отправляются злоумышленнику.
Умный кейлогер
Погодите, а есть ли смысл пытаться снимать всю подряд информацию со всех приложений?
Код выше тянет сырой ввод с клавиатуры с любого окна и поля ввода, на котором сейчас фокус. Если ваша цель – номера кредитных карт и пароли, то такой подход не очень эффективен. Для сценариев из реального мира, когда такие кейлогеры выполняются на сотнях или тысячах машин, последующий парсинг данных может стать очень долгим и по итогу потерять смысл, т.к. ценная для взломщика информация может к тому времени устареть.
Давайте предположим, что я хочу заполучить учетные данные Facebook или Gmail для последующей продажи лайков. Тогда новая идея – активировать кейлоггинг только тогда, когда активно окно браузера и в заголовке страницы есть слово Gmail или facebook. Используя такой метод я увеличиваю шансы получения учетных данных.
Вторая версия кода:
Этот фрагмент будет выявлять активное окно каждые 100мс. Делается это с помощью функции GetForegroundWindow (больше информации на MSDN). Заголовок страницы хранится в переменной buff, если в ней содержится gmail или facebook, то вызывается фрагмент сканирования клавиатуры.
Этим мы обеспечили сканирование клавиатуры только когда открыто окно браузера на сайтах facebook и gmail.
Еще более умный кейлогер
Давайте предположим, что злоумышленник смог получить данные кодом, на подобии нашего. Так же предположим, что он достаточно амбициозен и смог заразить десятки или сотни тысяч машин. Результат: огромный файл с гигабайтами текста, в которых нужную информацию еще нужно найти. Самое время познакомиться с регулярными выражениями или regex. Это что-то на подобии мини языка для составления неких шаблонов и сканирования текста на соответствие заданным шаблонам. Вы можете узнать больше здесь.
Для упрощения, я сразу приведу готовые выражения, которые соответствуют именам логина и паролям:
Эти выражения здесь как подсказка тому, что можно сделать используя их. С помощью регулярных выражений можно искать (т найти!) любые конструкции, которые имеют определенный и неизменный формат, например, номера паспортов, кредитных карт, учетные записи и даже пароли.
Действительно, регулярные выражения не самый читаемый вид кода, но они одни из лучших друзей программиста, если есть задачи парсинга текста. В языках Java, C#, JavaScript и других популярных уже есть готовые функции, в которые вы можете передать обычные регулярные выражения.
Для C# это выглядит так:
Где первое выражение (re) будет соответствовать любой электронной почте, а второе (re2) любой цифро буквенной конструкции больше 6 символов.
Бесплатно и полностью не обнаружим
В своем примере я использовал Visual Studio – вы можете использовать свое любимое окружение – для создания такого кейлогера за 30 минут.
Если бы я был реальным злоумышленником, то я бы целился на какую-то реальную цель (банковские сайты, соцсети, тп) и видоизменил код для соответствия этим целям. Конечно, также, я запустил бы фишинговую кампанию с электронными письмами с нашей программой, под видом обычного счета или другого вложения.
Остался один вопрос: действительно такое ПО будет не обнаруживаемым для защитных программ?
Я скомпилировал мой код и проверил exe файл на сайте Virustotal. Это веб-инструмент, который вычисляет хеш файла, который вы загрузили и ищет его в базе данных известных вирусов. Сюрприз! Естественно ничего не нашлось.
В этом основная фишка! Вы всегда можете менять код и развиваться, будучи всегда на несколько шагов раньше сканеров угроз. Если вы в состоянии написать свой собственный код он почти гарантированно будет не обнаружим. На этой странице вы можете ознакомиться с полным анализом.
Основная цель этой статьи – показать, что используя одни только антивирусы вы не сможете полностью обеспечить безопасность на предприятии. Нужен более глубинная оценка действий всех пользователей и даже сервисов, чтобы выявить потенциально вредоносные действия.
В следующих статья я покажу, как сделать действительно не обнаружимую версию такого ПО.
Также YARA является мультиплатформенным инструментом, работает на всех популярных ОС и может использоваться через интерфейс командной строки или из ваших собственных скриптов Python с расширением yara-python. Также можно использовать GUI(Рассмотрим далее).
Установка.
Чтобы установить Yara, сначала нужно выполнить следующую команду:
apt install yara
После этого мы можем использовать Yara, выполнив команду yara, которая по умолчанию отобразит справку по использованию, как показано ниже:
Мы видим, что для запуска Yara нам нужно предоставить набор правил (RULEFILE), которые мы хотим применить, и путь к файлу (FILE) или pid (PID) процесса, который мы хотим сканировать.
Подготовка правил для тестов.
Правила ClamAV:
Теперь нам нужно получить файл правил, чтобы использовать Yara. В следующей части мы сами напишем файл с правилами, но сейчас будем использовать правила ClamAV. Единственная проблема с правилами ClamAV состоит в том, что мы не можем использовать их непосредственно с Yara, потому что Yara имеет свой собственный способ их описания(свой синтаксис).
Но в этой статье мы проверим обнаруживают ли его инструмент Yara.
Где взять реальные вирусы.
Следующий сервис для скачивания и исследования вирусов это http://malc0de.com/database/
Почитать про остальные сервисы можно тут: Где скачать вирусы для проверки антивируса и изучения?
После всего этого мы можем классифицировать примеры вредоносных программ, используя только инструмент Yara, и нам больше не нужно сканировать их с помощью правил ClamAV и PEiD. Это потому что Yara уже содержит правила из ClamAV и PEiD, которые используются в процессе сканирования, что очень удобно так как у нас имеется довольно большая база сигнатур для поиска «зловреда».
Создав свой антивирус, а создавать мы будем используя базу Yara-правил. Мы можем автоматически классифицировать вредоносные программы, правда пока только с помощью правил. Это очень полезно, когда нам быстро необходимо просканировать образец вредоносного ПО определенной категории.
Также думаю я добавлю функционал заливки файла на VirusTotal для точного обнаружения.
Именно на основе Yara правил мы и будем создавать свой сигнатурный AV.
YARA GUI для Windows.
Как я и обещал, для тех кому не нравиться возиться с установкой yara либо с правилами и еще хочется работать в GUI режиме + под платформой Windows можно воспользоватся YARA GUI.
Скачать можно отсюда: YARA GUI Homepage
Как видно помимо различной информации вредоносный дамп был успешно обнаружен как Empire ReflectivePick x64.
Еще пару сканирований:
Теперь рассмотрим как ищет «зловреда» Yara GUI версия для Windows.
Подводим итог.
В этой статье мы рассмотрели, как мы можем использовать продукт Yara с использованием ClamAV, PEiD правил для поиска вредоносных сигнатур в файлах.
Вышеупомянутый подход основан только на проверке сигнатуру(блока информации), что означает, что нетрудно обмануть Yara (с загруженными правилами ClamAV и PEiD).
Честно сказать, данный продукт может обнаруживать только известные вредоносные программы. Но если мы напишем нашу собственный вирус или закодируем его с помощью нашего собственного кодировщика, он, вероятно, не будет обнаружен, поскольку в Yara не загружены соответствующие сигнатуры. Этот пункт касается и нашего будущего антивируса.
Тем не менее, использование Yara для обнаружения вредоносной активности в файлах по-прежнему выгодно, поскольку большинство вредоносных программ в Интернете представляют собой стандартные вредоносные файлы и не содержат дополнительной маскировки, поэтому большинство вредоносных файлов можно обнаружить.
На этом 1-я часть пожалуй завершена)). Всем спасибо.
Пример антивируса
Итак, нужно написать некую программу, которая будет сканировать каталоги указанного диска, искать зараженные файлы и исцелять их.
Важный момент – поиск и лечение должны производиться после загрузки с «чистой» дискеты. Это правило должно выполняться при использовании любого антивируса. Но если коммерческие программы, написанные профессиональными вирусологами, каким-то образом пытаются противодействовать «заразе», пресекая действия агрессивных резидентов, разыскивая и обращаясь к оригинальным обработчикам прерываний или проверяя свой код на целостность, то представленная программа из-за своей простоты этого делать не умеет.
В качестве языка программирования выбран С. Приоритетным признано использование таких библиотечных процедур, форматы которых идентичны во многих системах программирования. Поэтому, например, использовалась процедура _dos_findfirst(), а не findfirst(). Программа была написана и отлаживалась в системе программирования JPI TopSpeed C v3.01, а также была проверена на Borland C++ v3.1. Кроме того, контролировалось наличие, идентичность по функциям и форматам вызова использованных библиотечных функций в системах программирования Microsoft C++ v6.0 и Watcom C++ v10.0. Но если что-то и не совпадет, откорректировать программу любому программисту не составит труда.
Основу программы составляет алгоритм обхода дерева каталогов и поиска в них файлов с расширениями «СОМ» и «ЕХЕ».
В тот момент, когда обнаружен очередной потенциально зараженный файл, вызывается функция infected() с именем файла в качестве параметра. Задачей этой функции является проверка указанного файла на заражение и возврат соответствующего признака.
В случае положительного результата на заражение вызывается функция cure(), которая и выполняет операцию исцеления зараженной программы.
Если требуется написать программу для лечения для какого-либо другого вируса, достаточно просто изменить содержимое процедур cure() и infected().
Итак, как же узнать, заражена программа или нет? В прошлых главах это делалось чисто визуально, теперь же требуется определить формальные признаки зараженности.
В основе общепризнанного метода лежит принцип выделения сигнатуры вируса. Сигнатура – это последовательность байт, однозначно характерная для конкретного вируса.
Разумеется, неправильно было бы использовать для детектирования файла такие ненадежные признаки, как, например, 60 секунд во времени создания файла. Во-первых, это может быть признаком случайного изменения (например, при упаковке/распаковке некоторыми архиваторами). Во-вторых, слишком многие вирусы используют для самоопознания одинаковые признаки. Наконец, эти признаки могут принадлежать совершенно здоровой программе (как в истории с антивирусом antitime и сигнатурой MsDos).
Вообще говоря, сигнатура – это множество N пар
, i=1.N, где Pi – расположение i-го байта, Bi – значение i-го байта. Но на практике часто используют непрерывные сигнатуры, для которых важно определить только место расположения первого байта и длину сигнатуры.
Какой должна быть длина сигнатуры? Вообще говоря, чем больше – тем лучше, в идеале в сигнатуру должна входить вся неизменяемая часть вируса, что гарантирует однозначность распознавания. Но это невероятно увеличит объем антивируса (а известные программы лечат тысячи вирусов) и замедлит процесс распознавания. Таким образом, целесообразным следует считать количество от нескольких байт до нескольких десятков байт – не больше. Остановимся на цифре 6.
Итак, в качестве сигнатуры вируса SVC-1740 выберем 6 байт вируса, которые размещены начиная с 1724-го байта, если считать от конца зараженного файла (с 16-го байта вируса). Вполне возможно, что эти 6 байт совпадают для всех вирусов семейства SVC. Но вероятность того, что машина сразу заражена несколькими вирусами одного семейства, крайне мала. А вот выбор в качестве сигнатуры шести первых байт вируса был бы точно ошибочным, потому что, как уже говорилось выше, подобное начало характерно для очень большого числа вирусов.
Итак, сигнатура 0B4h 83h 0CDh 21h 5Eh 56h длиной 6 байт расположена начиная с 1724-го байта, если считать от конца зараженной программы.
Теперь рассмотрим вопрос лечения программы. Фрагменты зараженной программы, которые необходимо восстановить для излечения, определены ранее.
Напомним, что вирус SVC-1740, заражая программу, дописывается в ее конец, сохраняя в своем теле первые 24 байта оригинальной программы. Поэтому для излечения как ЕХЕ, так и СОМ-программ, вполне достаточно переписать сохраненные 24 байта в начало программы без учета того, что большая их часть не была изменена, и отсечь 1740 вирусных байт в конце зараженной программы.
Но с методической точки зрения, следуя стратегии заражения, необходимо в СОМ-программе восстановить только первые три байта, а в ЕХЕ-програмее – 6 ранее измененных слов заголовка.
Поэтому для функции cure() предусмотрен именно второй алгоритм лечения, хотя он более медленный и сложный.
Итак, для СОМ-файла считываем 3 байта, с 80-го по 78-й, если считать от конца файла, и переписываем их в начало файла, для ЕХЕ-файла – перемещаем 6 слов согласно таблице 6.1. и отсекаем последние 1740 байт.
Таблица 6.1. Таблица перемещений для EXE-файла
Тотальный антивирус: универсальный антивирусный центр своими руками
Содержание статьи
Появившаяся некогда идея проверять файл сразу по многим антивирусам оказалась
очень удачной. Онлайновая антивирусная служба www.virustotal.com имеет тысячи
посещений ежедневно, при этом обладая дюжиной недостатков. Сервис не раскрывает
своих секретов, однако автор давно разобрал его по винтикам и теперь работает
над улучшенной реализаций.
В то время как одни пользователи держат на компьютере целый зоопарк различных
антивирусов, конфликтующих друг с другом и тормозящим ПК (не говоря уже о
стоимости лицензий или сложности поиска правильного «лекарства»), хакеры
предпочитают ловить малварь самостоятельно. В крайнем случае – проверяют
подозрительные файлы на бесплатных онлайновых службах типа того же
www.virustotal.com. Эти
же службы используются для «обкатки» вирусов собственного написания на предмет
обнаружения эвристическими анализаторами. И хотя, если верить
блогу Евгения
Касперского, хакеры не доверяют virus-total’у, поскольку он передает
подозрительные файлы антивирусным компаниям и вирусы начинают палиться еще на
старте, эта точка зрения отражает лишь малую часть действительности. Да,
действительно, профессиональные разработчики атакующих программ и rootkit’ов
проверяют их на «вшивость» исключительно локальным способом на своих собственных
машинах, предотвращая утечку информации, но… профессионалов единицы, к тому же
экспериментируя с virus-total’ом, хакеры определяют общие критерии ругательства
антивирусов, выявляя последовательности машинных команд/вызовов API-функций,
приводящих к срабатыванию эвристического анализатора. Однажды «обломав»
антивирус, хакер может многократно использовать найденный способ обхода
эвристика. Достаточно посетить любые форумы, где обитают вирусописатели, чтобы
убедиться, что они весьма неравнодушны к virus-total’у и активно его используют.
А что если создать еще более качественный сервис? Ведь virus-total примитивен
до ужаса – качество сканирования оставляет желать лучшего, не говоря уже о
длинных «социалистических» очередях, в которых приходится подолгу простаивать
из-за частых перегрузок сервера (а все потому, что балансировка нагрузки и
оптимизация изначально не предусматривались!).
На момент написания этих строк, мыщъх по заказу одной антивирусной компании
(имя которой разглашать не вправе) руководит разработкой онлайнового сервиса,
рассчитанного на «магистральную» загрузку и предоставляющего пользователям кучу
всевозможных рычагов управления. Естественно, исходный код к статье не
прилагается, да он и не нужен, главное – это концепт, плюс некоторые неочевидные
тонкости, с которыми придется столкнуться при «промышленных» масштабах
эксплуатации.
Virus-total изнутри
Virus-total устроен не просто, а очень просто. Он использует консольные
версии антивирусов, управляемые посредством командой строки и выдающие результат
сканирования в стандартный проток вывода, который легко перенаправить в файл или
пайп (pipe).
Что мы делаем? Через специальную форму на сайте закачиваем «подопытный» файл,
скармливаем его антивирусу, предварительно перенаправив вывод во временный файл/пайп,
который тут же парсим (то есть выбрасываем все лишнее, оставляя только статус
проверки и имя вируса). Парсить вывод легче всего Perl’ом, поддерживающим мощный
механизм регулярных выражений, но Си-программы намного более производительны, а
потому предпочтительнее (особенно, при большом наплыве пользователей).
На этом, собственно говоря, возможности virus-total’а и заканчиваются. Это
создает большие проблемы: во-первых, далеко не все антивирусы имеют консольные
версии, а, во-вторых, даже те, что имеют, поведением зачастую радикально
отличаются от полноценных GUI-версий. В чем легко убедиться, сравнив результаты
сканирования большой коллекции вирусов локальным способом и через virus-total –
сравнение будет отнюдь не в пользу virus-total’а.
Учитывая, что практически все антивирусы (и GUI-версии в том числе)
поддерживают запись результатов сканирования в log-файл и позволяют задавать имя
сканируемого файла через командную строку или на худой конец через механизм DDE
(Dynamic Data Exchange), ничего не стоит прикрутить GUI-версию к онлайновой
службе. Просто «скармливаем» антивирусу файл, форсируем запись результатов
сканирования в log-файл, который парсим так же, как и вывод консольных версий.
Остается только собрать «показания» всех имеющихся в нашем распоряжении
антивирусов, оформить их в виде HTML-таблицы и выдать на экран, что по силам
даже самым начинающим программистам.
В клинических случаях, когда антивирус начисто игнорирует командную строку
или не умеет вести логи, на помощь приходит механизм Windows-сообщений (Windows
Message или, сокращенно, WM). Посылая WM-сообщения элементам управления
антивируса, мы можем манипулировать кнопками, меню и прочими элементами
управления по своему усмотрению. Аналогичным способом извлекается и содержимое
окна, содержащего результаты проверки. Получив форматированный rich-текст или
plain-текст, пропускаем его через парсер – и все!
Маленькие секреты больших серверов
При попытке реализации вышеописанной модели неизбежно всплывут проблемы
удручающе низкой производительности. Но мы не боимся трудностей и начнем щемить
проблемы одну за другой. Первое и очевидное. Как показывает статистика,
различные пользователи преимущество проверяют одни и те же файлы, как правило,
принадлежащие Windows или популярным программным пакетам. Чтобы сократить
накладные расходы, рекомендуется подсчитывать контрольную сумму файла перед его
проверкой и, если такой файл уже проверялся ранее, выдавать уже готовые
результаты сканирования, сохраненные в базе данных. На первый взгляд, в
реализации данного алгоритма нет ничего сложного, но тут притаилось немало
подводных камней. Вот только наиболее актуальные:
Также крайне желательно реализовать опцию, позволяющую пользователю выбирать
режим сканирования с эвристикой и без (чего не сделано на virustotal). Эвристика
представляет собой довольно затратную по времени и ресурсам ЦП операцию, но
далеко не все пользователи доверяют полученным результатам и хотят видеть имя
конкретного вируса (если он есть), а не расплывчатое предупреждение, обычно
ругающееся на упаковщик/протектор, которым обработан честный файл. С другой
стороны, вирусописателям совершенно неинтересно сканирование по базе (так как
только что написанного вируса там заведомо нет) и они предпочли бы задействовать
только эвристику, экономя тем самым ресурсы нашего сервера. Так почему бы не
пойти им навстречу?
Закачка больших файлов предоставляет серьезную проблему, имеющую несколько
решений. Самое простое (и глупое) – установить верхний предел закачиваемого
файла в пару мегабайт (или около того), чуть-чуть умнее: лимитировать суммарный
размер всех файлов, закачанных за сутки с одного IP (но тут возникает проблема
определения IP, поскольку очень часто мы будем видеть не IP пользователя, а IP
прокси сервера провайдера). Полезно рекомендовать пользователям сжимать файлы
перед отправкой zip’ом или другим популярным архиватором для уменьшения нагрузки
на канал или делать это автоматически на клиентской стороне специальным скриптом.
Наконец, за сканирование больших файлов можно взимать деньги, но об этом мы
поговорим чуть позже, а пока продолжим тему оптимизации.
Профилировка показывает, что львиная доля накладных расходов приходится на
запуск антивируса, инициализацию его движка и загрузку антивирусных баз.
Перемещение антивирусов на виртуальный диск существенно увеличивает
«подвижность» системы, но накладные расходы на создание новых процессов
по-прежнему будут большими, поэтому мы используем GUI-версии антивирусов и,
путем эмуляции клавиатурного ввода, воздействуем на элементы управления,
заставляя их сканировать новые файлы и выдавать результат. При этом антивирус
запускается всего один раз. Красота! Впрочем, можно реализовать и динамический
алгоритм: при небольшой нагрузке на сервер о накладных расходах на порождение
новых процессов можно не заботиться, а с ростом нагрузки – просто брать
несколько файлов, закачанных пользователями за последние несколько минут и
«скармливать» их антивирусу одним скопом, в результате чего количество запусков
последнего резко сокращается. Главное не запутаться, какой пользователь что
закачал, но это уже мелочи технической реализации.
Естественно, сканирование лучше запускать на всех антивирусах параллельно, а
не последовательно и вместо того, чтобы «тупо» запрещать пользователю закрывать
окно браузера до окончания процесса сканирования (как это делает virus-total),
отслеживать TCP/IP соединение и при его обрыве автоматически «выбрасывать» файл,
принадлежащий данному пользователю, из очереди на сканирование. Плюс реализовать
стандартную кнопку «отмены» (так же отсутствующую у virus-total’а) – если
пользователь видит, что первые три-четыре антивируса ничего не находят, так
следует ли дожидаться результатов проверки всех антивирусов? Особенно, если
самые качественные антивирусы поставить вперед остальных, выделив им
максимальный приоритет ЦП. Как вариант, можно вообще не следить за TCP/IP сессий
и при заливке нового файла назначать пользователю ID задачи, который он может
ввести в любое время, отключившись от Сети и повторно подключившись, например,
через час, когда его очередь уже подошла. А можно рассылать результаты
сканирования по e-mail – тогда пользователь не будет скучать в ожидании своей
очереди.
И совсем не помешает прикрутить к нашему сервису утилиту вроде PEiD,
определяющую тип и версию упаковщика/проектора (правда, довольно часто
ошибающуюся). И опционально реализовать распаковку набором статических
распаковщиков, работающих намного быстрее тех, что встроены в антивирусы. Тут
есть один подводный камень – хотя 99% вирусов распознаются по распакованному
дампу, некоторые, особо ленивые, сотрудники антивирусных компаний включают в
базу сигнатуры упакованного файла и после распаковки он перестает опознаваться
как вирус. Однако, учитывая, что распакованный файл прогоняется через легион
антивирусов, вероятность ложно-негативного срабатывания стремится к нулю.
Зарабатываем деньги лопатами
Мир жесток и все в нем упирается в деньги. На голом энтузиазме никой
онлайновый сервис долго не продержится, поэтому приходится разрабатывать не
только программный код, но и жизнеспособную бизнес-схему. Рассмотрим возможные
источники дохода. Первое – рост посещаемости нашего сайта. На посещаемости, как
известно, можно нехило заработать, особенно, если мы, например, продаем
собственные защитные комплексы, предлагаем услуги по пен-тестингу и т.д.
Онлайновый сервис привлекает клиентов намного активнее любых баннеров и,
главное, привлекает именно тот контингент, который нам нужен, следовательно,
возросшие объемы продаж покроют все расходы на поддержку и обслуживание
серверов, отплату трафика и т. д.
Третье – взимать деньги непосредственно с самих пользователей. Хочешь подолгу
стоять в очередях и сканировать файлы не больше чем … мегабайт? Пожалуйста,
пользуйся нашим сервисом бесплатно! Хочешь иметь определенные привилегии – будь
добр заплатить. Главное, выбрать удобную схему оплаты. Здесь вам не Америка,
здесь климат (финансовый) иной. Кредитные карты имеют единицы, электронные
системы платежей только начинают набирать популярность. Зато практически каждый
IT-специалист – владелец сотового телефона, а значит, можно воспользоваться
микро-платежами через SMS либо потребовать от клиента сообщить номер карты
универсальной оплаты (перечислив заданную сумму на счет, который он может
расходовать, когда пользуется нашим сервисом). Как показывает практика, сотовые
платежи приносят наибольшую отдачу, поскольку телефоны распространены
повсеместно, а сам процесс оплаты требует минимум телодвижений, и (что
немаловажно) клиент практически ничем не рискует. А вот с кредитными картами все
намного сложнее и есть риск, что нечестный оператор снимет с них совсем не ту
сумму, какая ожидалась. Тоже относится и к микро-платежам через SMS. Гарантий,
что снимут 150 рублей, а не 450, у клиента нет никаких.
А что в итоге?
Разумеется, в статье охвачены далеко не все проблемы, с которыми неизбежно
столкнется всякий, попытавшийся воздвигнуть подобный онлайновый сервис. Но
задача выполнена – мыщъх предоставил вполне законченную, отлаженную и
работоспособную схему, которая скоро будет запущена в промышленную эксплуатацию.
Полную версию статьи
читай в майском номере
Хакера!
Юридические проблемы лицензирования
Пользовательские соглашения (EULA) на коммерческие антивирусы не разрешают
использовать их в онлайновых сервисах без заключения специальных контрактов, что
вообще-то логично. Однако не стоит думать, что всякий контракт обязательно
связан с необходимостью выплаты дополнительных отчислений. Вовсе нет! Достаточно
проявить надлежащий дипломатический подход!
А что мелкие бренды? Они, конечно, понимают, что сравнение с конкурентами
будет не в их пользу. Тут есть один очень интересный момент. Мелкие антивирусные
компании страдают хронической нехваткой свежих вирусов, которые попадают к ним в
последнюю очередь, и потому онлайновый сервис, автоматически отсылающий уже
детектируемые конкурентами вирусы – для них прекрасное средство пополнения
вирусных баз и продвижения в различных рейтингах. С мелких брендов можно даже
взимать плату за каждый новый для них вирус, и большая вероятность, что платить
они согласятся!
Короче говоря, лицензионные проблемы – это и не проблемы вовсе. А вот разных
проволочек – предостаточно и нужно заранее быть готовыми к тому, что нас будут
перебрасывать от одного ответственного лица (которое ничего не решает) к
другому, третьему, и так по цепочке… Это уже издержки цивилизации, против
которых не попрешь.
Проблемы конфиденциальности
Вирусы встречаются не только в программах, но и в офисных документах, PDF’ах
и прочих файлах с конфиденциальной информацией, разглашать которую крайне
нежелательно, поэтому необходимо предусмотреть опцию «не отсылать данный файл в
антивирусные центры», при необходимости взводимую пользователем. Технически это
реализуется проще простого, но… как избежать злоупотреблений?! Особенно, если мы
строим наш бизнес на отправке свежих штаммов разработчикам антивирусов?
Идея первая (тупая до безобразия) – наплевать на все приличия и отсылать
файлы в антивирусные центры независимо от состояния каких-то там галочек.
Главное: создать у пользователя иллюзию, что его конфиденциальность строго
блюдут, ну а что происходит на самом деле, он все равно не узнает. Ну… до тех
пор, пока тайное не станет явным и не разразится скандал, идущий совсем не на
пользу нашему ресурсу.
Идея вторая – поддерживать эту опцию только для пользователей, открывшим у
нас счет. Кстати, это представляет собой нехилую мотивацию для оплаты услуг,
особенно с учетом того, что о конфиденциальности в основном беспокоятся
корпоративные пользователи, привыкшие платить за услуги (в отличие от домашних
юзеров, тяготеющих к халяве вне зависимости от стоимости полнофункционального
аккаунта).
Идея третья – файл все-таки отправлять, но перед этим удалять всю текстовую и
графическую информацию, что не противоречит ни логике, ни здравому смыслу, ни
даже соглашению, заключенному с пользователем нашего сервиса.