#23 Gray Hat C#. Руководство для хакера по созданию и автоматизации инструментов безопасности. Фаззинг XML-порта SOAP. Запуск фаззера.
Здравствуйте, дорогие друзья.
Чтобы фаззить XML-порт SOAP, нам нужно динамически создавать XML для отправки на сервер, что немного сложнее, чем создание параметров HTTP для отправки в запросе GET или POST. Однако начнем с того, что метод FuzzSoapPort() аналогичен методам FuzzHttpGetPort() и FuzzHttpPostPort(), как показано в листинге ниже.
Как и в случае с методами фаззинга GET и POST, нам необходимо собрать некоторую информацию о том, что мы собираемся фаззить, прежде чем мы сможем что-либо сделать. Сначала мы получаем соответствующий SoapPortType из свойства _wsdl.PortTypes с помощью LINQ; затем мы повторяем каждую операцию с помощью цикла foreach. Во время итерации мы выводим текущую операцию, которую мы подвергаем фаззингу, на консоль [1]. Чтобы отправить правильный XML на сервер, нам нужно выбрать классы SoapOperation и SoapMessage, соответствующие классу SoapBinding, переданному методу. Используя SoapOperation и SoapMessage, мы можем динамически создавать необходимый XML. Для этого мы используем LINQ to XML, который представляет собой набор встроенных классов в пространстве имен System.Xml.Linq, позволяющий создавать простой динамический XML, как показано в листинге ниже.
Сначала мы создаем два экземпляра XNameSpace, которые будут использоваться при построении XML. Первый XNameSpace — это пространство имен SOAP по умолчанию, но второй XNameSpace будет меняться в зависимости от свойства SoapAction текущей операции [1]. После определения пространств имен мы создаем два новых элемента XML, используя класс XElement. Первый XElement (который будет называться ) — это стандартный элемент XML, используемый в SOAP, который инкапсулирует данные для текущей операции SOAP. Второй XElement будет назван в честь текущей операции [2]. Экземпляры XElement используют пространство имен SOAP по умолчанию и пространство имен операций SOAP соответственно. Затем мы добавляем второй XElement к первому с помощью метода XElement Add(), чтобы XML-элемент SOAP содержал элемент операции SOAP.
После создания внешних элементов XML мы создаем список Guid для хранения сгенерированных нами значений, а также выбираем текущий SoapType с помощью LINQ [3], чтобы мы могли перебирать параметры, необходимые для вызова SOAP. Во время итерации мы сначала создаем новый XElement для текущего параметраx [4]. Если тип параметра является строкой, мы присваиваем XElement Guid для значения с помощью SetValue() [5], и сохраняем Guid в списке Guid, который мы создали для справки позже. Затем мы добавляем XElement в элемент операции SOAP и переходим к следующему параметру.
После того как мы завершили добавление параметров в XML-узел операции SOAP, нам нужно собрать воедино весь XML-документ, как показано в листинге ниже.
Нам нужно создать XDocument с еще одним XElement, называемым SOAP Envelope [1]. Мы создаем новый XDocument, передавая новый XElement конструктору XDocument. XElement, в свою очередь, создается с помощью пары атрибутов, определяющих пространства имен XML узла, а также тела SOAP, которое мы создали с помощью параметров [2].
Теперь, когда XML создан, мы можем отправить его на веб-сервер и попытаться вызвать ошибки SQL, как показано в листинге ниже. Продолжайте добавлять этот код в метод FuzzSoapPort().
Как и в случае с фаззерами, рассмотренными ранее в этом разделе, мы перебираем каждый Guid в списке значений, который мы создали при построении XML, для операции SOAP. Во время итерации мы заменяем текущий Guid в теле XML SOAP значением, которое должно вызвать ошибку SQL, если это значение используется в SQL-запросе небезопасно [1]. После того как мы заменим Guid на испорченное значение, мы преобразуем полученную строку в массив байтов с помощью метода GetBytes(), который запишем в HTTP-поток как данные POST.
Затем мы создаем HttpWebRequest, который будем использовать для выполнения HTTP-запроса и чтения результата. Следует отметить одну особую часть — заголовок SOAPAction [2]. Этот HTTP-заголовок SOAPAction будет использоваться конечной точкой SOAP для определения того, какое действие выполняется с данными, например: перечисление или удаление пользователей. Мы также установили метод HTTP POST, тип контента — text/xml, а длину контента — длину созданного нами массива байтов. Наконец, мы записываем данные в поток HTTP [3]. Теперь нам нужно прочитать ответ сервера и определить, вызвали ли отправленные нами данные какие-либо ошибки SQL, как показано в листинге ниже.
В листинге выше, для проверки ошибок SQL, используется почти тот же код, что и в фаззерах в листингах выше, но в этом случае мы обрабатываем обнаруженную ошибку по-другому. Сначала мы объявляем строку для хранения HTTP-ответа и запускаем блок try/catch. Затем в контексте оператора using мы используем StreamReader, чтобы попытаться прочитать содержимое ответа HTTP и сохранить ответ в строке [1]. Если исключение выдается из-за того, что HTTP-сервер вернул ошибку 50x, мы перехватываем исключение и пытаемся прочитать ответ еще раз. Если выдается исключение и данные ответа содержат синтаксическую ошибку фразы [2], мы печатаем сообщение, предупреждающее пользователя о возможной SQL-инъекции и потенциально уязвимом имени параметра. Наконец, мы увеличиваем k и переходим к следующему параметру.
Запуск фаззера
Теперь мы можем запустить фаззер на уязвимом сервисном устройстве SOAP CsharpVulnSoap. Фаззер принимает единственный аргумент: URL-адрес уязвимой конечной точки SOAP. В данном случае мы будем использовать http://192.168.1.15/Vulnerable.asmx. Передача URL-адреса в качестве первого аргумента и запуск фаззера должны дать результат, аналогичный приведенному в листинге ниже.
Из вывода мы можем увидеть различные этапы фаззинга. Начиная с порта VulnerableServiceSoap [1], мы обнаруживаем, что операция AddUser может быть уязвима для внедрения SQL в поля имени пользователя и пароля, передаваемые в операцию. Далее идет порт VulnerableServiceHttpGet [2]. Мы делаем фаззинг той же операции AddUser и печатаем созданный нами URL-адрес, который можно вставить в веб-браузер, чтобы увидеть ответ на успешный вызов. Опять же, параметры имени пользователя и пароля оказались потенциально уязвимыми для SQL-инъекций. Наконец, мы фаззинг SOAP-порта VulnerableServiceHttpPost [3], сначала фаззинга операции AddUser, которая сообщает то же самое, что и предыдущие порты. Операция ListUsers сообщает об отсутствии потенциальных SQL-инъекций, что имеет смысл, поскольку изначально у нее нет параметров. Операции GetUser и DeleteUser потенциально уязвимы для внедрения SQL в параметр имени пользователя.
Резюме
В этой главе Вы познакомились с классами XML, доступными в основных библиотеках. Мы использовали классы XML для реализации полного фаззера SQL-инъекций службы SOAP и рассмотрели несколько методов взаимодействия со службой SOAP.
Первым и самым простым методом были запросы HTTP GET, где мы создавали URL-адреса с параметрами динамической строки запроса на основе того, как документ WSDL описывает службу SOAP. Как только это было реализовано, мы создали метод фаззинга запросов POST к службе SOAP. Наконец, мы написали метод фаззинга XML SOAP с использованием библиотек LINQ to XML на C# для динамического создания XML, используемого для фаззинга сервера.
Мощные классы XML в C# упрощают использование XML и работу с ним. Поскольку так много корпоративных технологий полагаются на XML для межплатформенной связи, сериализации или хранения, понимание того, как эффективно читать и создавать XML-документы на лету, может быть невероятно полезным, особенно для инженера по безопасности или пентестера.
На этом все. Всем хорошего дня!