Vander
Команда форуму
- 10 Лис 2019
- 477
- 1,160
Приветствую уважаемую аудиторию форума Protey.
В этой статье мы рассмотрим такой тип уязвимостей в web-приложениях, как - XPath Injection.
Каждый день мы слышим сообщения о взломе веб-сайтов и обычно думаем, что хакер, который добился успеха, должен быть невероятно умным. Обычно на самом деле все наоборот. Большинство хакеров, которые портят веб-сайты, - это хакеры-новички, которые совершают эти поступки ради популярности. Веб-дизайнеры сосредотачиваются на разработке своих веб-сайтов, а хакеры - на эксплойтах.
Примечание: эта статья предназначена только для образовательных целей. Будьте частью конструктивного общества.
Веб-приложения хранят данные и получают доступ к ним различными способами и формами в зависимости от их вариантов использования. Исторически реляционные базы данных были популярным выбором среди других баз данных для хранения большого количества данных. Однако растет тенденция к использованию XML для хранения данных. При использовании XML данные хранятся во вложенной структуре в виде древа, а не столбцов и строк. У этого есть много недостатков, но его можно использовать для статических данных, таких как параметры конфигурации. Это связано с тем, что такие статические данные требуют меньше операций чтения/записи, что очень медленно происходит в базах данных XML.
При аудите веб-приложения можно легко упустить из виду определенные типы уязвимостей, если не проводить систематическую проверку каждого из них в отдельности. Инъекционные эксплойты хорошо известны, и действительно, они заняли первое место в рейтинге OWASP Top 10; однако в этой статье мы обсудим атаку, которая гораздо менее популярна, чем внедрение SQL, XPath и XQuery.
Что такое XPATH и XQuery?
XPATH - это язык, который запрашивает XML-документ, чтобы найти часть информации, элементы, соответствующие определенному шаблону или содержащие нужный атрибут. Если у клиента есть доступ к части используемого запроса XPath, и этот ввод не фильтруется, тогда клиент получит доступ ко всему XML-документу, если он сможет определить его структуру.
Данные, хранящиеся в XML, можно запрашивать через XPath, который концептуально аналогичен SQL. Это также язык запросов, который используется для поиска определенных элементов в XML-документе. Разрешения на уровне доступа отсутствуют, и можно ссылаться практически на любую часть XML-документа, в отличие от SQL, который допускает ограничения для баз данных, таблиц или столбцов.
Это связано с тем, что XPath отличается от других языков баз данных, поскольку в нем отсутствуют элементы управления доступом или аутентификация пользователей.
XQuery - это расширенный набор языка XPath, который добавляет синтаксис, подобный SQL, а также некоторые полезные функции для запросов к документу.
Что такое XPath Injection?
Проблемы, которые могут возникнуть при хранении данных с использованием XML, также аналогичны проблемам, возникающим в SQL. Внедрение XPath - это тип атаки, при которой злонамеренный ввод может привести к несанкционированному доступу или раскрытию конфиденциальной информации, такой как структура и содержимое XML-документа. Это происходит, когда ввод пользователя используется при построении строки запроса. Большое количество методов, которые можно использовать в атаке с использованием SQL-инъекции, зависят от характеристик диалекта SQL, используемого целевой базой данных, тогда как атаки с использованием XPath-инъекции могут быть гораздо более адаптируемыми и повсеместными.
Принцип XPath-инъекции очень похож на SQL-инъекцию. Цель атаки тоже очень похожа. Единственная разница между этими атаками заключается в том, что внедрение XPath использует XML-файл для хранения данных вместо базы данных. Один из способов получить данные из XML-файла, должен использоваться XPath.
В некоторых случаях параметры в теле SOAP напрямую используются в качестве входных данных для запроса xpath. Если этот ввод пользователя не подтвержден, вероятно, злоумышленник может изменить запрос Xpath по своему желанию. В худшем случае злоумышленник сможет прочитать весь запрошенный XML-документ.
- SOAP - протокол обмена структурированными сообщениями в распределённой вычислительной среде. Первоначально SOAP предназначался в основном для реализации удалённого вызова процедур (RPC). Сейчас протокол используется для обмена произвольными сообщениями в формате XML, а не только для вызова процедур. Официальная спецификация последней версии 1.2 протокола никак не расшифровывает название SOAP. SOAP является расширением протокола XML-RPC.
Подобно SQL Injection, атаки XPath Injection происходят, когда веб-сайт использует предоставленную пользователем информацию для построения запроса XPath для данных XML. Отправляя преднамеренно искаженную информацию на веб-сайт, злоумышленник может узнать, как структурированы данные XML, или получить доступ к данным, к которым у него обычно нет доступа. Они могут даже иметь возможность повысить свои привилегии на веб-сайте, если данные XML используются для аутентификации (например, файл пользователя на основе XML).
Запрос XML выполняется с помощью XPath, типа простого описательного оператора, который позволяет XML-запросу находить фрагмент информации. Как и в SQL, вы можете указать определенные атрибуты для поиска и шаблоны для сопоставления. При использовании XML для веб-сайта обычно принимают некоторую форму ввода в строке запроса, чтобы идентифицировать контент, который нужно найти и отобразить на странице. Этот ввод необходимо обработать, чтобы убедиться, что он не портит запрос XPath и не возвращает неверные данные.
XPath - стандартный язык; его нотация / синтаксис всегда не зависит от реализации, что означает, что атака может быть автоматизирована. Нет разных диалектов, как это происходит в запросах к базам данных SQL.
Поскольку нет уровня управления доступом, можно получить весь документ. Мы не столкнемся с какими-либо ограничениями, которые могут быть известны из атак с использованием SQL-инъекций.
Пример уязвимости XPath Injection
Мы будем использовать этот фрагмент XML для примеров:
Код:
<?xml version="1.0" encoding="utf-8"?>
<Employees>
<Employee ID="1">
<FirstName>Arnold</FirstName>
<LastName>Baker</LastName>
<UserName>ABaker</UserName>
<Password>SoSecret</Password>
<Type>Admin</Type>
</Employee>
<Employee ID="2">
<FirstName>Peter</FirstName>
<LastName>Pan</LastName>
<UserName>PPan</UserName>
<Password>NotTelling</Password>
<Type>User</Type>
</Employee>
</Employees>
Код:
VB:
Dim FindUserXPath as String
FindUserXPath = "//Employee[UserName/text()='" & Request("Username") & "' And
Password/text()='" & Request("Password") & "']"
C#:
String FindUserXPath;
FindUserXPath = "//Employee[UserName/text()='" + Request("Username") + "' And
Password/text()='" + Request("Password") + "']";
Код:
Username: blah' or 1=1 or 'a'='a
Password: blah
FindUserXPath becomes //Employee[UserName/text()='blah' or 1=1 or
'a'='a' And Password/text()='blah']
Logically this is equivalent to:
//Employee[(UserName/text()='blah' or 1=1) or
('a'='a' And Password/text()='blah')]
Рассмотрим следующее хранилище данных XML:
Код:
<addressBook>
<address>
<firstName>William</firstName>
<surname>Gates</surname>
<password>MSRocks!</password>
<email>billyg@microsoft.com</email>
<ccard>5130 8190 3282 3515</ccard>
</address>
<address>
<firstName>Chris</firstName>
<surname>Dawes</surname>
<password>secret</password>
<email>cdawes@craftnet.de</email>
<ccard>3981 2491 3242 3121</ccard>
</address>
<address>
<firstName>James</firstName>
<surname>Hunter</surname>
<password>letmein</password>
<email>james.hunter@pookmail.com</email>
<ccard>8113 5320 8014 3313</ccard>
</address>
</addressBook>
Код:
//address/email/text()
Код:
//address[surname/text()=’Dawes’]
Давайте посмотрим, как мы можем выполнить инъекцию на этом примере. Этот код поступает из веб-приложения, которое предоставляет информацию о кредитной карте пользователям, вошедшим в него. Запрос XPath, который эффективно проверяет предоставленные пользователем учетные данные и извлекает номер соответствующей кредитной карты пользователя, может быть:
Код:
//address[surname/text()=’Dawes’ and password/text()=’secret’]/ccard/text()
Код:
‘ or ‘a’=’a
Код:
//address[surname/text()=’Dawes’ and password/text()=’’ or ‘a’=’a’]/ccard/text()
Чтобы продолжить, можно использовать недостатки внедрения XPath для извлечения произвольной информации из целевого XML-документа. Один из широко используемых способов сделать это, используя ту же технику, что мы видели при внедрении SQL, заставляя приложение реагировать по-разному, в зависимости от условия, указанного злоумышленником.
Отправка следующих двух операторов в поле пароля приложения приведет к разному поведению приложения. Результаты возвращаются в первом случае, но не во втором:
Код:
‘ or 1=1 and ‘a’=’a
‘ or 1=2 and ‘a’=’a
Код:
‘ or //address[surname/text()=’Thomas’ and substring(password/text(),1,1)=‘S’] and ‘a’=’a
Код:
//address[surname/text()=’Mel’ and password/text()=’’ or //address[surname/text()=’Thomas’ and substring(password/text(),1,1)= ‘S’] and ‘a’=’a ‘]/ccard/text()
Поиск уязвимостей XPath Injection
Допустим, разработчик хранит данные аутентификации в XML-файле со следующей структурой:
Код:
...
<user>
<name>UserName</UserName>
<password>Password</password>
</user>
...
Код:
string//user[name/text()='"txtUserName.Text"' and password/text()='" txtPassword.Text"'])
Первый известный мне метод обнаружения подобного рода уязвимости, омнова на ручном вводе, пробуем подставлять следующие данные:
- 'whatever – basic test
- DROP
- Something
Второй способ - поиск уязвимостей в коде. Вы можете искать следующие строки:
- Xpath - многие классы, которые работают с XPath, имеют в своем имени строку 'xpath'
- SelectSingleNode () и SelectNodes () - методы, используемые для получения данных из файлов XML через XPath.
Код:
$xml = simplexml_load_file("passwords/heroes.xml");
$result = $xml->xpath("/heroes/hero[login='" . $login . "' and password='" . $password . "']");
Код:
blah' or id='2
Следующий пример - это форма поиска:
Код:
http://192.168.0.115/bWAPP/xmli_2.php?genre=action%27&action=search
Код:
http://192.168.0.115/bWAPP/xmli_2.php?genre=horror%27)]/password%20|%20a[contains(a,%27&action=search
Многие XML приложения используют XML дампы баз данных. Идея сосотоит в том,что можно ВСЕ ЧТО УГОДНО поместить в XML и потом использовать приложение или некоторый код для парсинга тех данных, которые вам нужны (Часто XML базы применяются для разгрузки занятого SQL сервера. Сформировав дампы можно перенести проблему получения нужных данных со сложных и тяжелых SQL запросов на файловую систему и простое чтение XML файлов.) Проблема же в том, что нет никакого контроля над уровнем доступа и если ваше приложение или код читает XML документ, то существует возможность того, что ЛЮБЫЕ данные в нем могут быть просмотрены.
Если ваш сайт использует XML документы для хранения данных и пользовательский ввод используется для построения запросов, то вполне возможно, что он уязвим для XPath инъекции.
Защита от XPath Injection- Необходимо использовать параметризованный интерфейс XPath, если он доступен, или избегать ввода пользователя, чтобы его можно было безопасно включить в динамически создаваемый запрос.
- Если вы используете кавычки для завершения ненадежного ввода в динамически созданном запросе XPath, вам нужно экранировать эту цитату в ненадежном вводе, чтобы ненадежные данные не могли вырваться из этого цитируемого контекста.
Код:
VB:
Dim FindUserXPath as String
FindUserXPath = "//Employee[UserName/text()='" & Request("Username").Replace("'", "'") & "' And
Password/text()='" & Request("Password").Replace("'", "'") & "']"
C#:
String FindUserXPath;
FindUserXPath = "//Employee[UserName/text()='" + Request("Username").Replace("'", "'") + "' And
Password/text()='" + Request("Password").Replace("'", "'") + "']";
- Использование предварительно скомпилированного запроса XPath1. Предварительно скомпилированные запросы XPath уже задаются до выполнения программы, а не создаются на лету после того, как пользовательский ввод был добавлен в строку. Это лучший способ, потому что вам не нужно беспокоиться об отсутствии символа, который нужно было экранировать.
- Пользовательский ввод можно отфильтровать, например, цитату (‘) можно заменить на «' ». Проверка должна быть добавлена как на стороне клиента, так и на стороне сервера.
- Использование параметризованных запросов (например, подготовленные операторы в SQL), в которых запросы предварительно скомпилированы, а пользовательский ввод передается как параметры, а не выражения.
Код:
"//users[LoginID/text()= $LoginID and passwd/text()= $password]"
- Использование корректных страниц вывода ошибок, не раскрывающие никакой информации, которая может быть использована злоумышленником.
Спасибо за внимание, матерал подготовлен специально для protey.net.
Останнє редагування: