SQL Insert Injection в одном интернет магазине

- КиТ :: Будь в СЕТИ!

Давно на Хабре не звучали истории про SQL injection

А уж рассказов из жизни про SQL INSERT injection вообще очень мало. Поэтому расскажу свою. Начало

На попытку отправить отчёт об ошибке через форму обратной связи, на пару секунд на странице появилась ошибка, в которой угадывался голос MySQL. Поэтому я открыл консоль браузера, повторил запрос и заглянул в ответ сервера: Итак, найдена SQL insert injection в интернет-магазине, которому я отдал свои кровные.

В первую очередь, я нашёл пару достойных материалов по теме. Самый интересный из них . Благодаря ему, взгляд упал на функцию , которая появилась в MySQL 5.1 (т.е. если не сработает, то можно будет сделать соответствующий вывод:UpdateXML(xml_target, xpath_expr, new_xml)

Смысл использования функции в том, чтобы создать заранее неверный XPath Expression (второй аргумент). Для этого Osanda предлагает делать конкатенацию с символом "~". Что ж, проверяем в локальном MySQL:

Да, работает. Теперь формируем тело сообщения для нашего магазина. Первый получившийся запрос выглядел так:

Потом я немного подумал, и сократил его до:

Ответ интернет-магазина:

Сработало! Всё крутится на MariaDB 5.5. Отличия от MySQL минимальны, версия 5.5 поддерживает множество полезных операторов и функций. Пройдясь по типичным для подобных ситуаций данным, я вытащил следующую информацию:

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

Но, разумеется, получил отказ:

Теперь нужно получить список таблиц в текущей БД. Для этого используем доступную с MySQL 5.0 мета-таблицу :

Меняя первый параметр в операторе LIMIT, можно перебрать все текущие таблицы. Меня хватило на Решаю автоматизировать. Речь идёт об AJAX POST-запросе и на сайте включён jQuery. Нам нужно отправлять сразу несколько запросов — это асинхронная работа, так что я решил сразу подгрузить библиотеку и попробовать с её помощью получить желаемый список таблиц. Получилась

Таким образом я получил список первых 20 таблиц, но понял, что одновременно посылать множество запросов нехорошо (на последние из них сервер отвечал в течении 20 секунд). Решил, что не стоит угрожать стабильности работы магазина и поменял функцию async.times на async.timesSeries, чтобы каждый следующий запрос отправлялся после получения ответа на предыдущий. Поменял параметр lim с 20 на 200 и ушёл за чашечкой чая. А когда вернулся, в моём распоряжении был Из этого списка стало понятно два факта: стоит Joomla и объем полезной информации ограничен 32-мя символов. Причём первых из них ("~") убрать мы не можем, значит у нас всего 31 символ. Что ж, не так уж мало. Было много интересных таблиц (3 таблицы *users и aabb_jshopping_coupons). Сначала я исследовал структуру таблицы users, модифицируя переменную injection: Потом её содержимое с помощью функции :

Но каждая запись получалась длинной ровно в 31 символ из-за избытка информации, поэтому сначала нужно было преодолеть это ограничение. Для этого я решил воспользоваться функцией , а получение новой порции данных реализовать через рекурсию. В итоге получился

По такому алгоритму данные будут вытягиваться ещё дольше, зато целиком и полностью. Теперь можно создавать сами запросы отдельно от общей логики:

И первые 30 строк таблицы users в консоли браузера.

Далее опишу лишь наиболее интересные моменты.

Купоны, в т.ч. для Хабра и Гиктаймс, оказались просроченными. Да и свою игрушку я уже купил. Все таблицы в полную длину для всех доступных баз данных:

Как оказалось, не только интернет-магазин A.B.ru работает на Joomla, но и такой же магазин B.ru на ней же и на том же сервере. Но перспектив от исследования ещё одного сайта я не увидел. В конце концов, моей целью не было получение наживы. Поэтому я решил, что читать данные хорошо, но…

Можно ли что-нибудь записать?

Как оказалось, нет. Так как нам доступны только . Решил, что стоит всё же попробовать работу с файлами. Но чтобы не навредить интернет-магазину своими неосторожными действиями, перенесу повествование на собственную машину, где провёл

Написал в интернет-магазин

День следующий

Ответа на второе письмо нет. Ну и ладно. Ровно через сутки зашёл на ту же страницу с формой обратной связи. Теперь в поле ввода фильтруются все спец. символы, разумеется, на стороне клиента. Что ж, молодцы, остаётся надеяться, что это просто заплатка на время исправления реальных ошибок. А пока решил продолжить исследования — хочется разобраться до конца.

Как оказалось, полезная часть текста об ошибке в ответе от MariaDB не всегда 32 символа. При попытке получить текст на русском получается выудить лишь 16 символов. Проверил на MySQL — то же самое. Значит, ограничение не в 32 символа, а в 32 байта. Что ж, переделал утилиту :

Теперь программа не зависит от константной длины, а продолжает искать конец строки, пока не будет возвращена ошибка (т.е. ответ с текстом ошибки не в том формате, в котором программа его ожидает). Да, чуть больше запросов. Зато нет проблемы с текстами в не latin кодировках. Кроме того, избавился от зависимости от библиотеки async (она присутствовала для скорости разработки и апробирования результатов). А так же добавил возможность не задавать конкретное количество строк в таблице, которые нужно получить, а рекурсивно получать все доступные (до ошибки). А так же добавил вывод результатов работы прямо на страницу сайта, чтобы легче было просматривать.

Возможны ли ужасные последствия такой уязвимости?

Как мы уже выяснили, записать что-то в файл или читать из него не получится даже если у пользователя есть на то права. Зато у нас в кармане таблицы с паролями и эл. адресами всех пользователей и администраторов. Лично я подбирать их и входить на сайт даже не пытался — мне это ни к чему. Тем не менее, можно констатировать факт возможности чтения любой информации из текущей базы данных, а в нашем случае и из соседней.

Другая открываемая подобной уязвимость возможность — это атака DoS, например, вот такой подстановкой: Через неделю

Решил написать

Ответа как и раньше не последовало.

P.S.: Статья опубликована через 13 дней с момента обнаружения уязвимости. Представители интернет-магазина на связь не выходят.

ПодпискаБудь в СЕТИ! Новости социальных сетей - всегда актуальное
 
Группы: ВК | OK | Tg