Базовые sql-инъекции в приложениях, использующих язык SQL. Руководство для чайниковИсточник: habrahabr rgen3
Примечание переводчикаДанная работа является переводом части работы Chris Anley Advanced SQL Injection In SQL Server Applications. (прямая ссылка для скачивания) В последующих статьях, при наличии свободного времени, данный перевод будет доведен до конца. P.S. Перевод будет интересен более в образовательных и исторических целях. Оригинальное название статьи: Продвинутые SQL-инъекции в приложениях, использующих язык SQL. АннотацияВ данной статье подробно рассматриваются общие способы "SQL-инъекции", для известной платформы Microsoft Internet Information Server/Active Server Pages/SQL Server. В ней обсуждаются различные варианты использования инъекции SQL в приложениях и объясняются методы проверки данных, а также защита баз данных, в которых могут быть использованы инъекции. ВведениеStructured Query Language (SQL) - это структурированный язык, используемый для взаимодействия с базами данных. Существует множетсво "диалектов" языка SQL, но сегодня, в основном, все они построены на основе стандарта SQL-92, один из ранних ANSI стандартов. Основной операционный блок SQL - запрос (query), который является совокупностью выражений, которые обычно возвращают совокупность результатов (result set). SQL выражения могут изменять структуру баз данных (используя выражения языков определения данных - DLL) и управлять их содержанием (используя выражения языков манипулирования данными - DML). В данной работе, мы рассмотрим transact-SQL, использующийся в Microsoft SQL Server. SQL-инъекции возможны в том случае, когда злоумышленник может вставить свой SQL-код в запрос (query), для управления данными, которые отправляются в приложение. Обычное SQL выражение выглядит следующим образом:
Это выражение берет "id", "forename" и "surname" из колонок таблицы "authors" и возвращает все строки в таблице. Выборка может быть ограниченна, определенным "автором", например:
Необходимо отметить, что в данном запросе строковые литералы разделены одинарной кавычкой. Предполагается, что "forename" и "surrname" являются данными, которые вводятся пользователем. В данном случае злоумышленник будет способен внести собственный SQL-запрос, путем добавления собственных значений в приложение. Например:
Тогда выражение примет следующий вид:
После того, как база данных попытается обработать подобный запрос будет возвращена следующая ошибка:
Причина ошибки будет заключаться в том, что введенная одиночная кавычка испортит структуру разделителей в запросе. Таким образом, база данных безуспешно попытается выполнить команду "hn", которая приведет к ошибке. В итоге, если злоумышленник введет в форму следующую информацию:
Таблица "authors" будет удалена, почему это произойдет мы рассмотрим позже. Вам может показаться, что если мы будем удалять одиночные кавычки из формы ввода, а также "заменять" их, это может решить нашу проблему. И вы будете правы, однако существуют некоторые проблемы с использованием этого способа, в качестве решения данной задачи. Во-первых, не вся вводимая пользователем информация является "строками" (strings). Если пользовательская форма будет содержать "id" автора, который обычно является числом. Например, наш запрос может выглядеть следующим образом:
В данном случае взломщик беспрепятственно сможет добавить любое SQL-выражение в после численных данных. В других разновидностях SQL-запросов, используются различные разграничители. Например, в Microsoft Jet DBMS разграничителем будет символ "#". Во-вторых, "избегание" ("escaping") одиночных кавычек вовсе не самый простой способ защиты, как это может показаться сперва. Подробнее об этом мы поговорим далее. Приведем пример на основе страницы входа на основе Active Server Pages (ASP), которая при помощи SQL получает доступ к базе данных, чтобы авторизовать пользователя в каком-либо приложении. Приведем код страницы, содержащей форму входа, в которую вводятся имя пользователя и пароль.
Ниже код (process_login.asp), определяющий корректность введенных данных.
Уязвимость здесь содержиться в "process_login.asp", который создает запрос следующего вида:
Если пользователь введет:
таблица "users" будет удалена, что закроет доступ к приложению для всех пользователей. Сочетание "--" в Transact-SQL определяет однострочный комментарий, а ";" обозначает конец одной строки и начало другой. Два последовательных тире в данном запросе используются с целью завершить запрос без ошибок. Более того, злоумышленник может зайти в систему под любым именем пользователя, используя следующую конструкцию:
А введя следующую информацию взломщик сможет зайти в систему в качестве выдуманного пользователя:
Причиной работоспособности этого способа заключается в том, что приложение "поверит", что вернувшийся фиктивный результат является набором записей из базы данных.
Получение информации, основываясь на сообщениях об ошибкахИзобретателем этой методики является David Litchfield, исследователь в области испытаний на проникновение (с целью проверки системы защиты). Позже David написал работу на эту тему[1], на которую ссылались многие другие авторы. В его работе объясняется механизм, использования сообщений об ошибках - "error message" technique. В своем труде он полностью объясняет читателям данную методику, и дает дальнейший толчок в развитии собственного понимания данной проблемы. Для успешного управления данными, злоумышленник должен знать структуру баз и таблиц, к которым он хочет получить доступ. Например, таблица наших "users" создана при помощи следующей комманды:
И содержит следующих пользователей:
Предположим наш хакер хочет вставить собственную запись в таблицу. Вряд ли ему это удастся, если он не знает её структуры. Но даже если ему это и удастся, то значение поля "privs" так и останется непонятным. Взломщик может вставить значение "1", создав себе аккаунт с низкими привелегиями, в то время как ему необходим доступ на уровне администратора приложения. К счастью, для хакера стандартное поведение ASP на ошибки - отображение сообщений о них, с их помощью полностью определив структуру базы данных, а следовательно узнать значения всех полей из аккаунтов пользователей, которые занесены в базу приложения. (В следующем примере мы будем использовать предложенную выше базу данных, а также asp скрипт, чтобы показать эту методику в действии.) Во-первых, взломщик захочет установить имена таблиц, с которыми работают запросы, а также имена полей. Для достижения поставленной цели злоумышленник будет использовать конструкцию "having" в select выражения:
Которое вызовет следующую ошибку:
Таким образом, зная имена таблиц и имя первой колонки в ней. Эту процедуру можно продолжать при помощи оператора "group by", как показано ниже:
(которое в свою очередь породит новую ошибку)
Полезной эта информация будте в том случае, если удастся узнать тип данных, который используется в каждой из колонок. Информацию о типе данных можно получить, используя "преобразование типов", например:
Попытка вычислить "сумму" текстового поля приведет к следующей ошибке:
С другой стороны, если мы попытаемся вычислить sum() численного типа, то получим сообщение уведомляющее, что число символов в наборе двух текстовых строк не совпадает:
Что в свою очередь поможет злоумышленнику сформировать хорошо составленный "insert" запрос, например:
Список стандартных ошибок можно добыть используя конструкцию:
Особенно полезными являются сведения о конвертации типов. Если вы попытаетесь сконвертировать string в integer, вернется сообщение, содержащее в себе весь контент string. В нашем примере, преобразование "username" вернет версию SQL server'а, а также версию операционной системы.
в целочисленное значение, так как первая колонка в таблице "users" имеет это тип данных. Метод может быть использован для чтения любого значения в любой таблице в базе данных. Таким образом, если злоумышленник захочет узнать имена пользователей и пароли, то скорее всего для чтения данных он воспользуется следующей конструкцией:
Необходимо отметить, что выражения Transact-SQL могут быть собраны вмсте в одну строку не изменяя своего значения - рассмотрим следующий пример:
Зачастую даже пользователь с низкими привелегиями имеет возможность создать таблицу в базе данных, или даже временную базу данных. Взломщик, таким образом, может выбрать все строки из этой таблицы, так же как и в предыдущем примере:
Нет необходимости говорить, что если злоумышленнику удается вызвать ошибку при обращении к базе данных, то их работа в разы упрощается./process_login.asp, line 35 |