Что это за строка?
Строка AND EXTRACTVALUE(2131,CONCAT(0x7e,((SELECT (ELT(2131=2131,1)))),0x7e))-- - — это типичный пример SQL-инъекции, нацеленной на базу данных MySQL. Она может появиться в логах веб-сервера, в поле ввода формы или в параметрах URL. Её основная цель — заставить сервер выполнить вредоносный SQL-код и вернуть злоумышленнику информацию о базе данных через сообщение об ошибке.
Подобные строки часто встречаются при сканировании уязвимых сайтов автоматическими инструментами, например sqlmap. Внешне они выглядят как случайный набор символов, но на самом деле представляют собой тщательно сконструированный запрос, эксплуатирующий функции MySQL.
Разбор компонентов инъекции
Давайте разберём строку по частям, чтобы понять, как она работает.
- AND — логический оператор, который добавляется к оригинальному запросу. Если исходный запрос был, например,
SELECT * FROM users WHERE id = 1, то после подстановки он станетSELECT * FROM users WHERE id = 1 AND EXTRACTVALUE(...). Это позволяет внедрить условие, которое вызовет ошибку. - EXTRACTVALUE(2131, CONCAT(...)) — функция MySQL, предназначенная для извлечения значения из XML-документа. Она принимает два аргумента: XML-документ и XPath-выражение. Если XPath-выражение некорректно, MySQL генерирует ошибку. В данном случае первый аргумент — число 2131, которое не является корректным XML, но это не важно: главное — вызвать ошибку через второй аргумент.
- CONCAT(0x7e, ((SELECT (ELT(2131=2131,1)))), 0x7e) — конкатенация строк. 0x7e — это шестнадцатеричное представление символа тильды (~). Функция CONCAT объединяет тильду, результат подзапроса и ещё одну тильду. Полученная строка передаётся как XPath-выражение в EXTRACTVALUE.
- (SELECT (ELT(2131=2131,1))) — подзапрос, который возвращает результат функции ELT. ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь N — это результат выражения 2131=2131, которое всегда истинно (1). Таким образом, ELT(1,1) возвращает строку '1'.
- -- - — комментарий в SQL. Всё, что идёт после двух дефисов и пробела (или дефиса в некоторых реализациях), игнорируется. Это нужно, чтобы обрезать остаток оригинального запроса и избежать синтаксических ошибок.
В итоге EXTRACTVALUE получает XPath-выражение вида ~1~, которое является недопустимым (XPath не может начинаться с тильды). MySQL выбрасывает ошибку: XPATH syntax error: '~1~'. В сообщении об ошибке отображается переданная строка, что позволяет злоумышленнику увидеть результат выполнения подзапроса. В данном примере результат — '1', но если вместо ELT подставить, например, (SELECT version()), то в ошибке отобразится версия MySQL.
Зачем это нужно злоумышленнику?
Основная цель таких инъекций — извлечение данных из базы. Когда приложение выводит сообщения об ошибках СУБД на страницу, атакующий может использовать технику error-based SQL injection. Подставляя в подзапрос различные функции, он получает информацию о:
- версии СУБД;
- имени текущей базы данных;
- таблицах и колонках;
- логинах и паролях пользователей.
В приведённой строке используется простейший подзапрос ELT(2131=2131,1), который всегда возвращает '1'. Это тестовый запрос, чтобы проверить, уязвим ли сайт. Если сервер возвращает ошибку с '~1~', значит, инъекция возможна. Далее злоумышленник заменит этот подзапрос на что-то вроде (SELECT password FROM users LIMIT 1) и получит пароль в тексте ошибки.
Почему используется именно EXTRACTVALUE?
EXTRACTVALUE — одна из функций MySQL, которые могут генерировать ошибку с контролируемым текстом. Другие подобные функции: UPDATEXML, GEOMETRYCOLLECTION, POLYGON, MULTIPOINT и т.д. Они часто применяются в error-based инъекциях, потому что позволяют выводить данные напрямую в сообщении об ошибке, не прибегая к слепым методам.
Однако начиная с MySQL 5.7.9 функция EXTRACTVALUE была помечена как устаревшая, а в MySQL 8.0 удалена. Поэтому в современных версиях эта инъекция не сработает. Тем не менее, многие сайты до сих пор работают на старых версиях MySQL, что делает такие атаки актуальными.
Как защититься от подобных инъекций?
Главная рекомендация — использовать параметризованные запросы (prepared statements). Это надёжно отделяет данные от SQL-кода и делает невозможным внедрение вредоносных конструкций. Если по каким-то причинам это невозможно, следует применять экранирование специальных символов с помощью функций вроде mysqli_real_escape_string.
Также важно:
- отключить вывод ошибок СУБД на страницы сайта (в production-окружении);
- регулярно обновлять СУБД и фреймворки;
- использовать веб-application firewall (WAF) для фильтрации подозрительных запросов;
- проводить аудит кода и пентесты.
Если вы обнаружили такую строку в логах, это сигнал о попытке взлома. Стоит проверить, не была ли атака успешной, и принять меры по устранению уязвимости.
Распространённые вариации
Вместо 2131 и 1 могут быть любые числа. Например, AND EXTRACTVALUE(5421,CONCAT(0x7e,((SELECT (ELT(5421=5421,1)))),0x7e))-- - или AND EXTRACTVALUE(7289,CONCAT(0x7e,((SELECT (ELT(7289=7289,1)))),0x7e))-- -. Смысл тот же: проверка уязвимости. Часто такие строки генерируются автоматическими сканерами, которые перебирают различные комбинации функций и операторов.
Также встречаются варианты с UNION ALL SELECT, например: ' UNION ALL SELECT NULL,concat(0x28,username,0x3a,password,0x29) FROM users #. Это уже другой тип инъекции — union-based, который пытается объединить результаты оригинального запроса с данными из таблицы users.
Вывод
Строка AND EXTRACTVALUE(2131,CONCAT(0x7e,((SELECT (ELT(2131=2131,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции для MySQL. Она использует функцию EXTRACTVALUE для вызова ошибки, содержащей результат подзапроса. Понимание таких конструкций помогает разработчикам и специалистам по безопасности лучше защищать свои системы.
Комментарии
—Войдите, чтобы оставить комментарий