Уровень сложности
Простой
Время на прочтение
11 мин
Количество просмотров 3.3K
В прошлый раз мы рассказали о том, что такое платформы и программы багбаунти, какой базовый инструментарий может использовать багхантер, чтобы облегчить или автоматизировать поиск, привели реальные примеры уязвимостей из старых версий приложений с открытым исходным кодом и посоветовали хорошую литературу для самостоятельного изучения.
В этой статье поговорим о том, что такое скоуп (scope) — устанавливаемые программой границы, в рамках которых разрешается проводить багхантинг, — как работать со скоупом и какие инструменты могут быть полезны. Кроме того, покажем несколько реальных примеров уязвимостей других классов, а в конце вас ждет небольшой бонусный раздел.
Дисклеймер
Имейте в виду, эта статья носит информационный характер и посвящена легальному поиску уязвимостей в информационных системах. Мы не призываем к совершению противоправных действий и обращаем внимание третьих лиц на необходимость во всех случаях соблюдать действующее законодательство и правила соответствующей программы по поиску уязвимостей. Неправомерный доступ к компьютерной информации влечет за собой юридическую ответственность.
Скоуп
Компании, размещающие свои программы на платформах багбаунти, как правило, указывают скоуп, или область действия, в рамках которой багхантеры должны проводить свои исследования. Такие работы будут считаться легитимными и легальными при условии, что багхантеры будут выполнять и остальные требования программы.
Например, в программе багбаунти Positive Technologies при проведении работ запрещено:
-
разглашать информацию о найденной уязвимости без разрешения компании;
-
воздействовать на учетные записи пользователей без их разрешения;
-
использовать обнаруженную уязвимость в личных целях;
-
использовать инструменты тестирования уязвимостей, автоматически генерирующие значительные объемы трафика и приводящие к атакам с исчерпанием ресурсов;
-
проводить атаки, наносящие вред целостности и доступности сервисов (например, DoS-атаки, брутфорс-атаки), пытаться эксплуатировать уязвимость, нацеленную на исчерпание ресурсов;
-
проводить физические атаки на персонал, дата-центры и офисы компании;
-
проводить атаки на системы Positive Technologies с использованием техник социальной инженерии (фишинг, вишинг и т. д.) и спам-рассылок клиентам, партнерам и сотрудникам;
-
исследовать серверную инфраструктуру, где размещены веб-приложения.
Cкоуп Positive Technologies включает пять доменов (ptsecurity.com, partners.ptsecurity.ru, group.ptsecurity.com, event.phdays.com, promo.ptsecurity.com).
Остановимся подробнее на том, что такое домен, субдомен и как их искать.
-
Домен (доменный адрес) — уникальный человекочитаемый адрес веб-сервера в сети, который связан с целевым или проксирующим IP-адресом сервера. Примеры доменов: XXX.com и XXX.ru.
-
Субдомен (поддомен) — отдельный домен, как правило третьего уровня и выше, являющийся частью домена более высокого уровня, как правило второго. Примеры субдоменов: api.XXX.com и login.XX.com.
Существует большое количество способов поиска субдоменов. Приведем некоторые из них:
-
анализ отдаваемого сервером кода веб-страницы или анализ исходного кода мобильного приложения для поиска конечных точек субдоменов в комментариях страницы, в адресах подключаемых скриптов и их содержимом, в забытых файлах;
-
Google Dork Queries — выполнение в поисковой системе Google специальных запросов, помогающих раскрыть дополнительную информацию;
-
веб-сервисы, специализирующиеся в том числе на поиске субдоменов: crt.sh, virustotal.com, searchdns.netcraft.com, dnsdumpster.com, www.shodan.io;
-
инструменты, собирающие субдомены из разных источников: Sublist3r (github.com/aboul3la/Sublist3r), crtsh (github.com/YashGoti/crtsh), Amass (github.com/OWASP/Amass);
-
перебор доменов методом брутфорса (brute force): subbrute (github.com/TheRook/subbrute), dnsrecon (www.kali.org/tools/dnsrecon), ffuf (github.com/ffuf/ffuf), nmap (nmap.org).
Другим примером на Standoff 365 Bug Bounty может служить программа компании ВКонтакте. В ее скоуп входят следующие домены: *.vk.com, vk.com, m.vk.com, api.vk.com, login.vk.com, oauth.vk.com, *.vk.me, *.vk.cc, *.vk.link, id.vk.com, *.vkontakte.(ru|com), *.vk-cdn.net, *.userapi.com, *.vkuser.net, *.vkuseraudio.(com|net), *.vkuservideo.(com|net), *.vkuserlive.(com|net).
Примечательный момент в скоупе этой программы — наличие звездочки в названиях доменов. Когда участвующая в программе багбаунти компания имеет большое количество субдоменов и все они входят в скоуп, перед названием домена ставится звездочка: *.vk.com.
Не стоит забывать о том, что в правилах программы багбаунти могут быть и дополнительные требования. К примеру, в исключения могут попасть тестовые домены, домены, делегированные партнерскими сервисами (за них текущая программа ответственности не несет), а также те, которые специально вывели из области действия.
Подводя итоги этого раздела, еще раз напомним, что, прежде чем приступать к поиску уязвимостей в разрешенном скоупе, необходимо внимательно ознакомиться со всеми правилами программы багбаунти. Приобретение и совершенствование навыков по поиску субдоменов, находящихся в скоупе программ, и дальнейшее выявление уязвимостей в них, могут принести багхантерам значимую награду в виде накопленного опыта, репутации на платформе и денежного вознаграждения.
Примеры часто встречающихся уязвимостей
В предыдущей статье мы рассмотрели атаки типа SQL injection, cross-site scripting (XSS) и cross-site request forgery (CSRF). В этом материале разберем следующие уязвимости:
-
insecure direct object references (IDOR) — уязвимость, позволяющая приложению использовать контролируемые пользователем данные для получения прямого доступа к объектам. Другими словами, эксплуатация этой уязвимости в системе может привести к утечке пользовательских данных или выполнению несанкционированного действия — добавлению, чтению, обновлению или удалению какой-либо информации в системе;
-
directory traversal — уязвимость, позволяющая злоумышленнику выйти за пределы разрешенного каталога и производить удаление, изменение или чтение произвольных файлов на сервере. В результате ее эксплуатации могут быть прочитаны системные файлы либо файлы приложения, которые раскроют злоумышленнику исходный код; файлы с переменными окружения, содержащими токены для подписи или данные для авторизации, например для базы данных или аккаунта администратора, а также любую другую критическую информацию, которая ни в коем случае не должна быть в открытом доступе.
Быстрый старт на настоящих примерах
Чтобы успешно заниматься поиском уязвимостей в рамках багбаунти, необходимо фундаментальное понимание того, каким образом возникают уязвимости, где они могут находиться и как их эксплуатировать для представления доказательств работы. В примерах этого раздела будут использоваться устаревшие и уязвимые плагины для одной из популярнейших систем управления содержимым — WordPress.
Insecure direct object references
Начнем с примера уязвимости класса insecure direct object references (IDOR). Для ее демонстрации выбран плагин для WordPress — Directorist версии 7.4.2.1 с общедоступным эксплойтом. Суть рассматриваемой уязвимости в том, что авторизованный пользователь даже с минимальными правами может изменить пароль любого другого пользователя, в том числе администратора.
В папке с плагином находится файл includes/classes/class-ajax-handler.php, в котором в функции update_user_profile в строке 850 вызывается функция directorist_update_profile; внутри нее вызывается еще одна функция — update_profile, которая обновляет информацию о пользователе с учетом полученных извне данных.
В функции update_profile обратите внимание на строку 486, где используется тернарный оператор для получения значения идентификатора пользователя. В случае если пользователь передает значение в ключе user[ID] при выполнении POST-запроса, берется это передаваемое значение. В ином случае — результат функции get_current_user_id(), что будет являться идентификатором текущего пользователя.
Другим любопытным моментом являются строки 500–501, в которых задается новый пароль для пользователя. В строке 518 вызывается функция wp_set_password, которая обновляет пароль пользователя в соответствии с данными, которые контролируются извне.
В этом случае пользователь с ролью «Подписчик» может выполнить POST-запрос к сценарию /wp-admin/admin-ajax.php?action=update_user_profile и передать в теле запроса данные, приведенные ниже, с указанием ID пользователя. Как правило, пользователь с ролью «Администратор» имеет идентификатор со значением «1».
Результатом будет несанкционированное изменение пароля пользователя с ролью «Администратор» при использовании плагина Directorist версии 7.4.2.1.
Directory traversal
Рассмотрим другой класс уязвимостей — directory traversal. Примером будет служить уязвимый плагин для WordPress — Simple Job Board версии 2.9.3. Для этой версии плагина существует общедоступный эксплойт. Суть рассматриваемой уязвимости заключается в том, что из-за неправильной обработки пользовательского ввода при получении файла с резюме злоумышленник может выйти за пределы разрешенного каталога и прочитать системный файл.
В папке с плагином расположен файл includes/class-simple-job-board-resume-download-handler.php; в функции download_resume в строке 49 этого файла формируется путь к файлу через глобальную переменную $_GET[‘sjb_file’], значение которой контролирует пользователь.
Видно, что эта переменная обрабатывается функцией esc_attr, однако использование данной функции в этом случае некорректно, потому что она предназначена для экранирования HTML-атрибутов, а именно спецсимволов <, >, &, « и ‘.
Для выполнения атаки directory traversal достаточно специальных символов . (точка) и / (косая черта), чтобы выйти за пределы текущей директории и обратиться к системным файлам или файлам приложения.
Поэтому пользователь с ролью «Редактор» может отправить на сервер запрос, описанный в статье с общедоступным эксплойтом, и в ответ получить системный файл, к которому доступа быть не должно. В данном случае происходит попытка получения системного файла /etc/passwd:
Сервер возвращает запрашиваемый злоумышленником системный файл:
Бонус
Пришло время вспомнить один из классов уязвимостей, который мы рассматривали в первой части статьи «Как начать заниматься багхантингом веб-приложений»: некорректную санитизацию данных при генерировании веб-страниц (межсайтовое выполнение сценариев (XSS), или, простыми словами, выполнение вредоносного JavaScript-кода в браузере жертвы).
В этом разделе расскажем про XSS-атаку postMessage и наше исследование под названием Fuzzing for XSS via nested parsers condition.
PostMessage XSS
Существует понятие postMessage. Это механизм отправки кросс-доменных запросов между сайтами. К примеру, есть некоторый сайт, у которого есть слушатель сообщений postMessage. Задача этого слушателя — обработать поступающее извне сообщение. Обработка может быть совершенно разной: работа с файлами куки, выполнение редиректа на произвольную страницу, модификация HTML-страницы и т. п. И существует другой сайт, способный запустить в iframe или открыть в новой вкладке целевой сайт, у которого есть слушатель сообщений, и передавать туда данные с помощью механизма postMessage. В некоторых случаях киберпреступник может воспользоваться этими функциями, чтобы выполнить так называемую атаку postMessage XSS.
Приведем небольшой пример того, как злоумышленник может использовать в своих целях функцию слушателя сообщений postMessage.
На странице есть код JavaScript, который устанавливает слушателя сообщений с помощью функции receiveMessage. В начале этой функции проверяется источник сообщения: с какого домена оно пришло. Если источником сообщения является домен, начинающийся на https://application.localhost, приложение продолжает работать: происходит парсинг строки с помощью функции JSON.parse в переменную data, после чего проверяется, есть ли в объекте ключ url, и, если он есть, выполняется редирект на страницу, которая и указана в значении data.url. Рассмотрим, как атакующие могут злоупотребить этой функциональностью на целевом сайте.
Во-первых, в коде содержится проверка источника сообщения: событие с сообщением должно быть отправлено с домена, имя которого начинается на https://application.localhost. Однако злоумышленник может обойти это условие, если сообщение будет отправлено с сайта, который он контролирует, например с https://application.localhost.evil.localhost.
Во-вторых, после того как прошла проверка origin (источника сообщения), злоумышленник мог поместить в ключ url значение javascript:alert(). При присваивании этого значения в location.href будет выполнена JavaScript-функция alert в браузере жертвы.
Злоумышленник размещает на своем сайте, который находится по адресу https://application.localhost.evil.localhost, следующую полезную нагрузку и заманивает на него жертву с помощью фишинга:
После того как жертва перешла на сайт злоумышленника https://application.localhost.evil.localhost и разрешила всплывающее окно, откроется новая вкладка в домене https://application.localhost. В открывшуюся вкладку в домене https://application.localhost спустя 1 секунду с сайта злоумышленника будет отправлено сообщение postMessage в виде строки ‘{«url»:»javascript:alert()»}’, что приведет к атаке postMessage XSS, или, другими словами, выполнению произвольного JavaScript-кода в браузере жертвы. Задержка в одну секунду обусловлена тем, что открываемому сайту необходимо дать полностью прогрузиться.
Возможны ситуации, когда в найденном слушателе сообщений postMessage может отсутствовать проверка на источник отправления (origin) либо эта проверка может быть недостаточно корректна, как это описано в примере выше. Дополнительно рекомендуем почитать о других способах обхода защитных механизмов в статье PostMessage vulnerabilities.
Стоит помнить еще и о том, что слушатели сообщений могут находиться не только на главной странице сайта, но и в подключаемых скриптах, в том числе сторонних. Чтобы найти их для проверки защищенности, следует либо вручную искать во всех подключаемых на страницу скриптах установку слушателя сообщения, либо использовать автоматизированное средство, определяющее, где могут находиться слушатели сообщений.
К автоматизированным средствам, помогающим находить слушатели postMessage, можно отнести плагин postMessage-tracker для браузера Google Chrome.
Fuzzing for XSS via nested parsers condition
Некоторое время назад мы опубликовали исследование Fuzzing for XSS via nested parsers condition. Мы выяснили, что при использовании определенного языка разметки и библиотеки парсинга к нему, например BBCode, можно внедрить такую синтаксическую конструкцию, которая запутает парсер разметки и позволит внедрить код JavaScript в результат парсинга (причем даже с условием того, что одной из задач парсера как раз и является недопущение внедрения JavaScript-кода в результат его работы). Полученный результат может быть отображен на странице пользователя, что приведет к XSS-атаке на него.
Вот реальный пример из нашего исследования, базирующийся на популярном бесплатном веб-форумном движке MyBB. В версии 1.8.25 команда разработки MyBB исправила синтаксическую конструкцию следующего вида, приводящую к XSS-атаке:
После ее исправления мы выпустили еще одно исследование — MyBB <= 1.8.31: Remote Code Execution Chain. В нем была обнаружена и продемонстрирована еще одна синтаксическая конструкция, которая запутывает парсер и тоже приводит к XSS-атаке на пользователя. Она имеет следующий вид:[email][email= onpointerover=alert()//]text[/email]
Приведенную выше синтаксическую конструкцию злоумышленник внедряет в свою подпись (сигнатуру) на форуме в режиме исходного кода и сохраняет ее.
Если после сохранения просмотреть данную сигнатуру в обычном режиме, в котором уже будет использован парсер для обработки внедренной пользователем нагрузки, то произойдет запутывание парсера и будет выполнен выход за пределы значения атрибута в виде события onpointerover и его значения — JavaScript-функции alert().
Поэтому при багхантинге или анализе защищенности веб-приложений не стоит забывать о наших примерах в бонусном разделе😉
Заключение
В конце нам хотелось бы обратить внимание багхантеров, особенно начинающих, на некоторые важные вещи:
-
при поиске уязвимостей необходимо очень внимательно прочитать правила программы на площадке багбаунти, тщательно изучить разрешенный скоуп и дополнительные условия;
-
при нахождении уязвимости или возможности проведения атаки в момент написания отчета прикладывать доказательство работы (PoC), обосновывая влияние на безопасность системы;
-
помнить, что, помимо уязвимостей, которые могут быть в самописных тестируемых системах, на других портах домена или субдомена также могут быть устаревшие версии систем, в которых тоже могут присутствовать известные уязвимости различного рода. О них также следует сразу сообщать компании;
-
необходимо искать новые техники эксплуатации уязвимостей и исследовательские подходы, постоянно углублять свои знания, фундаментально изучать, какие классы уязвимостей существуют, как их находить, и стараться понять, как их можно исправить.
Таким способом исследователи в сфере кибербезопасности помогают выявлять возможности проведения кибератак и своевременно предотвращать их, нивелировать возможные риски, повышать надежность сервисов, которыми пользуются миллионы людей, и делать мир вокруг безопаснее.
Алексей Соловьев
Старший специалист группы анализа защищенности веб-приложений компании Positive Technologies
Как начать заниматься багхантингом веб-приложений. Часть 2
В прошлый раз мы рассказали о том, что такое платформы и программы багбаунти, какой базовый инструментарий может использовать багхантер, чтобы облегчить или автоматизировать поиск, привели реальные примеры уязвимостей из старых версий приложений с открытым исходным кодом и посоветовали хорошую литературу для самостоятельного изучения.
В этой статье поговорим о том, что такое скоуп (scope) — устанавливаемые программой границы, в рамках которых разрешается проводить багхантинг, — как работать со скоупом и какие инструменты могут быть полезны. Кроме того, покажем несколько реальных примеров уязвимостей других классов, а в конце вас ждет небольшой бонусный раздел.
Дисклеймер
Имейте в виду, эта статья носит информационный характер и посвящена легальному поиску уязвимостей в информационных системах. Мы не призываем к совершению противоправных действий и обращаем внимание третьих лиц на необходимость во всех случаях соблюдать действующее законодательство и правила соответствующей программы по поиску уязвимостей. Неправомерный доступ к компьютерной информации влечет за собой юридическую ответственность.
Скоуп
Компании, размещающие свои программы на платформах багбаунти, как правило, указывают скоуп, или область действия, в рамках которой багхантеры должны проводить свои исследования. Такие работы будут считаться легитимными и легальными при условии, что багхантеры будут выполнять и остальные требования программы.
Например, в программе багбаунти Positive Technologies при проведении работ запрещено:
-
разглашать информацию о найденной уязвимости без разрешения компании;
-
воздействовать на учетные записи пользователей без их разрешения;
-
использовать обнаруженную уязвимость в личных целях;
-
использовать инструменты тестирования уязвимостей, автоматически генерирующие значительные объемы трафика и приводящие к атакам с исчерпанием ресурсов;
-
проводить атаки, наносящие вред целостности и доступности сервисов (например, DoS-атаки, брутфорс-атаки), пытаться эксплуатировать уязвимость, нацеленную на исчерпание ресурсов;
-
проводить физические атаки на персонал, дата-центры и офисы компании;
-
проводить атаки на системы Positive Technologies с использованием техник социальной инженерии (фишинг, вишинг и т. д.) и спам-рассылок клиентам, партнерам и сотрудникам;
-
исследовать серверную инфраструктуру, где размещены веб-приложения.
Cкоуп Positive Technologies включает пять доменов (ptsecurity.com, partners.ptsecurity.ru, group.ptsecurity.com, event.phdays.com, promo.ptsecurity.com).
Остановимся подробнее на том, что такое домен, субдомен и как их искать.
-
Домен (доменный адрес) — уникальный человекочитаемый адрес веб-сервера в сети, который связан с целевым или проксирующим IP-адресом сервера. Примеры доменов: XXX.com и XXX.ru.
-
Субдомен (поддомен) — отдельный домен, как правило третьего уровня и выше, являющийся частью домена более высокого уровня, как правило второго. Примеры субдоменов: api.XXX.com и login.XX.com.
Существует большое количество способов поиска субдоменов. Приведем некоторые из них:
-
анализ отдаваемого сервером кода веб-страницы или анализ исходного кода мобильного приложения для поиска конечных точек субдоменов в комментариях страницы, в адресах подключаемых скриптов и их содержимом, в забытых файлах;
-
Google Dork Queries — выполнение в поисковой системе Google специальных запросов, помогающих раскрыть дополнительную информацию;
-
веб-сервисы, специализирующиеся в том числе на поиске субдоменов: crt.sh , virustotal.com , searchdns.netcraft.com , dnsdumpster.com , www.shodan.io ;
-
инструменты, собирающие субдомены из разных источников: Sublist3r ( github.com/aboul3la/Sublist3r ), crtsh ( github.com/YashGoti/crtsh ), Amass ( github.com/OWASP/Amass );
-
перебор доменов методом брутфорса (brute force): subbrute ( github.com/TheRook/subbrute ), dnsrecon ( www.kali.org/tools/dnsrecon ), ffuf ( github.com/ffuf/ffuf ), nmap ( nmap.org ).
Другим примером на Standoff 365 Bug Bounty может служить программа компании ВКонтакте . В ее скоуп входят следующие домены: *.vk.com, vk.com, m.vk.com, api.vk.com, login.vk.com, oauth.vk.com, *.vk.me, *.vk.cc, *.vk.link, id.vk.com, *.vkontakte.(ru|com), *.vk-cdn.net, *.userapi.com, *.vkuser.net, *.vkuseraudio.(com|net), *.vkuservideo.(com|net), *.vkuserlive.(com|net).
Примечательный момент в скоупе этой программы — наличие звездочки в названиях доменов. Когда участвующая в программе багбаунти компания имеет большое количество субдоменов и все они входят в скоуп, перед названием домена ставится звездочка: *.vk.com.
Не стоит забывать о том, что в правилах программы багбаунти могут быть и дополнительные требования. К примеру, в исключения могут попасть тестовые домены, домены, делегированные партнерскими сервисами (за них текущая программа ответственности не несет), а также те, которые специально вывели из области действия.
Подводя итоги этого раздела, еще раз напомним, что, прежде чем приступать к поиску уязвимостей в разрешенном скоупе, необходимо внимательно ознакомиться со всеми правилами программы багбаунти. Приобретение и совершенствование навыков по поиску субдоменов, находящихся в скоупе программ, и дальнейшее выявление уязвимостей в них, могут принести багхантерам значимую награду в виде накопленного опыта, репутации на платформе и денежного вознаграждения.
Примеры часто встречающихся уязвимостей
В предыдущей статье мы рассмотрели атаки типа SQL injection, cross-site scripting (XSS) и cross-site request forgery (CSRF). В этом материале разберем следующие уязвимости:
-
insecure direct object references (IDOR) — уязвимость, позволяющая приложению использовать контролируемые пользователем данные для получения прямого доступа к объектам. Другими словами, эксплуатация этой уязвимости в системе может привести к утечке пользовательских данных или выполнению несанкционированного действия — добавлению, чтению, обновлению или удалению какой-либо информации в системе;
-
directory traversal — уязвимость, позволяющая злоумышленнику выйти за пределы разрешенного каталога и производить удаление, изменение или чтение произвольных файлов на сервере. В результате ее эксплуатации могут быть прочитаны системные файлы либо файлы приложения, которые раскроют злоумышленнику исходный код; файлы с переменными окружения, содержащими токены для подписи или данные для авторизации, например для базы данных или аккаунта администратора, а также любую другую критическую информацию, которая ни в коем случае не должна быть в открытом доступе.
Быстрый старт на настоящих примерах
Чтобы успешно заниматься поиском уязвимостей в рамках багбаунти, необходимо фундаментальное понимание того, каким образом возникают уязвимости, где они могут находиться и как их эксплуатировать для представления доказательств работы. В примерах этого раздела будут использоваться устаревшие и уязвимые плагины для одной из популярнейших систем управления содержимым — WordPress .
Insecure direct object references
Начнем с примера уязвимости класса insecure direct object references (IDOR). Для ее демонстрации выбран плагин для WordPress — Directorist версии 7.4.2.1 с общедоступным эксплойтом . Суть рассматриваемой уязвимости в том, что авторизованный пользователь даже с минимальными правами может изменить пароль любого другого пользователя, в том числе администратора.
В папке с плагином находится файл includes/classes/class-ajax-handler.php, в котором в функции update_user_profile в строке 850 вызывается функция directorist_update_profile; внутри нее вызывается еще одна функция — update_profile, которая обновляет информацию о пользователе с учетом полученных извне данных.
В функции update_profile обратите внимание на строку 486, где используется тернарный оператор для получения значения идентификатора пользователя. В случае если пользователь передает значение в ключе user[ID] при выполнении POST-запроса, берется это передаваемое значение. В ином случае — результат функции get_current_user_id(), что будет являться идентификатором текущего пользователя.
Другим любопытным моментом являются строки 500–501, в которых задается новый пароль для пользователя. В строке 518 вызывается функция wp_set_password, которая обновляет пароль пользователя в соответствии с данными, которые контролируются извне.
В этом случае пользователь с ролью «Подписчик» может выполнить POST-запрос к сценарию /wp-admin/admin-ajax.php?action=update_user_profile и передать в теле запроса данные, приведенные ниже, с указанием ID пользователя. Как правило, пользователь с ролью «Администратор» имеет идентификатор со значением «1».
Результатом будет несанкционированное изменение пароля пользователя с ролью «Администратор» при использовании плагина Directorist версии 7.4.2.1.
Directory traversal
Рассмотрим другой класс уязвимостей — directory traversal. Примером будет служить уязвимый плагин для WordPress — Simple Job Board версии 2.9.3 . Для этой версии плагина существует общедоступный эксплойт . Суть рассматриваемой уязвимости заключается в том, что из-за неправильной обработки пользовательского ввода при получении файла с резюме злоумышленник может выйти за пределы разрешенного каталога и прочитать системный файл.
В папке с плагином расположен файл includes/class-simple-job-board-resume-download-handler.php; в функции download_resume в строке 49 этого файла формируется путь к файлу через глобальную переменную $_GET[‘sjb_file’], значение которой контролирует пользователь.
Видно, что эта переменная обрабатывается функцией esc_attr , однако использование данной функции в этом случае некорректно, потому что она предназначена для экранирования HTML-атрибутов, а именно спецсимволов <, >, &, » и ‘.
Для выполнения атаки directory traversal достаточно специальных символов . (точка) и / (косая черта), чтобы выйти за пределы текущей директории и обратиться к системным файлам или файлам приложения.
Поэтому пользователь с ролью «Редактор» может отправить на сервер запрос, описанный в статье с общедоступным эксплойтом , и в ответ получить системный файл, к которому доступа быть не должно. В данном случае происходит попытка получения системного файла /etc/passwd:
Сервер возвращает запрашиваемый злоумышленником системный файл:
Бонус
Пришло время вспомнить один из классов уязвимостей, который мы рассматривали в первой части статьи «Как начать заниматься багхантингом веб-приложений» : некорректную санитизацию данных при генерировании веб-страниц (межсайтовое выполнение сценариев (XSS), или, простыми словами, выполнение вредоносного JavaScript-кода в браузере жертвы).
В этом разделе расскажем про XSS-атаку postMessage и наше исследование под названием Fuzzing for XSS via nested parsers condition.
PostMessage XSS
Существует понятие postMessage . Это механизм отправки кросс-доменных запросов между сайтами. К примеру, есть некоторый сайт, у которого есть слушатель сообщений postMessage. Задача этого слушателя — обработать поступающее извне сообщение. Обработка может быть совершенно разной: работа с файлами куки, выполнение редиректа на произвольную страницу, модификация HTML-страницы и т. п. И существует другой сайт, способный запустить в iframe или открыть в новой вкладке целевой сайт, у которого есть слушатель сообщений, и передавать туда данные с помощью механизма postMessage. В некоторых случаях киберпреступник может воспользоваться этими функциями, чтобы выполнить так называемую атаку postMessage XSS.
Приведем небольшой пример того, как злоумышленник может использовать в своих целях функцию слушателя сообщений postMessage.
На странице есть код JavaScript, который устанавливает слушателя сообщений с помощью функции receiveMessage. В начале этой функции проверяется источник сообщения: с какого домена оно пришло. Если источником сообщения является домен, начинающийся на https://application.localhost , приложение продолжает работать: происходит парсинг строки с помощью функции JSON.parse в переменную data, после чего проверяется, есть ли в объекте ключ url, и, если он есть, выполняется редирект на страницу, которая и указана в значении data.url. Рассмотрим, как атакующие могут злоупотребить этой функциональностью на целевом сайте.
Во-первых, в коде содержится проверка источника сообщения: событие с сообщением должно быть отправлено с домена, имя которого начинается на https://application.localhost . Однако злоумышленник может обойти это условие, если сообщение будет отправлено с сайта, который он контролирует, например с https://application.localhost.evil.localhost .
Во-вторых, после того как прошла проверка origin (источника сообщения), злоумышленник мог поместить в ключ url значение javascript:alert(). При присваивании этого значения в location.href будет выполнена JavaScript-функция alert в браузере жертвы.
Злоумышленник размещает на своем сайте, который находится по адресу https://application.localhost.evil.localhost , следующую полезную нагрузку и заманивает на него жертву с помощью фишинга:
После того как жертва перешла на сайт злоумышленника https://application.localhost.evil.localhost и разрешила всплывающее окно, откроется новая вкладка в домене https://application.localhost . В открывшуюся вкладку в домене https://application.localhost спустя 1 секунду с сайта злоумышленника будет отправлено сообщение postMessage в виде строки ‘{«url»:»javascript:alert()»}’, что приведет к атаке postMessage XSS, или, другими словами, выполнению произвольного JavaScript-кода в браузере жертвы. Задержка в одну секунду обусловлена тем, что открываемому сайту необходимо дать полностью прогрузиться.
Возможны ситуации, когда в найденном слушателе сообщений postMessage может отсутствовать проверка на источник отправления (origin) либо эта проверка может быть недостаточно корректна, как это описано в примере выше. Дополнительно рекомендуем почитать о других способах обхода защитных механизмов в статье PostMessage vulnerabilities .
Стоит помнить еще и о том, что слушатели сообщений могут находиться не только на главной странице сайта, но и в подключаемых скриптах, в том числе сторонних. Чтобы найти их для проверки защищенности, следует либо вручную искать во всех подключаемых на страницу скриптах установку слушателя сообщения, либо использовать автоматизированное средство, определяющее, где могут находиться слушатели сообщений.
К автоматизированным средствам, помогающим находить слушатели postMessage, можно отнести плагин postMessage-tracker для браузера Google Chrome.
Fuzzing for XSS via nested parsers condition
Некоторое время назад мы опубликовали исследование Fuzzing for XSS via nested parsers condition . Мы выяснили, что при использовании определенного языка разметки и библиотеки парсинга к нему, например BBCode , можно внедрить такую синтаксическую конструкцию, которая запутает парсер разметки и позволит внедрить код JavaScript в результат парсинга (причем даже с условием того, что одной из задач парсера как раз и является недопущение внедрения JavaScript-кода в результат его работы). Полученный результат может быть отображен на странице пользователя, что приведет к XSS-атаке на него.
Вот реальный пример из нашего исследования, базирующийся на популярном бесплатном веб-форумном движке MyBB. В версии 1.8.25 команда разработки MyBB исправила синтаксическую конструкцию следующего вида, приводящую к XSS-атаке:
После ее исправления мы выпустили еще одно исследование — MyBB <= 1.8.31: Remote Code Execution Chain . В нем была обнаружена и продемонстрирована еще одна синтаксическая конструкция, которая запутывает парсер и тоже приводит к XSS-атаке на пользователя. Она имеет следующий вид:[email][email= onpointerover=alert()//]text[/email]
Приведенную выше синтаксическую конструкцию злоумышленник внедряет в свою подпись (сигнатуру) на форуме в режиме исходного кода и сохраняет ее.
Если после сохранения просмотреть данную сигнатуру в обычном режиме, в котором уже будет использован парсер для обработки внедренной пользователем нагрузки, то произойдет запутывание парсера и будет выполнен выход за пределы значения атрибута в виде события onpointerover и его значения — JavaScript-функции alert().
Поэтому при багхантинге или анализе защищенности веб-приложений не стоит забывать о наших примерах в бонусном разделе.
Заключение
В конце нам хотелось бы обратить внимание багхантеров, особенно начинающих, на некоторые важные вещи:
-
при поиске уязвимостей необходимо очень внимательно прочитать правила программы на площадке багбаунти, тщательно изучить разрешенный скоуп и дополнительные условия;
-
при нахождении уязвимости или возможности проведения атаки в момент написания отчета прикладывать доказательство работы (PoC), обосновывая влияние на безопасность системы;
-
помнить, что, помимо уязвимостей, которые могут быть в самописных тестируемых системах, на других портах домена или субдомена также могут быть устаревшие версии систем, в которых тоже могут присутствовать известные уязвимости различного рода. О них также следует сразу сообщать компании;
-
необходимо искать новые техники эксплуатации уязвимостей и исследовательские подходы, постоянно углублять свои знания, фундаментально изучать, какие классы уязвимостей существуют, как их находить, и стараться понять, как их можно исправить.
Таким способом исследователи в сфере кибербезопасности помогают выявлять возможности проведения кибератак и своевременно предотвращать их, нивелировать возможные риски, повышать надежность сервисов, которыми пользуются миллионы людей, и делать мир вокруг безопаснее.
Алексей Соловьев
Старший специалист группы анализа защищенности веб-приложений компании Positive Technologies
Будьте на шаг впереди цифровой угрозы — подписывайтесь на наш канал и узнавайте, как выжить в цифровом мире!
Пошагово расскажу как за полчаса комплексно проверить безопасность сайта даже если вы не программист. Статья будет полезна разработчикам, тестировщикам, а также владельцам сайтов.
Всем привет! Сейчас большинство статей в интернете по теме поиска уязвимостей на своем сайте делятся на два типа: это либо банальный список онлайн-сканеров без подробных инструкций как ими пользоваться, либо хардкорные мануалы для фанатов информационной безопасности и прочих хакеров, где без Линукса не разобраться.
Поэтому я решил написать статью, которой мне не хватало, когда я только начинал разбираться в этой теме. Надеюсь эта статья сделает интернет чуть-чуть безопаснее, а вам поможет найти даже те уязвимости, которые вы изначально не закладывали😃.
Статья пригодится:
- Backend разработчикам: вы сможете быстро тестировать свои веб-приложения на наличие уязвимостей и тем самым повысить их надежность и безопасность данных ваших пользователей. (Если конечно исправите уязвимости, которые найдете )
- Frontend разработчикам: пока npm собирает ваш фронтенд, вы как раз успеете проверить API вашего веб-приложения. А если повезет и вы сможете найти уязвимости, то вы не только поможете своей компании в будущем сохранить свою репутацию (а себе выбить премию), но и сможете целую неделю незлобно троллить ваших backend разработчиков и DevOps инженеров в общем чате.
- Тестировщикам: освоите новые инструменты и сможете требовать законную прибавку к зарплате, а также немного считать себя хакерами.
- Владельцам веб-сайтов и стартаперам без раунда: вы сможете самостоятельно базово проверить свой сайт без привлечения дорогостоящих экспертов, а также сможете лучше понимать технические особенности работы вашей бизнес-машины.
А нужно ли проверять?
Немного фактов и мнений:
Факт доказанный практикой и личным опытом: даже если у вас небольшой интернет-магазин, в 2020 вы уже будете подвергаться кибератакам по несколько раз в день.
С момента попадания в индекс GoogleYandex ваш сайт становится мишенью десятка (а если сайт крупный, то сотни) специализированных ботов, которые круглосуточно мониторят даже небольшие сайты и серверы для поиска уязвимостей и дальнейшего взлома.
У вас может быть грамотная архитектура, красивый дизайн, быстрая скорость загрузки, но всего лишь небольшая ошибка или невнимательность разработчика может серьезно навредить вашему бизнесу. Поэтому необходимо регулярно проверять свой сайт или веб-приложение на наличие уязвимостей.
Хорошая новость — сейчас можно самостоятельно просканировать свое веб-приложение различными бесплатными сканерами безопасности и найти уязвимые места заранее.
Внимание, использование подобных сканеров уязвимостей на чужих сайтах без разрешения владельцев является нарушением закона почти во всех странах.
Теперь я наглядно и пошагово покажу как с помощью таких инструментов самостоятельно проверить свой сайт, а также как разобраться в сгенерированных отчетах .
Что будем проверять:
- Доступ к серверу и исходным кодам
- Уязвимости веб-серверов (Apache или NGINX)
- SQL инъекции
- Межсайтовый скриптинг (XSS).
- Устойчивость приложения и сервера к перебору паролей
- Получение доступа к системным каталогам
Если вы пока еще не знаете, что означают все эти страшные слова и сокращения на английском, то не переживайте, по ходу статьи я обязательно объясню их значения.
В качестве подопытного сайта я написал и развернул небольшой самописный блог с возможностью оставлять комментарии к статьям и добавил в него весь джентльменский набор:
- Многочисленные SQL инъекции
- XSS уязвимости
- Простой пароль для ssh доступа
- Открытый ftp
- Отсутствие защиты от перебора паролей
- База данных, доступная из интернета с простым паролем
- Слишком широкие права доступа к папкам и файлам
В общем все так, как делать не надо.
1. Проверяем сетевую инфраструктуру.
В кибератаках, также как и войне, все начинается с разведки, чтобы найти уязвимое место соперника. Для того, чтобы эффективно атаковать, злоумышленникам необходимо знать, какое ПО используется на сервере и какие двери открыты или закрыты недостаточно крепко. К несчастью владельцев сайтов, сейчас, чтобы все это узнать, нужно лишь здравое любопытство и утилита nmap.
Nmap — это набор инструментов для сканирования сетевой инфраструктуры веб-сервиса. Он может быть использован для проверки безопасности, для идентификации запущенных серверных приложений.
Nmap позволяет запускать готовые скрипты, которые значительно упрощают анализ вашего сервера. Минус — теперь даже смышленный школьник, вооружившись пачкой скриптов, может предоставлять опасность для серверов компании.
Интересный факт — сyществует целая галерея фильмов, где утилита nmap используется для кибератак. Часть представлено в галерее, под каждой картинкой описание. Более полный список и разбор можно посмотреть по ссылке
Посмотрели картинки, теперь можно и поработать! Приступаем к делу.
Устанавливаем nmap
В установке нет ничего сложного. Примеры установки покажу на примере Windows и Mac OS. В дистрибутивах Linux последняя версия nmap обычно установлена по умолчанию.
Установка на Windows 10
Перейдите по ссылке загрузки nmap и загрузите последнюю стабильную версию. На данный момент (16.09.2020) эта версия 7.80. Скачать ее можно по этой ссылке с официального сайта. Дальше запустите nmap-7.80-setup.exe от имени администратора. Программа установки по умолчанию предложит установить все компоненты, галочки можно не снимать. Описывать шаги далее подробно ( Примите лицензионное соглашение и тд) не буду, там все изи.
Запуск nmap на Windows
Запускать nmap можно как в режиме графического интерфейса, так и через командную строку.
Для запуска графической оболочки введите в строку поиска nmap и в результатах выберите nmap — Zenmap GUI
Для дальнейшей работы вы можете вводить нужные команды в поле «Команда», а затем нажимать на кнопку Сканирование. Результаты сканирования в виде текстового отчета вы можете посмотреть в окне, которое я старательно подписал «Отчет»
Мне ближе использование nmap через командную строку aka консоль. Для запуска командной строки введите «cmd» в строку поиска на панели инструментов. Нажмите Enter и затем откроется командная строка. Дальше прямо в нее можно вводить nmap команды.
Командная строка в Windows 10 c введенной командой nmap выглядит вот так:
Mac OS X
Нажмите Command+Space и введите «Терминал», после этого нажмите Enter. Дальше последнюю версию nmap можно установить через менеджер HomeBrew c помощью следующей команды, которую нужно ввести в терминале:
brew install nmap
Для запуска nmap просто начинайте команду с nmap, ничего сложного
nmap localhost
Устанавливаем скрипты
Также нам надо установить скрипт nmap_vulners, который будет проводить проверку на то, содержатся ли уязвимости в ПО, которое мы используем. Для его установки нужно скачать файлы скрипта и перенести файлы http-vulners-regex.nse и vulners.nse в C:Program Files (x86)Nmapscripts.
Если у вас Mac OS, то перенести файлы скрипта нужно в папку /usr/local/Cellar/nmap/<version>/share/nmap/scripts/
Начинаем проверку
Для начала запускаем сканирование своего сервера командой ниже, чтобы выяснить какие порты используются и для чего. Команда выглядит так (подставьте свой ip или домен). Команду нужно вводить в окне консоли, либо если вы используете Zenmap GUI, то в поле «Команда» (пример я привел выше):
nmap -sV -Pn -p- -T5 161.35.92.161
Параметр T5 отвечает за скорость анализа сервера. Скорость можно менять от T0 до T5, где T0 — очень медленная скорость анализа, а T5 — очень быстрая. Если вы не хотите сильно нагружать сервер, то используйте T2.
Параметр -p- означает, что мы будем проверять весь диапазон портов (‘это займет около 10 минут) . Его можно убрать и тогда скрипт просканирует не все порты, а только 1000 первых (самые распространенные).
Ответ будет выглядеть примерно так:
nmap -sV -Pn 161.35.92.161
Starting Nmap 7.80 ( https://nmap.org ) at 2020-09-16 20:03 RTZ 2 (ceia)
Nmap scan report for 161.35.92.161
Host is up (0.085s latency).
Not shown: 965 filtered ports, 31 closed ports
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
3306/tcp open mysql MySQL 5.5.5-10.2.24-MariaDB
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 32.39 seconds
Из отчета мы видим, что nmap отобразил нам порты (под колонкой PORT), которые активны. В данном случае у нас используются:
- Порт 21 занят под FTP
- Порт 22 занят под SSH.
- Порт 80 прослушивается сервером Apache.
- Порт 3306 используется MySQL
Теперь запускаем наш скрипт, который проверит уязвимости в нашем ПО на сервере. Для этого запускаем следующую команду с указанием портов, которые мы будем проверять. Вам нужно будет заменить список портов на свои .
nmap -T5 -sV -Pn 161.35.92.161 —script=vulners.nse -p22,80,443,8080,8443,3306,20,21,23
Пример отчета. Ссылки на описание уязвимости идут после строки vulners (пример такой строки со ссылкой в отчете: CVE-2014-9278 4.0 https://vulners.com/cve/CVE-2014-9278)
Starting Nmap 7.80 ( https://nmap.org ) at 2020-09-16 20:50 RTZ 2 (ceia)
Nmap scan report for 161.35.92.161
Host is up (0.094s latency).
PORT STATE SERVICE VERSION
20/tcp closed ftp-data
21/tcp open ftp vsftpd 3.0.3
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| vulners:
| cpe:/a:openbsd:openssh:8.2p1:
|_ CVE-2014-9278 4.0 https://vulners.com/cve/CVE-2014-9278
23/tcp filtered telnet
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
| vulners:
| cpe:/a:apache:http_server:2.4.41:
| CVE-2020-11984 7.5 https://vulners.com/cve/CVE-2020-11984
| CVE-2020-11984 7.5 https://vulners.com/cve/CVE-2020-11984
| CVE-2020-1927 5.8 https://vulners.com/cve/CVE-2020-1927
| CVE-2020-1927 5.8 https://vulners.com/cve/CVE-2020-1927
| CVE-2020-9490 5.0 https://vulners.com/cve/CVE-2020-9490
| CVE-2020-1934 5.0 https://vulners.com/cve/CVE-2020-1934
| CVE-2020-1934 5.0 https://vulners.com/cve/CVE-2020-1934
|_ CVE-2020-11993 4.3 https://vulners.com/cve/CVE-2020-11993
443/tcp closed https
3306/tcp open mysql MySQL 5.5.5-10.2.24-MariaDB
8080/tcp filtered http-proxy
8443/tcp filtered https-alt
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 24.23 seconds
Как видите из отчета, скрипт проанализировал активное ПО нашего сервера и любезно предоставил ссылки с описанием каждой найденной уязвимости. Что согласитесь, очень удобно как для нас, так и для злоумышленников.
Также можно записать результат анализа в файл, который потом можно скинуть ответственному разработчику или системному администратору. Сам файл результатов будет находиться в каталоге, из которого вы запускаете скрипт. Пример такой команды ниже:
nmap -T5 -sV -Pn 161.35.92.161 —script=vulners.nse -p22,80,443,8080,8443,3306,20,21,23 > result.txt
Чтобы избавиться от подобных проблем обычно достаточно обновить используемое ПО до последних версий, где уязвимости старых версий, как правило, уже исправлены.
2. Проверяем устойчивость к перебору.
В нашем случае nmap определил, что на сервере есть ssh, ftp и mysql. Попробуем проверить насколько устойчивые пароли используются.
SSH
Вводим следующую команду (напомню, что вводить нужно либо в консоль, либо в поле «Команда» программы Zenmap GUI.
nmap —script ssh-brute -p22 161.35.92.161 —script-args userdb=users.lst,passdb=passwords.lst
В случае успеха (процесс не быстрый) скрипт выведет подобранный пароль и логин . Подобранные пары логинпароль будут выведены после строчки Accounts:
22/ssh open ssh
ssh-brute:
Accounts
username:password
Statistics
Performed 32 guesses in 25 seconds.
Кроме того, можно расширить стандартные списки паролей и пользователей от nmap, заменив файлы users.lst и passwords.lst . Различные базы для брутфорса можно найти в этом gitbub репозитории. Файлы с базой паролей можно разместить в папке nmap/nselib/data
FTP
Теперь проверяем FTP порт следующей командой:
nmap -d —script ftp-brute -p 21 161.35.92.161
Аналогично, сервис выведет подобранные пары логинов и паролей:
PORT STATE SERVICE
21/tcp open ftp
| ftp-brute:
| Accounts
| root:root — Valid credentials
|_ Statistics: Performed 864 guesses in 544 seconds, average tps: 4.8
MySQL
Проверяем доступен ли анонимный вход.
nmap -sV —script=mysql-empty-password <target>
В случае успеха:
3306/tcp open mysql
| mysql-empty-password:
| anonymous account has empty password
|_ root account has empty password
Пытаемся подобрать пару логинпароль для входа в базу данных mysql.
nmap —script mysql-brute -p 3306 <target>
—script-args userdb=users.lst, passdb=passwords.lst
Также если у вас используются CMS (WordPress, Joomla, Drupal, Bitrix) и другие базы данных (Mongo, Postgres, Redis), то можно найти готовые скрипты для проверки устойчивости ваших паролей и форм. Ищите по ключевым словам <name_of_CMS_or_DB> brute force nmap
Проверяем формы авторизации
Найти формы авторизации можно с помощью такой команды (вместо <target> — подставьте домен вашего сайта):
nmap -p80 —script http-auth-finder <target>
После того, как нашли страницы с авторизацией, можно попробовать подобрать пароль и логин для входа в админку сайта.
Параметры
- http-brute.hostname — имя хоста
- http-form-brute.path — адрес страницы с формой или адрес с API
- http-brute.method — тип метода, по умолчанию POST
- http-form-brute.uservar — устанавливает имя переменной, которая отвечает за username. Если не установлено, то скрипт возьмет имя поля из формы
- http-form-brute.passvar — устанавливает имя переменной, которая отвечает за пароль. Если не установлено, то скрипт возьмет имя поля из формы
Параметры нужно перечислять через запятую после -script-args.
nmap -p-80 —script=http-form-brute —script-args=http-form-brute.path=/login <target>
Если скрипт успешно сработает, то выведет примерно вот такой результат.
Подобранные данные для входа будут отображены после строчки Accounts. В нашем случае скрипт подобрал логин user с паролем secret. В реальном приложении подбор может также занять продолжительное время, зависит от того насколько стойкий пароль используется.
PORT STATE SERVICE REASON
80/tcp open http syn-ack
| http-form-brute:
| Accounts
| user:secret — Valid credentials
| Statistics
|_ Perfomed 60023 guesses in 467 seconds, average tps: 138
Если ваша формы авторизации использует cookies параметры или csrf-token, то в этом случае выдаст ошибку. (И это хорошо, значит базовую защиту вы предусмотрели).
В качестве защиты стоит использовать стойкие пароли, а также ограничивать количество запросов с одного IP-адреса (Rate limiting).
3. Ищем скрытые папки и файлы
Часто разработчики или системные администраторы довольно халатно относятся к правам доступа и забывают закрыть доступ к системным и другим важным папкам. Проверить есть у нас на сервере такие папки можно также с помощью утилиты nmap. Команды будет выглядеть так (вместо <target> нужно подставить IP-адрес сервера или домен сайта) :
nmap -sV -p 80 -T5 —script http-enum <target>
В результате в отчете нам покажут доступные для просмотра папки, интересные файлы — файлы паролей, резервные копии базы данных и тд. (Если такие существуют). Дальше уже вам нужно самостоятельно решить какие папки и файлы нужно закрыть от просмотра, а какие оставить как есть.
Пример небольшого отчета.
Host is up (0.024s latency).
Not shown: 993 closed ports
PORT STATE SERVICE
80/tcp open http
| http-enum:
| /robots.txt: Robots file
| /css/: Potentially interesting directory w/ listing on ‘apache/2.4.41 (ubuntu)’
| /images/: Potentially interesting directory w/ listing on ‘apache/2.4.41 (ubuntu)’
|_ /js/: Potentially interesting directory w/ listing on ‘apache/2.4.41 (ubuntu)’
4. Проверяем на SQL инъекции
Так повелось, что большинство современных веб-приложений в той или иной мере используют SQL базы данных. Обычно параметры веб-страницы или какие-либо пользовательские данные подставляются в SQL запросы и результаты запроса отображаются на веб-странице. Если передаваемые параметры плохо фильтруются, то веб-сервис становится уязвимым для SQL инъекций.
Если сайт уязвим и выполняет такие инъекции, то по сути есть возможность творить с БД (чаще всего это MySQL) что угодно. Именно таким образом чаще всего воруют базы пользователей и их личные данные.
Далее я покажу как с помощью скриптов быстро и эффективно проверить есть в вашем продукте подобные уязвимости. Часто даже довольно опытные разработчики забывают о мерах предосторожности, поэтому даже серьезные продукты имеют подобные проблемы. Попробуем проверить наш тестовый веб-сервис на наличие таких проблем c помощью инструмента sqlmap.
Установка sqlmap.
Sqlmap — это кроссплатформенный сканер с открытым исходным кодом, который позволяет в автоматическом режиме тестировать веб-сервисы на наличие SQL инъекций, а затем использовать их для получения контроля над базой данных.
В данной статье я рассмотрю только способы как можно находить уязвимые для SQL инъекций страницы, API и формы без подробностей о том, как использовать найденные уязвимости для нанесения вреда. (Владельцы сайтов тут облегченно вздохнули). Для использования необходим python версии 2.7 и старше.
Установка на Windows
Для начала работы нам необходимо установить Python. Установщик Python для Windows можно найти на официальном сайте. Ссылку я прикрепил ниже.
На сайте две ветки — 2.x и 3.x, но скачать и установить лучше ветку 3.x. Sqlmap корректно работают с каждой из этих версий, но в дальнейшем нам потребуется версия 3.x.
Загрузить последнюю версию sqlmap можно здесь. Распакуйте архив в любую удобную папку (чтобы было проще ее найти можно распаковать в папку С:Users<имя вашего пользователя>)
Для запуска вначале нужно открыть командную строку. Нажмите Win+R, в появившемся окне введите cmd и нажмите enter. Пример запуска:
С:UsersAdminsqlmap>python ./sqlmap.py -u http://161.35.92.161/page.php?id=2
Установка на Mac OS X
Для начала установим Python. Для этого откройте Tерминал и запустите следующую команду.
brew install python3
Теперь установим sqlmap.
brew install sqlmap
Запуск sqlmap для Mac OS X.
sqlmap -u http://161.35.92.161/page.php?id=2 —dbs -o -random-agent
Начинаем проверку
В моем тестируемом сервисе я специально подготовил sql уязвимости. Попробуем найти их следующей командой. Параметр —dbs означает, что нам интересны имена баз данных. В случае успеха и наличия уязвимости, после определения баз данных можно перейти к поиску таблиц и получения нужных данных. Команду необходимо вводить в консоль.
python sqlmap.py -u http://161.35.92.161/page.php?id=2 —dbs -o -random-agent
Через некоторое время скрипт может попросить нас уточнить некоторые данные. В данном случае выбираю «нет», чтобы скрипт прогнал все тесты.
[01:14:57] [INFO] fetched random HTTP User-Agent header value ‘Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0; YComp 5.0.2.6; MSIECrawler)’ from file ‘C:UsersAcersqlmapdatatxtuser-agents.txt’
[01:15:04] [INFO] testing connection to the target URL
[01:15:04] [INFO] checking if the target is protected by some kind of WAF/IPS
[01:15:05] [INFO] testing NULL connection to the target URL
[01:15:05] [INFO] NULL connection is supported with GET method (‘Range’)
[01:15:05] [INFO] testing if the target URL content is stable
[01:15:05] [INFO] target URL content is stable
[01:15:05] [INFO] testing if GET parameter ‘id’ is dynamic
[01:15:05] [INFO] GET parameter ‘id’ appears to be dynamic
[01:15:06] [INFO] heuristic (basic) test shows that GET parameter ‘id’ might be injectable
[01:15:06] [INFO] testing for SQL injection on GET parameter ‘id’
[01:15:06] [INFO] testing ‘AND boolean-based blind — WHERE or HAVING clause’
[01:15:06] [INFO] GET parameter ‘id’ appears to be ‘AND boolean-based blind — WHERE or HAVING clause’ injectable
[01:15:07] [INFO] heuristic (extended) test shows that the back-end DBMS could be ‘CrateDB’
it looks like the back-end DBMS is ‘CrateDB’. Do you want to skip test payloads specific for other DBMSes? [Y/n] n
Скрипт выводит отчет:
[01:15:29] [INFO] testing ‘MySQL >= 5.0 AND error-based — WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)’
[01:15:29] [INFO] testing ‘PostgreSQL AND error-based — WHERE or HAVING clause’
[01:15:29] [INFO] testing ‘Microsoft SQL Server/Sybase AND error-based — WHERE or HAVING clause (IN)’
[01:15:30] [INFO] testing ‘Oracle AND error-based — WHERE or HAVING clause (XMLType)’
[01:15:30] [INFO] testing ‘MySQL >= 5.0 error-based — Parameter replace (FLOOR)’
[01:15:30] [INFO] testing ‘Generic inline queries’
[01:15:30] [INFO] testing ‘PostgreSQL > 8.1 stacked queries (comment)’
[01:15:30] [WARNING] time-based comparison requires larger statistical model, please wait…………………. (done)
[01:15:32] [INFO] testing ‘Microsoft SQL Server/Sybase stacked queries (comment)’
[01:15:32] [INFO] testing ‘Oracle stacked queries (DBMS_PIPE.RECEIVE_MESSAGE — comment)’
[01:15:32] [INFO] testing ‘MySQL >= 5.0.12 AND time-based blind (query SLEEP)’
[01:15:43] [INFO] GET parameter ‘id’ appears to be ‘MySQL >= 5.0.12 AND time-based blind (query SLEEP)’ injectable
[01:15:43] [INFO] testing ‘Generic UNION query (NULL) — 1 to 20 columns’
[01:15:43] [INFO] automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found
[01:15:45] [INFO] target URL appears to be UNION injectable with 4 columns
[01:15:46] [INFO] GET parameter ‘id’ is ‘Generic UNION query (NULL) — 1 to 20 columns’ injectable
GET parameter ‘id’ is vulnerable. Do you want to keep testing the others (if any)? [y/N] y
После продолжения анализа нас в первую очередь интересует строчка в конце: GET parameter ‘id’ is vulnerable. Do you want to keep testing the others (if any)? [y/N].
Как можно видеть, скрипт определил, что параметр id уязвим и предлагает протестировать другие параметры. В нашем конкретном случае других параметров нет, но в реальных веб-приложениях таких параметров может быть десятки, так что иногда имеет смысл проверить все.
Итоговый отчет:
sqlmap identified the following injection point(s) with a total of 74 HTTP(s) requests:
—
Parameter: id (GET)
Type: boolean-based blind
Title: AND boolean-based blind — WHERE or HAVING clause
Payload: id=2 AND 9795=9795
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: id=2 AND (SELECT 7989 FROM (SELECT(SLEEP(5)))geJr)
Type: UNION query
Title: Generic UNION query (NULL) — 4 columns
Payload: id=2 UNION ALL SELECT NULL,CONCAT(0x716a6a6b71,0x736654714b69505a4f6f64434776566d7a43455179446561434f7a46434241555449574d6759575a,0x7162627171),NULL,NULL— —
—
[INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Apache 2.4.41
back-end DBMS: MySQL >= 5.0.12
[INFO] fetching database names
available databases [2]:
[*] information_schema
[*] vc_test
[INFO] fetched data logged to text files under ‘C:UsersAdminAppDataLocalsqlmapoutput161.35.92.161’
В итоге скрипт не только определил, что параметр id является уязвимым, но и версию СУБД, а также получил название используемой базы данных на сервере — vc_test, в которой содержится контент сайта. Эту информацию можно найти в конце сгенерированного отчета.
В дальнейшем для злоумышленника уже обычно не проблема получить данные в таблицах, а возможно и полный контроль над всей БД, а то и всем нашим сервером и исходным кодом сайта, если для запросов используется пользователь с широкими правами.
Кроме того, sqlmap позволяет задавать http заголовки и параметры Cookies, что довольно удобно для тестирования, особенно когда для получения результата запроса требуется авторизации.
Пример тестирования запроса POST. Параметры, которые передаются в теле запроса записываются в опцию скрипта —data. Необходимые параметры для POST запроса можно подсмотреть в консоли браузера (Ctrl + Shift + I в Windows, затем перейти в вкладку Network, совершить нужное действие, а затем изучить каким образом формируется запрос)
sqlmap.py -u http://localhost/login —data=»username=alex&password=pass» —dbs -o -random-agent
После авторизации обычно необходимо передать нужные Сookie. В sqlmap за это отвечает опция —cookie. Нужные значения cookies можно получить в инструментах разработчика вашего браузера. (в Windows ctrl+shift+i, затем найдите вкладку Network, а в ней щелкните на запрос с именем домена сайта. В окне справа пролистайте пока не увидите параметр cookie)
Пример команды sqlmap c опцией —cookie.
sqlmap.py -u http://localhost/create —data=»name=alex&message=hacked» —cookie=»security_level=low; PHPSESSID=05aa4349068a1kkaje4kcqnr9o6″ —dbs -o -random-agent
Если параметров несколько, то можно явно указать какой параметр будем тестировать с помощью опции -p.
sqlmap.py -u «http://localhost/profile/?username=alex&page=2» -p username
Можно задавать http заголовки через опцию —headers. Это крайне полезно для тестирования ваших API.
Также если get параметр передается не как get параметр, а как URI, то в этом случае нужно явно указать с помощью *, что данная часть URI является параметром. Пример:
sqlmap.py -u «http://localhost/api/v2/news/2*» —headers=»Authorization: Bearer <token>» —dbs -o -random-agent
Таким образом можно довольно тщательно протестировать ваше веб-приложение на наличие SQL инъекций. Также крайне полезно использовать sqlmap для автоматических тестов и запускать их после каждого изменения кода вашего приложения и не допускать код в ветку master, если он содержит уязвимость.
Для защиты от SQL инъекций нужно тщательно фильтровать параметры и HTTP заголовки, а также использовать подготовленные запросы.
5. Проверка на XSS уязвимости.
Межсайтовый скриптинг (XSS) – это уязвимость, которая заключается во внедрении злоумышленником своего Javascript кода в веб-страницу, которая отображается в браузере пользователя.
После такого внедрения злоумышленник фактически захватывает веб-страницу и может манипулировать данными пользователя, когда он находится на странице. В случае успеха злоумышленник может:
- Внедрять свои скрипты в веб-страницу
- Отправлять на свой сервер пользовательские данные — банковские карты, идентификаторы сессий, пароли и тд.
- Совершать действия от имени пользователя — рассылать спам, совершать денежные переводы
Уязвимость возникает из-за недостаточной фильтрации данных, которые выводятся при отображении страницы.
Такие уязвимости довольно часто встречаются даже в крупных продуктах, поэтому стоит обязательно тестировать свои веб-приложения на наличие XSS уязвимостей.
В данном случае для тестирования мы воспользуемся утилитой XSStrike
ХSStrike — это довольно продвинутый сканер для поиска XSS уязвимостей c открытым исходным кодом. Он написано на Python3 и довольно прост в начальной настройке и использования.
Установка
Для установки необходимо скачать архив по ссылке и распаковать в удобную вам папку. После этого необходимо открыть консоль (ранее я уже показывал как это сделать в Mac и Windows) и перейти в распакованную папку. Затем нужно выполнить команды в консоле:
pip3 install pygame
Установим необходимые для корректной работы библиотеки:
pip3 install -r requirements.txt
Теперь мы готовы к тестированию. Пример простого запуска, вместо моего url укажите адрес страницы, которую хотите протестировать:
python xsstrike.py -u «http://161.35.92.161/index.php?page=2» —blind
Очень быстро скрипт обнаруживает, что параметр page является уязвимым ( строчка Reflections found ) и через него можно передать js код, который будет исполнен на странице. Пример такого кода приводится в строчке Payload. Такой тип XSS уязвимостей называется reflected XSS.
[~] Checking for DOM vulnerabilities
[+] WAF Status: Offline
[!] Testing parameter: page
[!] Reflections found: 1
[~] Analysing reflections
[~] Generating payloads
[!] Payloads generated: 3072
————————————————————
[+] Payload: <HTmL%0aONmOuSEoVeR+=+(prompt)«%0dx//
[!] Efficiency: 100
[!] Confidence: 10
[?] Would you like to continue scanning? [y/N] n
Кроме того, можно проверять и формы. Отправим на проверку форму, которая отправляет сообщение в наш сервис. Чтобы передать список POST параметров используем опцию —data.
python xsstrike.py -u «http://161.35.92.161/index.php» —data «name=&message=» —blind
Результат: параметр name уязвим.
[~] Checking for DOM vulnerabilities
[+] WAF Status: Offline
[!] Testing parameter: name
[!] Reflections found: 3
[~] Analysing reflections
[~] Generating payloads
[!] Payloads generated: 4608
————————————————————
[+] Payload: <A%0aOnmOUSeOVEr%0d=%0d(prompt)«%0dx>v3dm0s
[!] Efficiency: 100
[!] Confidence: 10
[?] Would you like to continue scanning? [y/N]
Как выглядит ответ, когда скрипт не находит уязвимых параметров:
[~] Checking for DOM vulnerabilities
[+] WAF Status: Offline
[!] Testing parameter: name
[-] No reflection found
[!] Testing parameter: message
[-] No reflection found
Кроме того, в XSStrike поддерживает возможность передавать http заголовки, в том числе и cookies и проверять страницы для открытия которых нужна авторизация. Для этого используется опция —headers
python xsstrike.py -u «http://161.35.92.161/index.php» —data «name=&message=» —headers «Authorization: Bearer <token> Cookie: zmname=none» —blind
Также можно запустить обход по всему сайту. Нужно указать стартовую страницу и сканер начнет обход всех найденных страниц. Запись -l 100 отвечает за количество страниц обхода.
python xsstrike.py -u «http://161.35.92.161» —blind —crawl -l 100
Скрипт покажет страницы, на которых были найдены уязвимые параметры. Найденные страницы можно уже исследовать подробнее.
[~] Crawling the target
[++] Vulnerable webpage: http://161.35.92.161/index.php
[++] Vector for message: <htMl%09oNMOuseoVER%0d=%0dconfirm()//
[++] Vulnerable webpage: http://161.35.92.161/index.php
[++] Vector for page: <hTMl%0donPointereNter%0a=%0a[8].find(confirm)>
[++] Vulnerable webpage: http://161.35.92.161/index.php
[++] Vector for name: <D3v/+/oNMoUSeoveR%0a=%0a(confirm)()%0dx>v3dm0s
!] Progress: 3/3
Также полезная функция — обход url страниц, которые указаны в файле с помощью опции —seeds. Можно также использовать вместе с опцией —headers.
python xsstrike.py -u «http://example.com» -l 3 —seeds urls.txt
Таким образом можно достаточно тщательно проверить свое веб-приложение на XSS уязвимости. Также хорошим ходом будет написать простой bash скрипт для объединения всех проверок XSS в один скрипт, специально заточенный под ваш проект.
Его задачей будет тестировать ваше веб-приложение после каждого изменения исходного кода и не пускать коммит в ветку master, если страницы и формы содержат XSS уязвимости .
Для борьбы с XSS уязвимости нужно также тщательно фильтровать данные, которые показываются пользователю.
Заключение
Надеюсь руководство будет полезным и поможет вам сделать свои сайты и веб-приложения безопаснее. Также стоит проверять не только сам сайт, но и ваши админки и вспомогательные сервисы на поддоменах, ведь они также могут быть уязвимы перед подобными автоматизируемыми системами и скриптами.
Конечно приведенные меры не обеспечивают 100% защиты, и я не рассказал о многих других типовых уязвимостях, но показанные меры помогут защитить проект от автоматизированных систем взлома и злоумышленников с невысокими навыками.
Если есть вопросы, то смело пишите их в комментариях или мне в телеграм t.me/alex.belousov92
Также будет интересно почитать, что вы используете для тестирования безопасности ваших веб-приложений. Если статья наберет достаточное количество плюсов, то напишу продолжение. Поэтому не забудьте проголосовать, если статья понравилась!
Поиск уязвимостей в программах с помощью анализаторов кода
- Введение
- Классификация уязвимостей защиты
- Обзор существующих анализаторов
- 1. BOON
- 2. CQual
- 3. MOPS
- 4. ITS4, RATS, PScan, Flawfinder
- 5. Bunch
- 6. UNO
- 7. FlexeLint (PC-Lint)
- 8. Viva64
- 9. Parasoft C++test
- 10. Coverity
- 11. Klocwork K7
- 12. Frama-C
- 13. CodeSurfer
- 14. FxCop
- 15. JavaChecker
- 16. Simian
- Вывод
- Библиографический список
В настоящее время разработано большое количество инструментальных средств, предназначенных для автоматизации поиска уязвимостей программ. В данной статье будут рассмотрены некоторые из них.
Введение
Статический анализ кода – это анализ программного обеспечения, который производится над исходным кодом программ и реализуется без реального исполнения исследуемой программы.
Программное обеспечение часто содержит разнообразные уязвимости из-за ошибок в коде программ. Ошибки, допущенные при разработке программ, в некоторых ситуациях приводят к сбою программы, а следовательно, нарушается нормальная работа программы: при этом часто возникает изменение и порча данных, останов программы или даже системы. Большинство уязвимостей связано с неправильной обработкой данных, получаемых извне, или недостаточно строгой их проверкой.
Для выявления уязвимостей используют различные инструментальные средства, например, статические анализаторы исходного кода программы, обзор которых приведён в данной статье.
Классификация уязвимостей защиты
Когда требование корректной работы программы на всех возможных входных данных нарушается, становится возможным появление так называемых уязвимостей защиты (security vulnerability). Уязвимости защиты могут приводить к тому, что одна программа может использоваться для преодоления ограничений защиты всей системы в целом.
Классификация уязвимостей защиты в зависимости от программных ошибок:
- Переполнение буфера (buffer overflow). Эта уязвимость возникает из-за отсутствия контроля за выходом за пределы массива в памяти во время выполнения программы. Когда слишком большой пакет данных переполняет буфер ограниченного размера, содержимое посторонних ячеек памяти перезаписывается, и происходит сбой и аварийный выход из программы. По месту расположения буфера в памяти процесса различают переполнения буфера в стеке (stack buffer overflow), куче (heap buffer overflow) и области статических данных (bss buffer overflow).
- Уязвимости «испорченного ввода» (tainted input vulnerability). Уязвимости «испорченного ввода» могут возникать в случаях, когда вводимые пользователем данные без достаточного контроля передаются интерпретатору некоторого внешнего языка (обычно это язык Unix shell или SQL). В этом случае пользователь может таким образом задать входные данные, что запущенный интерпретатор выполнит совсем не ту команду, которая предполагалась авторами уязвимой программы.
- Ошибки форматных строк (format string vulnerability). Данный тип уязвимостей защиты является подклассом уязвимости «испорченного ввода». Он возникает из-за недостаточного контроля параметров при использовании функций форматного ввода-вывода printf, fprintf, scanf, и т. д. стандартной библиотеки языка Си. Эти функции принимают в качестве одного из параметров символьную строку, задающую формат ввода или вывода последующих аргументов функции. Если пользователь сам может задать вид форматирования, то эта уязвимость может возникнуть в результате неудачного применения функций форматирования строк.
- Уязвимости как следствие ошибок синхронизации (race conditions). Проблемы, связанные с многозадачностью, приводят к ситуациям, называемым «состояние гонки»: программа, не рассчитанная на выполнение в многозадачной среде, может считать, что, например, используемые ею при работе файлы не может изменить другая программа. Как следствие, злоумышленник, вовремя подменяющий содержимое этих рабочих файлов, может навязать программе выполнение определенных действий.
Конечно, кроме перечисленных существуют и другие классы уязвимостей защиты.
Обзор существующих анализаторов
Для обнаружения уязвимостей защиты в программах применяют следующие инструментальные средства:
- Динамические отладчики. Инструменты, которые позволяют производить отладку программы в процессе её исполнения.
- Статические анализаторы (статические отладчики). Инструменты, которые используют информацию, накопленную в ходе статического анализа программы.
Статические анализаторы указывают на те места в программе, в которых возможно находится ошибка. Эти подозрительные фрагменты кода могут, как содержать ошибку, так и оказаться совершенно безопасными.
В данной статье предложен обзор нескольких существующих статических анализаторов. Рассмотрим подробнее каждый из них.
1. BOON
Инструмент BOON, который на основе глубокого семантического анализа автоматизирует процесс сканирования исходных текстов на Си в поисках уязвимых мест, способных приводить к переполнению буфера. Он выявляет возможные дефекты, предполагая, что некоторые значения являются частью неявного типа с конкретным размером буфера.
2. CQual
CQual — Инструмент анализа для обнаружения ошибок в Си-программах. Программа расширяет язык Си дополнительными определяемыми пользователем спецификаторами типа. Программист комментирует свою программу с соответствующими спецификаторами, и cqual проверяет ошибки. Неправильные аннотации указывают на потенциальные ошибки. Сqual может использоваться, чтобы обнаружить потенциальную уязвимость форматной строки.
3. MOPS
MOPS (MOdel checking Programs for Security) — инструмент для поиска уязвимостей в защите в программах на Си. Его назначение: динамическая корректировка, обеспечивающая соответствие программы на Си статической модели. MOPS использует модель аудита программного обеспечения, которая призвана помочь выяснить, соответствует ли программа набору правил, определенному для создания безопасных программ.
4. ITS4, RATS, PScan, Flawfinder
Для поиска ошибок переполнения буфера и ошибок форматных строк используют следующие статические анализаторы:
- ITS4. Простой инструмент, который статически просматривает исходный Си/Си++-код для обнаружения потенциальных уязвимостей защиты. Он отмечает вызовы потенциально опасных функций, таких, например, как strcpy/memcpy, и выполняет поверхностный семантический анализ, пытаясь оценить, насколько опасен такой код, а также дает советы по его улучшению.
- RATS. Утилита RATS (Rough Auditing Tool for Security) обрабатывает код, написанный на Си/Си++, а также может обработать еще и скрипты на Perl, PHP и Python. RATS просматривает исходный текст, находя потенциально опасные обращения к функциям. Цель этого инструмента — не окончательно найти ошибки, а обеспечить обоснованные выводы, опираясь на которые специалист сможет вручную выполнять проверку кода. RATS использует сочетание проверок надежности защиты от семантических проверок в ITS4 до глубокого семантического анализа в поисках дефектов, способных привести к переполнению буфера, полученных из MOPS.
- PScan. Сканирует исходные тексты на Си в поисках потенциально некорректного использования функций, аналогичных printf, и выявляет уязвимые места в строках формата.
- Flawfinder. Как и RATS, это статический сканер исходных текстов программ, написанных на Си/Си++. Выполняет поиск функций, которые чаще всего используются некорректно, присваивает им коэффициенты риска (опираясь на такую информацию, как передаваемые параметры) и составляет список потенциально уязвимых мест, упорядочивая их по степени риска.
Все эти инструменты схожи и используют только лексический и простейший синтаксический анализ. Поэтому результаты, выданные этими программами, могут содержать до 100% ложных сообщений.
5. Bunch
Bunch — средство анализа и визуализации программ на Си, которое строит граф зависимостей, помогающий аудитору разобраться в модульной структуре программы.
6. UNO
UNO — простой анализатор исходного кода. Он был разработан для нахождения таких ошибок, как неинициализированные переменные, нулевые указатели и выход за пределы массива. UNO позволяет выполнять несложный анализ потока управления и потоков данных, осуществлять как внутри- так и межпроцедурный анализ, специфицировать свойства пользователя. Но данный инструмент не доработан для анализа реальных приложений, не поддерживает многие стандартные библиотеки и на данном этапе разработки не позволяет анализировать сколь-нибудь серьёзные программы.
7. FlexeLint (PC-Lint)
FlexeLint (PC-Lint) — этот анализатор предназначен для анализа исходного кода с целью выявления ошибок различного типа. Программа производит семантический анализ исходного кода, анализ потоков данных и управления.
В конце работы выдаются сообщения нескольких основных типов:
- Возможен нулевой указатель;
- Проблемы с выделением памяти (например, нет free() после malloc());
- Проблемный поток управления (например, недостижимый код);
- Возможно переполнение буфера, арифметическое переполнение;
- Предупреждения о плохом и потенциально опасном стиле кода.
8. Viva64
Инструмент Viva64, который помогает специалисту отслеживать в исходном коде Си/Си++-программ потенциально опасные фрагменты, связанные с переходом от 32-битных систем к 64-битным. Viva64 встраивается в среду Microsoft Visual Studio 2005/2008, что способствует удобной работе с этим инструментом. Анализатор помогает писать корректный и оптимизированный код для 64-битных систем.
9. Parasoft C++test
Parasoft C++test — специализированный инструмент для Windows, позволяющий автоматизировать анализ качества кода Си++. Пакет C++test анализирует проект и генерирует код, предназначенный для проверки содержащихся в проекте компонентов. Пакет C++test делает очень важную работу по анализу классов C++. После того как проект загружен, необходимо настроить методы тестирования. Программное обеспечение изучает каждый аргумент метода и возвращает типы соответствующих значений. Для данных простых типов подставляются значения аргументов по умолчанию; можно определить тестовые данные для определенных пользователем типов и классов. Можно переопределить аргументы C++test, используемые по умолчанию, и выдать значения, полученные в результате тестирования. Особого внимания заслуживает способность C++test тестировать незавершенный код. Программное обеспечение генерирует код-заглушку для любого метода и функции, которые еще не существуют. Поддерживается имитация внешних устройств и входных данных, задаваемых пользователем. И та и другая функции допускают возможность повторного тестирования. После определения тестовых параметров для всех методов пакет C++test готов к запуску исполняемого кода. Пакет генерирует тестовый код, вызывая для его подготовки компилятор Visual C++. Возможно формирование тестов на уровне метода, класса, файла и проекта.
10. Coverity
Инструменты Coverity используются для выявления и исправления дефектов безопасности и качества в приложениях критического назначения. Технология компании Coverity устраняет барьеры в написании и внедрении сложного ПО посредством автоматизации поиска и устранения критических программных ошибок и недостатков безопасности во время процесса разработки. Инструмент компании Coverity способен с минимальной положительной погрешностью обрабатывать десятки миллионов строк кода, обеспечивая 100-процентное покрытие трассы.
11. Klocwork K7
Продукты компании Klocwork предназначены для автоматизированного статического анализа кода, выявления и предотвращения дефектов программного обеспечения и проблем безопасности. Инструменты этой компании служат для выявления коренных причин недостатков качества и безопасности программного обеспечения, для отслеживания и предотвращения этих недостатков на протяжении всего процесса разработки.
12. Frama-C
Frama-C — открытый, интегрированный набор инструментов для анализа исходного кода на языке Си. Набор включает ACSL (ANSI/ISO C Specification Language) — специальный язык, позволяющий подробно описывать спецификации функций Си, например, указать диапазон допустимых входных значений функции и диапазон нормальных выходных значений.
Этот инструментарий помогает производить такие действия:
- Осуществлять формальную проверку кода;
- Искать потенциальные ошибки исполнения;
- Произвести аудит или рецензирование кода;
- Проводить реверс-инжиниринг кода для улучшения понимания структуры;
- Генерировать формальную документацию.
13. CodeSurfer
CodeSurfer — инструмент анализа программ, который не предназначается непосредственно для поиска ошибок уязвимости защиты. Его основными достоинствами являются:
- Анализ указателей;
- Различные анализы потока данных (использование и определение переменных, зависимость данных, построение графа вызовов);
- Скриптовый язык.
CodeSurfer может быть использован для поиска ошибок в исходном коде, для улучшения понимания исходного кода, и для реинженерии программ. В рамках среды CodeSurfer велась разработка прототипа инструментального средства для обнаружения уязвимостей защиты, однако разработанное инструментальное средство используется только внутри организации разработчиков.
14. FxCop
FXCop предоставляет средства автоматической проверки .NET-сборок на предмет соответствия правилам Microsoft .NET Framework Design Guidelines. Откомпилированный код проверяется с помощью механизмов рефлексии, парсинга MSIL и анализа графа вызовов. В результате FxCop способен обнаружить более 200 недочетов (или ошибок) в следующих областях:
- Архитектура библиотеки;
- Локализация;
- Правила именования;
- Производительность;
- Безопасность.
FxCop предусматривает возможность создания собственных правил с помощью специального SDK. FxCop может работать как в графическом интерфейсе, так и в командной строке.
15. JavaChecker
JavaChecker — это статический анализатор Java програм, основанный на технологии TermWare.
Это средство позволяет выявлять дефекты кода, такие как:
- небрежная обработка исключений (пустые catch-блоки, генерирование исключений общего вида и.т.п.);
- сокрытие имен (например, когда имя члена класса совпадает с именем формального параметра метода);
- нарушения стиля (вы можете задавать стиль программирования с помощью набора регулярных выражений);
- нарушения стандартных контрактов использования (например, когда переопределен метод equals, но не hashCode);
- нарушения синхронизации (например, когда доступ к синхронизированной переменной находится вне synchronized блока).
Набором проверок можно управлять, используя управляющие комментарии.
Вызов JavaChecker можно осуществлять из ANT скрипта.
16. Simian
Simian — анализатор подобия, который ищет повторяющийся синтаксис в нескольких файлах одновременно. Программа понимает синтаксис различных языков программирования, включая C#, T-SQL, JavaScript и Visual Basic®, а также может искать повторяющиеся фрагменты в текстовых файлах. Множество возможностей настройки позволяет точно настраивать правила поиска дублирующегося кода. Например, параметр порога (threshold) определяет, какое количество повторяющихся строк кода считать дубликатом.
Simian — это небольшой инструмент, разработанный для эффективного поиска повторений кода. У него отсутствует графический интерфейс, но его можно запустить из командной строки или обратиться к нему программно. Результаты выводятся в текстовом виде и могут быть представлены в одном из встроенных форматов (например, XML). Хотя скудный интерфейс и ограниченные возможности вывода результатов Simian требуют некоторого обучения, он помогает сохранить целостность и эффективность продукта. Simian подходит для поиска повторяющегося кода как в больших, так и в маленьких проектах.
Повторяющийся код снижает поддерживаемость и обновляемость проекта. Можно использовать Simian для быстрого поиска дублирующихся фрагментов кода во многих файлах одновременно. Поскольку Simian может быть запущен из командной строки, его можно включить в процесс сборки, чтобы получить предупреждения или остановить процесс в случае повторений кода.
Вывод
Итак, в данной статье были рассмотрены статические анализаторы исходного кода, которые являются вспомогательными инструментами программиста. Все инструментальные средства разные и помогают отслеживать самые различные классы уязвимостей защиты в программах. Можно сделать вывод, что статические анализаторы должны быть точными, восприимчивыми. Но, к сожалению, статические средства отладки не могут дать абсолютно надёжный результат.
Библиографический список
- Alexey Kolosov. Using Static Analysis in Program Development.
- Брайан Гетц. Избавьтесь от ошибок.
- Криспин Кован. Безопасность систем с открытым кодом.
- С.С. Гайсарян, А.В. Чернов, А.А. Белеванцев, О.Р. Маликов, Д.М. Мельник, А.В. Меньшикова. О некоторых задачах анализа и трансформации программ.
Присылаем лучшие статьи раз в месяц
Сегодня я наткнулся на вот этот пост Intigriti в Twitter:
«Мы только что написали потрясающий фрагмент кода, но… Наша команда разработки утверждает, что он небезопасен. Помогите нам найти уязвимости в коде!».
Введение
Это фрагмент кода PHP, который в хакерской среде считается очень популярным языком, имеющим довольно много проблем! Одна из таких важных проблем — манипуляции с типами. Кто-то называет это частью функционала PHP, другие видят в этих манипуляциях множество багов (но видение этой проблемы зависит от того, в каком ракурсе ее рассматривать).
Все дело в том, что в PHP при сравнении двух значений с помощью оператора ==
и выполнении «свободных» сравнений результаты бывают довольно неожиданными из-за того, что в языке отсутствует строгая типизация. То есть здесь нет понятия строки и целых чисел: типы в PHP определяются динамически на основе содержащегося в переменной значения. А выполняемые над ними операции чреваты преобразованиями типов.
В этой таблице проиллюстрировано то, что я имел в виду под свободными сравнениями, приводящими к неожиданным результатам:
Итак, в PHP:
1 == true
То есть 1
дает true
.
И то же самое –1
:
–1 == true
И тут самое время задуматься: «А как убедиться в том, что сравнения точны?».
Для этого в PHP есть оператор ===
, с помощью которого сравнения проводятся так, как ожидалось.
В следующей таблице только записи, находящиеся на одной-единственной диагонали, дают true
. Другие, не находящиеся на этой диагонали, дают false
, свидетельствуя о том, что сравниваемые значения отличаются. И поэтому строгое их сравнение дает false
.
Но достаточно теории. Посмотрим теперь, насколько уязвим был код, выложенный в Twitter!
Проблемы
Взглянем на код и обсудим потенциальные проблемы:
Итак, какие уязвимости есть у этого кода?
Манипуляции с типами? Верно!
Что-нибудь еще?
Использование хеша md5
? Нет… Это проблема, но она не подразумевает никакой уязвимости.
Итак, манипуляции с типами и уязвимость. Имеется ли возможность ею воспользоваться и распечатать ветку недостижимого кода без взлома хеша md5
?
Похоже, что да!
Решение
Чтобы пройти проверки и добраться до желаемого оператора печати, нужно передать admin
, так как имя пользователя и пароль — все еще недостающая часть.
Так как же обойти эту проверку? Есть какие-нибудь идеи? Манипуляции с типами? Ну конечно же!
Задействуем манипуляции с типами, так как в коде выполняется свободное сравнение с использованием оператора ==
.
Заметили, что там дальше с правой стороны от оператора? Дальше 0e
?
0e
обозначает экспоненциальное представление, которое имеет следующий вид:
0 * (10 , возведенное в степень числа после 0e
) = 0 (ведь любое число, умноженное на ноль, равно нулю).
Поэтому, поработав с хешем md5
и приведя его к значению, также имеющему тип 0e
с последующим числом, будем считать его числовым значением (экспоненциальным представлением), равным 0.
Я нашел статью, в которой говорилось о нескольких возможных значениях для пароля, приводящего к нужному нам хешу (0e
с последующими числами):
Видите, какие значения надо взять? '240610708'
и 'QNKCDZO'
!
Я просто разместил фрагмент кода на сервере, использовав следующую команду:
php -S 127.0.0.1:8081
Затем попробовал оба возможных значения пароля (очевидно, понадобится больше значений из-за коллизий в MD5):
Логи сервера должны выглядеть так:
Заключение
PHP — это совершенно фантастический язык программирования для специалиста по анализу защищенности информационных систем. Так много возможностей столкнуться с трудностями нет ни в одном другом языке.
И самыми распространенными проблемами здесь являются манипулирование типами и путаница с порядком аргументов функций.
Читайте также:
- Как подключить базу данных MySQL к сайту на PHP
- Ключевое слово static в PHP
- Java убьет ваш стартап. PHP спасёт его
Читайте нас в Telegram, VK и Яндекс.Дзен
Перевод статьи SecurityGOAT: Intigriti’s PHP challenge breakdown