2016 is not over yet, but continues to delight us with cool image processing products. At first, everyone was sick with
FaceSwap , then
MSQRD appeared, now we have
Prisma . Even more joy / pride, of course, from the fact that the last 2 products - ours, relatives. MSQRD is made by guys from Belarus, Prisma is originally from Moscow. It is logical that competitors start producing fruit from any popular product right away. The prism in this regard was most fortunate - thanks to the coincidence of certain circumstances, the main competitor to the prism became Mail.ru Group, which almost immediately released already 2 similar products with similar functions:
Vinci (from vk.com team) and
Artisto (from my.com team) ).

And personally it became interesting to me to look at these "clones" from the inside. Why do I need all this and what conclusions did I come to - I told you about it on
roem.ru , I see no point in repeating. On Habré, I would like to share the technique of detailed analysis of iOS applications using the example of Prisma.
')
What are we up to? First, we learn that there is an application for iOS and what it consists of, what information can be extracted from there. Secondly, I will tell you how to sniff traffic from client-server applications, even if their authors do not want this very much. In fact, I will not tell you anything new, I have not invented any know-how, this is just a vector of well-known techniques and skills for applications. But it will be interesting. They drove.
iOS application, IPA file
An iOS application is a .ipa file. In fact, this is a zip-archive and can be opened by any archiver (yes, yes, mobilz promised to teach how to break applications, and in fact will show how to use the archiver). The .ipa file itself is easiest to get using iTunes - in the “Programs” section there is an AppStore tab, which is an analogue of the AppStore on the iPhone. Accordingly, you will need an account (AppleID); downloading an application using iTunes, we can go to the directory to it.


Next, the .ipa-file, as I said, opens with any archiver. Inside we find, among other things, the Payload directory and the iTunesMetadata.plist file. Payload is our application, or rather the directory with the extension .app, which MacOS will try to run, but we just need to open the contents. iTunesMetadata contains meta information from the AppStore. Which account downloaded the application, in which section the application is located, etc. and so on. There is nothing interesting in it for our analysis, we go directly to .app. We will analyze right away on a specific application, Prisma 2.3 - Payload / Prisma.app.
In different projects we can see a different structure, but Info.plist will always be certain (Payload / Prisma.app / Info.plist). These are the basic settings of the application, such as the minimum launch version, supported orientations, iPad support, and more. It is more interesting here:
<?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>
You can read more about the keys in the
official documentation , but we are only interested in some of them.
First, we can get API keys for third-party products (like crashlytics), group / page identifiers in vk / facebook. Secondly, we can know for sure the detailed url settings where the application goes:
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>
We see that the application will want to work with instagram, facebook and vkontakte. This information in no way, of course, will not help "break" the application, but will give us additional information.
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>
If I'm not mistaken, the flag appeared from the 9th version of iOS. Tells us where the application will break under the http-protocol (https any domain is available). Those. with all the desire, the application will not be able to contact http if NSAppTransportSecurity is not configured.
The key as a whole also gives us nothing special, except for information. But the chicken on the grain. We see that the application wants to break on http on vk.com and cdninstagram.com. OK.
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>
Perhaps the most interesting of useless keys. Again, he doesn’t give us anything particularly useful, but he talks about registered urls on this particular application. For example, if in a mobile safari you type fb582433738573752: // you will be transferred to the application (if installed, of course). This information, I repeat, can also be attributed to the conditionally useless. But a couple of times I ran across applications where, in addition to the standard URLs of social networks, I found URLs like “app-admin” or “app-dev”. In the transition to which it was possible to get the hidden settings of the application. In one application, I received editorial access to one edition, in which it was possible to publish articles, shove them to the main page, delete, change places and so forth.
Next we are interested in the Frameworks directory:
Payload / Prisma.app / Frameworks
In it we will find some more useless information about external frameworks and SDKs used.

I will write more in detail below about each framework, but I can say in advance that, for example, you can also get interesting information from here. Among other frameworks, we can see FLAnimatedImage, which works with animated GIFs - the conclusion involuntarily suggests that Prisma will still be with the video.
Also in the metafiles you can often find some garbage forgotten by the developers. Often I find README.md, .gitignore, licenses, and more. Again, Prisma is a good example, because from version 2.3, a photo of a friend just forgotten by the developers appeared in it. Those who get to the bottom, please do not lay out the name of the person in the comments, he was very requested.
Also we find USERTrustRSAAddTrustCA.cer - already interesting. As far as I understood this password-protected certificate, the analogue brute force did not give a profit.
Directly in the binaries are often hidden plist, which can be interesting. Also, if the application is compiled on webview technologies (such as Cordova), we will find the cords config.xml and, in fact, the source code of the application. For example, the
Sworkit application, which among other things offers users to pay for additional video tutorials, already has them in source code in a convenient .mp4 format. You want conveniently - pay. You want inconvenient, but for free - read this article on Habré.
Perhaps this is the main thing that can be obtained from the package with the application. More precisely the main thing that I managed to get. I am sure that you guys are smart and you will find even more useful things - write in the comments and we will add it to the article. But, again, everything is individual. In some applications you can find a lot, including the entire source.
Well, a little more about the application itself. Prism (2.3) 17.6Mb. Native swift, support for Russian and English. Frameworks:
Alamofire.framework - http client
AlamofireImage.framework
AlamofireNetworkActivityIndicator.framework
Bolts.framework - auxiliary toolkit for developers
FBSDKCoreKit.framework - facebook
FBSDKShareKit.framework - facebook
FLAnimatedImage.framework - a library for working with video
KeychainAccess.framework - authorization wrapper. Most often used to work with touchid
Obfuscator.framework - obfuscator, I think, no need to explain here
PINCache.framework - key / value storage for large objects with support for working in different threads.
PINRemoteImage.framework - picache module
pop.framework is a library for working with animation. Most often used for UI animations.
RHBOrientationObjC.framework - work with an accelerometer, more precisely, with the orientation of the device.
SDWebImage.framework - another http_client / cache for images
SwiftyJSON.framework - convenient work with json
Swinject.framework - DI pattern development
VK_ios_sdk.framework - vk.com
What do we have in the end? We have collected a lot of information about the application and understand what to expect from it. We found a certificate and saved it for ourselves. We learned that a video was waiting for us soon and found a cool picture of a friend of the founder Prisma. Moving on.
HTTP sniffing
Prisma and then turned out to be a good example for the article. If the same Artisto and Vinci walk on bare http and there is no difficulty in sniffing them, Prisma walks over https with certificate authentication. And here begin dances with tambourines. But let's order.
1. First we need http (s) proxies. I use
Charles , it is quite simple and functional.
2. We need an iOS device. Emulators will not work.
3. We need one network between devices. The simplest is Wi-Fi.
We launch a proxy on our terminal, at the same time we turn on the https proxy. On the device, respectively, in the settings of the Wi-Fi-network, we register with the hands of the proxy (IP of our terminal and port):
Then most often enough to slip your certificate in iOS. How to do this is well written on the same site
Charles . But in the case of Prisma, this didn’t work out - the developers are not bored and check the authenticity of the certificate. But this is done by means of the device, and we, too, are the sly ones. However, in order to force iOS not to check the certificate for authenticity, we need a jailbreak.
Act it was possible to make up to iOS 9.3.3, and then at your own risk and risk - as an option, use
thematic resources and carefully read the comments. In particular, some “jailbreak-type software” may ask AppleID along with a password, which is fraught with the disappearance of data and money from the attached card. All these details are described in detail.
I will not describe how I did it, because The unlock is very different depending on the version of the device and iOS. The only reason why we need this in this case is
https://github.com/nabla-c0d3/ssl-kill-switch2/releases — the latest version of the ssl kill switch. With the help of Cydia (again, all the information can be found on the network) we put any file browser, for example iFile. And with the help of it we upload the .deb file of the latest release of the ssl kill switch. Work ssl kill switch after rebooting the phone. It is important not to forget to turn it off after all the manipulations, since otherwise, we risk, because our device no longer verifies the authenticity of ssl.

Proxy is enabled, certificate verification is disabled, they are driven to look at the application. The first launch - as you can see, the application first collects the settings. Where does it take them? Twitches
https://cdn.neuralprisma.com/config.json with the usual GET `th, the default settings are there, not interesting. Then twitches
api3.neuralprisma.com/styles POST th with the body
{ "codes": ["public"] }
At the exit the list of filters. Already more interesting, played with an array of [«public»]. Trying to substitute there something like "dev", "new" and other things, I did not get a profit, but maybe one of you will succeed. I recommend using
Postman for this.

Okay, go ahead. The following request when uploading a photo again is POST to url
api3.neuralprisma.com/upload/image
And everything in my life was good, until I saw the heading prisma-image-sign with base64 from binary md5. Life is pain. All my dreams that I will now intercept the traffic of the prism and learn to do the same thing as the application, but just for http ... collapsed. What does it mean? Thus, developers are protected from people like me. Sending a picture via http, the application also calculates some kind of hash with some salt and adds this hash to the header. How to generate a hash knows only the application and the server. The photo is sent to the server, the server generates the hash from the photo using the same algorithm, checks the hashes, if they are different, then the request is forged. There is a way around this if you are strong in assembly language. Disassm binary + analysis of it on the generation of this title can give us an algorithm. But given that there is md5 (minimum) + base64, this can take a lot of time. Well, do not forget that everything is complicated by the presence of the framework Obfuscator.framework. In general, as I already wrote, life is a pain.
All further work of the application is quite simple. The picture is sent to a server, in response we get a certain image name. When you select a style, queries with this application name + style name are sent, the output is profit. But the victory was so close.
Well, okay, let's not despair and analyze the possibility of intercepting the API using the example of another similar Vinci application. As already said, everything goes on the bare http, so we do not even have to distort our device. Simply we register a proxy server and see what goes where when working with the application. All requests can be emulated in Postman, about which I have already written, or implemented in some server language.

Everything is quite simple. When you start the first request Vinci
collects the available styles, then registers the device, we do not care. Then I uploaded the photo, a POST request is sent to / preload from the photo, with any photo, in response we get a certain hash of our photo:

Well, then, as you can see, we get a ready-made image, turning on Urlu
http://vinci.camera/process/2_gNmHxDdthLsmPtuXGxRzQnKjbbspfO/21 , where
2_gNmHxDdthLsmPtuXGxRzQnKjbbspfO
hash photos and 21 - number of the filter, which you can get from
http: // vinci. camera / list
That's all. Total, what have we learned today? We learned how to collect information about the application by the application’s metafiles and learned how to sniff the application’s traffic, even if the entire API goes through https with certificate authentication. We learned to collect information from the API: what, where, why, and also I showed some "dead ends".
For this I will not distract you from the fascinating analysis of applications, if someone finds something interesting, throw in the comments, we laugh together.
By the way, an interesting fact. The same SQLinj. In the web, they are already difficult to meet, any developer understands the danger of injections. But mobile developers, who often come to mobile development not from the web (and even when from the web - trust their API, such as “who knows our API, only our application!”) ​​Often forget about the fun that can wait for full access to the database by a remote user.