О чем пойдет речь: забавный и экстравагантный способ «взлома» веб-сайта, у которого «всего-лишь» не экранируются кавычки одного из параметров. При этом пропустим рассуждения о том, почему все не экранируется на стороне самого языка программирования или ORM.
Вводная: веб-сайт, у которого не экранируется один из параметров в простом SELECT запросе. При этом все ошибки перехватываются, обрабатываются и выводится скромное «Нет данных» или «Произошла ошибка».
Казалось бы: не велика беда. Обновление или изменение данных в него втереть, данные наружу не открываются, все сводится к «Извините, нет данных» — черный ящик.
Но, что на самом деле можно сделать в данной ситуации?
Сразу соль: техника базируется на функции sleep(N) которую мы будем использовать как лакмус. Замеряем сколько «отдается» страница в обычной жизни. И сколько времени она «отдается» если мы введем
Например, подбираем имя таблицы, основываясь на мета-базе INFORMATION_SCHEMA, которая всегда присутствует и доступна всем:
Если время «отдачи» страницы существенно увеличилось — угадали, если нет — пробуем еще варианты, обычно их до 10. Дальше «угадываем» имена полей:
Зная имена таблицы и полей, можно «подобрать» длину логина, пароля а так же посимвольно вытащить сами логин и пароль.
При двоичном поиске пароля посимвольно потребуется всего 8 запросов на каждый символ.
Да, не ахти какой взлом, но забавный способ исследовать вслепую структуру БД, имена полей (так же можно подбирать посимволно) а так же сами данные.
Кстати, экранировать надо в том числе и постраничную навигацию — метод тот же, но с применением UNION SELECT…
Мораль сей басни: даже единственный не экранируемый параметр из-за которого ну максимум будет «извините, ошибка» может слить всю базу.
Заметка родилась в следствии анализа запросов к одному из сайтов и попыток их осмыслить.
Просьба не холиварить касательно ущербности MySQL как базы данных а так же «единственно истинного» способа экранирования данных.
Вводная: веб-сайт, у которого не экранируется один из параметров в простом SELECT запросе. При этом все ошибки перехватываются, обрабатываются и выводится скромное «Нет данных» или «Произошла ошибка».
Казалось бы: не велика беда. Обновление или изменение данных в него втереть, данные наружу не открываются, все сводится к «Извините, нет данных» — черный ящик.
Но, что на самом деле можно сделать в данной ситуации?
Сразу соль: техника базируется на функции sleep(N) которую мы будем использовать как лакмус. Замеряем сколько «отдается» страница в обычной жизни. И сколько времени она «отдается» если мы введем
' OR sleep(10)
вместо всех параметров которые присутствую в форме. Если время отдачи страницы выросло — дело в шляпе и дальше только дело техники.Например, подбираем имя таблицы, основываясь на мета-базе INFORMATION_SCHEMA, которая всегда присутствует и доступна всем:
' OR 1 = if((select count(*) from INFORMATION_SCHEMA.tables where TABLE_SCHEMA=database() and TABLE_NAME='users') = 1, sleep(10), null)
Если время «отдачи» страницы существенно увеличилось — угадали, если нет — пробуем еще варианты, обычно их до 10. Дальше «угадываем» имена полей:
' OR 1 = if((select count(*) from INFORMATION_SCHEMA.columns where TABLE_SCHEMA=database() and TABLE_NAME='users' and COLUMN_NAME='login') = 1, sleep(5), null)
Зная имена таблицы и полей, можно «подобрать» длину логина, пароля а так же посимвольно вытащить сами логин и пароль.
if((select count(*) from users where login='admin') = 1, sleep(5), null)
if((select length(password) from users where login='admin') = 1, sleep(5), null)
select if((select mid(password, 5,1) from users where login='admin') = 'a', sleep(5), null)
При двоичном поиске пароля посимвольно потребуется всего 8 запросов на каждый символ.
Да, не ахти какой взлом, но забавный способ исследовать вслепую структуру БД, имена полей (так же можно подбирать посимволно) а так же сами данные.
Кстати, экранировать надо в том числе и постраничную навигацию — метод тот же, но с применением UNION SELECT…
Мораль сей басни: даже единственный не экранируемый параметр из-за которого ну максимум будет «извините, ошибка» может слить всю базу.
Заметка родилась в следствии анализа запросов к одному из сайтов и попыток их осмыслить.
Просьба не холиварить касательно ущербности MySQL как базы данных а так же «единственно истинного» способа экранирования данных.