Введение
В логах веб-сервера или в поле ввода можно встретить загадочную строку: ) AND EXTRACTVALUE(7910,CONCAT(0x7e,((SELECT (ELT(7910=7910,1)))),0x7e))-- -. Для неспециалиста она выглядит как случайный набор символов, но на самом деле это целенаправленная попытка взлома базы данных через SQL-инъекцию. В этой статье мы разберём, что означает каждый элемент этой конструкции, как она работает и, главное, как защититься от подобных атак.
Что такое SQL-инъекция?
SQL-инъекция (SQL injection) — один из самых распространённых способов атаки на веб-приложения. Злоумышленник вставляет вредоносный SQL-код в поля ввода, URL-параметры или заголовки запросов, чтобы заставить базу данных выполнить нежелательные действия. Цели могут быть разными: от извлечения конфиденциальных данных (пароли, номера карт) до полного удаления базы.
Существует несколько типов SQL-инъекций, и одна из них — error-based (инъекция на основе ошибок). Именно к этому типу относится рассматриваемая строка.
Разбор строки по частям
Давайте последовательно разберём каждый фрагмент запроса.
1. AND
Оператор AND используется для добавления условия к существующему SQL-запросу. Если исходный запрос выглядел как SELECT * FROM users WHERE id = '$input', то после подстановки вредоносной строки он превращается в SELECT * FROM users WHERE id = '') AND EXTRACTVALUE(...)-- -. Закрывающая скобка и кавычка помогают «закрыть» оригинальное выражение, а AND позволяет присоединить новое условие.
2. EXTRACTVALUE(7910, CONCAT(...))
EXTRACTVALUE — это функция MySQL, предназначенная для извлечения значения из XML-строки. Синтаксис: EXTRACTVALUE(XML_document, XPath_expression). Однако при неправильном XPath-выражении функция генерирует ошибку, текст которой содержит переданное выражение. Это и используется для error-based инъекций: злоумышленник заставляет базу вернуть ошибку с внедрёнными данными.
Первый аргумент 7910 — произвольное число, которое не имеет смысла, но должно быть допустимым XML. Второй аргумент — это CONCAT(0x7e, ((SELECT (ELT(7910=7910,1)))), 0x7e).
3. CONCAT и 0x7e
CONCAT объединяет строки. 0x7e — это шестнадцатеричное представление символа ~ (тильда). Тильда используется как маркер, чтобы облегчить поиск внедрённых данных в сообщении об ошибке. В итоге конкатенация даёт строку вида ~1~ (если подзапрос вернёт 1).
4. (SELECT (ELT(7910=7910,1)))
Внутренний подзапрос содержит функцию ELT(N, str1, str2, ...), которая возвращает N-ю строку из списка. Здесь 7910=7910 — всегда истинное условие, которое возвращает 1. Таким образом, ELT(1, 1) вернёт строку '1'. Это простейшая проверка: если инъекция сработала, в ошибке появится ~1~.
В более сложных атаках вместо ELT(7910=7910,1) подставляются подзапросы, извлекающие реальные данные, например: SELECT password FROM users LIMIT 1.
5. -- -
Двойной дефис с пробелом — это комментарий в SQL. Он «отрезает» оставшуюся часть оригинального запроса, чтобы синтаксис оставался корректным. Пробел после -- обязателен в некоторых СУБД, а третий дефис добавлен для надёжности.
Как работает атака целиком
Предположим, уязвимый запрос: SELECT * FROM products WHERE category = '$_GET[cat]'. Злоумышленник передаёт в параметр cat строку ') AND EXTRACTVALUE(7910,CONCAT(0x7e,((SELECT (ELT(7910=7910,1)))),0x7e))-- -. После подстановки получается:
SELECT * FROM products WHERE category = '') AND EXTRACTVALUE(7910,CONCAT(0x7e,((SELECT (ELT(7910=7910,1)))),0x7e))-- -'
База данных выполняет EXTRACTVALUE с некорректным XPath (строка ~1~ не является валидным XPath), что вызывает ошибку вида: XPATH syntax error: '~1~'. Злоумышленник видит эту ошибку в ответе сервера и понимает, что инъекция возможна. Далее он может заменить 1 на подзапрос, извлекающий любые данные, и получать их через сообщения об ошибках.
Чем опасна такая инъекция?
- Утечка данных: через ошибки можно извлечь логины, пароли, номера банковских карт, персональные данные пользователей.
- Обход аутентификации: иногда с помощью инъекций удаётся войти в систему без пароля.
- Изменение или удаление данных: в некоторых случаях злоумышленник может выполнить
UPDATEилиDELETE, что приведёт к порче базы. - Полный контроль над сервером: при определённых конфигурациях возможна загрузка файлов или выполнение команд ОС.
Как защититься от SQL-инъекций?
Основной метод — использование параметризованных запросов (prepared statements). Вместо вставки пользовательских данных непосредственно в SQL-запрос, вы передаёте их как параметры, которые база данных обрабатывает отдельно от кода. Это полностью исключает возможность инъекции.
Дополнительные меры:
- Валидация и фильтрация входных данных (например, проверка, что число действительно является числом).
- Экранирование специальных символов с помощью функций вроде
mysqli_real_escape_string(но это менее надёжно, чем параметризация). - Ограничение прав пользователя базы данных: не давайте веб-приложению прав на удаление таблиц или доступ к системным функциям.
- Регулярное обновление СУБД и фреймворков.
- Использование WAF (Web Application Firewall) для блокировки подозрительных запросов.
Что делать, если вы нашли такую строку в логах?
Если вы обнаружили подобный запрос в логах сервера, это сигнал о попытке взлома. Необходимо:
- Проверить, не была ли атака успешной (например, поискать необычные ошибки в логах базы данных).
- Убедиться, что все формы и параметры URL используют параметризованные запросы.
- Провести аудит кода на предмет других уязвимостей.
- При необходимости обратиться к специалистам по информационной безопасности.
Заключение
Строка AND EXTRACTVALUE(7910,CONCAT(0x7e,((SELECT (ELT(7910=7910,1)))),0x7e))-- - — это не случайный мусор, а тщательно сконструированный эксплойт для проверки наличия SQL-инъекции. Понимание принципов его работы помогает разработчикам и администраторам лучше защищать свои системы. Помните: безопасность — это процесс, а не разовое действие. Используйте параметризованные запросы, следите за обновлениями и регулярно проверяйте логи.
Комментарии
—Войдите, чтобы оставить комментарий