В статье будет рассмотрены практики защиты уязвимого веб-приложения — от сигнатурного метода до искусственного интеллекта с использованием Web Application Firewall (коммерческая и Opensource версии). В качестве коммерческого решения мы будем использовать Nemesida WAF, в качестве некоммерческого — NAXSI. Статья содержит общую и техническую информацию по работе WAF, а также сравнение методов обнаружения атак, разбор их особенностей и недостатков.
Детектирование атак
Первая и основная задача любого WAF — максимально точно определить атаку с минимальным количеством ложных срабатываний (false positive). В NAXSI заложен только сигнатурный механизм определения атак (поведенческий анализ находится в начальном состоянии, поэтому мы его считать не будем), в Nemesida WAF — три: сигнатурный, качественный поведенческий анализ и машинное обучение. Говоря о комплексном методе определения атак мы подразумеваем симбиоз этих трех методов. Почему три? Давайте разберемся.
Сигнатурный метод определения атак
Несмотря на стремительное развитие технологий, большая часть атак выявляется сигнатурным методом, и от того, насколько качественно пишутся сигнатуры, зависит точность работы всех методов, построенных на базе сигнатурного анализа (в том числе машинное обучение). Рассмотрим пример определения атаки на веб-приложение сигнатурным методом:
index.php?id=-1'+union+select+1,2,3,4,5+--+1
В данном случае сигнатурой атаки будет вхождение цепочки «union+select».
Пример атаки, которую пропустит NAXSI:
index.php?id=-1'+Union+Select+1,2,3,4,5+--+1
NAXSI пропустит такую атаку, поскольку при обработке запроса из-за ошибки в коде не учитывается первая буква «стоп слова», указанная в верхнем регистре, и запрос не подходит под сигнатуры «union» и «select».
NAXSI пропустит прямое обращение для получения версии СУБД:
id=version();+--+
Это касается и других служебных функций — «CURRENT_USER()», «DATABASE()», «ROW_COUNT()» и других. NAXSI не преобразует (не нормализует) «URLENCODED» данные или бинарные строки для сравнения с базой сигнатур, поэтому такие атаки тоже будут пропущены:
id=concat_ws%23%0a(0b00111010,database%0b(%0b),database%09(%09)
id=1 anD 0 unio%6e %23def%0a sELEc%74%23zxc%0a
И такие атаки тоже пропустит:
Пример 1: <iframe/onload='this[«src»]=«javas cript:al»+«ert``»';>
Пример 2: <img/src=q onerror='new Function`al\ert\`1\``'>
Стоит отметить, что сигнатуры NAXSI учитывают не все современные методы маскировки пейлода и требуют значительной доработки. А учитывая регулярные выражения по синтаксису MySQL команд есть немалая вероятность внести в белый список (при ложных срабатываниях) кучу «опасных вхождений», например:
MainRule "rx:select|union|update|delete|insert|table|from|ascii|hex|unhex|drop" "msg:sql keywords" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:4" id:1000;
False Positive
Для того, чтобы свести количество ложных срабатываний к нулю, необходимо точно выставлять уровень угрозы для каждой сигнатуры (скоринг). Рассмотрим правило с неверным скорингом (на примере операторов «order» и «by»), приводящий к появлению ложных срабатываний:
The New World Order is a book written by H. G. Wells
Причина False Positive в примере выше — высокий скоринг вхождения операторов MySQL без учета применимости и зоны запроса.
А вот пример правила с верным скорингом (вхождение цепочки):
index.php?id=1+order+by+10+--+
Сигнатурный анализ: выводы
1. Для разработки сигнатур нужны высокие компетенции и понимание того, как работает злоумышленник. У нас такими знаниями обладают сотрудники отдела анализа защищенности.
2. Сигнатуры должны постоянно обновляться
3. Использование сигнатур без специализированной обработки (поведенческого анализа) приведет к ложным срабатываниям (False Positive).
Даже с точным и полным набором правил сигнатурный метод выявления атак имеет 2 основных недостатка, которые приведут или к появлению ложных срабатываний, или вовсе пропустят атаку:
- False positive в случае, если сигнатурный метод выявит вхождение операторов «union» и «select» в URI будет иметь высокий скоринг, что приведет к ошибочному блокированию запроса: /weareunion/sub/select_your_choice.php
- False negative в случае, если сигнатура или цепочка сигнатур атаки, имеет низкий скоринг, но позволяет получить «чувствительную» информацию: some.php?size=version%28%29%20;%20-
Чтобы устранить оба недостатка, потребуется расширенная модель определения атак — поведенческий анализ и машинное обучение.
Поведенческий анализ
Перейдем сразу к практике:
Запрос 1: index.php?id=1
Запрос 2: index.php?id=3-2
Запрос 3: index.php?id=-1
Запрос 4: index.php?id=1'
Запрос 5: index.php?id='1
Запрос 6: index.php?id=1 and sleep(5)
В этом примере мы видим попытку выявления SQL-инъекции путем манипуляции параметров, добавления символа кавычки и функции «sleep». Сами по себе эти разрозненные признаки не содержат явного вектора атаки, но их совокупность явно дает понять, что злоумышленник пытается «прощупать» веб-приложение. Математическая модель суммирует признаки поведения пользователя за период времени и на основании этого происходит блокировка, что позволяет не пропустить начало атаки, при этом запросы легитимных посетителей сайта не блокируются.
Искусственный интеллект
Машинное обучение (Machine Learning) — обширный подраздел искусственного интеллекта, изучающий методы построения алгоритмов, способных обучаться. Различают два типа обучения:
- обучение по прецедентам, или индуктивное обучение, основанное на выявлении общих закономерностей по частным эмпирическим данным
- дедуктивное обучение, предполагающее формализацию знаний экспертов и их перенос в компьютер в виде базы знаний. Дедуктивное обучение принято относить к области экспертных систем, поэтому термины машинное обучение и обучение по прецедентам можно считать синонимами.
Говоря простыми словами, мы используем весь накопленный опыт (как в области защиты веб-приложений, так и опыт тестирования на проникновения) для построения основы обучающейся модели, то есть используем дедуктивное обучение.
Дополнительный источник атак — лаборатории тестирования на проникновение
В 2013 году была запущена первая лаборатория тестирования на проникновение «Test lab», представляющая собой копию реальной корпоративной сети виртуальной компании, содержащая распространенные уязвимости и ошибки конфигурации. За 4 года разработки лабораторий их концепция не изменилась, изменились только ее размеры. Последние лаборатории представляют собой распределенные сети головного офиса и филиалов, а количество узлов увеличилось до 50 единиц (сервера, рабочие станции, сетевое оборудование etc). В отличие от CTF упор в «Test lab» сделан на реалистичность, а действия атакующих идентичны действиям внешнего нарушителя, что позволило собрать вокруг «Test lab» боле 18 000 участников.
Для нас лаборатории стали не только «just for fun», но и отличным полигоном для отладки и улучшения работы Nemesida WAF. Только представьте — 40-50 Мбит\с трафика «чистых» атак, которые нужно без задержек обработать и отфильтровать.
Одно из заданий в текущей (Test lab v.11) лаборатории было реализовано следующим образом: атакующему за внешним периметром доступен веб-сайт, содержащий SQL-инъекцию. В то же время сайт был защищен Nemesida WAF, блокирующий все попытки выполнить эксплуатацию. Раскрутить уязвимость можно было только проникнув внутрь корпоративной сети, используя заложенные уязвимости на других «публичных» сервисах. Тем не менее, одному из участников удалось обойти WAF, за что ему было выплачено вознаграждение. Мы очень ценим помощь сторонних исследователей в работе по улучшению механизмов защиты Nemesida WAF, поэтому открыли Bug Bounty с призовым фондом в 50000 рублей. Подробнее о конкурсе по ссылке. Мы дорожим доверием наших клиентов и всегда найдем возможность отблагодарить тех, кто нам в этом помогает.
Nemesida WAF
Являясь компанией, предоставляющей услуги и решения в области практической ИБ — тестирование на проникновение, анализ защищенности и т.д., обладая качественной базой поиска уязвимостей (в 8 из 10 пентестов завершаются получением доступа к критичным данным), мы сделали Nemesida WAF — систему комплексного выявления атак на основе искусственного интеллекта, точно выявляющую и блокирующую атаки на веб-приложения с практически 0% ложных срабатываний.
Личный кабинет
Nemesida WAF предоставляется или в виде облачного сервиса (когда трафик до защищаемого приложения проходит через защищаемый модуль, расположенный в нашей инфраструктуре), или в виде Standalone-версии (когда WAF устанавливается в инфраструктуре клиента).
Комментарии (6)
RomanovR Автор
24.08.2017 11:59+2Мы не сторонники подхода «казаться лучше за счет привлечения внимания к недостаткам других решений», готовы честно соревноваться и выигрывать, но решение оставляем за нашими клиентами, поэтому можете сами оценить, как точно Nemesida WAF способен блокировать атаки.
Есть как минимум 3 варианта это сделать:
— можно получить демо-доступ к личному кабинету, посмотреть за атаками в реальном времени\самому попытаться атаковать, наблюдая за работой Nemesida WAF на примере vulns.pentestit.ru;
— получить триальную Standalone-версию Nemesida WAF и развернуть в своей инфраструктуре;
— бесплатно встать под защиту облачной версии на 2 недели.
varvsn
24.08.2017 13:48Пример атаки, которую пропустит NAXSI:
index.php?id=-1'+Union+Select+1,2,3,4,5+--+1
Открываем стоковый naxsi_core.rules, смотрим:
MainRule «str:'» «msg:simple quote» «mz:ARGS|BODY|URL|$HEADERS_VAR:Cookie» «s:$SQL:4,$XSS:8» id:1013;
Naxsi реагирует на кавычку. До «стоп слова» дело даже не доходит (как бы это ни звучало).
Проверил все примеры из статьи на nginx 1.13.4+naxsi — всё прекрасно детектируется.LukaSafonov
24.08.2017 14:01+1Контекст применимости атаки относится к операторам MySQL, находящихся в запросе.
Naxsi реагирует на кавычку. До «стоп слова» дело даже не доходит (как бы это ни звучало).
Правило
MainRule «str:'» «msg:simple quote» «mz:ARGS|BODY|URL|$HEADERS_VAR:Cookie» «s:$SQL:4,$XSS:8» id:1013;
будет больше фолсить, чем приносить пользы (особенно в теле запроса |BODY|) и скорее всего может быть исключено из контекста.
В этом примере указывается на ошибку сравнения:
strncasechr(const char *s, int c, int len) { int cpt; for (cpt = 0; cpt < len && s[cpt]; cpt++) if (tolower(s[cpt]) == c) // сравнение lowercase с возможным uppercase return ((char *) s+cpt); return (NULL); } /* ** strstr: faster, stronger, harder ** (because strstr from libc is very slow) */ char * strfaststr(unsigned char *haystack, unsigned int hl, unsigned char *needle, unsigned int nl) { char *cpt, *found, *end; if (hl < nl || !haystack || !needle || !nl || !hl) return (NULL); cpt = (char *) haystack; end = (char *) haystack + hl; while (cpt < end) { found = strncasechr((const char *) cpt, (int) needle[0], hl); if (!found) return (NULL); if (nl == 1) return (found); if (!strncasecmp((const char *)found+1, (const char *) needle+1, nl-1)) return ((char *) found); else { if (found+nl >= end) break; if (found+nl < end) { /* the haystack is shrinking */ cpt = found+1; hl = (unsigned int) (end - cpt); } } } return (NULL); }
varvsn
24.08.2017 14:20Я всего лишь хотел указать на то, что NAXSI с дефолтным конфигом ловит всё, о чем идет речь в статье. А то, что некоторые срабатывания, возможно, будут false-positive для каких-то проектов — вопрос немного другой.
LukaSafonov
24.08.2017 14:44NAXSI c дефолтным конфигом практически все фолсит, от легитимных кавычек и запятых до названий файлов (например, xxx_640x480.png). NAXSI хорош для изучения базисных принципов защиты веб-приложений, но абсолютно не подойдет для enterprise-решений.
У многих правил довольно широкое трактование, и как только начнете строить WhiteList (количество может привышать 2000 строк на каждое отдельное веб-приложение), то загоните себя в ловушку, из которой уже не сможете выбраться. Каждый новый блок (фолс) придется разблокировать созданием правил, а это значит что будут потеряны легитимные клиенты. Но, повторюсь, если хотите изучить базовые принципы защиты веб-приложений — NAXSI будет отличным помощником.
equand
Как оно играет против Cloudbric, Cloudflare или Sophos?