Как это обычно бывает, во время простого серфинга мне попался сайт 
www.gamestyle.ru. Чутье мне подсказало - где-то тут есть ошибки. 
Недолго думая я приступил к анализу. Зарегистрировал пользователя tester, 
вошел в систему и начал смотреть, выискивая взглядом различные уязвимые места. 
После недолгого осмотра ресурса был найден скрипт статистики www.gamestyle.ru/rating.php, 
которому передавался параметр id. Подставив символ ' к значению я получил 
грязное ругательство mysql. Причем он не просто ругнулся, а показал весь запрос, 
что было мне только на руку, ибо я видел сколько полей требуется. 
Запрос был изменен до простого: 
www.gamestyle.ru/rating.php?act=catselect&id=-1/**/UNION/**/SELECT/**/1,2 
который и показал мне цифру 2 на страничке. 
После этого цифру 2 я заменил на version(), чтоб точнее определить, с чем я 
имею дело. 
Неплохо было бы найти в базе табличку с юзерами. Префикс, судя по всему, 
отсутствовал, но проверить было бы неплохо. "Соседний" скрипт оказался уязвим 
тоже и он с радостью выдал мне названия таблиц "ut_game_settings", "ut_game_genres", 
"ut_companies", что привело к мысле о префиксе "ut_" у таблиц этого непонятного 
мне движка.  
После этих рассуждений я смело вернулся к бажному скрипту в который и 
подставил SELECT из таблицы ut_users. И я не прогадал. Действительно, по запросу
 
www.gamestyle.ru/rating.php?act=catselect&id=-1/**/UNION/**/SELECT/**/1,name/**/FROM/**/ut_users
 
я получил пустую строку. Но как имя пользователя может быть пустым? 
Единственный вариант — поле name в таблице ut_users — это реальное имя 
пользователя, а не его логин. 
Я попробовал выдернуть первый пароль из базы. Запрос  
www.gamestyle.ru/rating.php?act=catselect&id=-1/**/UNION/**/SELECT/**/1,password/**/FROM/**/ut_users
 
вернул мне обычный md5-хэш из базы. Но логин оставался неизвестным. Стоило 
лишь предположить, что в таблице существует поле login. И вот чудо -  
интуиция меня не подвела! Запрос  
www.gamestyle.ru/rating.php?act=catselect&id=-1/**/UNION/**/SELECT/**/1,login/**/FROM/**/ut_users
 
выплюнул имя пользователя Outlaw. 
Но что бы сделать с этим хэшем? Логично было бы посмотреть куки. В них 
хранилось имя пользователя и хэш пароля. Я решил, что раз ошибки с 
SQL-инъекциями у программиста имеются — то и тут меня может ожидать удача. Имя 
пользователя в куках было изменено на Outlaw, пароль — на полученный ранее хэш. 
Так же, на всякий пожарный случай, я удалил из куков данные о своей сессии. И к 
моей великой радости по запросу www.gamestyle.ru/admin/ я попал в админ-панель 
портала! 
Далее я мог бы сделать что угодно. Но я решил ограничится мелким комментарием 
в теле последней на тот момент новости и письменным уведомлением админа. 
Подведем итоги. Взлом был бы невозможен, если бы задуманный целый параметр id 
приводился к типу int. Также взлом был бы затруднен если бы "по соседству" не 
был бы найден скрипт, плюющий ошибками. Кстати, в том скрипте уязвимость почти 
бесполезная и UNION сделать не удастся, т.к. тогда и первый, и второй запрос 
надо было бы взять в скобки, т.к. в первом запросе присутствует ORDER BY. 
Взлом был бы практически невозможен, если бы ошибки mysql не выводились. Хотя 
можно было бы попробовать и вслепую, но тогда префикс к таблице узнать было бы 
куда сложнее. Так же взлом был бы не возможен, если бы в куках хранились не хэши 
из базы, а хэши от соли+хэша, т.е. md5($salt+$hash). 
В принципе, все ошибки — тривиальны, и сколько не говори программистам о 
безопасности — среди них всегда будут находится самоучки, выдающие такие 
"движки". 
P.S.: Данная статья представлена в качестве пищи для ума, а не руководства к 
действию. В любом случае, за любые ваши действия, совершенные после прочтения 
этой статьи, автор ответственности не несет. И если вы разработчик подобных 
Web-приложений — не учитесь на своих ошибках, учитесь на чужих. 
  
Видео к статье 
		
	  |