Я тут заинтересовался темой веб антивирусов - то есть сервисов, которые сканируют URL и определяют, живет ли там зараза. Самые известные такие сканеры - это Virustotal и Google Safe Browsing (он же mawler, кажется), а вообще тьма их. (Неплохой список в этой теме.)
Теоретически, ятоб не дать малваре шанса спрятаться, сканеры должны работать скрытно, в идеале - абсолютно неотличимо от нормальных пользователей, зашедших с нормальных браузеров.
Практически, почему-то большинстов аверов на скрытность забивает. Чтоб разобраться, я поднял сайт с небольшим набором проверок, напустил на него всех собак, и почитал логи. Поделюсь, стало быть, наблюдениями, может кому пригодится B)
Теоретически, ятоб не дать малваре шанса спрятаться, сканеры должны работать скрытно, в идеале - абсолютно неотличимо от нормальных пользователей, зашедших с нормальных браузеров.
Практически, почему-то большинстов аверов на скрытность забивает. Чтоб разобраться, я поднял сайт с небольшим набором проверок, напустил на него всех собак, и почитал логи. Поделюсь, стало быть, наблюдениями, может кому пригодится B)
Сканеры можно разбить на три класса:
1. со статическим анализом, совсем простые. Обычно просто чекают, что на сайте нет ссылок из черного списка. Ну ингода еще ищут подозрительные скрытые iframe итп. Пример: Sucuri SiteCheck
2. Автоматизированные браузеры. То есть на виртуальной машине бежит реальный IE,FF,Chrome итп, через него прогоняют сайт, и проверяют, не появился ли, например, левый процесс или запись в реестре. Понятно, что это трудный случай. По идее, только так вообще и нужно сканировать. Примеры: упомянутый Google Safe Browsing, vURL Online, часть ав из вирустотала (я пока не определил, кто чему соответствует)
3. Эвристические сканеры - промежуточный вариант. Какую-то часть джаваскрипта запускают(в v8 или rhino, скажем) что-то по сигнатурам узнают. Пример: Wepawet, JSUnpack
Понятно, что на сайт заползают еще поисковики, приватные сканеры, определители прокси, тулзы для массового взлома и другая живность. Я только вскользь этим занимался, на эту тему и так много написано (гуглить по словам honeypot, cloaking, IDS).
Еще наблюдение: если сканер говорит, проверка пройдена, это еще не значит, что сайт отпустили с миром. За ним следят еще несколько часов, а то и дней. Гугль так не прекращает следить никогда. Зачастую в первой фазе проводятся только самые элементарные проверки, а тяжелая артиллерия подтягивается через час или два. А потом еще через часик. И еще. А еще аверы ссылками обмениваются. Или просто так заходят. Пролетарскую бдительность терять нельзя!
Это вводная часть была, теперь о демаскирующих факторах. Их много.
ip - самый простой. Тут надо вести черный список IP и подсеток, известных сканеров, подсеток, с которых нормальные люди редко приходят (Amazon EC), c Tor-а. Выручают блеклисты на основе DNS. Сервера Tor-а можно узнать по TorDNSEL, подсетку и ее владельца - по whois или сервису от Team Cymru (имейте ввиду, что хозяева сервиса непосредственно связаны с ФБР. Напрямую туда стучаться может и не стоит). Еще полезный список: SURBL.
Лучше имхо всего вести свою базу и обновлять по мере поступления логов.
заголовки запроса
user-agent - очень важно, потому что тут царит полная анархия. Некоторые сканеры даже сами представляются (Sucuri), некоторые дают совсем левые какие-то значения ("Browserlet" - это кто-то с вирустола) , некоторые косят под гугльбота (а ip при том не гугловский), некоторые и бингом тоже, а многие притворяются такими старинными версиями браузеров, что уже в природе почти не осталось. Были замечены Chrome 4 или FF2 . Смысл таких значений как бы в том, чтоб поймать побольше сплоитов на разные наживки, но все хорошо в меру. Антиквариат банить или хотя б кинуть мессагу, чтоб обновили софт, елы палы.
Тут большая база user-agent ов
Другая фишка - несколько user-agent-ов c одного IP в короткое время. Иногда авторы скупятся на железо и запусткают несколько сканов на одной машине. Но может быть и другая причина - трафик с прокси или из-за NAT. Здесь инфа об IP пригодится.
Referer тоже о многом говорит. Трафик с IFRAME, а Referer пустой? Подозрительно (очень часто случается с ботами). Referer со страницы, которую клиент еще не запрашивал - тоже плохо. Один ав с вирустотала любит рекурсию и ставит Referer = запрашиваемый URL . :huh1:
Cookie - должны сохранятся. Если нет,то имеем дело с неполноценной имитацией браузера (или посторонним ботом).
Etag и If-None-Match - малоизвестный аналог куков. Про них могли забыть. Читайте Википедию.
Accept, Accept-Encoding: должны соответствовать типу запрашиваемого ресурса и типу браузера. Подлинный Хром текущей версии при запросе HTML ресурса говорит:
и никак иначе.
А поддельные Хромы чего только не пишут. Особенно часто ставят * или пропускают. Почти все псевдохромы забывают sdcn в Accept-Encoding (об этом будет ниже) . У других браузеров - свои привычки, их на отдельную статью хватит, но надеюсь идея понятна
(Полезный ресурс: browsershots.org, там несколько десятков видов браузеров в виртуалках можно запускать и собирать логи для анализа)
Accept-Language - если выставлен американский английский язык то это "en-us" (Сафари), "en-US" (IE) "en-US,en;q=0.8" (Хром) или "en-US,en;q=0.5" (Firefox) ?
Запрашиваемые ресурсы
Должны запрашиваться в точности те ресурсы, которые требуются кодом страницы. Включая редиректы, ajax, сss, динамически создаваемые элементы и фишки вроде favicon.ico
Чтоб не было заморочек с кешированием, хорошо генерировать уникальные URLы (style18812.css, favicon1238384.ico)
Просят ресурс, на который не ведут ссылки - подозрительно. (часто так ищут админку или чекают страницу 404).
Просят странный URL ("//" - тоже кто-то из вирустоталов) - либо бот либо хакеры лезут.
Поисковики должны по идее с самого начала попросить robots.txt ,а потом уж входить. Сканеры так не поступают.
С другой стороны, нормальные браузеры просят файл иконки, который хорошо б ставить явно
FF без этого иконки не всегда берет.
У айфонов-айпадов чуть по другому:
А боты почти все про favicon забывают. Очень характерная черта.
У Chrome еще одна примочка. Если с HTML страницей отдать заголовок
то он должен запросить и этот somefile.dct. Файл можно и не создавать или выдать пустым. Если запрос есть, то хром наверняка настоящий. (Это мы используем специальный вид сжатия который называется sdch. В реале его только гугль и знает)
(Прим: в начале убедитесь, что sdch присуствует в Accept-Encoding. Его некоторые хостеры фильтруют.)
Если браузер прошел все испытания, то 99.99% это реальный браузер. но, возможно, автоматизированный или под отладчиком. Теперь требуется тонкая работа.
Проверки на автопилот
Поскольку на этом этапе часть кода уже видна сканеру, то есть шанс спалиться. Наверное можно попытаться прикинуться веб аналитикой какой-нибудь. Там инфа тянется практически та же самая:
Свойства окна: во-первых, координаты на десктопе (window.screenX, window.screenY или screenLeft,window.screenTop) - у ботов там иногда 0 или двже отрицательные значения. во-вторых, размеры внутренней и внешней границы окна. (innerWidth, innerHeight,outerWidth,outerHeight) У ботов они обычно фиксированые, а у пользователей - как придется. (Большая разница по размерам может кстати говорить об открытом дебаггере.)
Разрешение экрана: screen.availWidth, screen.availHeight, screen.colorDepth - у сканеров они иногда нестандартные.
Список плагинов с версиями итп тоже разумеется полезен: У автоматов плагинов обычно мало и все старье. Некоторые комбинации я только у ботов и видел.
Если есть флэш - то можно вытащить список шрифтов (пример) и тоже подсчитать. У реальных пользователей шрифты как-то быстро накапливаются. У ботов - нет.
Прочекать точную структуру DOM. Чистые эмуляторы джаваскрипта наоборот про DOM не знают .
Автоматизированные браузеры могут тоже накосячить (с вложенными айфреймов в частности. Если трафик с iframe, то top.location не должен быть равен window.location).
Приходящие события (onload, onclick итп) тоже проверить полезно - некоторые сканеры вызывают _все_ обработчики, которые только есть. Даже если у нормальных пользователей они никогда не срабатывают (как-то onscroll или onkeypress внутри айфрейма).
И сами события чуть по разному устроены: когда скажем в вебките срабатывает натуральный window.onunload, то event.target == document , а если посылать событие искусственно при помощи dispatchEvent, то event.target == window . А если функцию обработки вызвать напрямую, то arguments.caller выйдет ненулевой, чего случаться не должно.
Есть еще антидебаггерные приемы, но это отдельная тема.
Для сканеров, которые я проверял, вышеописанных приемов вроде достаточно. Там все довольно тупо - пока. Если кто еще что по теме знает, накидайте, было б интересно
humbsup:
1. со статическим анализом, совсем простые. Обычно просто чекают, что на сайте нет ссылок из черного списка. Ну ингода еще ищут подозрительные скрытые iframe итп. Пример: Sucuri SiteCheck
2. Автоматизированные браузеры. То есть на виртуальной машине бежит реальный IE,FF,Chrome итп, через него прогоняют сайт, и проверяют, не появился ли, например, левый процесс или запись в реестре. Понятно, что это трудный случай. По идее, только так вообще и нужно сканировать. Примеры: упомянутый Google Safe Browsing, vURL Online, часть ав из вирустотала (я пока не определил, кто чему соответствует)
3. Эвристические сканеры - промежуточный вариант. Какую-то часть джаваскрипта запускают(в v8 или rhino, скажем) что-то по сигнатурам узнают. Пример: Wepawet, JSUnpack
Понятно, что на сайт заползают еще поисковики, приватные сканеры, определители прокси, тулзы для массового взлома и другая живность. Я только вскользь этим занимался, на эту тему и так много написано (гуглить по словам honeypot, cloaking, IDS).
Еще наблюдение: если сканер говорит, проверка пройдена, это еще не значит, что сайт отпустили с миром. За ним следят еще несколько часов, а то и дней. Гугль так не прекращает следить никогда. Зачастую в первой фазе проводятся только самые элементарные проверки, а тяжелая артиллерия подтягивается через час или два. А потом еще через часик. И еще. А еще аверы ссылками обмениваются. Или просто так заходят. Пролетарскую бдительность терять нельзя!
Это вводная часть была, теперь о демаскирующих факторах. Их много.
ip - самый простой. Тут надо вести черный список IP и подсеток, известных сканеров, подсеток, с которых нормальные люди редко приходят (Amazon EC), c Tor-а. Выручают блеклисты на основе DNS. Сервера Tor-а можно узнать по TorDNSEL, подсетку и ее владельца - по whois или сервису от Team Cymru (имейте ввиду, что хозяева сервиса непосредственно связаны с ФБР. Напрямую туда стучаться может и не стоит). Еще полезный список: SURBL.
Лучше имхо всего вести свою базу и обновлять по мере поступления логов.
заголовки запроса
user-agent - очень важно, потому что тут царит полная анархия. Некоторые сканеры даже сами представляются (Sucuri), некоторые дают совсем левые какие-то значения ("Browserlet" - это кто-то с вирустола) , некоторые косят под гугльбота (а ip при том не гугловский), некоторые и бингом тоже, а многие притворяются такими старинными версиями браузеров, что уже в природе почти не осталось. Были замечены Chrome 4 или FF2 . Смысл таких значений как бы в том, чтоб поймать побольше сплоитов на разные наживки, но все хорошо в меру. Антиквариат банить или хотя б кинуть мессагу, чтоб обновили софт, елы палы.
Тут большая база user-agent ов
Другая фишка - несколько user-agent-ов c одного IP в короткое время. Иногда авторы скупятся на железо и запусткают несколько сканов на одной машине. Но может быть и другая причина - трафик с прокси или из-за NAT. Здесь инфа об IP пригодится.
Referer тоже о многом говорит. Трафик с IFRAME, а Referer пустой? Подозрительно (очень часто случается с ботами). Referer со страницы, которую клиент еще не запрашивал - тоже плохо. Один ав с вирустотала любит рекурсию и ставит Referer = запрашиваемый URL . :huh1:
Cookie - должны сохранятся. Если нет,то имеем дело с неполноценной имитацией браузера (или посторонним ботом).
Etag и If-None-Match - малоизвестный аналог куков. Про них могли забыть. Читайте Википедию.
Accept, Accept-Encoding: должны соответствовать типу запрашиваемого ресурса и типу браузера. Подлинный Хром текущей версии при запросе HTML ресурса говорит:
Код:
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8] Accept-Encoding: gzip,deflate,sdch
А поддельные Хромы чего только не пишут. Особенно часто ставят * или пропускают. Почти все псевдохромы забывают sdcn в Accept-Encoding (об этом будет ниже) . У других браузеров - свои привычки, их на отдельную статью хватит, но надеюсь идея понятна
(Полезный ресурс: browsershots.org, там несколько десятков видов браузеров в виртуалках можно запускать и собирать логи для анализа)
Accept-Language - если выставлен американский английский язык то это "en-us" (Сафари), "en-US" (IE) "en-US,en;q=0.8" (Хром) или "en-US,en;q=0.5" (Firefox) ?
Запрашиваемые ресурсы
Должны запрашиваться в точности те ресурсы, которые требуются кодом страницы. Включая редиректы, ajax, сss, динамически создаваемые элементы и фишки вроде favicon.ico
Чтоб не было заморочек с кешированием, хорошо генерировать уникальные URLы (style18812.css, favicon1238384.ico)
Просят ресурс, на который не ведут ссылки - подозрительно. (часто так ищут админку или чекают страницу 404).
Просят странный URL ("//" - тоже кто-то из вирустоталов) - либо бот либо хакеры лезут.
Поисковики должны по идее с самого начала попросить robots.txt ,а потом уж входить. Сканеры так не поступают.
С другой стороны, нормальные браузеры просят файл иконки, который хорошо б ставить явно
Код:
<link href="..." rel="shortcut icon" type="image/vnd.microsoft.icon" />
У айфонов-айпадов чуть по другому:
Код:
<link rel="apple-touch-icon-precomposed" href="file.png"/>);
А боты почти все про favicon забывают. Очень характерная черта.
У Chrome еще одна примочка. Если с HTML страницей отдать заголовок
Код:
Get-Dictionary: somefile.dct
(Прим: в начале убедитесь, что sdch присуствует в Accept-Encoding. Его некоторые хостеры фильтруют.)
Если браузер прошел все испытания, то 99.99% это реальный браузер. но, возможно, автоматизированный или под отладчиком. Теперь требуется тонкая работа.
Проверки на автопилот
Поскольку на этом этапе часть кода уже видна сканеру, то есть шанс спалиться. Наверное можно попытаться прикинуться веб аналитикой какой-нибудь. Там инфа тянется практически та же самая:
Свойства окна: во-первых, координаты на десктопе (window.screenX, window.screenY или screenLeft,window.screenTop) - у ботов там иногда 0 или двже отрицательные значения. во-вторых, размеры внутренней и внешней границы окна. (innerWidth, innerHeight,outerWidth,outerHeight) У ботов они обычно фиксированые, а у пользователей - как придется. (Большая разница по размерам может кстати говорить об открытом дебаггере.)
Разрешение экрана: screen.availWidth, screen.availHeight, screen.colorDepth - у сканеров они иногда нестандартные.
Список плагинов с версиями итп тоже разумеется полезен: У автоматов плагинов обычно мало и все старье. Некоторые комбинации я только у ботов и видел.
Если есть флэш - то можно вытащить список шрифтов (пример) и тоже подсчитать. У реальных пользователей шрифты как-то быстро накапливаются. У ботов - нет.
Прочекать точную структуру DOM. Чистые эмуляторы джаваскрипта наоборот про DOM не знают .
Автоматизированные браузеры могут тоже накосячить (с вложенными айфреймов в частности. Если трафик с iframe, то top.location не должен быть равен window.location).
Приходящие события (onload, onclick итп) тоже проверить полезно - некоторые сканеры вызывают _все_ обработчики, которые только есть. Даже если у нормальных пользователей они никогда не срабатывают (как-то onscroll или onkeypress внутри айфрейма).
И сами события чуть по разному устроены: когда скажем в вебките срабатывает натуральный window.onunload, то event.target == document , а если посылать событие искусственно при помощи dispatchEvent, то event.target == window . А если функцию обработки вызвать напрямую, то arguments.caller выйдет ненулевой, чего случаться не должно.
Есть еще антидебаггерные приемы, но это отдельная тема.
Для сканеров, которые я проверял, вышеописанных приемов вроде достаточно. Там все довольно тупо - пока. Если кто еще что по теме знает, накидайте, было б интересно