Обычно приложения обрабатывают данные все время - как никак, именно для этого компьютеры и предназначены. Когда же непредвиденные входные данные приводят к уязвимости? Вообще, это может произойти в любой момент при взаимодействии приложения с пользователем или другим (непроверенным) приложением. Но известны наиболее общие ситуации, которые рассмотрим подробнее.

Локальные приложения и утилиты

Под управлением операционной системы на компьютере выполняются различные приложения, по мере необходимости запущенные пользователем или самой системой. Многие из этих приложений взаимодействуют с пользователем, предоставляя злоумышленнику шанс ввести в программу непредусмотренные разработчиком данные. Например, злоумышленник может нажать необычную последовательность клавиш, введя тем самым большой массив данных или определив неверные величины.

Обычно такие шалости не доставляют больших хлопот. Если пользователь сделал что-то не так, то приложение аварийно завершается, и всё. Но в мире систем UNIX, включая очень похожую на UNIX BSD операционную систему Macintosh OS X, у некоторых из приложений установлены специальные разрешения suid (set user ID - установленный идентификатор пользователя) и sgid (set group ID - установленный идентификатор группы), позволяющие им выполняться с повышенными привилегиями относительно привилегий обычного пользователя. Если манипуляции с обычным приложением не принесут злоумышленнику выгоды, то взятие под свой контроль приложения с установленными suid или sgid может предоставить злоумышленнику привилегии администратора. Далее будут рассмотрены некоторые типичные способы похищения прав приложений.

Протокол HTTP и язык разметки HTML

В приложениях Интернет много ошибок, основанных на неверных предположениях о работе сети. Часть из них обусловлена дезинформацией, но большинство - ошибками программирования из-за недостаточного знания программистами принципов работы протокола передачи гипертекстовых файлов HTTP (Hypertext Transfer Protocol). (HTTP -протокол уровня приложений для распределенных информационных систем гипермедиа, позволяющий общаться системам с различной архитектурой. Используется при передаче HTML-файлов по сети страниц WWW и языка гипертекстовой разметки HTML (HyperText Markup Language). Язык HTML - стандартный язык, используемый для создания страниц WWW).

Самая большая ошибка, которую допускают программисты, - необоснованное доверие заголовкам запроса в HTTP-запросе и вера в них как в средство обеспечения безопасности. Заголовок запроса ссылки Referer в HTTP-запросе содержит адрес страницы, на которой находилась ссылка на запрашиваемый документ. Заголовок запроса Referer поддерживается клиентом в клиентских настройках. Так как он создается клиентом, то его можно легко фальсифицировать. Например, при Telnet-обращении к 80 порту (НТТР-порт) Web-сервера можно набрать следующее:

GET / HTTP/1.0 User-Agent: Spoofed-Agent/1.0

Referer: http://www.wiretrip.net/spoofed/referer/

Видно, что в заголовке указана фальсифицированная ссылка и подложный агент пользователя. (В сетях агент пользователя (user agent) - прикладной процесс OSI,

представляющий пользователя или организацию, который создает, передает и обеспечивает доставку сообщений для пользователя.) Единственно, чему можно доверять из переданной пользователем информации, - это IP-адресу клиента. (Хотя и он может быть фальсифицирован. Подробнее об этом сказано в главе 12.) Другой недостаток HTTP -зависимость от ограничений представления информации средствами HTML. Зная это, многие разработчики предлагают пользователям выбирать данные из списка (например, из трех элементов). Конечно, совсем не обязательно ограничивать пользователя списком данных, заданным разработчиком. Однажды автор наблюдал достаточно ироничную ситуацию, когда сотрудник Microsoft предлагал использовать списки как эффективный метод борьбы с непредвиденными данными пользователя. Это предлагал человек из группы разработчиков SQL Server, не входивший в группу обеспечения безопасности или разработки Web-решений. От него нельзя требовать больше, чем знание внутренней логики работы SQL-сервера.

Рассмотрим пример HTML-формы, подготовленной приложением:

<FORM ACTION-’process.cgi” METHOD=”GET”> <SELECT NAME=”author”>
<OPTION VALUE-’Ryan Russell”>Ryan Russell
<OPTION VALUE-’Hal Flynn”> Hal Flynn
<OPTION VALUE-’Ryan Permeah”> RyanPermeah
<OPTION VALUE-’DanKaminsky”> Dan Kaminsky
</SELECT>
<INPUT TYPE-’Submit”>
</FORM>

В HTML-форме описан список, составленный из имен некоторых авторов. Получив HTML-форму, клиентское приложение разрывает соединение, анализирует полученную HTML-форму и предъявляет ее пользователю. После выбора из списка автора клиентское приложение посылает отдельный запрос на Web-сервер с приведенным ниже URL (Uniform Resource Locator - унифицированный указатель информационного ресурса. Стандартизованная строка символов, указывающая местонахождение документа в сети Интернет):

process. cgi?author=Ryan Russell

Все очень просто. Но нет никаких причин, препятствующих посылке другого URL: process.cgi?author=Rain Forest Puppy

Так обходится предполагаемое «ограничение» HTML-формы. Более того, можно ввести URL, не запрашивая HTML-форму. Для этого следует обратиться к 80 порту Web-сервера по Telnet и сделать запрос вручную. При этом совсем не обязательно обращаться к основной форме. Не следует считать, что полученные на запрос данные - это обязательно результат обработки предыдущей HTML-формы. Одно из заблуждений, которое автор любит опровергать, - это использование фильтра данных в клиентской части. Многие включают в HTML-формы небольшие сценарии на JavaScript или VBScript, которые контролируют заполнение всех элементов формы. Некоторые предусматривают в сценариях контроль введенных данных: введенные числовые значения действительно числовые и т. д. После такого контроля приложение работает, исходя из предположения об отсутствии ошибок в данных, введенных пользователем, и, следовательно, может сразу передать их системной функции.

На самом деле клиентская часть должна сообщать о проведенных проверках введенных данных. Если читатель не знает, как можно обойти контролирующие ввод пользователя сценарии, то задумайтесь над имеющейся даже у технически непросвещенных людей возможности отключения поддержки сценариев. Например, некоторые корпоративные межсетевые экраны отфильтровывают сценарии HTML-формы. Или злоумышленник может использовать браузеры, не поддерживающие сценарии (например, Lynx).

Следует особенно отметить, что использования параметра size HTML-формы, который описывает размер входного поля, недостаточно для предотвращения переполнения буфера.

Значение параметра size клиент может установить сам, если в этом есть необходимость (или если он понимает значение этого параметра).

Если бы в протоколе HTTP придумали что-нибудь в интересах безопасности, это обязательно затронуло бы файлы cookies (небольшой фрагмент данных о предыстории обращений пользователя к WWW-серверу, автоматически создаваемый сервером на машине пользователя). Похоже, что никто еще до конца не понял, что это такое и как им правильно пользоваться. Пресса объявила их самой большой угрозой персональной безопасности в Интернет. Некоторые используют их для хранения важных данных аутентификации. Плохо, что никто из них не прав.

Механизм cookies является эффективным методом передачи данных клиентам с возвратом. Является ли это нарушением безопасности? Единственные данные, возвращаемые клиентами на сервер, - это ранее переданные им данные. Существует возможность ограничить cookies так, что клиент будет только отсылать их обратно на сервер. Предназначен cookies для обеспечения сохранения информации состояния во время многочисленных запросов, поскольку HTTP - протокол без сохранения состояния, то есть каждый запрос, выполненный индивидуальным клиентом, независимый и анонимный.

Поскольку cookies - составляющая часть HTTP, любая передаваемая с их помощью информация - это текст. Обмануть cookies не так уж и сложно. Рассмотрим обращение Telnet к 80 порту Web-cepeepa:

GET / НТТР/1.0 User-Agent: HaveACookie/1.0

Cookie: MyCookie=SecretCookieData

Только что был отправлен файл cookie «MyCookie» вместе с хранящимися в нем данными «SecretCookieData». Другой интересный факт о cookies: они обычно хранятся в текстовом файле клиента. Поэтому при сохранении важной информации в cookie всегда есть вероятность неавторизованного доступа к ним.

Непредвиденные данные в запросах SQL

Многие приложения и системы электронной коммерции взаимодействуют с базами данных. Небольшие базы данных могут быть встроены в приложения для настройки и структурированного хранения данных, например системный реестр Windows. Короче говоря, базы данных присутствуют везде.

Язык структурированных запросов SQL (Structured Query Language) - стандартный международный язык доступа к реляционным базам данных, используемый для передачи команд системе управления базами данных и получения от нее ответов. Можно смело сказать, что большинство коммерческих реляционных серверов баз данных совместимы с языком SQL, поскольку SQL является стандартом ANSI.

А теперь самое ужасное в SQL. Считается, что для нормальной работы приложение должно иметь доступ к базе данных. Поэтому приложение должно иметь права, необходимые для получения доступа к серверу базы данных и соответствующим ресурсам. При попытках злоумышленника изменить команды, посылаемые приложением к серверу базы данных, он воспользуется установленными правами приложения. Никакой дополнительной проверки подлинности злоумышленнику не потребуется. Он даже напрямую не взаимодействует с сервером базы данных. Можно расставить столько межсетевых экранов между сервером базы данных и сервером приложений, сколько вы можете себе позволить. Но если приложение может использовать базу данных, то у злоумышленника есть возможность получить доступ к базе данных.

Естественно, что получение доступа к базе данных не означает возможности злоумышленника сделать с сервером базы данных все, что угодно, потому что приложение может иметь ограниченный доступ к ресурсам. В результате фактический доступ атакующего к серверу базы данных и его ресурсам также будет ограничен.

Одна из самых больших угроз, вызванная включением данных пользователя в запрос SQL, заключается в передаче злоумышленником дополнительных команд, выполняемых сервером. Представьте, что простенькое приложение захочет просмотреть таблицу данных пользователя. Запрос может выглядеть примерно так:

SELECT * FROM table WHERE x=$data

В этом запросе вместо переменной $data будут подставлены данные пользователя. Затем запрос будет передан системе управления базами данных. А теперь представим, что злоумышленник подготовил следующую строку данных:

1; SELECT * FROM table WHERE y=5

После подстановки в запрос данных пользователя системе управления базами данных будет передано:

SELECT * FROM table WHERE x=l; SELECT * FROM table WHERE y=5 В большинстве случаев это приведет к обработке системой управления базами данных двух отдельных запросов: ожидаемого запроса и непредвиденного дополнительного:

SELECT * FROM table WHERE y=5.

Написано «в большинстве случаев» потому, что каждая система управления базами данных обрабатывает дополнительные запросы по-разному. Одни не допускают выполнения более одного запроса за одно обращение, другие требуют специальных символов для разделения запросов, а третьим символы разделения запросов не нужны. Например, приведенная ниже часть кода является правильной (на самом деле это два запроса, отправленных одновременно) для серверов баз данных Microsoft SQL Server и Sybase SQL: SELECT * FROM table WHERE x=l SELECT * FROM table WHERE y=5 Обратите внимание на отсутствие символов разделения запросов между выражениями SELECT. Важно понимать, что возвращенный результат зависит от ядра базы данных. Некоторые возвращают два набора записей, каждый из которых содержит результаты запроса SELECT. На рисунке 7.1 показан этот случай. Другие могут объединять наборы, если возвращаемые наборы записей состоят из одних и тех же колонок. А большинство приложений написаны таким образом, что возвращают результаты только первого запроса. В этом случае результат второго запроса увидеть нельзя, но это не значит, что он не был выполнен. Сервер MySQL позволяет сохранить результат запроса в файле. В состав MS SQL Server включены процедуры рассылки результатов запроса по электронной почте. И конечно, в обоих случаях не отображается результат выполнения команды DROP.

Некоторые сервера баз данных, как, например, Microsoft SQL Server, разрешают указывать несколько команд в одном SQL-запросе Пытаясь передать в запросе дополнительные команды, злоумышленник может указать серверу базы данных на необходимость игнорирования части запроса

Рис. 7.1. Некоторые сервера баз данных, как, например, Microsoft SQL Server, разрешают указывать несколько команд в одном SQL-запросе Пытаясь передать в запросе дополнительные команды, злоумышленник может указать серверу базы данных на необходимость игнорирования части запроса. Рассмотрим, например, запрос:

SELECT * FROM table WHERE x=$data AND z=4 При подстановке в запрос ранее упомянутых данных получим следующий запрос:

... WHERE х=1; SELECT * FROM table WHERE y=5 AND z=4 В результате во вложенный дополнительный второй запрос оказалось включено выражение AND z=4, которое по замыслу злоумышленника лишнее. Для его исключения из запроса следует использовать символ комментария, который в каждой системе управления базами данных свой. В сервере MS SQL включение двойного дефиса (-) говорит об игнорировании части запроса за ним, который выполняет роль символа комментария, как это показано на рис. 7.2. В MySQL символом комментария служит знак «решетки» (#). Поэтому в случае сервера MySQL подстановка злоумышленником значения 1; SELECT * FROM table WHERE y=5 # приводит к выполнению запроса

Использование символа комментария в Microsoft SQL Server для игнорирования части запроса

Рис. 7.2. Использование символа комментария в Microsoft SQL Server для игнорирования части запроса ... WHERE х=1; SELECT * FROM table WHERE y=5 # AND z=4 и заставляет сервер игнорировать выражение AND z=4. В этих примерах было известно название атакуемой таблицы, что случается нечасто. Для составления правильного SQL-запроса нужно знать имя таблицы и названия столбцов. Обычно главная проблема в том, что эта информация недоступна пользователям. Но для злоумышленника не все так плохо. Разные системы управления базами данных обеспечивают различные способы получения системной информации о таблицах базы данных. Например, обращаясь с запросом к таблице sysobjects Microsoft SQL Server (с помощью запроса Select * from sysobjects запрос), можно получить информацию о всех зарегистрированных в базе данных объектах, включая хранимые процедуры и названия таблиц.

Занимаясь хакингом SQL, хорошо бы знать возможности серверов баз данных. Из-за особенностей хакинга SQL злоумышленник может не увидеть результатов своей работы, поскольку большинство приложений не предназначены для обработки вложенных запросов. Поэтому злоумышленнику может потребоваться много времени, прежде чем он удостоверится, что получил доступ к базе данных. К счастью, здесь нет легких решений, потому что для нормальной работы большинство команд SQL требуют задания имен таблиц.

Следует творчески поработать, чтобы узнать их.

Вслепую или нет, но хакинг SQL возможен. Для этого может потребоваться понимание принципов работы серверов баз данных. Следует познакомиться с хранимыми процедурами и расширениями SQL анализируемого сервера. Например, сервер Microsoft SQL поддерживает хранимую процедуру рассылки результатов запроса по электронной почте. Это может пригодиться для просмотра результатов работы вложенных запросов. Сервер MySQL может сохранять результаты запросов в файле, позволяя впоследствии восстанавливать результат. Всегда следует попытаться использовать дополнительные возможности сервера базы данных с выгодой для себя.

Аутентификация приложений Обсуждение аутентификации всегда интересно. В каких случаях пользователю необходимо получить доступ к приложению, ведающему данными аутентификации? Каким образом осуществляется аутентификация пользователя? Для однопользовательских приложений это не такие уж и трудные вопросы, но для Web-приложений это серьезная проблема.

Для того чтобы успешно противостоять атакам «грубой силы», часто используются случайные ключи сессии и аутентификации, образующие большое ключевое пространство (общее число возможных ключей). Но в этом подходе два серьезных недостатка. Во-первых, ключ должен быть действительно случайным. Любая предсказуемость ключа повысит шансы злоумышленника вычислить его. Ключ не следует вычислять при помощи линейной возрастающей функции. Системные функции UNIX /dev/random и /dev/urandom могут не обеспечить необходимой случайности ключей, особенно при генерации ключей большого размера. Например, слишком быстрый вызов функций /dev/random или /dev/ urandom может отразиться на «случайности» генерируемых ключей, потому что в этом случае функции обращаются к предсказуемому генератору псевдослучайных чисел.

Во-вторых, ключевое пространство должно быть достаточно большим по отношению к числу ключей, необходимых в любой момент времени. Пусть ключ имеет 1 млрд возможных значений. Страшно даже подумать об атаке «грубой силы» на ключевое пространство в 1 млрд ключей. Но популярный сайт электронной коммерции может обслуживать около 500 ООО открытых сессий каждый рабочий день. В этом случае у злоумышленника хорошие шансы найти подходящий ключ в каждой серии из 1 ООО проверенных ключей (в среднем) и его не отпугнет последовательный перебор 2000 ключей со случайно выбранного значения. Рассмотрим некоторые современные схемы аутентификации. Какое-то время назад организация PacketStorm (www.packetstormsecurity.org) решила перепрограммировать на языке Perl программное обеспечение своего Web-форума после нахождения уязвимости в пакете wwwthreads.

Выбранный способ аутентификации оказался очень любопытным. После регистрации пользователю передавался URL-адрес с двумя специфичными параметрами:

authkey=rfp .234623 82. temp&uname=rfp Рассматривая систему аутентификации как «черный ящик» без малейшего представления о принципах его работы, была предпринята попытка найти закономерности работы системы при изменении входных данных параметров. Первый шаг состоял в изменении значения параметра authkey: сначала имени пользователя, а затем случайного числа и дополнительной величины «temp». Целью данных манипуляций было проверить возможность аутентификации пользователя с другими случайными недействительными значениями параметра. Не получилось. Затем значение параметра ипате было изменено на другое правильное имя пользователя. В результате была получена строка вида authkey=rfp.234623 82. temp&uname=fringe.

После этого удалось зарегистрироваться под именем другого пользователя («fringe»). Исходя из этого, был восстановлен фрагмент программы аутентификации на языке Perl (заметим, что без знания истинного кода форума PacketStorm): if (-е “authkey_directory/$authkey”) { print “Welcome $uname!”;

# do stuff as $uname } else {
print “Error: not authenticated”;
}

Таким образом, authkey - это файл, создаваемый при входе в систему с использованием случайного числа. Приведенный фрагмент программы позволяет любому пользователю, изменившему параметр ипате, получить доступ к учетной записи иного пользователя, используя известный и правильный authkey (например, свой собственный). Основываясь на форматах параметров authkey и ипате, естественно было предположить, что значение authkey относится к файловой системе. Прежде всего потому, что значение параметра authkey в формате username.999999. temp не похоже на информацию, которую хранят в базе данных. Вполне возможно, что приложение разделяло параметр authkey на три части, используя для запроса к базе данных имя пользователя и случайное число. При этом отпадала необходимость в передаче через значение параметра ипате имени пользователя, а постоянное окончание «.temp» становилось бесполезным и бессмысленным. Следуя интуиции и зная, что формат представления параметра authkey похож на задание имени файла, было высказано предположение, что значение параметра authkey определяет имя файла, как в итоге и оказалось.

Конечно, PacketStorm была поставлена в известность, и ошибка была исправлена. Выбранное ими решение лаконично, но давайте рассмотрим другой вариант исправления ошибки. Пусть программа была бы исправлена следующим образом:

if (-е “ authkey_directory/$authkey” && $authkey=~/A$uname/) { print “Welcome $uname!”;

# do stuff as $uname } else {
print “Error: not authenticated”;
}

Хотя это решение и выглядит правильным (в фрагменте кода выполняется проверка того, что значение параметра authkey начинается со строки символов, совпадающих со значением параметра ипате), но оно ошибочно. В фрагменте кода проверяется только то, что параметр authkey начинается со значения параметра ипате. Это значит, что если значение authkey было бы «rfp.234623.temp», то можно было бы использовать в качестве значения параметра ипате символ «г», так как строка «rfp» начинается с символа «г». Ошибка исправляется заменой $authkey=~/A$uname/ ia $authkey=~/A$uname\./. В результате выполняется проверка на совпадении всего значения первой части параметра authkey с ипате. PacketStorm решил использовать вариант, похожий на следующий:

@authkey_parts = split(“.”, $authkey); if ($authkey_parts[0] eq $uname && -e «authkey _directory/
$authkey»){ ...,

Приведенный вариант - всего лишь иной способ убедиться в совпадении значения первой части параметра authkey со значением ипате. Но все равно в демонстрационном коде присутствуют погрешности. Зачем дублировать и сравнивать имя пользователя параметра authkey со значением ипате? Оно всегда должно быть одним и тем же. Храня его в двух местах, всегда существует вероятность ошибок. Корректнее использовать следующий код: if (-е «authkey_directory/$uname.$authkey.temp»){...

В этом случае следует лишь переслать URL: authkey=234562&uname=rfp.

В новом варианте программы имя файла «rfp.234562.temp» собирается из двух половинок. Тем самым гарантируется, что в приложении будет использовано одно и то же имя пользователя, совпадающее со значением параметра ипате, и что атакующий может ссылаться только на файлы с расширением имени «.temp», поскольку так определено в программе. Тем не менее возможны и другие трюки злоумышленника. Например, передача символа NULL в конце значения параметра authkey вынудит систему проигнорировать добавление строки «.temp». Этого можно избежать, убрав все NULL из переданной строки. Но злоумышленник может использовать для аутентификации любой известный, temp-файл с помощью символов «../» в совокупности с другими хитростями. Поэтому лучше убедиться, что параметр $ипате содержит только допустимые символы (предпочтительно лишь буквы), a Sauthkey - только числа. В общем случае для аутентификации лучше использовать запросы SQL к базе данных пользователей и паролей. Например, следующий запрос:

SELECT * FROM Users WHERE Username=,$name’ AND Password=’$pass’, где $name и $pass - параметры имя пользователя и его пароль. В результате выполнения запроса будут найдены все записи в базе данных, у которых имя пользователя и пароль совпадают со значениями параметров, введенными пользователем. Полученный результат может быть обработан следующим образом:

if ( numberofreturnrecords > 0) { # username and password were found; do stuff } else {
# not found, return error
}

Приведенный фрагмент программы обрабатывает результат запроса. Если в результате запроса были найдены записи, то введенная пользователем комбинация из имени пользователя и его пароля действительна. Тем не менее это образец небрежного программирования, основанного на ошибочном предположении. Представьте, что злоумышленник передаст в качестве параметра $pass следующее значение: boguspassword OR TRUE

В результате злоумышленник будет аутентифицирован как законный пользователь, потому что в ответ на запрос будут найдены все записи базы данных, а согласно логике приложения при нахождении хотя бы одной записи, удовлетворяющей запросу, полномочия пользователя считаются подтвержденными. Ошибка заключается в логическом условии (при number of_return_records > 0). Это условие предполагает наличие ситуации, при которой одной комбинации имени пользователя и его пароля соответствуют многочисленные записи в базе данных. В правильно разработанном приложении подобная логическая ошибка должна быть исправлена. Исправленное логическое условие должно быть таким: (number of return records = = 1). Потому, что если число записей равно нулю, то в результате запроса не было найдено ни одной записи с заданной комбинацией имени пользователя и пароля, что свидетельствует о неуспешном завершении процедуры аутентификации. Одна найденная запись говорит об успешном завершении процедуры аутентификации, а более одной - о наличии проблемы из-за ошибки работы с базой данных или атаки злоумышленника.

Конечно, из-за взятого в кавычки параметра $pass описанная только что ситуация может не произойти. Результат непосредственной подстановки значения параметра в запрос будет выглядеть так:

... AND Password=’boguspassword OR TRUE’

В итоге часть запроса OR TRUE не будет интерпретироваться как команда. Можно расставить собственные кавычки (boguspasswordV OR TRUE) и преодолеть это ограничение. При этом запрос примет вид:

... AND Password=’boguspassword’ OR TRUE’

Обычно это приводит к выдаче диагностического сообщения о том, что кавычка непарная. Для того чтобы избавиться от сообщения, можно использовать символ комментария за ключевым словом TRUE или использовать в запросе замыкающую кавычку. При присвоении параметру $pass значения

boguspassword’ OR NOT Password=’otherboguspassword запрос станет следующим:

... AND Password=’boguspassword’ OR NOT Password=’otherboguspassword’ и замыкающая кавычка окажется на своем месте. Естественно, что правильно выполненная в программе проверка корректности данных и расстановки кавычек не даст такому запросу выполниться. Именно так и реализована аутентификация в пакете wwwthreads (www.wwwthreads.com). Запрос, включенный в их демоверсию, выглядит следующим образом:

my $query = qq! SELECT *
FROM Users
WHERE Username = $Username_q
I-
• i

А этому фрагменту кода предшествуют следующие строчки:

my $Username_q = $dbh->quote($Usemame); ту $Password_q = $dbh->quote($Password); В этих строчках проводимые проверки гарантируют, что значение параметра $Username правильно взято в кавычки. Благодаря этому все, что говорилось по поводу расстановки кавычек, работать не будет. Несмотря на это, еще раз рассмотрим запрос. Видно, что описанная проверка анализирует только имя пользователя. Это означает, что если кто-то использует правильное имя пользователя, то результат запроса заставит поверить пакет wwwthreads в то, что пользователь успешно прошел процедуру аутентификации. Исправленный запрос выглядит следующим образом: my $query = qq! SELECT *

FROM Users
WHERE Username = $Username_q AND Password = $Password_q
I-
• i

О найденной ошибке была оповещена служба поддержки пакета wwwthreads, и проблема была решена. Маскировка непредвиденных данных

Многие люди часто не замечают разновидности атак злоумышленника, основанных на маскировке характерных признаков (сигнатуры) непредвиденных разработчиком входных данных программы. На проверке сигнатуры данных основана работа некоторых приложений: сканеров вирусов и систем обнаружения вторжений. Цель маскировки сигнатуры данных состоит в преобразовании злонамеренной сигнатуры (сигнатуры вируса или атаки) таким образом, чтобы приложение не смогло ее распознать. Более подробно системы обнаружения вторжений (IDS) описаны в главе 16.

В основе работы всех сетевых систем обнаружения вторжений, основанных на проверке сигнатуры, лежит список различных величин и ситуаций, которые они ищут в сети. Системы обнаружения вторжений оповещают об опасности при нахождении совпадающих характеристик сети с данными из списка. Обычно системы обнаружения вторжений используются для предупреждения об атаках и нарушений установленных правил поведения в сети (например, политики безопасности).

В качестве примера рассмотрим Web-запрос. Пусть система обнаружения вторжений настроена на подачу сигнала тревоги при появлении любого запроса, содержащего строку /cgi-bin/phf. Предполагается, что в рассматриваемом случае давно известная уязвимость, основанная на вызове программы phf интерфейса CGI, будет оформлена по стандартным правилам протокола HTTP, и поэтому ее будет легко обнаружить. Но опытный злоумышленник, используя тонкие моменты в работе протокола HTTP и атакуемого Web-cepeepa, может исказить сигнатуру строки /cgi-bin/phf.

Например, запрос может быть представлен в эквивалентном шестнадцатеричном виде: GET /%63%67%69%2d%62%69%6e/phf HTTP/1.0

Приведенная строка не соответствует в точности строке /cgi-bin/phf, но Web-cepeep перед использованием полученной строки переведет каждый фрагмент %ХХ в соответствующий ASCII-символ. В запросе может также использоваться нечасто встречаемая форма указания директории самой на себя:

GET /cgi-bin/./phf HTTP/1.0

Включенные в состав запроса символы указания директории самой на себя /./ позволяют изменить сигнатуру уязвимости. Или пусть, для примера, атакуемый Web-cepeep

- информационный сервер Интернет (IIS) Windows NT (хотя phf - это программа интерфейса CGI системы UNIX). Тогда запрос можно оформить следующим образом:

GET /cgi-bin\phf HTTP/1.0

Приведенная строка маскирует сигнатуру искомой строки. Недавно получил распространение способ маскировки данных, поставивший всех в тупик. Он основан на кодировании URL при помощи метающих друг друга кодировок UTF-8 и Unicode, которые понимают сервера Microsoft IIS и некоторые другие. (UTF-8 - ASCII-совместимый многобайтовый код, приметаемый в языке Java. Unicode - 16-битный стандарт кодирования символов, позволяющий представлять алфавиты всех существующих в мире языков). Для представления символов ASCII можно использовать 16-битное кодирование Unicode. Обычно приложения воспринимают эти 16-битные величины как неверные, хотя некоторые могут их обрабатывать.

Хорошим примером, иллюстрирующим возможности перехода к представлению данных на Unicode-коде, является уязвимость, исправленная патчем Microsoft MS00-078. Ранее можно было обмануть информационный сервер Интернет IIS и получить доступ к файлам, размещенным за пределами Web-директории, при помощи обращения к родительской директории. Пример подобного трюка с URL выглядит так

/cgi-bin/../../../../winnt/system32/cmd.exe

В идеальном для злоумышленника случае это позволило бы ему получить доступ к корневой директории, а затем к системной директории WINNT и ее поддиректориям, вызвав программу операционной системы cmd.exe. Позволило бы, если бы информационный сервер Интернет не был достаточно умен, чтобы противостоять злоумышленнику и не позволить ему преодолеть систему безопасности. Меняя некоторые символы на их эквиваленты в Unicode-коде, злоумышленник может обмануть информационный сервер Интернет IIS, заставив его поверить в безопасность URL. После декодирования URL информационный сервер Интернет выполнит программу cmd.exe. Результат замены символов в URL может выглядеть так:

/cgi-bin/.. %c0%af..%c0%af..%c0%af..%c0%afwinnt/system32/cmd.exe

В этом примере символ «/» заменен на 16-битный эквивалент в Unicode-коде с представлением в шестнадцатеричном формате «OxCOAF», который затем был перекодирован в URL как «%cO%af». Вместо символа «/» можно было закодировать в Unicode-коде любой другой символ. Символ «/» был использован только в качестве примера.

Опасность непредвиденных входных данных | Защита от хакеров корпоративных сетей | Методы поиска и устранения уязвимостей, обусловленных непредвиденными входными данными


Защита от хакеров корпоративных сетей



Новости за месяц

  • Июль
    2019
  • Пн
  • Вт
  • Ср
  • Чт
  • Пт
  • Сб
  • Вс