Перейти к содержимому
← Каталог php SQL Injection

UNION SQL Injection в поиске каталога

UNION-based SQL-инъекция через поиск товаров позволяет извлечь данные из таблицы пользователей.

mediumphpPro
Задача
# SQL Injection: UNION-based извлечение данных через поиск каталога ## Сценарий Перед вами PHP-приложение интернет-магазина SecureShop. На странице каталога есть форма поиска по названию товара: введённая строка попадает в условие `LIKE` SQL-запроса, и сервер возвращает страницу со списком найденных товаров. Реализация имеет ту же фундаментальную ошибку, что и в других задачах класса SQLi: значение из формы попадает в SQL-запрос **через строковую конкатенацию текста запроса**, без отделения данных от кода. Атакующий может управлять структурой запроса через содержимое поискового поля. Особенность этой задачи — обработчик **прямо отображает** результат запроса в HTML-ответе (карточки найденных товаров): атакующему доступен **прямой канал** вывода данных из БД. Это существенно мощнее blind-вариантов: один payload — и любые данные из БД попадают на страницу. Классическая техника для этого — объединение результатов через `UNION` оператор: к исходному запросу добавляется второй запрос, выбирающий нужные данные из любой другой таблицы; результаты обоих запросов склеиваются в одну выборку, и нужные данные приходят в ответе как «дополнительные товары» на странице каталога. В таблице пользователей хранятся логины и хеши паролей (включая `admin`), и у `admin`'а в каталоге есть необычный товар «CTF Flag», который дешёвый аккаунт `demo` купить не может — баланса не хватит. ## Что нужно понять - Каталог рендерит **массив строк** из БД в виде HTML-карточек. Если в массив попадут строки из другой таблицы, они тоже отрисуются как «карточки». - Поисковая форма вызывает обработчик каталога с параметром `q`. Этот параметр становится **частью SQL-кода**, а не данными — это и есть точка инъекции. - SQLite (СУБД лабы) поддерживает объединение выборок через оператор объединения двух SELECT'ов; число столбцов в обоих SELECT'ах должно совпадать. ## Уязвимый паттерн ```php $search = $_GET['q'] ?? ''; if ($search !== '') { // Конкатенация значения параметра q в текст SQL — данные становятся частью кода: $sql = "SELECT id, name, description, price, image FROM products WHERE name LIKE '%" . $search . "%'"; $stmt = $db->query($sql); } else { $stmt = $db->query('SELECT id, name, description, price, image FROM products'); } $products = $stmt->fetchAll(); // далее $products рендерится в шаблоне как массив HTML-карточек товаров ``` Значение `$_GET['q']` склеивается с фрагментом SQL `LIKE '%...%'`. Парсер БД получает уже склеенную строку и не отличает «искомое имя товара» от управляющих SQL-конструкций. Атакующий, контролирующий параметр `q`, может закрыть строковый литерал кавычкой, приписать `UNION SELECT ...` и «дополнить» выборку строками из любой другой таблицы — те уйдут в `$products` и отрисуются как обычные карточки. ## Цели 1. Подтвердите, что в форме поиска значения попадают в SQL **как часть синтаксиса**. Соберите классический payload объединения в два шага: сначала определите количество колонок в исходном запросе (через `ORDER BY` с возрастающим номером — пока не получите ошибку), затем подберите типы колонок, чтобы объединение не падало. 2. Через инъекцию извлеките хеш пароля пользователя `admin` из таблицы пользователей: значение придёт прямо на страницу каталога в виде «дополнительных» карточек товара. 3. Подберите пароль `admin`'а по хешу (или используйте известный — он словарный, см. подсказки). 4. Войдите как `admin`; купите «CTF Flag»; заберите CTF-флаг со страницы профиля. ## Данные | Параметр | Значение | |----------|----------| | URL приложения | Доступен в интерфейсе лабы | | Обычный пользователь | `demo` / `demo` | | Точка входа | поле `q` в строке URL `/catalog` | | СУБД | SQLite | | Поле для редактирования (Fix Mode) | `internal/handlers/handlers.php` |
🚧 Сайт в разработке. Полный функционал пока недоступен. Все вопросы — support@hackandfix.ru