Новая техника быстрого извлечения данных при 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.


12 комментариев

  1. Best, 14. апреля 2009, 22:54

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

     
  2. halkfild, 14. апреля 2009, 23:42

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

     
  3. Kuzya, 15. апреля 2009, 7:00

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

     
  4. Raz0r, 15. апреля 2009, 16:48

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

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

     
  5. Best, 16. апреля 2009, 1:30

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

     
  6. Best, 16. апреля 2009, 12:43

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

     
  7. Raz0r, 16. апреля 2009, 14:19

    @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. Beta, 23. июня 2009, 23:02

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

     
  9. FIXER, 23. апреля 2010, 18:59

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

     
  10. biggabr0, 10. мая 2010, 15:06

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

     
  11. Raz0r, 10. мая 2010, 16:45

    Я использую простой скрипт:
    http://pastebin.com/7zADLw6G

     
  12. biggabr0, 10. мая 2010, 17:24

    Спасибо.

     

Write a comment: