Что это за строка?
Строка ` AND EXTRACTVALUE(5421,CONCAT(0x7e,((SELECT (ELT(5421=5421,1)))),0x7e))-- - — это типичный пример SQL-инъекции, нацеленной на базу данных MySQL. Она может появиться в логах веб-сервера, в поле ввода формы или в параметрах URL. Её основная цель — заставить сервер выполнить произвольный SQL-код и вернуть информацию об ошибке, которая раскроет структуру базы данных или её содержимое.
Подобные строки часто встречаются в отчётах систем обнаружения вторжений (IDS) и в логах WAF. Они не являются случайным набором символов, а представляют собой тщательно сконструированную полезную нагрузку (payload) для эксплуатации уязвимости типа «SQL-инъекция на основе ошибок» (error-based SQL injection).
Разбор компонентов инъекции
Давайте разберём каждый элемент этой строки, чтобы понять, как она работает.
1. Обратный апостроф (`) и логический оператор AND
Символ обратного апострофа (`) в MySQL используется для экранирования идентификаторов (имён таблиц, столбцов). В данном случае он, вероятно, закрывает предыдущее выражение в исходном SQL-запросе, которое было сформировано разработчиком. Затем идёт AND — логический оператор, который позволяет добавить дополнительное условие к существующему запросу. Если исходный запрос был, например, SELECT * FROM users WHERE id = '1', то после подстановки инъекции он может превратиться в SELECT * FROM users WHERE id = '1' AND EXTRACTVALUE(...)-- -.
2. Функция EXTRACTVALUE
EXTRACTVALUE(XML_frag, XPath_expr) — это встроенная функция MySQL, которая извлекает значение из фрагмента XML, используя выражение XPath. Она возвращает текст узла, соответствующего XPath-выражению. Однако, если XPath-выражение содержит синтаксическую ошибку, MySQL генерирует сообщение об ошибке, в котором отображается часть переданного XPath-выражения. Это и используется злоумышленниками для извлечения данных.
3. CONCAT и шестнадцатеричные литералы
CONCAT объединяет строки. В данном случае он собирает строку из трёх частей:
0x7e— шестнадцатеричное представление символа тильды (~).((SELECT (ELT(5421=5421,1))))— подзапрос, возвращающий некоторое значение.- Ещё один
0x7e— закрывающая тильда.
Тильда используется как разделитель, чтобы облегчить поиск извлечённых данных в сообщении об ошибке.
4. Подзапрос с ELT
ELT(N, str1, str2, ...) — функция, возвращающая N-ю строку из списка. В нашем случае ELT(5421=5421,1) возвращает 1, так как условие 5421=5421 всегда истинно (1). Это простейший случай, но на практике вместо 1 мог бы быть, например, database(), user() или version(). Тогда EXTRACTVALUE вызвал бы ошибку, содержащую имя базы данных или другую полезную информацию.
5. Комментарий -- -
Два дефиса и пробел (-- ) — это комментарий в SQL, который игнорирует оставшуюся часть исходного запроса. Символ - после пробела добавлен для надёжности, так как некоторые реализации требуют, чтобы после -- был пробел или специальный символ. В результате весь код после инъекции не выполняется, что позволяет избежать синтаксических ошибок.
Как это работает на практике
Предположим, уязвимый запрос выглядит так:
SELECT * FROM articles WHERE id = '$_GET[id]'Злоумышленник передаёт в параметре id следующее значение:
1' AND EXTRACTVALUE(5421,CONCAT(0x7e,((SELECT (ELT(5421=5421,1)))),0x7e))-- -После подстановки получается:
SELECT * FROM articles WHERE id = '1' AND EXTRACTVALUE(5421,CONCAT(0x7e,((SELECT (ELT(5421=5421,1)))),0x7e))-- -'MySQL выполняет запрос. Функция EXTRACTVALUE получает XPath-выражение, которое начинается с тильды, что является синтаксической ошибкой. MySQL возвращает ошибку вида:
XPATH syntax error: '~1~'
В этом сообщении видно значение, возвращённое подзапросом (в нашем случае 1). Если бы вместо 1 стояла функция database(), в ошибке отобразилось бы имя текущей базы данных. Таким образом, злоумышленник может извлекать произвольные данные посимвольно или целыми строками, если позволяет длина сообщения об ошибке.
Зачем это нужно злоумышленнику?
Основная цель — получить информацию о базе данных: имена таблиц, столбцов, учётные данные пользователей, хеши паролей и другую конфиденциальную информацию. Error-based инъекции считаются одними из самых быстрых и удобных, так как не требуют слепого перебора (boolean-based) или временных задержек (time-based). Однако они работают только в том случае, если веб-приложение выводит сообщения об ошибках СУБД на страницу.
Меры защиты
Чтобы предотвратить подобные атаки, необходимо:
- Использовать подготовленные выражения (prepared statements) с параметризацией запросов. Это самый надёжный способ, так как данные не попадают напрямую в SQL-код.
- Экранировать специальные символы с помощью функций вроде
mysqli_real_escape_string(), но это менее надёжно, чем подготовленные выражения. - Ограничить права пользователя базы данных, от имени которого работает приложение. Не давайте ему прав на чтение системных таблиц и выполнение опасных функций.
- Отключить вывод ошибок СУБД на страницу. Ошибки должны логироваться, но не показываться пользователю.
- Использовать WAF (Web Application Firewall) для фильтрации подозрительных запросов.
Заключение
Строка ` AND EXTRACTVALUE(5421,CONCAT(0x7e,((SELECT (ELT(5421=5421,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции, использующей особенности функций MySQL EXTRACTVALUE и CONCAT. Понимание таких payload'ов помогает специалистам по безопасности выявлять и блокировать атаки, а разработчикам — писать защищённый код. Если вы встретили подобную строку в логах, это сигнал о попытке взлома вашего сайта, и необходимо срочно проверить безопасность приложения.
Комментарии
—Войдите, чтобы оставить комментарий