Sql ін'єкція в mysql сервері
SecurityLab.ru спільно з Навчальним центром "Інформзахист" і інтернет магазином ПО Softkey.ru організовує конкурс на налучшую статтю за тематикою інформаційної безпеки.
SQL injection - вразливість, що виникає як наслідок недостатньої перевірки прийнятих від користувача значень, в скрипті або програмі. Я буду розглядати ін'єкції в MySQL базі даних. Ця база даних є однією з найпоширеніших. Якщо не обумовлено окремо, то вважається, mysql ін'єкція можлива в php скрипт.
Виявлення наявності SQL ін'єкції.
Найчастіше, про наявність SQL ін'єкції можуть сказати помилки, явно вказують, що сталася помилка в sql запиті. У той же час про наявність помилки в SQL запиті можна судити і за непрямими ознаками.
Аналіз БД через MySQL ін'єкцію.
Наявність докладних повідомлень про помилки, з текстом SQL запиту, в якому сталася помилка зведе труднощі експлуатації SQL ін'єкції до мінімуму. Однак, багато чого можна зробити навіть якщо повідомлень про помилки виводяться взагалі.
Слід взяти до відома той факт, що навіть якщо текст помилки не виводитися, можна все одно однозначно судити про те, сталася помилка, чи ні (наприклад, запит повернув порожній результат).
Зокрема, можлива ситуації, коли при помилку, повертається код відповіді 500, або редирект на головну сторінку, в той час як при порожньому результаті запиту буде повернута порожня сторінка.
Для того, щоб виявити ці другорядні ознаки, слід скласти http запити, про які відомо, що призведе до правильного (але повертає порожній висновок) SQL запиту, і який приведе до невірного SQL запиту. Наприклад, при не фільтровану параметрі id
Тепер, знаючи як відрізнити помилкові запити від порожнього, починаємо послідовно витягувати інформація про запит і базі даних.
Розглянемо випадок, коли ін'єкція відбувається після where. Якщо ми розглядаємо MySQL базу даних, то отримання інформації з бази даних може бути можливим тільки, якщо сервер має версію 4. *, ті є можливість вставити в запит union
1) кількість полів між select і where
Пробуємо послідовно, поки не отримаємо вірний запит:
більше, того, якщо немає можливість відокремити невірний запит від возвратившего порожній результат, можна зробити так:
Для цього, нам достатньо вміти відокремлювати правильний запит від неправильного, а це можливо завжди, якщо є факт наявності SQL ін'єкції.
Після того, як ми отримаємо правильний запит, кількість null, буде дорівнює кількості полів між select і where
2) номер стовпчика з висновком. Нам знадобиться знати, в якому за рахунком стовпці відбувається висновок на сторінку.
При цьому, якщо виводитися на сторінку кілька параметрів, то краще знайти той, який, як здається, має найбільший розмір типу даних (text найкраще), як наприклад, опис, текст статті і тд. Шукаємо його:
І до тих пір, поки не побачимо слово test в потрібному нам місці.
Слід звернути увагу, що в цьому випадку один з подібних запитів обов'язково поверне непорожнє значення.
Тут можна наткнуться на підводний камінь: в скрипті, можливо є перевірка на Не порожнечі одного з параметрів (наприклад, id) тут доведеться скористатися властивістю MySQL, числовий тип може бути приведений до будь-якого типу даних, без виникнення помилки, причому так, що збереже своє значення.
Цей же фокус пройде і там, де лапки екрануються.
Тепер можна перебирати імена таблиць.
Правильні запити будуть відповідати існуючим іменах таблиць. Напевно, цікаво буде перевірити на існування таблиць users, passwords, regusers і тд і тп.
у нас вже достатньо інформації щоб скласти такий запит.
У разі, якщо є права на select з бази даних mysql, то цей запит поверне нам хеш пароля, який в більшості випадків легко розшифрують. Якщо виводитися тільки один рядок із запиту (наприклад, замість тіла статті), то можна пересуватися по рядках
Крім того можна дізнатися багато цікавого:
5) назви стовпців в таблиці
текст файлів через MySQL ін'єкцію.
Якщо користувач, під яким здійснюється доступ до бд, має права file_priv, то можна отримати текст довільного файлу
запис файлів в веб директорію (php shell).
Як показала практика, якщо ми маємо права file_priv, директорію, доступну на запис всім користувачам, доступну крім того з web, (іноді, директорії upload, banners і тд.), А так само знаємо ім'я хоча б однієї таблиці (mysql.user, наприклад зійде, якщо є доступ до mysql базі даних), то можна вивантажити довільний файл на сервер використовуючи ін'єкцію подібного типу.
При цьому конструкція from table1 обов'язкове.
Якщо крім того, на сайті є вразливість, що дозволяє виконувати довільні файли на сервері, (include ( "/ path / $ file.php")), то, в будь-якому випадку можна закачати php shell, наприклад в директорію / tmp /, і потім підчепити цей файл звідти за допомогою вразливості в include.
ін'єкція послеlimit.
Досить частини можливість SQL ін'єкції виникає всередині параметра, що передається до limit. Це може бути номер сторінки і тд і тп.
Практика показує, що все вищесказане може бути застосовано і в цьому випадку.
MySQL коректно реагує на запити типу:
Select ... limit 1,2 union select ....
Select ... limit 1 union select ....
Якщо необхідно щоб перший підзапит повернув порожній результат, необхідно штучно задати великі зміщення для першого запити:
Select ... limit 99999,1 union select .... Або, Select ... limit 1,0 union select ....
деякі "підводні камені".
Найбільш частим підводним каменем може виявитися включення магічних лапок в конфігурації php. У разі строкових параметрів це взагалі дозволить уникнути можливості SQL ін'єкції, а в разі цілий (дрібних) параметрів, в подібних запитах неможливо буде використовувати лапки, а отже і рядки.
Частково, вирішити цю проблему допоможе нам функція char, яка повертає рядку за кодами символів. наприклад
Єдине обмеження. У разі, якщо хочеться зробити into outfile, то а як ім'я файлу, необхідно передати ім'я файлу в лапках. into outfile char (.) видає помилку.
Здавалося б, цей модуль веб сервера apache, унеможливлює експлуатацію уразливості SQL ін'єкції. Однак, при деяких конфігураціях PHP і цього модуля, атаку можна провести прозоро для цього модуля.
Конфігурація за замовчуванням модуля mod_security не фільтрує значення, передані як cookie. Одночасно, в деяких випадках, а також в деяких конфігураціях за замовчуванням php, змінні cookie реєструються автоматично.
Таким чином, зловмисні значення змінних, абсолютно прозоро для mod_security можна передати як cookie значення.
DOS в MySQL ін'єкції.
Якщо немає можливості застосування union в запиті, наприклад, MySQL має версію 3. *, то, проте, ін'єкцію можна експлуатувати, наприклад, для того, щоб змусити сервер бази даних вичерпати всі свої ресурси.
Для цього, будемо використовувати функцію BENCHMARK, яка повторює виконання виразу expr задану кількість разів, вказане в аргументі count. В якості основного вираження візьмемо функцію, яка сама по собі вимагає деякого часу. Наприклад, md5 (). Як рядки візьмемо current_date, щоб рядок не містила лапок. Функції BENCHMARK можна вкладати один в одного. І так, складаємо запит:
1000000 запитів md5 виконуються (в залежності від потужності сервера), приблизно 5 секунд, 10000000 будуть виконуватися близько 50 секунд. Вкладений benchmark буде виконуватися дуже довго, на будь-якому сервері. Тепер залишиться відправляти до декількох десятків подібних http запитів в секунду, щоб ввести сервер в безпробудний даун.
інші типи MySQL ін'єкції.
Фільтрувати цілі значення для цілих параметрів і лапки для строкових параметрів часом недостатньо. Іноді до незапланіруемой функціональності може привести застосування% і _ спеціальних символів всередині like запиту. наприклад:
mysql_query ( "select id from users where password like '" .addslashes ($ password). "' and user like '" .addslashes ($ user). "'");
в цьому випадку до будь-якому користувачеві підійде пароль%
У деяких випадках, СКЛ ін'єкція можлива навіть в параметрі, який перетворюється методами mod_rewrite модуля apache, до GET параметру скрипта.
Наприклад, скрипти типу /news/127.html перетворюються до /news/news.php?id=127 наступним правилом: RewriteRule ^ / news / (. *) \. Html $ "/news/news.php?id=$1"
Це дозволить передати зловмисні значення параметра скрипту. Так, наприклад /news/128-1.html
коротко про захист.
Для захисту від усього вищесказаного досить дотримуватися декількох простих правил.
1) для цілих і дробових величин, перед їх використанням в запиті досить привести величину до потрібного типу.
Замість цього можна вставити систему стеження за тестуванням на SQL ін'єкцію.
// пишемо в лог про спробу
2) для строкових параметрів, які не використовуються в like, regexp і тд, екрануючи лапки.
3) в рядках, які передбачається використовувати всередині like, regexp і тд, необхідно так само заекранувати спеціальні символи, що застосовуються в цих операторах, якщо це необхідно. В іншому випадку, можна задокументувати використання цих символів.
Компанія SoftKey - це унікальний сервіс для покупців, розробників, дилерів і афіліат-партнерів. Крім того, це один з кращих Інтернет-магазинів ПО вУкаіни, Україні, Казахстані, який пропонує покупцям широкий асортимент, безліч способів оплати, оперативну (часто миттєву) обробку замовлення, відстеження процесу виконання замовлення в персональному розділі, різні знижки від магазину і виробників ПЗ .