Источник: https://github.com/AnaktaCTF/CTF/blob/main — WEB/SQL Injection.md

Авторы данной страницы: Шуруб Игорь (https://github.com/igorshurub) и Заднепрянская Алисия (https://github.com/ZadnepryanskayaAlicia)

Теория

Историческая справка

SQL-инъекции были впервые детально описаны в конце 90-х годов, когда веб-приложения начали массово использоваться для предоставления услуг в интернете. По мере того как всё больше компаний стало полагаться на веб-технологии и базы данных, уязвимость SQL-инъекций начала активно эксплуатироваться злоумышленниками.
Согласно докладам различных исследовательских групп (включая OWASP), SQL-инъекции стабильно входят в топ самых опасных уязвимостей.

Определение

SQL-инъекция (SQL Injection) — это один из самых распространённых и опасных видов атак на веб-приложения, при котором злоумышленник может встраивать вредоносный SQL-код в запросы к базе данных. Цель таких атак — получить несанкционированный доступ к данным, изменить их или даже полностью удалить.

Как это работает?

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

  • SELECT * FROM users WHERE username = 'имя' AND password = 'пароль';

Если в поле ввода злоумышленник введёт не просто имя, а что-то вроде:

  • имя' OR '1'='1

SQL-запрос изменится следующим образом:

  • SELECT * FROM users WHERE username = 'имя' OR '1'='1' AND password = 'пароль';

Что здесь произошло? Вторая часть запроса OR '1'='1' всегда возвращает истину. Это значит, что запрос пропустит проверку и даст доступ даже без правильного имени пользователя или пароля.

Виды SQL-инъекций:

  • Простая инъекция: когда злоумышленник напрямую добавляет свой код в поле ввода. Это может привести к раскрытию данных или выполнению произвольных команд.

  • Слепая инъекция: когда сайт не возвращает ошибку или данные напрямую, но злоумышленник может делать выводы на основе поведения приложения (например, задержки в ответах).

  • Инъекция в условие: злоумышленник может добавлять в запрос логические операторы (как в примере выше), чтобы заставить систему принять его данные.

  • Error-based инъекция: тип инъекции, при котором злоумышленник провоцирует возникновение ошибок в базе данных и извлекает из них ценную информацию (например, названия полей таблиц).

  • Union-based инъекция: злоумышленник использует оператор UNION, чтобы «добавлять» свои собственные SELECT-запросы и получать дополнительную информацию из других таблиц базы данных.

Ошибки, облегчающие SQL-инъекции

  • Формирование запросов «на лету» (dynamic SQL): если приложение формирует строку запроса, конкатенируя неподготовленные входные данные и SQL-код, это даёт злоумышленнику пространство для манёвра.

  • Отсутствие механизма экранирования/валидации: многие SQL-инъекции возникают просто потому, что специальным символам (', ;, --, # и т.д.) не уделяется должное внимание или они не экранированы.

  • Избыточные права: если у приложения есть права на DROP/CREATE/ALTER и т.п., то успешная инъекция может привести к полному уничтожению базы данных.

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

Как защититься от SQL-инъекций?

  1. Используйте подготовленные запросы (prepared statements): преимущество таких запросов в том, что они отделяют SQL-код от данных. Даже если злоумышленник попытается вставить фрагмент SQL-кода в поле ввода, он будет восприниматься как обычная строка, а не как часть запроса.

  2. Используйте ORM (Object-Relational Mapping): фреймворки уровня ORM (такие как Hibernate для Java, SQLAlchemy для Python, Doctrine для PHP и т.д.) упрощают работу с базой данных и снижают риск неконтролируемого формирования SQL-запросов.

  3. Валидация ввода: проверяйте и фильтруйте данные, которые вводят пользователи. Например, убедитесь, что вместо букв они не вставляют SQL-код. Регулярные выражения, списки допустимых символов, проверка длины и формата — всё это должно применяться при обработке пользовательского ввода.

  4. Ограничьте права доступа к базе данных: приложение должно иметь только минимальные необходимые права для выполнения своих функций. Если для чтения данных достаточно SELECT, не стоит выдавать права на изменение структуры таблицы (ALTER, DROP).

  5. Использование Web Application Firewall (WAF): WAF может анализировать входящие запросы и блокировать потенциально опасные. Это не панацея, но даёт дополнительный уровень защиты.

  6. Разделение логики и данных (бизнес-логики и SQL-кода): старайтесь, чтобы логика приложения не была «зашита» непосредственно в SQL-запросы. Любое усложнение SQL-запросов повышает риск пропуска ошибок.

  7. Регулярные тесты и аудит кода: периодически проводите пентест и ревизию кода, чтобы вовремя находить уязвимости. Инструменты статического анализа кода могут помочь отлавливать проблемные места ещё на этапе разработки.

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

  1. Инструменты сканирования уязвимостей: такие как SQLMap, Burp Suite, ZAP (OWASP Zed Attack Proxy) могут автоматически обнаруживать наличие SQL-инъекций.

  2. Логирование и мониторинг: внедряйте системы логирования (например, ELK Stack — Elasticsearch, Logstash, Kibana), чтобы оперативно замечать аномальные SQL-запросы.

  3. Тестовые базы данных и песочницы: используйте тестовые окружения и тренировочные стенды (подобные Hackerdom, DVWA, bWAPP и другие), чтобы отработать навыки и протестировать свои приложения без риска повредить реальную инфраструктуру.

Практика:

Теперь давайте закрепим теорию на практике и попробуем выполнить несколько упражнений по эксплуатированию SQL-инъекций, для этого воспользуемся следующим бесплатным сервисом: (https://sql.training.hackerdom.ru/) Попробуйте выполнить их самостоятельно ниже будет разбор данных заданий.

Задание 1.

image

Пояснение: выполняем запрос к БД users, выводя данные для строки 12, обращаем внимание, что ссылка выглядит следующим образом: https://sql.training.hackerdom.ru/1.php?text=SELECT+*+FROM+users+WHERE+id%3D12

Задание 2.

image

Пояснение:
Нам дана подсказка использовать кавычку, этим и воспользуемся.

То есть мы пытаемся получить данные из таблицы users для пользователя с id=2 или с login=1, а также для пользователя с id=9, при этом id=9 отделено кавычкой с одной стороны и закрывается кавычкой оригинального SQL-запроса. Поскольку пользователя с id=-1 не существует, никаких данных по нему мы не получаем, но id=9 существует в базе. В итоге запрос возвращает две строки — одну для пользователя с id=2 и другую для пользователя с id=9. Данная уязвимость реализуема потому что вводимые (входные) данные никак не фильтруются. https://sql.training.hackerdom.ru/2qnbutn.php?text=text%3D-1%27+or++id%3D%279

Задание 3.

image

Пояснение:
Видим, что по сравнению с предыдущим заданием присутствует условие limit 1 - ограничение на вывод в 1 строку. Выйти из этой ситуации можно следующим образом, добавляем комментарий, например --hello, limit 1 уберет его (комментарий), но при этом выведет нужную нам строку с id=13. https://sql.training.hackerdom.ru/3sdjjy.php?text=text%3D%27-1+or++id%3D%2713+%27--+123

Задание 4.

image

Пояснение:
Нам дано две таблицы и запрос по умолчанию будет выполнен не к той таблице, которая нам нужна. Чтобы выйти из данной ситуации воспользуемся оператором UNION, позволяющий выполнять запросы к разным таблицам в рамках одного запроса. Для использования объединения запросов важно, чтобы количество полей во всех объединённых запросах совпадало. Также учитываем, что по условию нам нужно получить данные из таблицы sercet, где значение поля ggg равно abc. https://sql.training.hackerdom.ru/4qjqhweh.php?text=-1%27+union+select+*+from+secret+where+ggg%3D%27abc%27+--+123

Вывод:

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