Новая техника быстрого извлечения данных при SQL-инъекциях в MSSQL

Прежде всего хочу поделиться ценной ссылкой – http://www.indianz.ch/. Данный ресурс имеет огромный и постоянно обновляемый каталог утилит и программ, имеющих отношение к информационной безопасности и взлому – от полезных скриптов в несколько десятков строк до таких монстров как metasploit. Именно здесь я нашел PoC, реализующий способ, который позволяет извлекать таблицы целиком за один запрос при SQL-инъекциях в MSSQL.

Новая техника называется SFX-SQLi – Select For Xml SQL Injection. В ее основе лежит применение оператора FOR XML для SELECT, который впервые появился в MSSQL 2000 и служит для преобразования результата выборки в формат данных XML, при чем на выходе всегда будет одна строка. Пример:

	SELECT *
	FROM [test].[dbo].[articles]
	FOR XML RAW

sfxsqli1

Несмотря на то, что оператор FOR XML известен еще со времен SQL Server 2000, техника SFX-SQLi получила освещение лишь в феврале этого года в работе Daniel Kachakil. Тем не менее, некоторые специалисты указывают на упоминание применения FOR XML в SQL-инъекциях еще в 2007 году.

Новая техника не имеет ограничений на максимальную длину возвращаемых данных, как это происходит в MySQL при использовании функции GROUP_CONCAT(), поэтому применение SFX-SQLi имеет смысл только в UNION-векторах, так как в SQL-инъекциях, основанных на ошибках (error-based SQLi), длина строки с ошибкой имеет ограничение на длину. Алгоритм проведения атаки во многом схож с традиционным:

  1. Определение количества колонок в исходном запросе:
    • С использованием оператора ORDER BY
    • С использованием операторов HAVING и GROUP BY
    • Последовательный перебор колонок в UNION SELECT
  2. Определение типов данных каждой колонки
    Последовательная подстановка строкового значения в поля таблицы до тех пор, пока не будет найдено поле с выводом. Замечу, что для предотвращения ошибок, связанных с типом данных ntext, следует использовать конструкцию UNION ALL SELECT.
  3. Получение имен таблиц из системной базы данных information_schema
  4. Получение содержимого таблиц с помощью подзапроса SELECT … FOR XML
    Здесь стоит отметить, что FOR XML возвращает данные о структуре таблиц, поэтому знать имена колонок не нужно

Пример SQL-запроса с внедренным кодом, реализующим SFX-SQLi:

	SELECT *
	FROM [test].[dbo].[articles]
	WHERE [id] = 1
	UNION 
	ALL SELECT null, (
		SELECT  [username] 
		       ,[password] 
		FROM [test].[dbo].[users] 
		FOR XML RAW
	), null

Большинство языков программирования имеют встроенные средства по работе с XML, именно поэтому автоматизация SFX-SQLi довольно тривиальна, в чем можно убедиться, просмотрев исходные коды PoC (написан на VB.NET). Утилита также реализует метод извлечения данных, позволяющий избежать потерь при больших объемах и высокой нагрузке SQL-сервера.

К сожалению, реализация FOR XML в MSSQL 2000 отличается от более новых версий, что выражается в ряде ограничений. Прежде всего это отсутствие поддержки FOR XML в подзапросах. Более подробная информация доступна в официальной документации SQL Server 2000.

Join the Conversation

12 Comments

  1. То есть на серверах старше 2000, эта тема не пашет, так? (я имею ввиду через инъект)

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

  3. Спасибо! Заинтересовало. Всё больше убеждаюсь в том что для проведения инъекций не нужно никаких особенных знаний. Достаточно хорошо разбираться в SQL-синтаксисе и операторах инъектируемой СУБД.

  4. @Best
    как раз наоборот: в MSSQL 2005/2008 будет отлично работать, а вот в MSSQL 2000 результат подзапроса с FOR XML вставить не удастся.

    @Kuzya
    знания SQL-синтаксиса и есть особенные 🙂

  5. Тема пашет на ура. Меня она уже спасла. В слепом инъекте приходилось переберать таблицы через NOT IN, запрещены одинарные кавычки, и имя каждой таблицы в NOT IN было настолько длинный, что со временем, сервер переставал принимать запросы, из-за очень длинного URL. Приходилось очень сильно извращаться, чтоб достать таблицы. А теперь все одной строкой выдается. Спасибо Raz0r.

  6. А есть ли у FOR XML RAW дом параметры? чтоб например изменить имя тега, или еще что-нибудь?

  7. @Best
    в NOT IN() можно вставлять подзапрос:

    SELECT TOP 1 username, password FROM users WHERE id NOT IN(SELECT TOP x id FROM users)

    А есть ли у FOR XML RAW дом параметры?

    есть:

    SELECT username, password FROM users FOR XML RAW 'tagname'

    или использовать в качестве имени тэга название колонки:

    SELECT username, password FROM users FOR XML AUTO

    более подробно в документации

  8. Спасибо за инфу, как всегда компетентно и в тему 🙂

  9. Как раз помогло этот вариант …
    спасибо за инфу

  10. Raz0r, не подскажешь удобный xml парсер под это дело для win?

Leave a comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.