Спонсор: Microsoft
Опубликован: 25.06.2010 | Уровень: специалист | Доступ: свободно
Лекция 16:

Анализ защищенности информационной системы на основе выявления уязвимостей и обнаружения вторжений

Уязвимости "SQL injection"

Уязвимости типа " SQL Injection " ("инъекция в SQL -запросы") позволяют нарушителю выполнять несанкционированные операции над содержимым баз данных SQL -серверов путём вставки дополнительных команд в SQL -запросы. Любой SQL -запрос представляет собой последовательность команд для сервера СУБД, сформированную на основе специализированного языка структурированных запросов SQL ( Structured Query Language ). Данная уязвимость характерна для приложений, которые получают в качестве входных данных параметры доступа к базе данных, после чего на их основе формируют SQL -запрос к серверам СУБД. Уязвимость " SQL Injection " заключается в отсутствии проверки корректности данных, поступающих на вход программе, что потенциально может позволить нарушителю составить входные данные таким образом, что приведёт к искажению искомого SQL -запроса к СУБД. Описание различных примеров использования уязвимостей типа " SQL Injection " приводится ниже.

Активизация уязвимости "SQL Injection" с целью получения несанкционированного доступа к ИС

В ряде случаях уязвимости " SQL Injection " могут иметь место в программах, которые выполняют функции идентификации и аутентификации пользователя в ИС. Активизация таких уязвимостей может позволить нарушителю получить несанкционированный доступ системе путём обхода процедуры аутентификации. В листинге 23.3приведён пример исходного текста уязвимой программы, которая проводит аутентификацию пользователя на основе пароля.

SQLQuery = "SELECT Username FROM Users WHERE Username = '" &
strUsername & "' AND Password = '" & strPassword & "'"
strAuthCheck = GetQueryResult(SQLQuery)
If strAuthCheck = "" Then
boolAuthenticated = False
Else
boolAuthenticated = True
End If
Листинг 23.3. Фрагмент исходного кода уязвимой программы аутентификации пользователей

Алгоритм работы приведённой выше программы выглядит следующим образом. На основе регистрационного имени и пароля, введённого пользователем, программа формирует SQL-запрос, текст которого содержится в переменной SQLQuery. Далее при помощи сформированного запроса программа проводит в таблице Users поиск записи, содержащей имя и пароль, введённые пользователем. Если такая запись находится в таблице, то делается вывод о том, что аутентифицируемый пользователь зарегистрирован в системе и ему разрешается доступ к содержимому ИС. Поиск и извлечение информации из таблицы базы данных осуществляется при помощи SQL -оператора " SELECT ".

Сущность уязвимости рассмотренной программы состоит в отсутствии проверки корректности значений регистрационного имени и пароля, вводимых пользователем. Эти значения содержатся в переменных strUsername и strPassword, соответственно. Воспользовавшись этой ошибкой разработчика программы, злоумышленник может путём манипуляциями со значениями переменных strUsername и strPassword модифицировать SQL -запрос. Так, например, в случае если нарушитель в качестве регистрационного имени и пароля введёт значение "'OR ''='", то тогда будет сформирован следующий SQL -запрос:

"SELECT Username FROM Users WHERE Username = '' OR ''='' AND Password = '' OR ''='' " (полужирным шрифтом выделены команды, которые внедряются нарушителем в исходный SQL-запрос).

Поскольку в SQL -запрос были добавлены два новых параметра - "OR ''=''", то одновременно с поиском пустой учётной записи пользователя в таблице Users, будет возвращена первая строка таблицы. Поскольку в результате выполнения функции GetQueryResult будет возвращено непустое значение, то нарушитель сможет беспрепятственно пройти через процедуру аутентификации и получить доступ к ИС как легальный пользователь.

Активизация уязвимости "SQL Injection" с целью несанкционированного извлечения данных из СУБД

Для несанкционированного извлечения данных из СУБД нарушитель может добавить в исходный текст SQL -запроса оператор UNION SELECT, который позволяет формировать одновременно несколько запросов к таблицам СУБД. Рассмотрим процедуру активизации уязвимости " SQL Injection " этого типа на примере следующего запроса, выполняющего выборку из таблицы Employees по названию города, которое вводится пользователем и передаётся в запрос через переменную strCity:

SQLString = "SELECT FirstName, LastName 
FROM Employees WHERE City = '" & strCity & "'"

Для того, чтобы дополнительно извлечь информацию из другой таблицы с именем OtherTable нарушитель может ввести следующее значение через переменную strCity: "' UNION ALL SELECT OtherField FROM OtherTable WHERE ''='".В результате такой вставки получится SQL -запрос, который позволит получить доступ к информации, которая хранится в поле OtherField таблицы OtherTable:

SELECT FirstName, LastName FROM Employees WHERE City =
'' UNION ALL SELECT OtherField FROM OtherTable WHERE ''=''

После выполнения этого SQL -запроса будет сделана выборка данных из таблицы OtherTable. При этом никакой информации из таблицы Employees извлечено не будет, поскольку в сформированном запросе указано, что из этой таблицы необходимо получить только те записи, в которых поле City содержит пустое значение.

Несанкционированное извлечение данных из таблиц СУБД возможно путём несанкционированного искажения не только запроса SELECT, но и INSERT. Оператор INSERT используется для добавления информации в базы данных ИС. Активизация уязвимости " SQL Injection " в операторе INSERT возможна в том случае, если уязвимое приложение предусматривает возможность добавления в СУБД информации, вводимой пользователем, а также позволяет просматривать добавленные данные. Продемонстрируем вышесказанное следующим примером. Предположим, что в приложении проводится процедура регистрации пользователя, где он вводит свои персональные данные, которые затем при помощи INSERT -запроса записываются в таблицу TableName:

INSERT INTO TableName VALUES ('" & strValueOne &
"', '" & strValueTwo & "', '" & strValueThree & "')"

При этом после прохождения процедуры регистрации пользователь имеет возможность просмотреть ранее введённые данные. С целью модификации исходного SQL -запроса нарушитель может ввести вместо одной из переменных strValueOne, strValueTwo или strValueThree SQL -запрос типа "' + (SELECT TOP 1 FieldName FROM OtherName) + '". Это позволит злоумышленнику добавить в таблицу TableName не только свои персональные данные, но и информацию, извлечённую из СУБД при помощи вставленного запроса SELECT. Нарушитель может получить доступ к извлечённой информации при просмотре своих персональных данных.

Активизация уязвимости "SQL Injection" с целью несанкционированного изменения данных в СУБД

Для несанкционированного изменения содержимого таблиц SQL -сервера нарушитель может воспользоваться уязвимостью, базирующейся на возможности модификации исходного SELECT -запроса. Для внесения изменений в текст запроса необходимо добавить лишь оператор INTO, в параметрах которого указывается имя таблицы БД, куда необходимо добавить сделанную выборку. В результате такого изменения должен получиться запрос следующего типа: "SELECT <критерии выборки> FROM <имя таблицы, в которой делается выборка> INTO <имя таблицы, куда должна быть записана выборка>".

Активизация уязвимости "SQL Injection" с целью нарушения работоспособности SQL-сервера

Работоспособность SQL -сервера может быть нарушена при помощи несанкционированного использования рассмотренных выше запросов SELECT с параметром INTO. Для этого нарушителю достаточно сформировать их последовательность, которая предусматривала бы запись избыточного объёма информации в базу данных. После заполнения свободного дискового пространства работа сервера СУБД будет нарушена.

Уязвимости "format string"

Уязвимости типа " format string " ("форматирующая строка"), могут быть характерны для тех приложений, в которых используются функции типа printf() с непроверяемым параметром форматирующей строки. Форматирующая строка используется для определения общего числа параметров вызова функции, а также правил преобразования параметров вызова в символьные значение. В листинге 23.4 приведён фрагмент исходного кода программы, в котором используется функция printf(), выводящая на экран десятичные значения переменных i и j. Форматирующая строка функции printf(), приведённой в листинге, содержится в строковой переменной format_string.

int i = 10;
int j = 20;
char *format_string = "Переменная i = %d, переменная j = %d";
printf(format_string, i, j);
Листинг 23.4. Пример использования функции printf()

Параметры форматирующей строки задаются при помощи управляющего символа "%". Так, например, параметр "%d" используется для вывода десятичного числа, а параметр "%x" - для вывода шестнадцатеричного значения. Каждому параметру форматирования соответствует один аргумент, который указывается сразу после форматирующей строки. Для двух параметров "%d", приведённых в листинге 23.4, аргументами являются переменные i и j. Необходимо отметить, что если в форматирующей строке определён параметр, но отсутствует его аргумент, то в этом случае на экран будет выведено содержимое участка памяти стека, где должен находиться параметр. В форматирующей строке также может быть использован параметр "%n", который позволяет записывать в произвольный адрес памяти значение, которое определяется до параметра.

Потенциальная уязвимость " format string " возникает в том случае, когда содержимое форматирующей строки задаётся не разработчиком программы, а формируется на основе непроверяемых входных параметров вызова одной из функций программы. Например, для вывода на экран строкового значения переменной str можно использовать два варианта записи функции printf():

  1. printf("%s", str); - при таком варианте использования функции printf() форматирующая строка "%s" задаётся разработчиком в явном виде и не может быть скомпрометирована нарушителем;
  2. printf(str) ; - такое использование функции printf() может привести к тому, что потенциальный нарушитель сможет самостоятельно сформировать значение форматирующей строки при помощи переменной str и активизировать уязвимость " format string " путём манипуляции со значениями параметров "%x" и "%n".

Несанкционированное использование параметра "%x" может позволить нарушителю получить доступ к содержимому любого участка памяти в стеке, а при помощи параметра "%n" возможно изменение адреса возврата функции путём записи нового значения и передачи управления на вредоносный код, размещённый в памяти компьютера.

Уязвимости класса " format string " могут быть присущи любым приложениям, которые некорректно используют следующие функции: fprintf(), printf(), snprintf(), vprintf(), vsprintf(), vsnprintf(), secproctitle() и syslog().

Евгений Виноградов
Евгений Виноградов

Прошел экстерном экзамен по курсу перепордготовки "Информационная безопасность". Хочу получить диплом, но не вижу где оплатить? Ну и соответственно , как с получением бумажного документа?

Илья Сидоркин
Илья Сидоркин

Добрый день! Подскажите пожалуйста как и когда получить диплом, после сдичи и оплаты?????