Однажды мне попался сайт, который был написан с нуля. Это было веб-приложение с авторизацией. Для входа требовались логин и пароль, но разработчики предусмотрели гостевой доступ. На главной странице были написаны гостевые учётные данные. Любой мог войти и посмотреть, как работает система. Это и стало отправной точкой.
Действия пользователей сохранялись в Истории. У каждой записи был заголовок и текст. Я заметил, что поля не фильтруются на специальные символы и слова. Решил проверить на XSS, уязвимость, которая позволяет выполнять JavaScript-код на странице. Я ввёл:
И на странице Истории появилось всплывающее окно. XSS подтвердилась. Через такую уязвимость можно украсть кукиз других пользователей. Но проблема была в том, что История была привязана к каждому пользователю отдельно. Максимум, что я мог сделать, это получить кукиз пользователей с такими же правами, как у меня, то есть гостевых. Возможно, у администратора был доступ к Истории всех пользователей, но это не точно. К тому же надо было придумать, как заставить админа зайти в Историю. А он мог зайти туда через год или никогда.
Я подумал, что если специальные символы не фильтруются, то данные, скорее всего, хранятся в базе данных. Это могло означать, что есть уязвимость SQL-инъекция, которая позволяет получить доступ к базе. Но я не успел это проверить, потому что нашёл более простую уязвимость. Небезопасную выгрузку файлов.
Когда я создавал новое действие, мне были доступны текстовые поля, в которых я нашёл XSS и мог искать SQL-инъекцию. Но при открытии сохранённого действия из Истории появлялось ещё одно поле. Поле для загрузки файла. Это меня заинтересовало.
На многих сайтах загрузка файлов ограничена по расширениям. Но из-за того, что разработчики не фильтровали текстовые поля, у меня была надежда, что и с файлами они тоже напортачили. Я создал файл:
И загрузил его на сервер. Сервер выдал ссылку на этот файл. Я перешёл по ней. Вместо того чтобы скачать файл или показать его содержимое, сервер выполнил его. Я увидел информацию, которую выводит функция phpinfo().
Вот в чём были ошибки программиста. Такой безалаберный стиль программирования нельзя совмещать с публичной учётной записью. Если бы на главной странице не были написаны гостевые данные, поиск уязвимостей занял бы гораздо больше времени. Но главная ошибка в том, что при написании кода всегда нужно фильтровать данные и ограничивать загружаемые файлы. Даже если вы программируете для себя и держите сайт на локальном компьютере, кто-то может подключиться к вашему серверу по локальной сети или через белый IP. Для публичного сайта код должен писаться с постоянной мыслью о безопасности.
Что было дальше
После того как я загрузил бэкдор, я осмотрелся на сервере. Скачал исходный код сайтов, узнал, какие ещё сайты работают на этом сервере. Взломал MySQL, проанализировал пароли. Нашёл слабые настройки сервера, попробовал брут-форс SSH и FTP. В итоге взломал почту.
Этот рассказ может показаться перечислением детских ошибок, которые могут допустить начинающие программисты. Но это не так. Это реальный разбор реального сервера. Организация, которой он принадлежит, находится в Москве. На стене у них висит большой триколор. Не могу сказать больше о контексте, но факт остаётся фактом.
Вывод
Я почти не использовал специализированные утилиты. Почти все взломы заключались в том, что я знал, где и что смотреть, и просто смотрел. Поэтому обучение аудиту безопасности сайтов заключается не только в изучении утилит. В первую очередь нужно понимание процессов. Если мы говорим о сайтах, надо понимать, как они функционируют. Нельзя делать тест на проникновение, если нет опыта программирования на PHP и создания веб-приложений. Если пентестинг продолжается на сервере, без понимания работы Linux, командной строки и ходовых утилит делать нечего.
Спасибо, что дочитали. Если было полезно, ставьте лайк и пишите комментарии.
Действия пользователей сохранялись в Истории. У каждой записи был заголовок и текст. Я заметил, что поля не фильтруются на специальные символы и слова. Решил проверить на XSS, уязвимость, которая позволяет выполнять JavaScript-код на странице. Я ввёл:
Код:
<script>alert(1)</script>
Я подумал, что если специальные символы не фильтруются, то данные, скорее всего, хранятся в базе данных. Это могло означать, что есть уязвимость SQL-инъекция, которая позволяет получить доступ к базе. Но я не успел это проверить, потому что нашёл более простую уязвимость. Небезопасную выгрузку файлов.
Когда я создавал новое действие, мне были доступны текстовые поля, в которых я нашёл XSS и мог искать SQL-инъекцию. Но при открытии сохранённого действия из Истории появлялось ещё одно поле. Поле для загрузки файла. Это меня заинтересовало.
На многих сайтах загрузка файлов ограничена по расширениям. Но из-за того, что разработчики не фильтровали текстовые поля, у меня была надежда, что и с файлами они тоже напортачили. Я создал файл:
Код:
<?php phpinfo(); ?>
Вот в чём были ошибки программиста. Такой безалаберный стиль программирования нельзя совмещать с публичной учётной записью. Если бы на главной странице не были написаны гостевые данные, поиск уязвимостей занял бы гораздо больше времени. Но главная ошибка в том, что при написании кода всегда нужно фильтровать данные и ограничивать загружаемые файлы. Даже если вы программируете для себя и держите сайт на локальном компьютере, кто-то может подключиться к вашему серверу по локальной сети или через белый IP. Для публичного сайта код должен писаться с постоянной мыслью о безопасности.
Что было дальше
После того как я загрузил бэкдор, я осмотрелся на сервере. Скачал исходный код сайтов, узнал, какие ещё сайты работают на этом сервере. Взломал MySQL, проанализировал пароли. Нашёл слабые настройки сервера, попробовал брут-форс SSH и FTP. В итоге взломал почту.
Этот рассказ может показаться перечислением детских ошибок, которые могут допустить начинающие программисты. Но это не так. Это реальный разбор реального сервера. Организация, которой он принадлежит, находится в Москве. На стене у них висит большой триколор. Не могу сказать больше о контексте, но факт остаётся фактом.
Вывод
Я почти не использовал специализированные утилиты. Почти все взломы заключались в том, что я знал, где и что смотреть, и просто смотрел. Поэтому обучение аудиту безопасности сайтов заключается не только в изучении утилит. В первую очередь нужно понимание процессов. Если мы говорим о сайтах, надо понимать, как они функционируют. Нельзя делать тест на проникновение, если нет опыта программирования на PHP и создания веб-приложений. Если пентестинг продолжается на сервере, без понимания работы Linux, командной строки и ходовых утилит делать нечего.
Спасибо, что дочитали. Если было полезно, ставьте лайк и пишите комментарии.