Как провести тестирование на безопасность: руководство для Manual QA

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

Вступление

Когда я был Manual QA, мне всегда казалось, что искать уязвимости очень трудно, что этим могут заниматься только те люди, которые умеют программировать. Поэтому я выбрал сначала путь автоматизатора, так как зачастую QA развиваются именно в этом направлении. Но после более чем полутора лет в должности автомейшена мне стало скучно... Да-да, стало скучно, так как мне неинтересно было все время писать код и не общаться с командой девелоперов, продактами и другими членами команды, как я делал это, когда был мануальщиком.

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

Немного о себе: в тестировании я уже больше 7 лет, занимаюсь поиском уязвимостей больше 4 лет. Веду тренинги по тестированию безопасности. Помимо основной работы провожу аудиты по QA. Веду блог.

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

  1. Проблема с тем, где без регистрации и СМС найти и бесплатно почитать нужную литературу. Чтобы вот просто было написано понятным языком без заумных фраз, как любят описывать, чтобы все было структурировано и были примеры, где можно было бы попрактиковаться с прочитанным. При гуглении я получал огромный вброс инфы без разбору, что же надо для начала.
  2. Проблема с нехваткой времени. Согласитесь, трудно найти время на то, чтобы заставить себя учить что-то новое без надобности срочно применять эти навыки :-)

А вот и решения:

  1. С первой проблемой мне помогли... даже не поверите кто — те же самые ловцы уязвимостей, которые атаковали нас и писали нам репорты о наших уязвимостях. Читая эти репорты, я параллельно гуглил и искал в статьях информацию о причинах возникновения и критичности данных уязвимостей. В итоге я составил для себя чек-лист массовости (насколько распространен этот вид уязвимости среди продуктов) и критичности (насколько опасно иметь такую уязвимость в зависимости от того, сколько бед, которые могут привести к потере доверия к бренду, можно натворить с ней на проекте).
  2. Также решением первой и второй проблем стали мои выступления перед публикой на тему уязвимостей. За время подготовки к тому, чтобы учить кого-то чему-то, вы изучите материал настолько хорошо и настолько быстро, что сами удивитесь :-) У вас сразу появляется:
    • дедлайн, к которому вы должны успеть подготовиться и хорошо изучить тему;
    • стимул учить новое, так как перед вами стоит задача выступить перед публикой, а опозориться не сильно хочется, чтобы не показать, что вы чего-то не знаете в этой области, но что-то там вещаете;
    • время. Скажете откуда? Да вы просто под психологическим воздействием, что нужно подготовиться к выступлению, меньше бездействуете (меньше времени уделяете просмотру видосов с котиками и остальными приколясами). Да и после работы вместо просиживания штанишек перед сериальчиком вы готовитесь к своему дебюту на сцене. Нормальный такой лайфхак? :-)
  3. И самое главное: после того как вы ознакомились с какой-либо теорией о уязвимости, немедленно идите применять ее на практике, так как теория в голове без практики имеет способность пропадать, не подавая виду, быстро и бесследно. И это будет реально напрасно потраченное время. Попрактиковаться можно у себя на проекте с разрешения руководства — а я думаю, оно по-любому разрешит вам, так как хорошо, когда есть человек, который может проверить хоть на какую-то безопасность. Либо можно прогуглить Broken Web Application и по первой ссылке скачать себе приложение, запустить его на VirtualBox и применять там свои наработанные навыки.

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

А теперь давайте поговорим о самых распространенных уязвимостях, которые могут встретиться вам на пути, и о том, как их искать...

XSS

Это один из типов уязвимости web application, который дает скрипту возможность отрабатывать на страницу, написанную на JS. Такая уязвимость дает возможность злоумышленнику внедрить свой сценарий в работу вашего приложения. По статистике, 40% компаний, прошедших через сканеры, имеют эту уязвимость. В рейтинге OWASP Top 10 она на 7-м месте. Причина появления этой уязвимости — это доверие со стороны разработчика, что пользователь не будет вносить разнообразные куски кода на сайт.

Что же может сделать в своих целях ловец уязвимостей?

  • Изменить настройки (например, заменить бэкграунд сайта, всунуть, допустим, на задний фон скрин Joycasino, размещать рекламу через всплывающие попапы).
  • Стырить куки пользователя.
  • Фишинг (хакер может вставить поддельную форму для входа на страницу, которую вы посещаете, используя DOM, установив в атрибуты action этой формы отправку данных на свои собственные серваки).
  • Кейлогер (хакер может внедрить что-то типа отслеживания действий, выполняемых на клавиатуре пользователем, используя addEventListener, а потом отправить все эти нажатия клавиш на свой серверок, записав конфиденциальную информацию пользователя. Например, это могут быть пароли и номера кредитных карт. Стремно, согласитесь.

Бывает три типа XSS:

  • Непостоянные (отраженные) XSS.
  • Постоянные (хранимые) XSS.
  • XSS DOM-модели.

Рассмотрим каждую из них.

Непостоянные (отраженные) XSS

Этот класс XSS является самым распространенным на сайтах. Давайте смоделируем вектор атаки с помощью этого класса. Рассмотри это на примере специально подготовленной лаборатории по уязвимостям DVWA. У нас есть форма с инпутом, при этом инпут, как мы видим по исходному коду этой формы, не фильтруется никаким фильтратором. То есть переменная $_GET['name']принимает без перебора все, что в нее впишут. Соответственно, вписанный в этот инпут скрипт <script>alert(1);</script> вызовет попап на этой странице со значением в нем цифры 1, после того как мы отправим на сервер запрос с этим скриптом. В итоге то, что мы отправили через этот инпут на сервер, передается GET-параметром в урле, так как эта форма общается с сервером по GET.

На следующей картинке мы можем увидеть результат:

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

Допустим, SEO-менеджер изучил новый способ распространения рекламы — через попапы этой уязвимости. Он находит сайт, где эта уязвимость срабатывает, в нашем случае это bank.ua. Он дописывает в аргумент поиска после названия скрипт ')%3Balert('XSS')%3Bvar b=(', при этом браузером будет экранироваться попап, отображающий то, что в него напишет наш менеджер, так как данные не подвергаются обработке. Затем паренек просто распространяет весь этот урл через разные социальные сети. Если пользователь, который получит этот скрипт, внимательный, он просто может удалить добавленный в урл скрипт, и попап не выпрыгнет при открытии страницы банка, но если не заметил, то он, помимо открытия страницы сайта, получит вывод попапа, в котором будет информация, которую написал туда наш менеджер.

Хранимые (постоянные) XSS

Этот вид XSS уже считается более разрушительным типом атаки, чем предыдущий. Он возможен, когда ловцу уязвимостей удается закинуть на сервак скрипт JS, который будет выполняться в браузере каждый раз при заходе на запрашиваемую вами страницу. Самым простым примером этой уязвимости являются форумы, на которых разрешено оставлять комментарии в HTML-формате без ограничений. Другими словами, хранимый XSS возникает, когда разработчики осуществляют некорректную фильтрацию при сохранении входных данных в БД на сервере, а затем выводят эти же данные в браузер пользователя.

Примерчик на том же ресурсе DVWA:

В этот раз мы внедряем JS-скрипт (<script>prompt(111)</script>) в поле Message, которое, как мы видим в коде, тоже не фильтруется нормальным образом от пользовательского ввода. После отправки этого скрипта на сервер он положится в базу на сервер и каждый раз будет вызываться при посещении этой страницы. Ах да... в этом случае будет не просто попап с выводом текста «111», а будет задействован еще и инпут, в которой можно что-то вписывать. А если хорошенько подумать над реализацией этого скрипта, то можно так подхачить его, что как будто выпрыгивает форма авторизации, в которую пользователь введет свои данные, а они будут отправлены на сервер злоумышленника. Как вам такой исход этой уязвимости?

И этот попап будет воспроизводиться до тех пор, пока кто-то не почистит значение в базе на сервере, куда отправили храниться этот скрипт, либо не пофиксит саму экранизацию XSS на веб-странице.

DOM-модели XSS

А вот этот вид XSS самый опасный из всех. XSS в DOM-модели появляются на стороне клиента во время обработки данных внутри самого JavaScript. Этот тип XSS получил такое название, потому что нам нужна Document Object Model, чтобы сделать его. Как вы поняли, DOM — это сокращение. Через него можно получать доступ к содержимому HTML- и XML-документов, даже изменять содержимое: либо структуру документа, либо его оформление.

Что можно сделать с помощью этой уязвимости:

  • Изменить страницу сайта (можно добавлять/заменять картинки, добавлять куски нового функционала и так далее).
  • Можно воровать сессии, куки пользователя (своровав эти данные, злоумышленник может воспользоваться ими в своих целях: например, можно авторизоваться под этими данными и быть как будто тем пользователем).
  • Кейлогер (заюзав скрипт на странице с уязвимостью, злоумышленник будет получать все данные, которые вводит пользователь на клавиатуре, находясь на зараженной странице).
  • Мало того что можно сделать то, что описано выше, так еще можно и залезть в операционную систему с помощью уязвимости ms10_002_aurora, которая доступна для старых браузеров Safari и Internet Explorer 7. Вы скажете: «Да это же древние браузеры, кто ими будет пользоваться?» Но нет, давайте вспомним банковские конторы, которые заключили десятилетние контракты на использование этой версии браузера, — вот тут такие пользователи и попадутся на эту уязвимость.

Приведу пример, как можно своровать куки пользователя, а потом применить их у себя в браузере и стать этим пользователем, используя при этом инструмент BeEF:

Injection

А теперь перейдем к первой уязвимости из рейтинга OWASP Top 10 — к Injection. По статистике, ею заражено 28% компаний... Я рассматриваю ее позднее, так как эта уязвимость с каждым годом становится все менее распространенной, но остается наиболее критичной из всех, потому что с ее помощью можно увести всю вашу базу данных. Эта уязвимость делится на такие векторы для атаки:

  • инъекции через запросы SQL, LDAP, XPath;
  • инъекции через команды OS command;
  • инъекции через синтаксический анализ XML.

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

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

Итак, тут мы видим форму, при заполнении которой введенные данные будут отправлены в SQL-запрос, и он вытянет нам ответ из базы данных. Если такой юзер есть в базе данных, то нас авторизует. Если нет, то нам скажет: сорян, зарегайся. То, что мы будем вводить в поле User, передается в переменную $username, а то, что введут в поле Pass, передается в переменную $password нашего SQL-запроса. А теперь рассмотрим то, что будет происходить при вводе значений в эти поля.

Давайте введем такие данные:

  • в поле User — значение Svyat, которое, как мы видим (отмечено красной стрелкой), станет на место переменной $username;
  • в поле Pass — значение 1234, которое, как мы видим (отмечено синей стрелкой), станет на место переменной $password.

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

Давайте теперь рассмотрим, что может сделать злоумышленник в нашем случае...

Тут злоумышленник совершает ход конем и целится в юзера admin. Давайте разберем подробнее, что он ввел:

  • в поле User — значение admin, которое, как мы видим, станет на место переменной $username;
  • в поле Pass — значение ' OR 100=100 --, которое, как мы видим, станет на место переменной $password.

А теперь давайте разберем, что происходит с переменной $password, когда в нее попадают данные такого рода, и как сервер обработает их.

  • Символом кавычки ' из заданного значения ’ OR 100=100 — мы закрываем дефолтную кавычку данной переменной, оставив пароль незаполненным. Это видно на картинке выше.
  • Затем переходим к слову OR из нашего значения ' OR 100=100 -- — оно говорит о том, что мы вызываем оператор OR, который будет выполнять свою функцию в SQL-запросе, так как предыдущей кавычкой мы закрыли нашу переменную.
  • А выражение 100=100 из нашего значения ' OR 100=100 -- говорит серверу: даже если пароль не подошел, все равно прими за true, как будто он подошел для тебя, так как 100=100 является true.
  • И напоследок символы -- из нашего значения ' OR 100=100 -- закомментируют дефолтную кавычку. То есть весь код, который находится после символов --, становится нерабочим. У каждой базы данных вызов операции, чтобы закомментировать код, происходит по-разному: бывает #, бывает —, бывает */.

Исходя из изложенного выше, SQL-запрос получил дополнительное условие, которое диктует серверу новые правила игры, заставляющие его авторизовать нас как пользователя системы, несмотря на то что мы не ввели правильный пароль. А так как это еще и пользователь-админ, мы имеем все привилегии управления приложением. В запрос добавлено значение OR 100=100, которое всегда будет оцениваться как true (так как 100 всегда равно 100, чтобы получить true, необязательно писать именно 100=100, можно взять любое значение, которое равно такому же значению). Теперь этот пользователь будет авторизован как администратор, даже если он не знает пароля. Это не прикольно, согласитесь. Но если есть такая уязвимость, то это может дойти и до такого случая, как на картинке ниже...

Если в поле Pass ввести значение '; DROP TABLE users --, а затем отправить на сервер, то можно вообще лишиться данных юзера в нашей базе, но опять же это если мы не фильтруем в нашем приложении то, что вводит пользователь.

Если подытожить, эта уязвимость нацелена на применение дополнительных команд и операторов в запросах на сервер. И если в ней, как в XSS, нет фильтрации на это дело, то такая дыра будет присутствовать у вас в приложении.

Инструменты

Эту и другие уязвимости с OWASP Top 10 можно искать с помощью автоматизированного инструмента. С ним может справиться и Manual QA, достаточно знать, какие есть самые критические уязвимости, и уметь пользоваться инструментами для их поиска.

К инструментарию Penetration Tester можно отнести такие:

Бесплатные:

  • OWASP ZAP;
  • Nmap;
  • Metasploit;
  • SQLmap;
  • Wireshark;
  • Ettercap;
  • BeEF.

Платные:

  • Burp Suite;
  • Acunetix;
  • Charles;
  • Veracode.

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

Что такое OWASP ZAP

Начнем с того, что OWASP ZAP — это в первую очередь инструмент, который достаточно прост в использовании для тестирования на проникновение в ваше приложение, а также для поиска уязвимостей в веб-приложениях. Программа предназначена как для пользователей, имеющих опыт работы в сфере информационной безопасности, таких как разработчики и мануальные QA, так и для начинающих.

Режимы OWASP ZAP

В ZAP есть несколько режимов работы, при которых он будет проводить сканирование:

1) Безопасный режим — в этом режиме нельзя совершить что-либо потенциально опасное для приложения.

2) Защищенный режим — в этом режиме пользователь (бот) может выполнять только вредоносные действия по URL-адресам, указанным в области браузера.

3) Стандартный режим — в этом режиме пользователь (бот) может делать все, что имеет значение для приложения.

4) Режим Attack — при нахождении новых узлов в области действия шпиона они активно сканируются, как только обнаруживаются.

Оповещение

После того как вы запустите сканер, все найденные ошибки OWASP ZAP будут отсортированы по степени серьезности уязвимостей и будут находиться на вкладке «Оповещение». Красным флажком будут отмечены самые серьезные, такие как XSS, SQL Injection и так далее, оранжевым — менее серьезные уязвимости типа CSRF и остальные малозначимые.

Чтобы более подробно посмотреть найденные сканером уязвимости, достаточно несколько раз кликнуть по какой-то из них.

При этом откроется попап, в котором будет расписано:

  • что это за уязвимость и на что она влияет;
  • ее критичность;
  • скрипт, с которым она воспроизводится;
  • литература о том, как можно починить ее.

Авторизация

Если в вашем проекте присутствует авторизация, то те ссылки, которые доступны для авторизированного пользователя, не будут доступны для OWASP ZAP без выполненной настройки юзера (бота), под которым наш сканер сможет зайти для выполнения поиска уязвимостей на тех страницах, которые доступны для авторизованного юзера. Для того чтобы быстро настроить этого юзера, кликаем по иконке встроенного браузера. При этом откроется сам браузер, в котором введены настройки прокси для обмена данными (request и response). То есть OWASP ZAP становится посредником, запросы, которые вы посылаете в браузере на сервер, сначала идут на OWASP ZAP, а с него — на сервер.

Так же происходит и в обратном порядке: ответ от сервера будет тоже сначала идти на OWASP ZAP, а уже с него — в браузер. Таким образом, вы сможете мониторить весь трафик. Затем выполните авторизацию на сайте, который собираетесь тестировать, через этот браузер.

Все данные, которые вы ввели, будут перехвачены нашим приложением OWASP ZAP. Это мы сможем увидеть в приложении ZAP, с левой стороны. Там появится папочка с названием нашего хоста (сайта), который мы прогнали через браузер с прокси.

Когда мы расхлопнем эту папку, мы увидим иерархию нашего приложения. Здесь мы и увидим наш запрос POST, с которым авторизовались. И если мы будем видеть, что, помимо нужного нам хоста, загрузились еще и другие ресурсы, которые интегрированы в наше веб-приложение, типа разных соцсетей, чтобы не тратить время на сканирование и их — так как нужно же проверять наш проект, а не другие :) — нам нужно задать «контекст» только для одной папки, которую мы хотим проверить. Для этого выбираем нужную папку и включаем ее в контекст.

После того как мы задали папке контекст, мы должны найти в ней запрос, который выполнялся на авторизацию, а затем создать юзера для этого метода, выбрав пункт «Использовать как контекст», а там — пункт Form-based.


После выбора этого пункта отобразится попап с настройками локаторов для заполнения. Нам надо определить, где локатор логина и где локатор пароля, дабы ZAP мог понимать, где какое поле ввода, чтобы он мог вписывать туда данные для авторизации. Тут нам надо выбрать из выпадающего списка, что будет применяться в качестве значения в локаторе.

В этом случае нам надо выбрать в первом ДД username, во втором — password. Нажимаем OK. На POST-запросе у вас появится иконка двери.

Затем надо создать самого бота (юзера), задать ему креденшелы, которые он будет вводить в те инпуты, настроенные нами ранее. Для этого заходим в раздел Users и в этом разделе добавляем нашего пользователя, который сможет авторизоваться.

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

Теперь нам надо показать OWASP ZAP какой-то локатор (XPath) на странице авторизованного юзера, чтобы сканер понимал, что авторизация прошла успешно. Для этого нам надо зайти на ответ, полученный от сервера, с HTML-разметкой, которую получает авторизованный юзер. Затем находим какой-то локатор, к которому привяжем наш сканер. Этот локатор OWASP будет искать после выполнения авторизации и понимать, успешно ли он прошел авторизацию на сайте.

Этот локатор вставляем в раздел аутентификации, в котором мы задавали параметры входа, — в инпут Regex pattern identified in Logged.

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

После этого в выпадающем списке находим нашего пользователя, под которым зайдет сканер.

И вуаля! Пошло сканирование вашего проекта на всевозможные уязвимости.

Но помните: никакая из программ не может гарантировать, что будут найдены все уязвимости. Найденные уязвимости могут быть и false-positive, то, что найдет сканер, по-любому надо проверять руками.

Подытожим

Теперь вы знаете:

  • о двух уязвимостях;
  • с помощью какого инструмента можно искать уязвимости;
  • где можно практиковаться в поиске уязвимостей.

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

И помните: все показанное выше сделано в целях обучения! Применять на своих проектах можно только с разрешения.


Читайте также: Зарплаты украинских тестировщиков — июнь 2019

Похожие статьи:
Многие вебмастера, когда начинают работу с WordPress вообще не имеют никакого представления о том, какое программное обеспечение и плагины...
Пропонуємо список технічних запитань, які, ймовірно, вам поставлять на співбесідах з C++. Питання надали фахівці, що проводять...
Приглашаем на комбинированный класс с углубленной программой по Product Discovery и Product Delivery и получением двух сертификатов...
З 8 лютого 2022 року в Україні запрацював спецрежим для IT-галузі Дія City. Відтоді з’явилася і нова форма договору між...
В рубрике DOU Проектор все желающие могут презентовать свой продукт (как стартап, так и ламповый pet-проект). Если вам...
Яндекс.Метрика