Содержание статьи
Для приблизительной оценки степени защищенности того или иного веб-ресурса мы часто прибегаем к помощи различных сканеров уязвимостей — монстро-продуктов, требующих обязательной установки на компьютер. В этой статье мы рассмотрим процесс создания инструмента, который полностью изменит твое представление о проведении аудита веб-приложений.
Наиболее полную картину о защищенности той или иной инфраструктуры позволяют получить только комплексные методы анализа. Если говорить о веб-среде в общем и ее технологиях в частности, то подавляющее большинство распространенных уязвимостей являются следствием некорректной работы того или иного алгоритма фильтрации входящих данных. Не спеши бросать в автора камни, описывая причины появления и принципы обнаружения (эксплуатации) уязвимостей типа XSS/SQL-inj/PHP-including. Несомненно, техническая сторона атак подобного типа заметно выделяется и направлена на разные объекты, но нас не интересует эксплуатация багов. Мы, как примерные аудиторы/пентестеры/администраторы, заинтересованы в их обнаружении, а методы обнаружения, в свою очередь, можно свести к принципу выявления «внештатных» ситуаций в работе фильтров веб-приложения. А это возможно только путем передачи фильтру различных входных данных. Кстати, именно так и действуют сканеры уязвимостей (да простят меня их разработчики), анализируя полученные результаты мощными эвристическими алгоритмами.
Но имеется ряд ситуаций, когда использование этих инструментов для нас нежелательно. Большинство серьезных коммерческих продуктов при сканировании целевого ресурса оставляют в логах веб-сервера записи, однозначно идентифицирующие факт сканирования, а иногда и узел, с которого оно проводилось. Вряд ли кому-то нужна излишняя «популярность» в кругах администрации целевого сайта. К тому же процесс сканирования весьма ресурсоемок и требует временных затрат, в некоторых случаях эквивалентных денежным. А теперь пришло время приступить к созданию инструмента, который, в силу своих особенностей, не имеет вышеописанных недостатков и будет доступен для нас в виде веб-сервиса.
Глазами разработчика
С позиции разработчика процесс сканирования — однотипная процедура, которая представляет собой формирование запросов к целевому ресурсу и обработку полученных результатов. Договоримся сразу, что исследуемый сайт для нас — это некоторое подобие «черного ящика», то есть нам неизвестны детали функционирования его скриптов. В общем, все как в настоящем тесте на проникновение, где все параметры, передаваемые исследуемому скрипту, приходится подбирать случайным образом, опираясь исключительно на свой опыт и интуицию.
Почему именно веб-сервис? Да хотя бы потому, что в рунете нет аналогичных приложений «(по крайней мере, на момент сдачи статьи — начало апреля — прим. ред.)». А это значит, что данная ниша будет интересна как разработчикам, так и пользователям, поскольку теперь им не придется устанавливать требовательные к ресурсам и дорогие продукты, чтобы просканировать свою домашнюю страничку с целью получить хотя бы приблизительное представление о ее защищенности. Другие причины можешь придумать сам, а я пока перейду к теоретической части, а затем непосредственно к кодингу.
И в первый день создал он…
Как я уже отмечал, наша разработка будет представлять собой веб-сервис. Попробуем дать более точное определение. Web-service — приложение, которое:
- Исполняется на веб-сервере;
- Ожидает поступления HTTP-запросов и предоставляет веб-методы для их обработки;
- Непосредственно исполняет веб-методы и возвращает результаты.
У истоков данной технологии стоит Microsoft, которая реализовала ее в рамках Microsoft .NET. Кстати, именно веб-сервисы являются основной причиной существования .NET Framework: их задача — максимально упростить разработку веб-серверов и веб-клиентов. За примерами далеко ходить не надо — в предыдущем номере журнала мы рассмотрели, как с помощью технологии .NET Remoting можно быстро создать сеть распределенных вычислений. И все же веб-сервисы — не собственность MS. Они являются промышленным стандартом на основе открытых протоколов HTTP и SOAP (Simple Object Access Protocol). Именно поэтому их можно писать в любом текстовом редакторе, однако .NET Framework — несомненно, лучший вариант, который значительно упрощает процесс кодинга. Кстати, кодить мы будем на языке C#, но ничто не мешает тебе писать приложение на любом другом языке, поддерживаемым ASP.NET — технологией создания веб-приложений от Майкрософт в рамках платформы .NET. С инструментами разобрались, теперь перейдем к проектированию логики приложения.
Хочу сразу сказать, что процесс создания онлайн-сканера будет рассмотрен на примере уязвимостей класса «CrossSite Scripting» (также известного как XSS), так как на их поиске основаны методы обнаружения и других багов (с точки зрения сканера как автоматизированного инструмента). Тебе, как программисту, нужно будет научить приложение передавать специальные данные и обрабатывать полученные результаты указанным тобой способом. Моя же задача — продемонстрировать тебе концептуальные особенности программирования веб-сервисов, ну и задать направление дальнейшего развития приложения и поделиться своими идеями. Но обо всем по порядку.
Рассмотрим логику работы сканера:
- Переход по ссылке на целевой сайт;
- Сбор всех скриптов на целевом сайте;
- Определение всех параметров, принадлежащих конкретному скрипту;
- Передача собранным параметрам специальных значений, характерных для данного вида уязвимостей;
- Анализ полученного результата (произошло ли внедрение наших переданных значений в код страницы).
Как видишь, приблизительный алгоритм функционирования приложения довольно прост, однако не стоит спешить с выводами: у каждого из вышеперечисленных пунктов есть свои подводные камни, часть из которых нам придется преодолевать вместе, а часть я оставлю тебе в качестве домашнего задания.
Напиши программу мышкой
Создается впечатление, что если Майкрософт продолжит развивать свои технологии, входящие в комплект .NET Framework и среду программирования Visual Studio, то процесс создания программного обеспечения будет доступен для широких масс, умеющих собирать конструкторы и владеющих только мышкой.
При создании проекта «ASP.NET Web Service Application» студия автоматически формирует структуру каталогов, характерную для приложения данного типа, а также создает все необходимые файлы для его корректного функционирования. Обычно структура проекта содержит в себе файлы одного или нескольких типов:
- ASPX-файлы, содержащие web-формы;
- ASMX-файлы, которые, собственно, и реализуют webсервисы;
- файлы Web.config, в которых описываются параметры конфигурации;
- файл Global.asax, который содержит глобальные элементы приложения;
- различные DLL, включающие в себя специфичные для приложения типы.
Файл ICholeScaner.asmx, находящийся в проекте (ищи его на нашем диске), демонстрирует несколько важных принципов программирования веб-сервисов с помощью .NET Framework. Вот что в нем содержится:
Содержимое ASMX-файла
<%
@ WebService Language="C#"
CodeBehind="~/App_Code/ICholeScaner.cs"
Class="ICholeScaner"
%>
Директива @WebService содержит обязательный атрибут Class, задающий класс, из которого состоит веб-сервис, и атрибут CodeBehind, который содержит описание веб-методов класса. Веб-методы объявляются в файле ICholeScaner.cs путем назначения открытым методам класса “ICholeScaner” атрибута [WebMethod]. Таким образом .NET Framework автоматически делает этот метод доступным для внешних вызовов.
[WebMethod]
public string StartScan(string domen)
{
// инструкции метода
…
}
В этом отражается вся суть веб-сервиса — предоставить функционал своих методов (то есть, предоставить «сервис») для обработки данных, поступающих от клиента, который может являться как обычным пользователем, передающим информацию через какие-либо поля ввода, так и программой (сайтом), предоставляющим свои данные в автоматическом режиме средствами HTTP и SOAP. SOAP — это XML-язык для вызова удаленных процедур по HTTP и другим протоколам.
Наш веб-сервис предоставляет метод StartScan, который принимает единственный строковой параметр — доменное имя целевого сайта, — и инициализирует процедуру сканирования. Если URL сервиса, например, www.site.com/icholescaner.asmx
, то клиент может вызвать метод StartScan, переслав SOAP-конверт в HTTP-запросе. Задача вебсервиса в этом случае:
- Разобрать SOAP-конверт, содержащий входные данные;
- Выполнить сканирование;
- Сгенерировать SOAP-конверт, содержащий результат;
- Возвратить его клиенту в теле HTTP-отклика.
Также параметры сканирования можно задавать с помощью обычных HTTP-команд GET и POST, например:
GET /icholescaner.asmx/StartScan?domen=www.enemysite.
com HTTP/1.1
Host: www.site.com
После того, как мы рассмотрели особенности создания и функционирования веб-сервисов и их принципиальное отличие от обычных вебприложений (которые функционируют в закрытом режиме, не предоставляя никому свои методы), ты уже можешь начинать писать свой сервис, аналогов которому нет в онлайн-приложениях, но полнымполно на пользовательских компьютерах. Однако я настоятельно рекомендую не останавливаться на полученных знаниях, а перейти к следующему этапу, на котором мы сможем реализовать процесс обнаружения XSS-уязвимостей.
Да у вас жуки, батенька!
Уязвимости класса «межсайтовый скриптинг», как известно, являются следствием неправильной работы фильтра, принимающего входные данные от пользователя. Таким образом, хакер может вставить в исходный код страницы свой набор символов (в подавляющем большинстве случаев это JavaScript-код), который впоследствии может скомпрометировать легитимного пользователя, открывшего страницу.
Различают два подтипа XSS-уязвимостей: активные и пассивные. В двух словах: первые встраиваются непосредственно в код страницы, и пользователю достаточно ее открыть, а вторые требуют активности со стороны компрометируемого (например, переход по специально сформированной ссылке). За подробностями атак этого типа я отправлю тебя… нет, не к гуглу, а к сноскам в этой статье, где собран список полезных ресурсов, призванных обогатить тебя информацией по данному вопросу. Для программиста различия в уязвимостях сервиса не играют никакой роли, ведь так или иначе они являются следствием некорректной фильтрации, поэтому не будем дальше заострять внимание на описании багов, а перейдем непосредственно к их обнаружению средствами онлайн-сканера. Для начала нам нужно составить список всевозможных скриптов, имеющихся на исследуемом ресурсе.
Как это сделать, — однозначного ответа дать не смогу, так как подходы к этой задаче у каждого свои, и скорость ее выполнения может заметно отличаться. С другой стороны, зачем нам лишние заботы? Пусть пользователь сам укажет тот скрипт, который хочет проверить.
После того, как у нас появился URL-адрес скрипта, нам необходимо получить генерируемый им исходный код страницы и записать его в какую-нибудь переменную для последующего анализа. Делается это просто:
Получение HTML-кода страницы
//формирование запроса к скрипту
WebRequest request =
WebRequest.Create(Url+"?"+Parametrs);
//получение ответа
WebResponse response = request.GetResponse();
//запись полученного ответа в строковую переменную
StreamReader reader = new
StreamReader(response.GetResponseStream());
Content = reader.ReadToEnd();
reader.Close();
Имея на руках исходный код страницы, нужно определить количество параметров, принимаемых скриптом, чтобы проверить корректность их фильтрации. Сделать это можно двумя способами: определить на странице все формы для ввода каких-либо данных или же пропарсить полученный HTML-код на наличие строк вида "/script. php?a=abcd&b=1234"
, где script.php — имя исследуемого скрипта. Во втором случае у нас в распоряжении будет находиться вся мощь регулярных выражений.
После того, как параметры скрипта собраны и аккуратно помещены в массив, наступает самый интересный момент — подстановка «ядовитых» запросов и анализ полученных ответов. Под «ядовитыми» запросами понимается такое значение, передаваемое параметру, которое вызовет выполнение запланированного нами действия, например, внедрение в исходный код страницы нашего тега JavaScript-кода и т.п. Коллекция таких «ядовитых» строк собрана в массиве XSSrequest. Вот несколько элементов этого массива:
string[] XSSrequest =
{ "<script>alert()</script>",
"<IMG SRC=\"javascript:alert();\">",
"<IMG SRC=javascript:alert("XSS")>",
…
}
Поочередно подставляя их в каждый из собранных параметров, необходимо анализировать ответ на наличие внедренного JavaScript-кода. Другими словами, нужно каждый раз парсить исходный HTML-код, полученный после отправки запроса, на наличие искомой последовательности символов.
Про SQL-inj, PHP-inc и прочую нечисть
Распространенные уязвимости прочих классов хоть и имеют другую природу и способы эксплуатации, но все же находятся одинаковым, с точки зрения автоматизированного поиска, способом. Рассмотрим, например, SQL-инъекции — уязвимости, позволяющие хакеру изменить логику запроса скрипта к базе данных. Ошибки этого типа также, в подавляющем большинстве случаев, являются следствием некорректной обработки поступающих от пользователя данных, а это значит, что нам не придется менять алгоритмы поиска в нашем сканере. Достаточно создать массив «ядовитых» запросов, характерных для уязвимостей подобного типа, и проанализировать реакцию скрипта (полученный HTML-код + регулярные выражения).
Вот небольшой список характерных ответов SQL-сервера, говорящих о возможности проведения атаки:
string[] SQLErrors = { "mysql_fetch",
"mysql_query", "\\[obdc", "mysql error",
"you have an error in your sqlsyntax",
"odbc drivers error", "\\[microsoft sql"
...
};
Существуют еще и «слепые» SQL-инъекции, которые в силу своей природы не вносят изменения в исходный код страницы и, как следствие, не подлежат обнаружению простым парсингом страницы. С другой стороны, тебе открывается широкий спектр атак, дающий повод для постоянного совершенствования своего продукта.
Пасмурно, но без осадков
Перспектива развития облачных технологий и веб-сервисов становится заметна не только крупным компаниям и конечным пользователям. С развитием технологий создания веб-приложений разработчики приобретают возможность воплотить самые яркие идеи, которые уже давно реализованы в качестве стандартных (оффлайновых) приложений и востребованы у пользователей персональных компьютеров. Кому-то важна финансовая сторона дела, кто-то гонится за оригинальностью, а кто-то просто находится «на волне» и за пару часов создает продукт, приносящий пользу как юзеру, так и своему создателю. Если тема онлайн-сервисов вообще и онлайнсканера уязвимостей в частности стала тебе интересна, и ты решил попробовать себя в этом направлении, то прошу не держать в себе накопившиеся вопросы, а смело задавать их мне — разберемся вместе. Облачных тебе приложений на работе и безоблачной погоды во время отпуска!
Links
- forum.antichat.ru/thread20140.html — полезный материал по XSS-уязвимостям. Способы их обнаружения и эксплуатации.
- www.w3.org/TR/soap/ - описание спецификации протокола SOAP. Полезно знать, если собираешься создавать приложения, эксплуатирующие методы твоего веб-сервиса.
- defec.ru - мой ресурс, где ты можешь задать вопросы, поделиться идеями, а также поучаствовать в разработке различных приложений и проектов.