Коротко
Была обнаружена уязвимость в мобильной версии сайта vk.com. Она позволяла просматривать превью скрытых фотографий, в том числе фотографии из диалогов пользователей, плюс можно было получить информацию о пользователях лайкнувших это скрытое фото. На данный момент уязвимости уже нет — её устранили полгода назад. ВКонтакте выразили благодарность в размере 700$ (нет, не в голосах).
С чего всё начиналось
Во время сессии отвлекаешься на все, лишь бы не готовиться к экзаменам. Так и я, увидев статью о Bug Bounty программе от ВКонтакте на hackerone.com, вместо подготовки к экзаменам, взялся искать уязвимости. Почему-то сразу потянуло искать уязвимости, связанные с фотографиями скрытыми настройками приватности, и как оказалось — не зря.
Поиск уязвимости на полной версии сайта
Предположив, что id скрытой фотографии мне известен (о его поиске — ниже), я начал пробовать подставлять этот id во всевозможные запросы curl'ом — пробовал сохранять скрытые изображения в свой альбом, отмечать себя на них, лайкать, репостить и т.п. ничего не давало положительный результат, пока я не попробовал просто отправить скрытую фотографию себе на стену. Результат был странным — в консоли запрос возвращал корректный результат и на стене появлялся новый пост, но его содержимое было пустым. Как я не старался, на сервере пресекались все попытки отправить скрытое фото на стену — посты были пустыми.
Переход на мобильную версию
Затем, я вспомнил этот комментарий и решил попробовать сделать то же самое в мобильной версии сайта.
Отправляем фото на стену:
curl 'http://m.vk.com/wall53083705' -H 'Cookie: remixsid=#remixsid' --data 'act=post&hash=#hash&attach1_type=photo&attach1=idВладельцаФото_idСкрытогоФото'
# id фотографии состоит из двух частей разделенных знаком подчеркивания idВладельцаФото_idСкрытогоФото
Этот запрос выполнился не корректно, но обновив страницу, я с удивлением обнаружил, что на форме отправки появилась прикрепленная уменьшенная копия фотографии.
Максимальный размер фотографии — 130x130, но этого достаточно, чтобы, например, распознать лица на фото. Попытки получить ссылку на полное фото ни к чему не привели. Видимо, после закрытия этой уязвимости, с мобильной версии сайта прямые ссылки на полный размер просто так уже не получить.
Перебор фотографий
Уязвимость найдена. Для эксплуатации найденной уязвимости нужно получить id атакуемой фотографии.
id фотографии состоит из двух частей: photo12345_330000000 (idВладельца_idФото), вторая часть — растет от фотографии к фотографии, но это не обычный автоинкремент. Так как алгоритм выбора шага неизвестен, будем перебирать с шагом 1.
Для перебора воспользуемся методом api photos.delete. Данный метод для всех существующих фотографий (в том числе и скрытых) вернет error_code: 15. А для всех несуществующих id фотографий вернется единица.
Скорость перебора
Из этой статьи можно узнать, как быстро перебирать фотографии. Да, данные в ней не самые новые, но даже если учесть, что за год фотографий стало в два раза больше, время перебора все равно остается приемлемым.
чтобы узнать прямые ссылки на фотки юзера, допустим, за прошлый год, нужно перебрать всего лишь 30 млн (от _320000000 до _350000000) различных вариаций ссылок
Воспользовавшись ускорениями перебора из указанной статьи, фотографии пользователя можно было бы перебрать:
за 1 минуту получить все ваши вчерашние фотографии, за 7 минут — все фото, загруженные на прошлой неделе, за 20 минут — прошлый месяц, за 2 часа — прошлый год.
Отсев открытых/скрытых
Получив ссылки на все (и скрытые и открытые) фотографии пользователя, можно выбрать только скрытые, попробовав получить информацию о фотографии с помощью метода photos.getById. Те фотографии, информация о которых не возвращается этим методом — являются скрытыми.
Информация о лайкнувших пользователях
Также можно было узнать пользователей, которые поставили лайки на скрытое фото. Метод likes.getList возвращал всех пользователей, которые добавили заданный объект в свой список мне нравится, даже если этот объект скрыт для пользователя запускающего этот метод.
Репорт на hackerone
Мой репорт был открыт в июне. Закрыли уязвимость через два с половиной месяца, ничего мне не сообщив. Еще через месяц я получил ответ что уязвимость подтверждена и закрыта. А еще через какое-то время получил и вознаграждение.
P.S.: тем, кто впервые пытается вывести вознаграждение с hackerone.com на новый аккаунт paypal — советую внимательно прочитать условия. Paypal при переводе средств, может без вашего согласия конвертнуть вознаграждение в валюту страны указанной в вашем профиле.