Сайт взломан через SQL Injection
Недавно мой сайт был взломан через SQL-инъекцию. Хакер использовал следующий запрос
чтобы получить имя моей БД. Я не могу понять этот запрос, который они написали.
Query:
=-999.9%20UNION%20ALL%20SELECT%20concat(0x7e,0x27,Hex(cast(database()%20as%20char)),0x27,0x7e),0x31303235343830303536,0x31303235343830303536,0x31303235343830303536--
После запуска запроса он показал целочисленный результат, что-то вроде "74545883
".
Можете ли вы объяснить, как работает запрос?
Ответы
Ответ 1
Похоже на переполнение атаки. Они UNION
-ed с вашим существующим запросом. заменяя все ваши %20
на (пробел), поскольку его url-закодированные выходы:
=-999.9 UNION ALL SELECT CONCAT(0x7e,0x27,Hex(cast(database() as char)),0x27,0x7e),0x31303235343830303536,0x31303235343830303536,0x31303235343830303536-
сломайте его:
-
=-999.9
просто заканчивает ваш текущий запрос
-
0x31303235343830303536
NULL
- они просто соответствуют количеству столбцов в вашем существующем запросе. Если у вас SELECT * FROM users
и users
было 4 столбца, UNION
также должен иметь 4 столбца. В результате они просто использовали значения NULL для заполнения этих столбцов.
- реальная путаница находится в
CONCAT()
. Они объединяют 126, 39, имя базы данных как шестнадцатеричное значение, 39 и 126
-
--
- комментарий mysql - он игнорирует остальную часть вашего запроса после
Судя по этой атаке, я подозреваю, что вы не вставляете ввод в mysql_real_escape_string()
, что позволяет атаковать, чтобы выпрыгнуть из вашего запроса и выполнить свои собственные.
Подробнее см. owasp.org.
Ответ 2
Это не полный запрос, на самом деле человек ввел эту строку в ваше веб-приложение.
Теперь, сначала замените %20 пробелом в объединенной части, вы получите:
SELECT concat(0x7e,0x27,Hex(cast(database() as char)),0x27,0x7e),0x31303235343830303536,0x31303235343830303536,0x31303235343830303536--
Кажется, что пользователь поставил строку в каком-то месте, где вы ожидали числа. Итак, вы видите, что сначала есть число (999.9), чтобы выполнить исходное условие запроса. Затем добавляется часть UNION.
Наконец, после части UNION символы комментария добавляются (-), так что остальная часть запроса (который может быть добавлена вашей системой) обходит.
Мы можем отформатировать код для лучшего понимания:
SELECT
concat
(
0x7e,
0x27,
Hex(cast(database() as char)),
0x27,
0x7e
),
0x31303235343830303536,
0x31303235343830303536,
0x31303235343830303536
Теперь подстрока первого столбца результата будет содержать шестнадцатеричную кодировку формы вашего имени базы данных. Фактически, он должен быть окружен одинарными кавычками (0x27), а затем снова окружен ~ (0x7e)
Ответ 3
Запрос возвратил имя базы данных с помощью DATABASE(), затем преобразовал это значение в шестнадцатеричное значение, используя HEx().
Как только у них это получилось, они могут использовать UNHEX функцию
Посмотрите примеры UNHEX
mysql> SELECT UNHEX('4D7953514C');
-> 'MySQL'
mysql> SELECT 0x4D7953514C;
-> 'MySQL'
mysql> SELECT UNHEX(HEX('string'));
-> 'string'
mysql> SELECT HEX(UNHEX('1267'));
-> '1267'
Хорошо знать, как они вошли, но в целом вам нужно исправить свой код, чтобы избежать SQL Injection.
Ответ 4
-999.9 UNION ALL SELECT
CONCAT('Hex(cast(database() as char))'),
0x31303235343830303536,
0x31303235343830303536,
0x31303235343830303536
Я думаю, что у вас должны быть другие записи в вашем журнале, если бы он не знал, что у вас есть 3 столбца.
Ответ 5
Это пример инъекции с использованием Havij
0x7e и 0x27 соответствуют ~ и ', которые будут использоваться для отображения HTML-дисплея
такие как
ID = 999999,9 + объединение + все + выбрать + 0x31303235343830303536, (выбрать + CONCAT (0x7E, 0x27, unhex (Hex (литой (sample_tbl.name + как + char))), 0x27,0x7e) + с + test
.sample_tbl + Заказ + по + ид + предел + 0,1) + -
Этот запрос отобразит ~ 'Alfred' ~, который является значением поля имени столбца, из таблицы sample_tbl в тесте таблицы
~ 'r3dm0v3_hvj_injection' ~ - это код подписи Havij unhex 0x7233646D3076335F68766A5F696E6A656374696F6E в соответствии с http://www.string-functions.com/hex-string.aspx
Ответ 6
Во-первых, запрос выглядит так, как он закодирован в HTML. Замените %20
пробелами, и он станет немного более читаемым. Также они преобразуют часть запроса в шестнадцатеричное представление чего-то. Попробуйте шестнадцатеричное декодирование этой части инструкции.
При попытке создать SQL динамически как строку, а затем отправить ее в СУБД, возникает риск инъекции SQL. Представьте, что такая строка хранится в вашей системе для использования в строке поиска и т.д.:
SELECT * FROM SOME_TABLE WHERE SOME_COLUMN=
Чтобы завершить запрос и включить атаку, им нужно будет сделать свой ввод следующим образом:
'x' or 1=1
В этом случае запрос будет выглядеть следующим образом:
SELECT * FROM SOME_TABLE WHERE SOME_COLUMN='x' or 1=1
SOME_COLUMN
может быть любой переменной, неважно, где она терпит неудачу. Дело в том, что 1=1
является ALWAYS true, тем самым потенциально дает злоумышленнику доступ к каждой строке в этой таблице.
Теперь, когда вы знаете об этом, просмотрите свой код и замените каждый динамически созданный запрос на подготовленные заявления. На сайте OWASP есть много ресурсов для защитного кодирования:
www.owasp.org
Ответ 7
Да, у него есть шестиугольная форма вашего имени базы данных, которое вы называете "74545883".
По Unhexing он получил бы настоящее имя базы данных.