Статья является анализом одного из приложения в списке. Статья была написана сразу после обнаружения уязвимости в приложении. Разработчик получил отчет и подтвердил существование проблемы, обещая в скором времени всё исправить. На данный момент вышло обновление приложения на обоих платформах.
Уже несколько лет AppNana (AppJoy) находится на волне популярности, ведь они дают возможность бесплатно, без смс, скачивать платные приложения из магазинов приложения для iOS и Android. В чем подвох, спросите вы? Где спрятаны подводные камни? Всё очень просто: вы тратите своё время на просмотр рекламы, установку левых, не подписанных приложения по прямым ссылкам, а также делитесь своей личной информацией с пол-дюжиной рекламных агрегаторов для мобильных телефонов, передавая им всю информацию к которой имеет доступ AppNana (включая личный email).
Вроде всё понятно. Бесплатный сыр только в мышеловке, тут-же есть плата и она не соизмерима награде. Если быть точным, минимальная сумма для «вывода» 45,000 nanas (внутренняя валюта, 45,000 nanas = 2 $), стартовый капитал 10,400, ежедневно активные пользователи получают 400 nanas (в случае если за предыдущие сутки они смогли собрать 4,000 nanas тем или иным способом), одно «задание» оплачивается от 20 (большинство) до 450 nanas (пока такое задание было только одно), при этом самую большую сумму nanas получают пользователи через рефералов (2 500 nanas приглашающему и приглашенному).
Теперь становится яснее. Самим приложением пользуются не для мизерных премий за скачивание антивирусов бесплатно без смс, а для приглашения всех и вся. Получается что все пользователи (500,000 — 1,000,000 по метрике Google Play) только и делают что создают несколько аккаунтов и по очереди отправляют себе приглашения? Не всё так просто, Max Guan (китайский разработчик, живущий в San Francisco), продумал это заранее. Для того чтобы воспользоваться реферальным кодом, который принесет 2,500 nanas, необходимо предварительно заработать 15 000 nanas, что само по себе является подвигом.
Ладно, оставим в покое «легальные» способы заработка. Попробуем с другой стороны. Устанавливаем Fiddler2 и прокси для Android. Настраиваем прокси для AppNana и смотрим запросы. А они оказываются очень интересными. К примеру вот этот:
POST to appnana2.mapiz.com/api/nanaer_login/ email=someone%40example.com&password=1234567890&source=Android&android_id=abc
В ответ придет SUCCESS и вам выдадут cookie с ID сессии. Вроде все просто правильно? Но вот только этот скрипт никак не ограничивает количество запросов. Brute Force обеспечен. К сожалению если проверять все email и password комбинации, сервер просто отвалится. Хотя оказывается что он может отвалиться с пятисотой ошибкой если android_id будет символом пробела…
Попробуем решить проблему подбора email. Для этого нам понадобится следующий запрос:
GET appnana2.mapiz.com/api/get_nanaer_info/?email=someone%40example.com
В ответ придет полный список с input_invitation (количество принятых рефералов)б paypal_email (AppNana получает его при выводе денег на PayPal), redeem_times (сколько раз получалось вознаграждение), login_times (сколько раз производился вход), bitcoin_address (используется для вывода в BitCoin), offer_nanas (количество «заработанных» nanas), register_ip (IP использованный при регистрации), devices (содержит список всех устройств с которых был произведен вход, вместе с их mac адресами и идентификаторами ios), email(адрес использованный при регистрации), lastlogin_ip (последний IP), nanas (баланс счёта), sent_invitation (количество отправленных приглашений «рефералов»), gift_email (дополнительный адрес для отправки подарочного кода). И еще пара не релевантных полей.
Что мы имеем? API который выдает без авторизации все данные пользователя. Как он нам поможет? Достаточно погуглить AppNana hack и мы тут-же получим почти полный список людей которые пытаются собрать как можно больше nanos через рефералов. В блогах можно найти записи с полутора тысячами комментарием, каждый содержит реферальный код и… почти каждый привязан к аккаунту Google, так как блог работает на Blogger. Наша задача упрощается в разы: парсим выдачу Google, находим все упоминания реферального кода (одна буква, затем 8 цифр), рядом ищем ссылки на профиль Google или email для связи. За пару часов, такой парсер сможет создать высококачественный словарь для brute force атаки на вышеупомянутый скрипт.
Теперь у нас есть база сотен или даже тысяч пользователей с балансом их личных счетов. Что мы можем делать? Всё. Абсолютно всё. Вы скажете что это невозможно, но ведь я еще не раскрыл все карты! Далее нам понадобятся еще два API:
POST to appnana2.mapiz.com/api/invite_verify/
POST to appnana2.mapiz.com/api/redeem/
Первый, активирует реферальный код и начисляет 2,500 nanas на счет. Второй, выводит nanas в Bitcoin или PayPal. Оба работают без авторизации.
В первую очередь вы составим пары аккаунтов у которых есть более 15,000 nanas на счету. Затем мы возьмем привязанные к аккаунтам реферальные коды и обналичим их для всех аккаунтов. Когда все будет готово, можно предположить что имея 1000 кодов и связанных с ними аккаунтами, можно получить 999,000 действительных связей. С учетом того что многие активно используют коды других для получения реферальной награды, можно предположить что 25% связей уже были использованы, это оставляет на с почти 750 новыми связями на аккаунт. Каждая связь приносит 5,000 nanas в систему. Обналичив все доступные нам реферальные коды (750,000 запросов), мы получим 3.75 миллиарда nanos, распределенных по всей системе.
Если брать самую дорогую награду (1,200,000 nanos за 100 $ PayPal), то мы сгенерируем 312,500 $ или если мы предпочитаем анонимность, и готовы за не платить, то мы можем вывести все деньги в Bitcoins, что в результате даст нам 267,857 $ в bitcoins на день конвертации. Это без учета уже доступных балансов пользователей. Всё что нам остается сделать, это воспользоваться Redeem API для перевода денег на наш PayPal аккаунт или Bitcoin кошелёк.
Конечно, навряд ли стартап с одним разработчиком, который по совместительству является и начальником тех поддержки (информация из профиля LinkedIn), имеет PayPal счет или bitcoin кошелек с 312,500 $, но если весь процесс автоматизировать и не вызывать сильных подозрений, можно легко вывести круглую сумму.
Самое интересное, это не является прямым нарушением публичной оферты сервиса. В ней есть пункт 8a который запрещает сбор и хранение личной информации пользователей, при этом ее анализ, без последующего хранения по идее разрешен, также можно игнорировать личную информации, а сохранять только имя пользователя, баланс счета и реферальный код. Пункт 8k запрещает вмешивание в работу системы защиты, включая её отключение, в данном случае системы защиты нет как таковой, то есть используя API без авторизации я не нарушаю этот пункт. Пункт 8r самый обширный. Он запрещает использования автоматического программного обеспечения для доступа к сервису в обход их системе защиты и/или файла robots.txt (ни того не другого у них нет), а модификацию и использования модифицированных версий программного обеспечения для не авторизованного доступа к инфраструктуре AppNana. Тут все еще проще, модификация ПО не нужна, при этом запросы API никак не закрыт файлом robots.txt.
Мною были сняты 90 000 nanas со счета с более 1.5 миллионами nanas. Затем я отправил письмо в тех-поддержку с просьбой отменить транзакцию и вернуть средства пользователю, или хотя-бы вернуть средства пользователю, если транзакция уже была завершена. На следующие утро мне пришел ответ от самого Макса (владельца компании), о том что он уже знает (!) о проблеме и она решается. Интересно что это API работает как минимум с мая 2013 года. В приложении до миллиона человек. Доход с рекламы должен покрыть все затраты и еще хватит на одного программиста который закроет все дыры.
К счастью, или сожалению, это единственное приложение из 20 установленных мною из топа Google Play, которые содержало явную уязвимость. Почти половина из установленных приложения была построена на одном «движке». Запросы были как под копирку, ну и соответственно они были защищены ключом сессии и при малейших вмешательствах требовали повторной авторизации. Пара приложений так и не смогла загрузить рекламу для показа. Еще одно, по всей видимости, не собиралось выплачивать деньги, так как учет баланса вёлся в SharedPrefrences, а запросы отправлялись только для получения списка рекламодателей.
Автор: xeos