sql injection что это
Что такое SQL инъекция: изучаем на примерах
В этой статье мы рассмотрим методы, используемые при SQL-инъекциях и способы защиты веб-приложений от таких атак.
Как работает SQL-инъекция
Рассмотрим простое веб-приложение с формой входа. Код HTML-формы приведен ниже:
Предположим, что запрос для проверки идентификатора пользователя на стороне сервера выглядит следующим образом:
Примечание : вам нужно будет написать инструкции SQL :
Шаг 1. Введите этот код в левую панель:
Шаг 2. Нажмите кнопку « Build Schema ».
Шаг 3. Введите приведенный ниже код в правой панели:
Шаг 4. Нажмите « Run SQL ». Вы увидите следующий результат:
Предположим, что пользователь предоставляет адрес электронной почты admin@admin.sys и 1234 в качестве пароля. Запрос, который должен быть выполнен в базе данных, может выглядеть следующим образом:
Приведенный выше код SQL инъекции примера может быть обойден путем выведения в комментарии части пароля и добавления условия, которое всегда будет истинным. Предположим, что злоумышленник подставляет следующие данные в поле адреса электронной почты:
и xxx в поле пароля.
Сгенерированный динамический оператор будет выглядеть следующим образом:
Хакерская активность: SQL-инъекции в веб-приложения
Оно обеспечивает базовую безопасность, такую как санация поля электронной почты. Это означает, что приведенный выше код не может использоваться для обхода данного механизма.
Чтобы обойти его, можно использовать поле пароля. На приведенной ниже диаграмме показаны шаги, которые нужно выполнить:
Предположим, что злоумышленник предоставляет следующие данные:
Шаг 1 : Вводит xxx@xxx.xxx в качестве адреса электронной почты;
Шаг 2 : Вводит xxx’) OR 1 = 1 — ] ;
Нажимает кнопку « Отправить ».
Он будет направлен в панель администрирования. Сгенерированный запрос будет выглядеть следующим образом:
На приведенной ниже диаграмме показано, как запрос был сгенерирован:
Как правило, злоумышленники для достижения своих целей пытаются применить в атаке с использованием SQL инъекций несколько различных методов.
Другие типы атак с использованием SQL-инъекций
SQL-инъекции могут нанести гораздо больший ущерб, чем вход в систему в обход механизма авторизации. Некоторые из таких атак могут:
Инструменты для автоматизации SQL-инъекций
Защита от SQL инъекций
Вот несколько простых правил, которые позволят защититься от атак с использованием SQL-инъекций :
Хранимые процедуры — они могут инкапсулировать SQL-запросы и обрабатывать все входные данные в качестве параметров.
Хакерская активность: использование для SQL-инъекций Havij
В этом практическом сценарии мы собираемся использовать программу Havij Advanced SQL Injection для сканирования уязвимостей сайта.
Упомянутый выше инструмент можно использовать для оценки уязвимости / приложения.
Заключение
Пожалуйста, опубликуйте свои комментарии по текущей теме материала. За комментарии, дизлайки, подписки, лайки, отклики огромное вам спасибо!
Пожалуйста, оставляйте свои комментарии по текущей теме статьи. Мы крайне благодарны вам за ваши комментарии, дизлайки, отклики, лайки, подписки!
SQL инъекции. Проверка, взлом, защита
SQL инъекция — это один из самых доступных способов взлома сайта.
Суть таких инъекций – внедрение в данные (передаваемые через GET, POST запросы или значения Cookie) произвольного SQL кода. Если сайт уязвим и выполняет такие инъекции, то по сути есть возможность творить с БД (чаще всего это MySQL) что угодно.
Как вычислить уязвимость, позволяющую внедрять SQL инъекции?
Если при заходе на данные страницы появляется ошибка, значит сайт уязвим на SQL инъекции.
Пример ошибки, возникающей при проверке уязвимости
Возможные SQL инъекции (SQL внедрения)
1) Наиболее простые — сворачивание условия WHERE к истиностному результату при любых значениях параметров.
2) Присоединение к запросу результатов другого запроса. Делается это через оператор UNION.
3) Закомментирование части запроса.
Практика. Варианты взлома сайта с уязвимостью на SQL внедрения
Итак, у нас есть уже упоминавшийся сайт test.ru. В базе хранится 4 новости, 3 из которых выводятся. Разрешение на публикацию новости зависит от парметра public (если параметр содержит значение 1, то новость публикуется).
Список новостей, разрешённых к публикации
При обращении к странице test.ru/?detail=4, которая должна выводить четвёртую новость появляется ошибка – новость не найдена.
В нашем случае новость существует, но она запрещена к публикации.
Но так как мы уже проверяли сайт на уязвимость и он выдавал ошибку БД, то пробуем перебирать возможные варианты запросов.
В адресной строке плюс (+) выполняет роль пробела, так что не пугайтесь
В итоге удача улыбнулась и два запроса (первый и третий) вернули нам детальное описание четвёртой новости
Разбор примера изнутри
За получение детального описания новости отвечает блок кода:
$detail_id=$_GET[‘detail’];
$zapros=»SELECT * FROM `$table_news` WHERE `public`=’1′ AND `id`=$detail_id ORDER BY `position` DESC»;
Глядя на запрос, получаемый при обращении к странице через test.ru/?detail=4+OR+1
SELECT * FROM `news` WHERE `public`=’1′ AND `id`=4 OR 1 ORDER BY `position` DESC
становится не совсем ясно, почему отобразилась 4-ая новость. Дело в том, что запрос вернул все записи из таблицы новостей, отсортированные в порядке убывания сверху. И таким образом наша 4-ая новость оказалась самой первой, она же и вывелась как детальная. Т.е просто совпадение.
Защита от SQL инъекций (SQL внедрений)
Защита от взлома сводится к базовому правилу «доверяй, но проверяй». Проверять нужно всё – числа, строки, даты, данные в специальных форматах.
Числа
Строки
$a=»пример текста с апострофом ‘ «;
echo addslashes($a); //будет выведено: пример текста с апострофом \’
Кроме этого существуют две функции, созданные именно для экранизации строк, используемых в SQL выражениях.
Это mysql_escape_string($str); и mysql_real_escape_string($str);.
Магические кавычки
Магические кавычки – эффект автоматической замены кавычки на обратный слэш (\) и кавычку при операциях ввода/вывода. В некоторых конфигурациях PHP этот параметр включён, а в некоторых нет. Для того, что бы избежать двойного экранизирования символов и заэкранизировать данные по-нормальному через mysql_real_escape_string($str);, необходимо убрать автоматические проставленные обратные слеши (если магические кавычки включены).
Проверка включённости магических кавычек для данных получаемых из GET, POST или Куков организуется через функцию get_magic_quotes_gpc(); (возвращает 1 – если магические кавычки включены, 0 – если отключены).
В закючении привожу код с полной экранизацией строк для записи в БД
if(get_magic_quotes_gpc()==1)
<
$element_title=stripslashes(trim($_POST[«element_title»]));
$element_text=stripslashes(trim($_POST[«element_text»]));
$element_date=stripslashes(trim($_POST[«element_date»]));
>
else
<
$element_title=trim($_POST[«element_title»]);
$element_text=trim($_POST[«element_text»]);
$element_date=trim($_POST[«element_date»]);
>
$element_title=mysql_real_escape_string($element_title);
$element_text=mysql_real_escape_string($element_text);
$element_date=mysql_real_escape_string($element_date);
Статья была подготовлена на основе практических навыков по защите веб-систем. Теория дело хорошее, но практика важнее и главное она работает.
внедрение кода SQL;
Внедрение кода SQL — это атака, во время которой вредоносный код вставляется в строки, которые позже будут переданы на экземпляр SQL Server для анализа и выполнения. Любая процедура, создающая инструкции SQL, должна рассматриваться на предмет уязвимости к внедрению кода, так как SQL Server выполняет все получаемые синтаксически правильные запросы. Даже параметризованные данные могут стать предметом манипуляций опытного злоумышленника.
Принцип действия атаки путем внедрения кода SQL
Основная форма атаки SQL Injection состоит в прямой вставке кода в пользовательские входные переменные, которые объединяются с командами SQL и выполняются. Менее явная атака внедряет небезопасный код в строки, предназначенные для хранения в таблице или в виде метаданных. Когда впоследствии сохраненные строки объединяются с динамической командой SQL, происходит выполнение небезопасного кода.
Атака осуществляется посредством преждевременного завершения текстовой строки и присоединения к ней новой команды. Поскольку к вставленной команде перед выполнением могут быть добавлены дополнительные строки, злоумышленник заканчивает внедряемую строку меткой комментария «—». Весь последующий текст во время выполнения не учитывается.
Следующий скрипт показывает простую атаку SQL Injection. Скрипт формирует SQL-запрос, выполняя объединение жестко запрограммированных строк со строкой, введенной пользователем:
Предположим, однако, что пользователь вводит следующее:
В этом случае запрос, построенный скриптом, будет следующим:
Если вставленный код SQL синтаксически верен, искаженные данные нельзя выявить программно. Поэтому необходимо проверять правильность всех вводимых пользователями данных, а также внимательно просматривать код, выполняющий созданные с помощью SQL команды на сервере. Рекомендуемые приемы программирования описываются в следующих подразделах этого раздела.
Проверка достоверности всех вводимых данных
Всегда проверяйте все данные, вводимые пользователем, выполняя проверку типа, длины, формата и диапазона данных. При реализации мер предосторожности, направленных против злонамеренного ввода данных, учитывайте архитектуру и сценарии развертывания приложения. Помните, что программы, созданные для работы в безопасной среде, могут быть скопированы в небезопасную среду. Рекомендуется следующая стратегия:
Не делайте никаких предположений о размере, типе или содержимом данных, получаемых приложением. Например, рекомендуется оценить следующее.
Как приложение будет вести себя, если пользователь по ошибке или по злому умыслу вставит MPEG-файл размером 10 МБ там, где приложение ожидает ввод почтового индекса?
Проверьте размер и тип вводимых данных и установите соответствующие ограничения. Это поможет предотвратить преднамеренное переполнение буфера.
Проверяйте содержимое строковых переменных и допускайте только ожидаемые значения. Отклоняйте записи, содержащие двоичные данные, управляющие последовательности и символы комментария. Это поможет предотвратить внедрение скрипта и защитит от некоторых приемов атаки, использующих переполнение буфера.
При работе с XML-документами проверяйте все вводимые данные на соответствие схеме.
Никогда не создавайте инструкции Transact-SQL непосредственно из данных, вводимых пользователем.
Для проверки вводимых пользователем данных используйте хранимые процедуры.
В многоуровневых средах перед передачей в доверенную зону должны проверяться все данные. Данные, не прошедшие процесс проверки, следует отклонять и возвращать ошибку на предыдущий уровень.
Внедрите многоэтапную проверку достоверности. Меры предосторожности, предпринятые против случайных пользователей-злоумышленников, могут оказаться неэффективными против организаторов преднамеренных атак. Рекомендуется проверять данные, вводимые через пользовательский интерфейс, и далее во всех последующих точках пересечения границ доверенной зоны.
Например, проверка данных в клиентском приложении может предотвратить простое внедрение скрипта. Однако если следующий уровень предполагает, что вводимые данные уже были проверены, то любой злоумышленник, которому удастся обойти клиентскую систему, сможет получить неограниченный доступ к системе.
Никогда не объединяйте введенные пользователем данные без проверки. Объединение строк является основной точкой входа для внедрения скрипта.
Не допускайте использование в полях следующих строк, из которых могут быть созданы имена файлов: AUX, CLOCK$, COM1–COM8, CON, CONFIG$, LPT1–LPT8, NUL и PRN.
По возможности отклоняйте вводимые данные, содержащие следующие символы:
Использование SQL-параметров безопасных типов
В этом примере параметр @au_id обрабатывается как буквенное значение, а не исполняемый код. Это значение проверяется по типу и длине. Если значение @au_id не соответствует указанным ограничениям типа и длины, то будет вызвано исключение.
Использование параметризованного ввода с хранимыми процедурами
Хранимые процедуры могут быть подвержены атакам SQL Injection, если они используют нефильтрованные входные данные. Например, следующий код является уязвимым:
Если используются хранимые процедуры, то в качестве их входных данных следует использовать параметры.
Использование коллекции Parameters с динамическим SQL
Если невозможно использовать хранимые процедуры, сохраняется возможность использования параметров, как показано в следующем примере кода:
Фильтрация ввода
Для защиты от атак SQL injection посредством удаления escape-символов можно также использовать фильтрацию ввода. Однако этот метод защиты не является надежным в связи с тем, что проблемы может создавать большое число символов. В следующем примере производится поиск разделителей символьных строк:
Предложения LIKE
Обратите внимание, что при использовании предложения LIKE подстановочные знаки по-прежнему нужно выделять escape-символами:
Просмотр кода на предмет возможности атаки SQL Injection
Упаковка параметров с помощью функций QUOTENAME() и REPLACE()
Убедитесь, что в каждой выбранной хранимой процедуре все используемые в динамическом Transact-SQL переменные обрабатываются правильно. Данные, поступающие через входные параметры хранимой процедуры или считываемые из таблицы, должны быть помещены в функции QUOTENAME() или REPLACE(). Помните, что значение @variable, передаваемое функции QUOTENAME(), принадлежит к типу sysname и имеет ограничение длины в 128 символов.
@переменная | Рекомендуемый упаковщик |
---|---|
Имя защищаемого объекта | QUOTENAME(@variable) |
Строка, содержащая не более 128 знаков. | QUOTENAME(@variable, »») |
Строка из > 128 символов | REPLACE(@variable,»», »»») |
При использовании этого метода инструкция SET может быть исправлена следующим образом:
Атака Injection, проводимая с помощью усечения данных
Любое присваивАՐܐސпеременной диݐАܐؑǐՑPڐސзначение Transact-SQL усекается, если оно не вмещается в буфер, назначенный для этой переменной. Если организатор атаки способен обеспечить усечение инструкции, передавая хранимой процедуре непредвиденно длинные строки, он получает возможность манипулировать результатом. Так, хранимая процедура, создаваемая с помощью следующего скрипта, уязвима для атаки Injection, проводимой методом усечения.
Передавая 154 знака в буфер, рассчитанный на 128 знаков, злоумышленник может установить новый пароль для sa, не зная старого пароля.
Усечение при использовании функций QUOTENAME(@variable, »») и REPLACE()
Если строки, возвращаемые функциями QUOTENAME() и REPLACE(), не умещаются в выделенном пространстве, они усекаются без взаимодействия с пользователем. Хранимая процедура, создаваемая в следующем примере, показывает, что может произойти.
Таким образом, следующая инструкция установит для паролей всех пользователей значение, переданное предыдущим фрагментом кода.
Возможно выполнить принудительное усечение строки, для чего нужно превысить выделенное для буфера пространство при использовании функции REPLACE(). Хранимая процедура, создаваемая в следующем примере, показывает, что может произойти.
Следующий расчет применим ко всем случаям.
Усечение при использовании функции QUOTENAME(@variable, ‘]’)
При сцеплении значений типа sysname рекомендуется использовать временные переменные достаточно больших размеров, чтобы они могли вмещать до 128 знаков на одно значение. По возможности функцию QUOTENAME() следует вызывать непосредственно внутри динамического Transact-SQL. Или же необходимый размер буфера можно рассчитать, как это показано в предыдущем разделе.
Базовые sql-инъекции в приложениях, использующих язык SQL. Руководство для чайников
Примечание переводчика
Данная работа является переводом части работы Chris Anley Advanced SQL Injection In SQL Server Applications. (прямая ссылка для скачивания)
В последующих статьях, при наличии свободного времени, данный перевод будет доведен до конца.
P.S. Перевод будет интересен более в образовательных и исторических целях.
Оригинальное название статьи: Продвинутые SQL-инъекции в приложениях, использующих язык 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 получает доступ к базе данных, чтобы авторизовать пользователя в каком-либо приложении.
Приведем код страницы, содержащей форму входа, в которую вводятся имя пользователя и пароль.
Первое знакомство с SQL-инъекциями
SQL-инъекции (SQL injection, SQLi, внедрение SQL-кода) часто называют самым распространённым методом атак на веб-сайты. Их широко используют хакеры и пентестеры в применении к веб-приложениям. В списке уязвимостей OWASP Топ-10 присутствуют SQL-инъекции, которые, наряду с другими подобными атаками, находятся на первом месте среди угроз, с которыми сталкиваются веб-проекты.
Несмотря на то, что SQL-инъекции существуют уже более 20 лет, этот метод атаки на веб-проекты всё ещё можно успешно применить для взлома тех веб-сайтов и приложений, создатели которых не реализовали в них соответствующие защитные механизмы.
Этот материал рассчитан на абсолютных новичков, на тех, кто ничего не знает о SQL-инъекциях. Начнём мы с разбора основ, в которых необходимо ориентироваться перед разговором о SQLi. А именно, сначала мы поговорим о реляционных базах данных. Потом — о SQL, и о формировании SQL-запросов. И наконец — о том, как работают SQL-инъекции, и о том, почему они так опасны для веб-приложений.
Реляционные базы данных
Прежде чем говорить о SQL (и о SQL-инъекциях), нам надо познакомиться с реляционными базами данных (БД).
В реляционной БД хранятся взаимосвязанные данные, которые часто размещаются в таблицах. Каждая таблица содержит набор столбцов и строк.
Беглый взгляд на эту таблицу позволяет сделать вывод о том, что в ней, вероятно, хранятся учётные данные пользователей некоей системы. После того, как пользователь вводит имя и пароль в форме аутентификации, веб-приложение сверяет эти данные с вышеприведённой таблицей. Именно после того, как данные пользователя найдены (или не найдены) в таблице, приложение узнаёт о том, следует ли, например, дать этому пользователю возможность работать с ресурсами проекта, предназначенными только для зарегистрированных пользователей.
Это — лишь простой пример. Реляционные базы данных обычно представляют собой гораздо более сложные конструкции, в состав которых входит множество таблиц, в каждой из которых имеется много атрибутов и записей (иногда их количество исчисляется миллионами). Таблицы могут быть связаны с другими таблицами.
На этом мы закончим разговор о реляционных базах данных, так как этого достаточно для того чтобы разобраться в том, о чём речь пойдёт дальше.
SQL (Structured Query Language, язык структурированных запросов) — это язык, который предназначен для работы с реляционными БД. С его помощью, взаимодействуя с базой данных, можно просматривать, добавлять, обновлять, удалять данные.
▍Основные SQL-выражения
Веб-приложение взаимодействует с базой данных, пользуясь SQL-выражениями. Каждое такое выражение начинается с некоей команды.
Вот пример, который поможет нам разобраться в синтаксисе подобных выражений:
За командой SELECT идёт символ звёздочки ( * ). Тут он олицетворяет все столбцы таблицы. Это значит, что мы хотим извлечь данные из всех столбцов.
Если вы хоть немного понимаете английский, то ключевое слово FROM в дополнительных пояснениях не нуждается.
И, наконец, users — это имя таблицы, из которой мы хотим извлечь данные.
Если «перевести» вышеприведённое SQL-выражение на обычный язык, то получится следующее:
Давайте теперь сделаем вышеописанное SQL-выражение немного интереснее:
Пока то, о чём мы тут говорим, может показаться не таким уж и интересным. Но это — лишь до тех пор, пока мы не добрались до следующего раздела, посвящённого SQL-инъекциям.
▍Команды и ключевые слова SQL
Теперь, в завершение этого раздела, хочу рассказать о некоторых наиболее часто используемых командах и ключевых словах SQL. Для того чтобы понять то, о чём речь пойдёт дальше, знать все эти команды и ключевые слова вам необязательно, но я настоятельно рекомендую вам поближе с ними познакомиться после того, как вы дочитаете эту статью.
SQL-инъекции
Как уже было сказано, SQL-инъекции — это разновидность атаки на веб-приложения. В ходе проведения такой атаки делается попытка модификация SQL-выражения, которое приложение отправляет базе данных. Выполняется атака путём подстановки особым образом подготовленных данных в поля ввода, которые может заполнять пользователь.
Для того чтобы вышесказанное стало бы понятнее — рассмотрим пример.
▍Простая атака с использованием SQL-инъекции
Предположим, имеется форма аутентификации, которая предлагает пользователю ввести в её поля имя и пароль. Приложение предоставляет пользователям доступ к закрытым ресурсам после проверки введённых данных. Если говорить точнее, то приложение отправляет к базе данных SQL-запрос, направленный на проверку наличия там тех данных, которые ввёл пользователь. Используемое при этом SQL-выражение может выглядеть примерно так:
Теперь представьте, что вместо того, чтобы ввести в поле формы имя, пользователь вводит туда следующее:
А затем, в качестве пароля, вводит произвольный набор символов (то, что будет введено в поле для пароля, значения не имеет; ниже мы с этим разберёмся).
После этого приложение формирует такое SQL-выражение:
Но выражение 1=1 всегда истинно, поэтому этот запрос приведёт к получению всех записей из таблицы.
Кроме того, так как два дефиса в SQL используются для оформления однострочных комментариев, всё, что идёт после них, окажется закомментированным, то есть — соответствующие команды базой данных обрабатываться не будут. Если выделить ту часть SQL-запроса, которая будет выполнена базой данных, то получится следующее:
База данных, обрабатывая этот запрос, вернёт список записей, не являющихся NULL-значениями, и, в результате, веб-приложение даст пользователю доступ к закрытым ресурсам.
Итоги
Мы рассмотрели лишь один пример SQL-инъекции. Но существует и множество других способов внедрения SQL-кода в веб-приложения. Если вы хотите посмотреть больше примеров — рекомендую взглянуть на этот материал, опубликованный на сайте Netsparker, и на этот материал с сайта PortSwigger.
Если вы хотите попрактиковаться в деле выполнения атак на веб-приложения с использованием SQL-инъекций — попытайте удачу в варгейме Natas на OverTheWire. Если вы не знаете о том, что это такое — вот моя статья об этом.
Как вы защищаете свои веб-проекты от SQL-инъекций?