Что это за строка?
Строка ` AND EXTRACTVALUE(3075,CONCAT(0x7e,((SELECT (ELT(3075=3075,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции (инъекции на основе ошибок) для СУБД MySQL. Такие конструкции используют для извлечения данных из базы через вывод сообщения об ошибке. Злоумышленник внедряет вредоносный SQL-код в параметры запроса, и если приложение не фильтрует ввод, база данных выполняет этот код и возвращает результат в тексте ошибки.
Подобные строки часто встречаются в логах веб-серверов, в отчётах систем обнаружения вторжений (IDS) и в базах уязвимостей. Они не являются частью легитимного кода — это попытка атаки.
Разбор компонентов инъекции
Чтобы понять, как работает эта строка, разберём её по частям.
1. Обратная кавычка и AND
Символ ` (обратная кавычка) часто используется для экранирования идентификаторов в MySQL. Злоумышленник может добавить её, чтобы разорвать исходный SQL-запрос и внедрить свой код. Затем следует AND — логический оператор, который позволяет присоединить дополнительное условие. Если исходный запрос был, например, SELECT * FROM users WHERE id = '...', то после подстановки получается нечто вроде ... WHERE id = '` AND EXTRACTVALUE(...)-- -'. Всё, что идёт после -- -, становится комментарием и игнорируется.
2. Функция EXTRACTVALUE
EXTRACTVALUE() — это встроенная функция MySQL для работы с XML. Она принимает два строковых аргумента: фрагмент XML-разметки и выражение XPath. Функция возвращает текст (CDATA) первого текстового узла, который является дочерним для элемента или элементов, соответствующих XPath-выражению. Синтаксис:
EXTRACTVALUE(XML_fragment, XPath_expression)
Если XPath-выражение некорректно или не соответствует ни одному узлу, MySQL генерирует ошибку. Именно на этом строится error-based инъекция: злоумышленник заставляет базу выдать ошибку, содержащую полезные данные.
3. CONCAT и 0x7e
CONCAT() объединяет строки. 0x7e — это шестнадцатеричное представление символа ~ (тильда). Тильда используется как маркер, чтобы в сообщении об ошибке было легко найти границы внедрённых данных. Конструкция CONCAT(0x7e, (подзапрос), 0x7e) оборачивает результат подзапроса в тильды.
4. Подзапрос с ELT
SELECT (ELT(3075=3075,1)) — это подзапрос, который возвращает число 1. Функция ELT() возвращает N-й элемент из списка строк. Здесь ELT(3075=3075,1) — условие 3075=3075 всегда истинно (1), поэтому ELT возвращает первый элемент — строку '1'. Фактически это заглушка, которая возвращает предсказуемое значение. В реальной атаке вместо этой заглушки был бы подзапрос, извлекающий имя пользователя, хеш пароля или другую конфиденциальную информацию, например: SELECT (ELT(1=1, (SELECT password FROM users LIMIT 1))).
5. Комментарий -- -
Двойной дефис с пробелом или другим символом в конце (-- -) — это комментарий в MySQL. Он «отрезает» оставшуюся часть оригинального запроса, чтобы синтаксис оставался корректным.
Как работает атака целиком?
Предположим, есть уязвимый параметр id, который подставляется в запрос без параметризации:
SELECT * FROM articles WHERE id = '$id'
Злоумышленник передаёт значение:
' AND EXTRACTVALUE(3075,CONCAT(0x7e,((SELECT (ELT(3075=3075,1)))),0x7e))-- -
Итоговый запрос становится:
SELECT * FROM articles WHERE id = '' AND EXTRACTVALUE(3075,CONCAT(0x7e,((SELECT (ELT(3075=3075,1)))),0x7e))-- -'
MySQL выполняет EXTRACTVALUE. Второй аргумент — CONCAT(0x7e, (SELECT (ELT(3075=3075,1))), 0x7e) — даёт строку ~1~. Эта строка не является корректным XPath-выражением, поэтому MySQL генерирует ошибку:
XPATH syntax error: '~1~'
В тексте ошибки злоумышленник видит ~1~. Если вместо ELT-заглушки подставить подзапрос, возвращающий, например, версию MySQL или имя базы данных, то в ошибке отобразится именно эта информация. Такой метод позволяет посимвольно извлекать данные, используя функции SUBSTRING, LIMIT и т.д.
Почему это опасно?
Error-based инъекции — один из самых быстрых способов получить данные из уязвимой базы. В отличие от слепых инъекций, где приходится угадывать по времени или логическим условиям, здесь сервер сам возвращает результат в сообщении об ошибке. Это позволяет атакующему:
- получить версию СУБД и имена таблиц;
- извлечь логины, пароли, хеши, номера кредитных карт;
- при наличии прав — выполнить произвольные команды через
INTO OUTFILEили другие техники.
Подобные строки часто автоматически генерируются инструментами вроде sqlmap, которые перебирают множество техник инъекций.
Как защититься?
Основная причина успеха таких атак — отсутствие параметризации запросов и недостаточная фильтрация ввода. Вот ключевые меры защиты:
- Используйте подготовленные выражения (prepared statements). Параметризация гарантирует, что пользовательский ввод никогда не интерпретируется как SQL-код.
- Применяйте ORM. Современные ORM (Hibernate, Entity Framework, Django ORM) по умолчанию используют параметризацию.
- Экранируйте спецсимволы. Если параметризация невозможна, используйте функции экранирования, например
mysqli_real_escape_string. - Ограничьте права пользователя БД. Приложение должно работать под учётной записью с минимально необходимыми привилегиями (обычно только SELECT, INSERT, UPDATE, DELETE для конкретных таблиц).
- Отключите вывод ошибок на продакшене. Сообщения об ошибках не должны попадать в ответ клиенту — это лишает error-based инъекции смысла.
- Используйте WAF. Веб-прикладной брандмауэр может блокировать подозрительные конструкции, содержащие EXTRACTVALUE, CONCAT и т.п.
- Регулярно обновляйте СУБД и фреймворки. В новых версиях MySQL функция EXTRACTVALUE помечена как устаревшая, но старые версии всё ещё уязвимы.
Важно понимать: появление такой строки в логах — это сигнал о попытке взлома. Необходимо немедленно проверить логи веб-сервера и базы данных, а также провести аудит кода на предмет уязвимостей.
Заключение
Строка ` AND EXTRACTVALUE(3075,CONCAT(0x7e,((SELECT (ELT(3075=3075,1)))),0x7e))-- - — это не случайный набор символов, а тщательно сконструированная SQL-инъекция, эксплуатирующая функцию EXTRACTVALUE в MySQL для извлечения данных через сообщения об ошибках. Понимание механики таких атак помогает разработчикам и администраторам своевременно закрывать уязвимости и защищать свои системы.
Комментарии
—Войдите, чтобы оставить комментарий