А лично мне стало интересно посмотреть на эти «клоны» изнутри. Зачем мне всё это и к каким выводам я пришёл — об это я рассказал на roem.ru, повторяться не вижу смысла. На Хабре же я бы хотел поделиться техникой детального анализа приложений для iOS на примере Prisma.
Что нам предстоит? Во-первых, мы узнаем, что есть приложение для iOS и из чего оно состоит, какую информацию можно оттуда извлечь. Во-вторых, я расскажу как снифать траффик client-server приложений, даже если их авторы этого очень сильно не хотят. По факту я не расскажу вам ничего нового, я не придумал никакого ноу-хау, это просто вектор известных техник и умений на приложения. Но будет интересно. Погнали.
iOS-приложение, IPA-файл
iOS-приложение представляет собой .ipa-файл. По факту это zip-архив и может открываться любым архиватором (да да, mobilz обещал научить ломать приложения, а на самом деле покажет, как пользоваться архиватором). Сам .ipa-файл проще всего получить с помощью iTunes — в разделе «Программы» есть вкладка AppStore, которая является аналогом AppStore в iPhone. Соответственно, вам потребуется аккаунт (AppleID); загрузив приложение с помощью iTunes мы можем перейти в директорию к нему.
Далее .ipa-файл, как я уже говорил, открывается любым архиватором. Внутри мы найдём помимо прочего директорию Payload и файл iTunesMetadata.plist. В Payload находится наше приложение, а точнее директория с расширением .app, которую MacOS будет пытаться запустить, но нам достаточно просто открыть содержимое. iTunesMetadata содержит метаинформацию из AppStore. Какой аккаунт скачал приложение, в каком разделе приложение находится и т.д. и т. п. Ничего интересного в нём для нашего анализа нет, идём непосредственно к .app. Разберём сразу на конкретном приложении, Prisma 2.3 — Payload/Prisma.app.
В разных проектах мы можем увидеть разную структуру, но всегда точно будет Info.plist (Payload/Prisma.app/Info.plist). Это основные настройки приложения, такие как минимальная версия для запуска, поддерживаемые ориентации, поддержка iPad и прочее. Тут уже интереснее:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>DTPlatformVersion</key>
<string>9.3</string>
<key>DTSDKName</key>
<string>iphoneos9.3</string>
<key>CFBundleName</key>
<string>prisma</string>
<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>
<key>CFBundleIcons</key>
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>AppIcon29x29</string>
<string>AppIcon40x40</string>
<string>AppIcon60x60</string>
</array>
</dict>
</dict>
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>CFBundleDisplayName</key>
<string>Prisma</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>instagram</string>
<string>fb</string>
<string>fbauth2</string>
<string>fbshareextension</string>
<string>fbapi</string>
<string>fb-profile-expression-platform</string>
<string>vk</string>
<string>vk-share</string>
<string>vkauthorize</string>
</array>
<key>DTSDKBuild</key>
<string>13E230</string>
<key>CFBundleShortVersionString</key>
<string>2.3</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>iPhoneOS</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>Pushwoosh_APPID</key>
<string>46F12-BE2E4</string>
<key>BuildMachineOSBuild</key>
<string>15G31</string>
<key>DTPlatformBuild</key>
<string>13E230</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>MinimumOSVersion</key>
<string>8.0</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>DTXcodeBuild</key>
<string>7D1014</string>
<key>CFBundleVersion</key>
<string>40</string>
<key>UIStatusBarHidden</key>
<true/>
<key>FacebookAppID</key>
<string>582433738573752</string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>
</array>
<key>Fabric</key>
<dict>
<key>Kits</key>
<array>
<dict>
<key>KitName</key>
<string>Crashlytics</string>
<key>KitInfo</key>
<dict/>
</dict>
</array>
<key>APIKey</key>
<string>8e17945e7d29d1c775f321348caef29075f5ab9a</string>
</dict>
<key>FacebookDisplayName</key>
<string>Prisma.AI</string>
<key>CFBundleIdentifier</key>
<string>com.prisma-ai.app</string>
<key>DTXcode</key>
<string>0731</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>vk.com</key>
<dict>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
<key>cdninstagram.com</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
<key>CFBundleExecutable</key>
<string>prisma</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>DTPlatformName</key>
<string>iphoneos</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>fb582433738573752</string>
</array>
</dict>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>vk5530956</string>
</array>
</dict>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>prisma</string>
</array>
</dict>
</array>
</dict>
</plist>
Про ключи вы можете почитать подробнее в официальной документации, нас же интересуют лишь некоторые из них.
Во-первых, мы можем добыть API-ключи для сторонних продуктов (вроде crashlytics), идентификаторы групп/страниц в vk/facebook. Во-вторых, мы можем точно знать детальные настройки урлов, куда ходит приложение:
LSApplicationQueriesSchemes
<key>LSApplicationQueriesSchemes</key>
<array>
<string>instagram</string>
<string>fb</string>
<string>fbauth2</string>
<string>fbshareextension</string>
<string>fbapi</string>
<string>fb-profile-expression-platform</string>
<string>vk</string>
<string>vk-share</string>
<string>vkauthorize</string>
</array>
Видим, что приложение захочет работать с инстаграмом, фейсбуком и вконтактом. Эта информация никаким образом, конечно, не поможет «сломать» приложение, но даст нам дополнительную информацию.
NSAppTransportSecurity
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>vk.com</key>
<dict>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
<key>cdninstagram.com</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
Если не ошибаюсь, флаг появился с 9-ой версии iOS. Рассказывает нам, куда приложение будет ломиться по http-протоколу (https доступен любой домен). Т.е. при всём желании приложение не сможет обратиться на http, если не настроен NSAppTransportSecurity.
Ключ в целом тоже нам особо ничего не даёт, кроме как информации. Но курочка по зёрнышку. Видим, что приложение хочет ломиться по http на vk.com и cdninstagram.com. Ок.
CFBundleURLTypes
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>fb582433738573752</string>
</array>
</dict>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>vk5530956</string>
</array>
</dict>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>prisma</string>
</array>
</dict>
</array>
Пожалуй, самый интересный из бесполезных ключей. Опять же, он нам ничего особо полезного не даёт, но рассказывает о зарегистрированных урлах на этом конкретном приложении. Например, если в мобильном сафари вы наберёте fb582433738573752:// вас перекинет в приложение (если оно установлено, конечно). Данную информацию, повторюсь, тоже можно отнести к условно-бесполезной. Но пару раз я натыкался на приложения, где помимо стандартных урлов соцсетей я находил урлы типа «app-admin» или «app-dev». При переходе на которые можно было получить скрытые настройки приложения. В одном приложении я получил редакторский доступ к одному изданию, в котором можно было публиковать статьи, пихать их на главную, удалять, менять местами итп.
Далее нас интересует директория Frameworks: Payload/Prisma.app/Frameworks
В ней мы найдём ещё немного бесполезной информации об используемых внешних фреймворках и SDK.
Подробнее я напишу чуть ниже про каждый фреймворк, но заранее могу сказать, что, например, отсюда можно тоже выцепить интересную информацию. Среди прочих фреймворков видим FLAnimatedImage, который работает с анимированными GIF — невольно напрашивается вывод, что Prisma всё же будет и с видео.
Также в метафайлах часто можно найти какой-то мусор, забытый разработчиками. Часто я нахожу README.md, .gitignore, лицензии и прочее. Опять же, Prisma хороший пример, т.к. с версии 2.3 в ней появилась просто забытая разработчиками фотка одного из друзей. Те, кто докопаются, прошу не выкладывать имя человека в комментах, он очень просил.
Также находим USERTrustRSAAddTrustCA.cer — уже интересней. Насколько я понял это запароленный сертификат, аналоговый брутфорс профита не дал.
Непосредственно в бинарнике часто находятся скрытые plist, которые могут быть интересными. Также, если приложение собрано на webview-технологиях (типа Cordova), мы найдём config.xml кордовы и, собственно, исходник приложения. Например, приложение Sworkit, которое помимо прочего предлагает пользователям оплатить дополнительные видеоуроки, уже имеет их в исходниках в удобном .mp4-формате. Хочешь удобно — плати. Хочешь неудобно, но бесплатно — читай на Хабре эту статью.
Пожалуй, это основное, что можно добыть из пакета с приложением. Точнее основное, что удалось добыть мне. Уверен, вы ребята умные и найдёте ещё больше полезного — пишите в комментарии и мы добавим это в статью. Но, опять же, всё индивидуально. В некоторых приложениях можно найти очень многое, в том числе и целиком исходники.
Ну и чуть подробнее о самом приложении. Призма (2.3) 17.6Мб. Нативный swift, поддержка русского и английского языка. Фреймворки:
Alamofire.framework — http-клиент
AlamofireImage.framework
AlamofireNetworkActivityIndicator.framework
Bolts.framework — вспомогательный набор инструментов для разработчика
FBSDKCoreKit.framework — facebook
FBSDKShareKit.framework — facebook
FLAnimatedImage.framework — библиотека для работы с видео
KeychainAccess.framework — враппер авторизации. Чаще всего используется для работы с touchid
Obfuscator.framework — обфускатор, тут, думаю, объяснять не нужно
PINCache.framework — key/value хранилище для больших объектов с поддержкой работы в разных потоках.
PINRemoteImage.framework — модуль picache
pop.framework — библиотека для работы с анимацией. Чаще всего используется для UI-анимации.
RHBOrientationObjC.framework — работа с акселерометром, точнее, с ориентацией устройства.
SDWebImage.framework — ещё один http_клиент/кешер для изображений
SwiftyJSON.framework — удобная работа с json
Swinject.framework — DI паттерн разработки
VK_ios_sdk.framework — vk.com
Что в итоге мы имеем? Мы собрали кучу информации о работе приложения и понимаем, чего от него ожидать. Мы нашли некий сертификат и сохранили его себе. Мы узнали, что нас скоро ждёт видео и нашли классную фотку друга основателя Prisma. Двигаемся дальше.
Сниффаем HTTP
Prisma и тут оказалась хорошим примером для статьи. Если те же Artisto и Vinci ходят по голому http и нет труда их сниффать, Prisma ходит по https с проверкой подлинности сертификата. И тут начинаются танцы с бубнами. Но давайте по порядку.
1. Для начала нам нужен http(s)-прокси. Я пользуюсь Charles, он достаточно простой и функциональный.
2. Нам нужно iOS-устройство. Эмуляторы не подойдут.
3. Нам нужна одна сеть между устройствами. Самое простое — Wi-Fi.
На своём терминале запускаем прокси, заодно включаем и https-прокси. На устройстве, соответственно, в настройках Wi-Fi-сети прописываем руками прокси (IP нашего терминала и порт):
Дальше чаще всего достаточно подсунуть в iOS свой сертификат. Как это сделать хорошо написано на том же сайте Charles. Но в случае с Prisma этого сделать не получилось — разработчики не лыком шиты и проверяют подлинность сертификата. Но делается это средствами устройства, а мы тоже хитрюги те ещё. Однако для того, чтобы заставить iOS не проверять сертификат на подлинность, нам потребуется jailbreak.
Действуйте можно было сделать до версии iOS 9.3.3, и то на свой страх и риск — как вариант, используйте тематические ресурсы и внимательно читайте комментарии. В частности, некоторый софт «типа для джаилбрейка» может попросить AppleID вместе с паролем, что чревато исчезновением данных и денег денег с привязанной карты. Все эти тонкости подробно описаны.
Я не буду описывать как делал это я, т.к. разлочка сильно отличается в зависимости от версий устройства и iOS. Единственное, зачем нам это надо в данном случае — https://github.com/nabla-c0d3/ssl-kill-switch2/releases — крайняя версия ssl kill switch. С помощью Cydia (опять же, всю информацию можно найти в сети) ставим любой просмоторщик файлов, например iFile. И с помощью него заливаем .deb-файл последнего релиза ssl kill switch. Работать ssl kill switch после перезагрузки телефона. Важно не забыть его выключить после всех манипуляций, т.к. в противном случае мы рискуем, ведь наше устройство больше не проверяет подлинность ssl.
Прокси включён, проверка сертификата выключена, погнали смотреть на приложение. Первый запуск — как видим, приложение сначала собирает настройки. Откуда же оно их берёт? Дёргается https://cdn.neuralprisma.com/config.json обычным GET`ом, там стандартные настройки, не интересно. Потом дёргается api3.neuralprisma.com/styles POST-ом с телом
{
"codes": ["public"]
}
На выходе список фильтров. Уже интересней, поигрался с массивом [«public»]. Пытаясь подставить туда что-то вроде «dev», «new» и прочего, профита я не получил, но может у кого из вас получится. Я рекомендую использовать для этого Postman.
Ладно, идём дальше. Следующий запрос при загрузке фото опять POST на урл api3.neuralprisma.com/upload/image
И всё было в моей жизни хорошо, пока я не увидел заголовок prisma-image-sign с base64 от бинарного md5. Жизнь боль. Все мои мечты о том, что я сейчас перехвачу траффик призмы и научусь делать то же самое, что и приложение, но просто по http… рухнули. Что это значит? Таким образом разработчики защищаются от таких как я. Посылая фотку по http, приложение также вычисляет какой-то хеш с какой-нибудь солью и добавляет этот хэш в заголовок. Как сгенерить хэш знает только приложение и сервер. Фотка отправляется на сервак, сервак генерит хеш от фотки по тому же алгоритму, сверяет хэши, если они отличаются — значит запрос подделан. Есть способ обойти это, если вы сильны в ассемблере. Дизассм бинарника + анализ его на тему генерации этого заголовка может дать нам алгоритм. Но учитывая, что там md5 (минимум) + base64, на это может уйти много времени. Ну и не забываем, что всё усложняется ещё и наличием фреймворка Obfuscator.framework. В общем, как я уже писал, жизнь боль.
Вся дальнейшая работа приложения достаточно простая. Картинка отправляется на сервак, в ответ получаем некое имя изображения. При выборе стиля шлются запросы с этим именем приложения + именем стиля, на выходе профит. А ведь победа была так близка.
Ну да ладно, давайте не будем отчаиваться и разберём возможность перехвата API на примере другого подобного приложения Vinci. Как уже говорил, там всё ходит по голому http, поэтому нам даже не придётся коверкать наше устройство. Просто прописываем прокси сервер и смотрим что куда ходит при работе с приложением. Все запросы можно эмулировать в Postman, о котором я уже писал, или реализовать на каком-нибудь серверном языке.
Всё достаточно просто. При запуске первым запросом Vinci собирает доступные стили, далее регистрирует девайс, нам это пофиг. Затем я загрузил фото, отправляется POST-запрос на /preload с фото, с любым фото, в ответ мы получаем некий хэш нашего фото:
Ну и далее, как видно, получаем уже готовое изображение, обращаясь по урлу http://vinci.camera/process/2_gNmHxDdthLsmPtuXGxRzQnKjbbspfO/21, где
2_gNmHxDdthLsmPtuXGxRzQnKjbbspfO
хеш фото, а 21 — номер фильтра, которые можно добыть из http://vinci.camera/listВот и всё. Итого, чему мы научились сегодня? Мы научились собирать информацию о приложении по метафайлам самого приложения и научились сниффать трафик приложения, даже если всё API ходит по https с проверкой подлинности сертификата. Мы научились собирать информацию из API: что, куда, зачем, а также я показал некоторые «тупики».
За сим не буду отвлекать вас от увлекательных анализов приложений, если кто что интересное найдёт, скидывайте в комменты, вместе посмеёмся.
Кстати, интересный факт. Те же SQLinj. В вебе их сейчас уже сложно встретить, любой разработчик понимает всю опасность инъекций. Но вот мобильные разработчики, которые часто приходят в мобильную разработку не из веба (а даже когда из веба — доверяют своим API, типа «да кто его знает наше API-то, только наше приложение!») частенько забывают про веселье, что может их ждать при полном доступе к базе удалённым пользователем.
Комментарии (53)
navion
24.08.2016 22:26+1Также находим USERTrustRSAAddTrustCA.cer — уже интересней. Насколько я понял это запароленный сертификат, аналоговый брутфорс профита не дал.
Это сертификат удостоверяющего центра, который выпустил сертификат для сервера с API.
Ничего интересногоmobilz
24.08.2016 23:35Это понятно, я даже корневой для него нашёл, но зачем он в приложении?
navion
24.08.2016 23:53+2Какая-нибудь защита от MitM, чтобы приложение не пыталось отправлять картинки на captive portal.
Funbit
25.08.2016 05:09Сомневаюсь что это защита. Просто они пользуются не сильно популярным сертификационным центром, для проверки которого нужно вручную устанавливать промежуточные СА. Эти промежуточные сертификаты обычно выложены на сайтах для скачивания и последующей регистрации вручную.
grossws
25.08.2016 11:23+1Просто они пользуются не сильно популярным сертификационным центром, для проверки которого нужно вручную устанавливать промежуточные СА
Бред. Никто не подпишет вам TLS сертификат напрямую сертификатом CA, им подписывают intermediate, сертификаты для подписи crl и ocsp и т. п. А для того, чтобы клиент мог проверять всю цепочку сервер отдаёт не только сертификат хоста, но и все промежуточные, кроме сертификата root CA.
Funbit
25.08.2016 12:10SSL сертификаты как раз подписываются промежуточным СА, что я и написал. Про корневые сертификаты речь вообще не шла…
Что касается автоматического скачивания цепочек, это всё в идеале (в Windows, например). В реальности же почти везде мало известные промежуточные СА сертификаты нужно вставлять вручную. Зайдите, например, в AWS и попробуйте зарегистрировать SSL сертификат, скажем, от Cybertrust. У вас ничего не получится, пока вы не предоставите, вручную (в нужное текстовое поле), соответвующий промежуточный СА: https://www.cybertrust.ne.jp/sureserver/support/download_ca.htmlgrossws
25.08.2016 12:30Мой коммент про root CA касался того, что должно быть в "хранилище сертификатов"/ca-certificates/keychain/whatever.
Что касается автоматического скачивания цепочек, это всё в идеале (в Windows, например).
Intermediate CA certs не "скачиваются" и не устанавливаются в системное/браузерное хранилище. Они отдаются сервером в рамках установления TLS-соединения (в
Server certificate
, сразу послеServer hello
), см. RFC 2246 и RFC 6101.
Скачивают и устанавливают их, разве что, по глупости. Своей или администраторов сервера, которые не осилили сделать cat и своего сертификата и цепочки intermediate.
Причём здесь винда — хз, оно так работает, как минимум, со времён SSL v3. У всех, кто может в стандарты.
Зайдите, например, в AWS и попробуйте зарегистрировать SSL сертификат, скажем, от Cybertrust. У вас ничего не получится, пока вы не предоставите, вручную (в нужное текстовое поле), соответвующий промежуточный СА
Тёплое с мягким-то не путайте. Естественно амазону нужны промежуточные сертификаты, иначе как он их будет отдавать в
Server certificate
? S3/CF-то работают в качестве сервера.Funbit
25.08.2016 12:46Intermediate CA certs не «скачиваются» и не устанавливаются в системное/браузерное хранилище.
Еще как скачиваются и устанавливаются, по крайней мере в Windows. Зайдите в certmgr.msc и посмотрите категорию «Intermediate Certification Authorities». Можете даже сравнить до и после посещения сайта, с подобным редким промежуточным СА (которого в чистой системе еще нет).
Тёплое с мягким-то не путайте. Естественно амазону нужны промежуточные сертификаты, иначе как он их будет отдавать в Server certificate? S3/CF-то работают в качестве сервера.
Здесь я имел в виду то, что эта процедура требуется не для всех сертификатов, а только для тех, чей промежуточный СА достаточно редкий, чтобы AWS не имел его у себя в своем хранилище.grossws
25.08.2016 16:04-1Зайдите в certmgr.msc
-> % certmgr.msc zsh: command not found: certmgr.msc
Извините, не удержался.
Если серьёзно, то это, скорее всего, то, что обычно именуется CryptoAPI cache. Он пополняется при получении intermediate из gpo/enterprise policies или через AIA (authority information access), прописанном в самом сертификате.
Тот же firefox раньше использовал своё NSS-хранилище и на виндовое ему было плевать. Как сейчас — не ведаю; с виндой давно не имею дел без крайней необходимости.
Здесь я имел в виду то, что эта процедура требуется не для всех сертификатов, а только для тех, чей промежуточный СА достаточно редкий, чтобы AWS не имел его у себя в своем хранилище.
Иии? Логично, что aws надо откуда-то получить всю цепочку. То, что они упростили пользователям жизнь в каких-то частных случаях ни коим образом не говорит о том что требуется "устанавливать промежуточные СА" потому что "они пользуются не сильно популярным сертификационным центром, "для проверки которого нужно вручную устанавливать промежуточные СА".
Напомню, речь шла о зашитом в клиентское приложение сертификате, который как выше предположил navion, скорее всего, используется для cert pinning.
rockin
24.08.2016 23:08+2Кто ж снифит через прокси? :)
Нужен софт, который проводит arp-атаку, например, nighthawk (под винду), что заставляет весь трафик с исследуемого устройства (мобилы, планшета, телики, приставки) идти через ваш комп, где услужливо торчит теплый и ламповый wireshark.mobilz
24.08.2016 23:28+3Это путь джедая, а я скрипткидди же ) я стар и ленив и уже не люблю руками разбирать gzip`ы, возиться с wireshark`ом итп. В моём случае эволюция дала обратный виток, из джадая я превратился в штурмовика )
grossws
25.08.2016 00:19+1Один из стандартных вариантов жеж, подсунуть HTTP_PROXY + HTTPS_PROXY, а дальше mitmproxy ,)
Chupakabra303
25.08.2016 09:51+1Некоторый роутеры, например микротик, умеют дампить трафик для дальнейшего анализа в wireshark. Либо коммутатор с mirror портом. Никакого вмешательства в трафик.
0Ilya
24.08.2016 23:35+1Спасибо, отличная статья!
Побольше бы таких статей, обходящих интересные моменты уязвимости и написанных понятным языком.)
abyrkov
24.08.2016 23:37Сказать, как получить алгоритм от Prism'ы?
С помощью фотки, хах.mobilz
24.08.2016 23:39Алгоритм открыт, был опубликован на сайте MIT. Ребята доработали его и вложили в приложение.
Кстати, в последней версии призмы есть оффлайн фильтры, которые так же можно выудить из приложения описанным выше способом. Точнее не алгоритм, а модель нейросети, конечно.grossws
25.08.2016 00:20Это не с ними был скандал, что они использовали чужую сеть без указания авторства и ссылки на первоисточник?
jehy
25.08.2016 10:05+6Минус за заголовок в сочетании с тем, что вы не нашли в приложении ровно ничего интересного. Содержание воды в статье больше, чем в человеке.
mobilz
25.08.2016 11:00-1Простите господин, что не нашёл ничего интересного для вас в приложении и посмел написать о этом.
Мне надо было списком выложить приложения и их уязвимости? )jehy
25.08.2016 12:03+7Не то что вы не нашли ничего интересного для меня, вы не нашли ничего интересного вообще.
Вы открыли приложение и обнаружили там:
1) О мой бог — фреймворки! Приложение использует фреймворки!
2) Сертификат, назначение которого не поняли.
3) API ключи для crashlytics. Ценная находка — теперь вы можете собрать своё приложение и отправить ребятам ложные сообщения о ошибках. Мда.
4) Идентификаторы групп в фейсбуке и вконтакте. Сомнительное достижение с учётом того, что они и так открыты…
5) Фотка друга. Единственное что вообще претендует на интересное и смешное открытие.
Далее статья изобилует чудесными утверждениями типа
Видим, что приложение захочет работать с инстаграмом, фейсбуком и вконтактом. Эта информация никаким образом, конечно, не поможет «сломать» приложение, но даст нам дополнительную информацию.
Какую же это вам дало дополнительную информацию? А что, без этого не видно, что приложение работает с этими сеточками? Очередное ведро воды в тексте.
В финале вы облажались с подделкой запроса в призму и почему-то написали кучу текста про запросы в Vinci — непонятно, какое это имеет отношение к статье кроме набивки объёма.
Если бы статья называлась «что мы можем понять с первого взгляда на мобильное приложение на примере Prisma и Vinci» — не вопрос, плюсик вам в карму и все дела. Но претендует-то она на совсем другое. А называть статью по аналогии с другой плохой шуточной статьёй с упоминанием мейнстримного приложения для накрутки просмотров — с моей точки зрения очень плохой тон.mobilz
25.08.2016 12:37-1Перед текстом я явно указал:
По факту я не расскажу вам ничего нового, я не придумал никакого ноу-хау, это просто вектор известных техник и умений на приложения.
Я даю вам удочку, а рыбу ловите сами. Если вы знали все эти техники до этой статьи, зачем вообще читали? Хотя вряд ли вы были в курсе этих техник, если для подделки crashlytics евентов предлагаете собирать собственное приложение…
Для вас пошаговая демонстрация техники это вода, а кому-то может пригодиться. Для этого и стоит флажок «туториал» рядом с названием статьи. «Облажался» с запросами к призме я не случайно, статья писалась не пошагово, а сразу после всей экспертизы этих приложений. И Призма отличный пример для объяснения техники обхода защиты от mitm и отличный пример тупика. Винчи тут как раз для того, чтобы логично завершить блок с рассказом о сниффе и зачем он нужен.
А называть статью по аналогии с другой плохой шуточной статьёй с упоминанием мейнстримного приложения для накрутки просмотров — с моей точки зрения очень плохой тон.
Мне просмотры вообще по барабану, а называть статьи по аналогии с другими популярными, это хорошая традиция на хабре. У моих статей на хабре достаточно просмотров, чтобы перестать уже мастурбировать на них. Конечно, мне как автору, приятно видеть положительные отзывы и плюсики моему тексту. Но это давно уже не самоцель )
TimsTims
25.08.2016 16:54+2> Перед текстом я явно указал: я не расскажу вам ничего нового, я не придумал никакого ноу-хау
В то же время вы пишите, что будете делать ДЕТАЛЬНЫЙ АНАЛИЗ:
> я бы хотел поделиться техникой детального анализа приложений
Это как-бы подразумевает, что вы сейчас разберете все приложение и даже найдете, как считается хэш файлов, как работает программа и разберете её детально, на ДЕТАЛИ. У вас не только заголовок получился желтым, но и содержание.
akov
25.08.2016 10:36+2Алгоритм подписи prisma-image-sign можно изучить, разобрав приложение для android. Так же в этом поможет davlik код, дописав который можно на консоль IDE вывести все, что используется для генерации этой подписи.
mobilz
25.08.2016 11:19Алгоритм подписи я знаю, это хеш-функция, md5/sha256 или что-то подобное + base64. Мне интересней соль, которая используется для генерации хеша. Как получить её быстро и без особых усилий — мне не известно.
Scratch
25.08.2016 13:15+10Там особо нечего получать, код выковыривается из APK андроида очень легко, даже почти читабелен (хоть и обфусцирован)
Этот метод как раз вызывает HmacSHA256 с так желанной вами солью
private String a(byte[] bArr) { if (bArr.length >= 82) { bArr = a.a(Arrays.copyOfRange(bArr, 0, 42), Arrays.copyOfRange(bArr, bArr.length - 42, bArr.length)); } String str = BuildConfig.FLAVOR; try { str = Base64.encodeToString(i.a(bArr, "duGB^Vy3Q&FQrJz2guKJBxNH3dAr/sQx"), 0).trim(); } catch (Throwable e) { Log.e(g.class.getName(), "Error encoding image", e); } return str; }
А вот метод, который принимает этот массивчик из 42 байт и соль
public static byte[] a(byte[] bArr, String str) throws Exception { Mac instance = Mac.getInstance("HmacSHA256"); String trim = Base64.encodeToString(a(PrismaApplication.b().getString(2131165323).getBytes()).getBytes(), 0).trim(); str.getBytes(); instance.init(new SecretKeySpec(trim.getBytes("UTF-8"), "HmacSHA256")); return instance.doFinal(bArr); }
Правда либо криво декомпильнулось, либо они эту соль не используют, а вместо неё какой то строковый видимо ресурс getString(2131165323). Это вы уже сами
Так что, всё расковыривается на раздва, никаких проблемmobilz
25.08.2016 13:48пора подтягивать свои познания в андройдовских apk ) спасибо, очень интересно
negodnik
01.09.2016 11:32Там не сложно даже тому, кто Android в глаза не видел. Любой APK можно онлайн декомпилировать в Java-код, бесплатных сервисов вагон. И внутри уже посмотреть строковое значение ключа. На самом деле ребята не морочились с безопасностью особо.
negodnik
01.09.2016 11:33Вошел, чтобы написать коммент о том, что проще взять вариант Android и декомпилить его в Java-код за минуту.
mihmig
25.08.2016 15:55Спасибо топикстартеру за postman (не знал) и charles (знало, но только после статьи сподобился разобраться с MITM SSL)
Тут же подсмотрел протокол общения утилиты MTS для отправки СМС с компьютера
nomn
Газетный заголовок какой-то получился.
Boomburum
Думаю, это кавер на этот пост )
nomn
Понятно, спасибо)
mobilz
Поддерживая традицию аналогии https://habrahabr.ru/post/307822/
neolink
интересно почему айди вашей статьи меньше на 200к…
https://habrahabr.ru/post/123238/
mobilz
Я в прошлое написал, очевидно же
BaRoN
а резюме уже у вас на рабочем столе! :D
ragequit
Старый неопубликованный черновик. Ему присвоился когда-то ID вот такой мелкий, который никак не зависит от того, была статья опубликована или нет.
mobilz
Может на сервере хабра начало кончаться место и они решили повторно использовать id удалённых постов?
ragequit
ноуп :)
neolink
теплый, ламповый черновик июля 2011 года…
enniel
Мне заголовок больше напомнил текст с рекламного баннера.