image


Безопасность веб-приложений находится в первой десятке трендов и угроз информационной безопасности уже свыше 10 лет. Действительно, современные бизнес-процессы и повседневная жизнь — все больше и больше зависит от использования веб-приложений, в разнообразнейших аспектах: от сложных инфраструктурных систем до IoT устройств. Тем не менее специализированных средств защиты веб-приложений довольно мало, по большей части эту задачу возлагают (или надеются что она будет решена) на разработчиков. Это и использование различных фреймворков, средств санации, очистки данных, нормализации и многого другого. Тем не менее, даже с использованием этих средств безопаснее веб не стал, более того, в все уязвимости "классического веба" практически в неизменном виде мигрировали в мобильную разработку. В этой статье будет рассказано не как не допустить уязвимость, а как защитить веб-приложение от ее эксплуатации с использованием Web Application Firewall.


Из чего складывалась защита веб-приложения раньше? Из грамотной настройки веб-сервера, чистки сайта от ненужных файлов и участков кода и минимального контроля. Действительно, каналы были слабые, DDoS не был распространен, уязвимостей было мало, приложения были простыми, действия пользователей предсказуемы несколькими сценариями.


Со временем усложнялись веб-приложения, серверная инфраструктура и взаимодействие, код становился все более объемным и громоздким — это намного увеличило т.н. "поверхность атаки". Веб стал очень популярным, в нем появились возможности финансового роста — что естественно привлекло в эту сферу желающих незаконно воспользоваться чужим трудом.


Экспоненциально стало расти количество и разновидность атак на веб-приложения, которые условно можно разделить на две категории (исходя из концепции информационной безопасности):


  • угрозы направленные на нарушение конфиденциальности информации;
  • угрозы направленные на нарушение доступности информации.

В первую очередь это касается эксплуатации уязвимостей, во вторую атак на отказ в обслуживании. И если часть атак можно попытаться избежать на этапе планирования и разработки приложения (использую инструменты тестирования, отладки, анализ кода и т.д.), то при размещении веб-приложения в сети интернет сайт (особенно популярной сферы деятельности или компании) начинает подвергаться атакам практически по всем направлениям:


  • автоматические системы эксплуатации уязвимостей;
  • профессиональные кибер-преступники;
  • начинающие, любители.

Они обладают различными методами, способами и инструментарием — объединяет их только одна цель взломать или вывести из строя веб приложение.


Практика и статистика


Хватит теории, давайте перейдем к практике. Очень часто многие оппоненты из dev апеллируют к тому, что уязвимостей скоро (или уже) не будет, есть фреймворки, модные и секюрные, исходный код проверяют тысчи человек, хакеры скоро вымрут. А как же на практике?


Давайте пройдемся по блогу "информационная безопасность" и посмотрим что было "горячего" за последнее время:


Кейс: 3 апреля: 0day в банковском ПО для геолокации (топик удален)
Тип уязвимости: SQL injection, RCE, Auth Bypass.
Описание: слепая инъекция на форме входа в службу геолокации банка. Сервис критичный, доступен в сети интернет.
Риски: бизнес процессы, безопасность, кража, репутация.
Защита: выявлять и блокировать паттерны эксплуатации SQL инъекции, такие как: использование кавычек, специальных конструкций — в данном примере функции sleep.

Кейс: 24 марта: Взлом сайта доставки пиццы, взлом mobidel.ru
Тип уязвимости: Insecure Direct Object References, хранимая XSS, захват сессии
Описание: отсутствие каких-либо проверок, классические клиент-сайд атаки.
Риски: бизнес процессы, безопасность, кража, репутация.
Защита: выявлять и блокировать паттерны эксплуатации XSS вектора — использование функций инъекций html кода, множества запросов авторизации с разными id.

Кейс: 22 марта: Немного о приватности реальных Git-репозиториев
Тип уязвимости: Insecure Direct Object References, раскрытие информации
Описание: прямой доступ к критичным объектам.
Риски: получения информации о приложения для развития атаки.
Защита: выявлять и блокировать множественные обращения к служебным файлам репозитория.

Кейс: 12 марта: Надёжная авторизация для веб-сервиса за один вечер
Тип уязвимости: SQL injection
Описание: типичный разработчик, фигак-фигак и в продакшн.
Риски: security through obscurity.
Защита: выявлять и блокировать паттерны эксплуатации SQL инъекции (union, select и т.д.) — даже зная где она находится (при наличии исходного кода), злоумышленник не сможет ее проэксплутировать.

Кейс: 6 марта: Как взламывают телеком-провайдеров: разбор реальной атаки
Тип уязвимости: SQL injection
Описание: взлом периметра через веб, проникновение в сеть.
Риски: бизнес процессы, безопасность, кража, репутация.
Защита: выявлять и блокировать паттерны использования автоматических средств поиска уязвимостей (по заголовкам, частоте (парсингу) обращений.

Это все то, что как говорится "на виду". Веб-приложения как ломали, так и будут ломать дальше. Никакие инструкции по разработке безопасного кода, рекомендации, бест-прэкстис и т.д. не работают. Необходимы дополнительные защитные, или даже страховочные меры, для того чтобы предотвратить взлом веб-приложения. Это не значит что современные WAF — панацея. Это одна из защитных мер, которая поможет предотвратить взлом веб-приложения.


Выявление паттернов


Давайте разберем основные паттерны из представленных выше кейсов.


Инъекции


Эксплуатация sql-инъекции. В первую очередь злоумышленник (или автоматической средство) будет смотреть на поведение приложения, при подстановке в тот или иной параметр кавычки:


site?id=1'

Будем считать, что инъекция есть, и сайт нам выведет ошибку (классика) you have an error in your sql syntax. Можем ли мы блокировать простую кавычку? По идее да, но вот что делать с фамилиями типа О'Коннор, служебными или админ-панелями, где применение кавычки вполне уместно? (та же markdown-разметка даст нам множество false-детектов).


site?search=O'Connor

Такие запросы напрямую не относятся к эксплуатации, это можно назвать зондированием, probe-запросом, который помогает злоумышленнику обнаружить признак уязвимости. Т.е. такие запросы должны блокироваться, но в тех зонах, где не определено другое правило. Также, необходимо осуществлять проверку IP-адреса, откуда пришел запрос: если ранее с этого адреса были атаки, он в черном списке и т.д. — можно осуществлять блокировку на основе репутационной политики.


Злоумышленник нашел уязвимость, теперь он попытается ее проэкплуатировать (для начала подобрать количество полей):


site?id=1+union+select+null,null/*

Либо, как в первом примере:


demo’+sleep(10)+’

Эти запросы явно относятся к попыткам эксплуатации (и их как правило много) и должны быть заблокированы защитными средствами. Но, стоит учитывать область применения — если это находится в теле запроса, необходимо проводить преобразование (либо очистку) опасных конструкций средствами веб-приложения. Как например в моей статье — хабр не ругается на сломанный синтаксис запроса и дает мне нормально опубликовать кавычку и паттерн атаки (без выполнения).


Атака. Злоумышленник знает как устроено веб-приложение (у него есть код, как из примера выше), он может заранее подготовить конструкцию для атаки, например с применением специальных запросов типа drop/infile/outfile/dumpfile/load_file:


site?id=1+union+select+null,LOAD_FILE('/etc/passwd'),null/* 

Это явная атака и она должна быть заблокирована (опять же по зоне применения правила). Если брать за основу балльную систему — то эта конструкция должна получить множество штрафных баллов: использование паттерна union select (и вариаций), функции LOAD_FILE, наличия спецсимволов и их потенциально опасных комбинаций ('/, обращений к служебным файлам /etc/passwd, и символов терминации/комментирования /*.


XSS


Теперь перейдем к XSS. Тут вариаций пейлоадов довольно много, они более разнообразные и сложные. В этом случае необходимо и защищать веб приложение и давать возможность пользователю вводить данные в формы ввода, не блокируя его. Это необходимо делать, как на уровне приложения, так и средствами защиты.


К примеру, простейшая форма ввода телефона (возьмем вариант без валидации вводимых значений и типов) может быть заполнена пользователем в силу его умений и фантазии:
канонично:


+7 999 999 99 99

со сломанным пробелом:


+79999999999

привычно:


+7 (999) 999-99-99

на европейский манер:


+7.999.999.99.99

Т.е. пользователь даже в такой простой форме может использовать несколько вариаций использования символов и их комбинаций, что говорить про большие веб-формы, которые содержат множество полей? А если они предполагают украшение/выделение текста? Ваша компания:


++"ООО "Ромашка"++

Конечно такой запрос не будет блокироваться, опасных комбинаций здесь нет. "Обычные" xss-зонды, тоже выявляются довольно просто:


alert(
prompt(
onload=
onerror=
onmouseover=
location.href=
document.cookie(

Это может дать выявить попытки эксплуатации уязвимости, поэтому такие запросы будут заблокированы.
Есть и более серьезные запросы на выявления XSS — например классика жанра (практически не устаревающая) — универсальный XSS вектор от raz0r:


javascript:/*--></marquee></script></title></textarea></noscript></style></xmp>">[img=1]<img -/style=-=expression&#40&#47;&#42;’/-/*&#39;,/**/eval(name)//&#41;;width:100%;height:100%;position:absolute;behavior:url(#default#VML);-o-link:javascript:eval(title);-o-link-source:current name=alert(1) onerror=eval(name) src=1 autofocus onfocus=eval(name) onclick=eval(name) onmouseover=eval(name) background=javascript:eval(name)//>"

В этом запросе есть практически все, чтобы "выстрелить" при наличии XSS. Такой запрос — это явная атака и он должен быть немедленно заблокирован.


Сканеры уязвимостей


Обычно предвестником атаки является сканирование веб-приложения теми или иными утилитами. Явный признак: частое обращение с одного IP к разными страницам, больше количество 404 ошибок. Это может быть поисковый бот (его ни в коем случаем не баним, но и при этом мы должны быть точно уверены что это именно бот — проверка поля User Agent не даст таких гарантий). Это может быть краулер или парсер — если нам не жалко — пусть парсит, можно лишь ограничить ему "аппетит" количеством запросов в минуту, если у вас слабый сервер. Другое дело сканеры: в первую очередь их можно сразу же определить по User Agent/служебным заголовкам (а большинство из тех, кто ими пользуется, никогда его не меняют и скорее всего даже не догадываются об этом): например сразу же выявляются такие сканеры, как: acunetix, w3af, netsparker, nikto и т.д. Такие обращения необходимо блокировать сразу же, чтобы не облегчать злоумышленникам работу (и не засорять логи). Если заголовки все-таки замаскированы — определить сканер можно по множеству 404 ошибок, попыток авторизации и обращений к служебным файлам.


Защита


Как мы видели в вышеприведенных примерах, используются разные технологии, платформы — поэтому современные защитные средства должны это учитывать. Во всех случаях использование WAF могло бы предотвратить эксплуатацию уязвимости, а система уведомлений сообщить о попытке эксплуатации.


Для того, чтобы избежать эксплуатации тех или иных уязвимостей, современный WAF должен:


  • моментально обрабатывать трафик;
  • блокировать нелегитимные запросы;
  • выявлять бот-активность;
  • уметь работать с любым протоколом http/https;
  • не зависеть от платформы веб-приложения;
  • уметь выявлять брутфорс-атаки, краулинг и т.д.
  • уметь работать с вебсокетами и т.д.;
  • минимизировать false детекты;
  • блокировать DoS (L7);
  • выявлять и блокировать новые атаки, в т.ч. с помощью машинного обучения;
  • содержать актуальную и пополняемую базу сигнатур атак;
  • содержать актуальную и пополняемую базу IP-reputation;
  • применять virtual patching.

Продолжение


В следующей части я разберу методы противодействия защитным средствам со стороны злоумышленников: популярные методы обхода современных Web Application Firewall, атаки на сами сервисы защиты и т.д.




Nemesida WAF — это межсетевой экран прикладного уровня (Web Aplication Firewall), позволяющий эффективно защищать сайты от хакерских атак даже в случае наличия на сайте уязвимости «нулевого дня».

Поделиться с друзьями
-->

Комментарии (15)


  1. sidristij
    06.04.2017 14:50

    Хакеры будут всегда. Просто уровень подготовки будет расти из года в год.


  1. OlegZH
    06.04.2017 15:25
    -1

    Интересно, что было бы с безопасностью, если бы вместо классических WEB-приложений были бы обыкновенные распределённые приложения, которые работают с пакетами (сокетами)?

    В таких приложениях совершенно невозможно представить инъекции и эксплуатацию уязвимостей по причине того, что, уж, если приложение решило получить число, то оно получит именно число, а не некий кусок, который, почему-то, оказался куском кода, и, опять же почему-то, смог выполниться на сервере.

    Зачем предоставлять пользователю в браузере строку для ввода URL? Если бы браузер предоставлял пользователю всегда только форму ввода (а в ней уже допускался выбор значений только из реальных справочников), то эксплуатировать было бы нечего. ЯТД.


    1. pentestit-team
      06.04.2017 15:33
      +3

      OWASP — «All Input is Evil», says Michael Howard in his famous book «Writing Secure Code»


    1. Vallid
      06.04.2017 15:45
      +1

      Допустим, браузер не предоставлял бы таких возможностей. Но разве браузер – единственный способ общения с веб-приложением?


    1. jMas
      06.04.2017 16:44
      +1

      Ди ничего бы не изменилось… Развивались бы инструменты мониторинга сокетов, составлялись бы похожие запросы, а на стороне бэка у таких приложений всеравно база данных, возможно SQL. И при проектировании например решили делать выборку по статусу, а это строка, подставляемая в SQL запрос, строгая типизация позволит проверить, что да — это строка, но не проверит на SQL-инъекцию. Все что прислал клиент, в данном случае внешнее распределенное приложение, априори нужно валидировать и экранировать.


    1. Free_ze
      06.04.2017 17:55

      В таких приложениях совершенно невозможно представить инъекции и эксплуатацию уязвимостей

      А как же переполнения буферов, arbitrary code execution и все такое?


      1. OlegZH
        10.04.2017 17:05

        Скажите, пожалуйста, в какой момент и при каких обстоятельствах происходит переполнение буфера?


    1. michael_vostrikov
      06.04.2017 18:09

      с пакетами (сокетами)

      Мне сложно представить область, в которой эти термины используются как синонимы. Сокет это точка соединения, пакет это набор данных, передающийся через эту точку. Браузеры и так работают через сокеты.


      В таких приложениях совершенно невозможно представить инъекции и эксплуатацию уязвимостей по причине того, что, уж, если приложение решило получить число, то оно получит именно число, а не некий кусок, который, почему-то, оказался куском кода, и, опять же почему-то, смог выполниться на сервере.

      Веб-приложения, о которых в статье идет речь, тоже могут решить получить число. Этому ничто не мешает, так и делают во многих случаях, явно задавая преобразование входной строки в число. Но во-первых, на входе часто бывают и строки (пример с фамилией из статьи), во-вторых, эти данные часто передаются дальше в запросы к базе данных. И вот если передача данных в запрос построена неправильно, то нет никакой разницы, обычный сайт у вас или распределенное приложение. Потому что база данных есть и там и там.


      Зачем предоставлять пользователю в браузере строку для ввода URL?

      А как я должен задавать, какой сайт я хочу открыть — хабр или гугл?


      Если бы браузер предоставлял пользователю всегда только форму ввода (а в ней уже допускался выбор значений только из реальных справочников), то эксплуатировать было бы нечего. ЯТД.

      Вы думаете неправильно. Браузер предоставляет форму ввода, пользователь выбирает правильное значение из списка, браузер отправляет значение на сервер с приложением. Ничто не мешает написать свою программу, которая прикинется браузером, подключится к серверу, и отправит туда неправильное значение.


      1. OlegZH
        10.04.2017 17:29

        Вы поднимаете очень интересную тему. В принципе, мы всегда имеем дело с работой того или иного ПО, можно, условно говоря, «записать» всё, что угодно, и будет довольно трудно отличить результат работы реального пользователя и заранее заготовленного скрипта. Если, вообще, возможно.

        И вот если передача данных в запрос построена неправильно
        Вопрос следует, на мой взгляд, поставить иначе: можно ли сделать так, чтобы правильная настройка передачи данных была бы встроена в технологию?

        Если существует положительный ответ на этот вопрос, то «прикинуться» будет гораздо сложнее. Но это будет, также, означать и то, что Вы не сможете «просто так» открыть какой-либо сайт, поскольку для пользователя каждый сайт (в недостижимом идеале) должен выглядеть как поставщик сервисов (служб) и данных.

        Более того. Само понятие «открыть сайт» содержит в себе серьёзную методологическую ошибку. Отсюда и возможность организации распределённых атак и т.д. и т.п. Если Вы «обращаетесь» к какому-либо сайту, то Вы это делаете (если следовать написанному мною сценарию в собственной статье) в рамках своей собственной ОС, и Вы не сможете организовать никакую распределённую атаку, потому как у Вас не будет никакого доступа к другим компьютерам во Всемирной Паутине, или Вам будет предоставлен доступ только к тем сервисам (службам), которые предусмотрены с точки зрения интересующего Вас сайта.

        На самом деле, мне вполне понятен смысл Ваших весьма справедливых замечаний. Однако, сказанное Вами не отменяет возможность построения «другого мира». А в этом «другом мире» всё другое. Нет привычных для нас всех понятий «сайт» и «браузер»…


        1. michael_vostrikov
          10.04.2017 18:37

          можно ли сделать так, чтобы правильная настройка передачи данных была бы встроена в технологию? Если существует положительный ответ на этот вопрос, то «прикинуться» будет гораздо сложнее

          Вы не поняли. Передача данных в запрос осуществляется на вашей стороне, т.е. на стороне сервиса. Тут неважно, кто кем прикидывается. Вам пришли данные и вы на основе них строите запрос. Данные могут быть полностью правильные, но в вашем коде может быть неправильная их подстановка в запрос.


          Вы не сможете организовать никакую распределённую атаку, потому как у Вас не будет никакого доступа к другим компьютерам во Всемирной Паутине

          Что мне помешает арендовать 20 компьютеров? Что мне помешает запустить вирус, который предоставит мне доступ к 100000 компьютеров?


          А в этом «другом мире» всё другое. Нет привычных для нас всех понятий «сайт» и «браузер»…

          В вашем мире есть доступ по сети и все связанные с ним проблемы. Также в вашем мире есть базы данных и запросы к ним. Единственный тип атак, которых не будет в вашем мире с жесткими ограничениями — это XSS атаки. Зато будет много других проблем, о которых я написал в комментариях к вашей статье.


          1. OlegZH
            11.04.2017 15:03

            Можете меня не убежать в том, что единственный способ борьбы против злоумышленников — это открытый мир и хорошее воспитание. Никакая самая хитроумная система не остановит того, кто замышляет зло.


  1. rraderio
    06.04.2017 16:59

    SQL injection

    Используйте NoSQL)


    1. LukaSafonov
      06.04.2017 17:03
      +4

      1. izzholtik
        07.04.2017 11:08
        +1

        we need to go deeper


  1. Happy_dayZ
    11.04.2017 10:04

    На любое действие всегда будет противодействие.