📜 ⬆️ ⬇️

We break iOS-application. Part 1

You did a good job, and here is your app in the App Store!


Reason to think about the security of the code and data! We will look for vulnerabilities in the test application. In this article we will talk about data security, and in the next - let's move on to the code.

Disclaimer


The purpose of this lesson is not to make you a hacker, but to show how intruders can circle you around a finger. The article missed some infa, necessary for hacking a real application on the device. We will torment the simulator (by the way, it seems to be even legitimate [citation needed] ).
')
Disclaimer from the translator: a lot of “water” and references to Hollywood (and so long) are removed from the original text. Added a number of key explanations.

so


No application is safe! If someone really wants to find your vulnerabilities, he will find them. There is no guaranteed way to prevent an attack. Is that not to release the application. But there are great ways to prevent burglars. (According to the author, they get bored, and they will go to sleep to look for easier prey, yeah. - Approx. Lane. )

Before reading further, you should understand approximately what a terminal is, as well as Objective-C and Cocoa (however, there will not be much code).

Let's get started


We will need:
1. Class-dump-z utility;
2. A proxy for debugging over the network, for example, Charles (the trial version is distinguished by annoying messages and works for a maximum of 30 minutes in 1 session). In the comments to the source of the article advise an alternative to Charles - Burpsuite .

That you creatively approached the process, I offer you a script. Imagine: a new application for the iPad - “Meme Collector” (Meme Collector). Everyone likes. But you whispered in your ear that the built-in purchases pulled you a significant amount of money.



In general, you are thinking of getting paid content (memes) for free. There are several areas where you can move, we will talk about them - and about the appropriate methods of protection.

Slight simplification
Because of the length of this lesson, we initially made some simplifications in the test project. For example, the “purchase” of game currency is not a real in-app purchase, but a fake request to StoreKit (everything happens locally on the device).


What is what? "Map" of the application (application mapping)


Take a look at the application from a bird's eye view! What does it do from the user's point of view? What is its main structure?

Open the Meme Collector project in your favorite IDE or in Xcode (not ads).



We will run the application in the Release configuration.
Xcode: Product> Scheme> Edit scheme ... ( ⌘ < ) - select Run ... on the left, Info> Build Configuration: Release tab on the right.
AppCode: Run> Edit configurations ... > Configuration: Release.

Run the application on the iPad simulator ( ⌘R ). And now forget that you have the source code, you are the user. One of two things will open:


Do you have an option on the left?
It is habraeffekt or problem with connection. Memes are taken from the memegenerator.net API - check that this URL produces {"success":true,"result":[ ]} . During the translation of the article, they had problems with the server. If there is a desire to save the project from dependence on this API, velkam github.

This strange interface allows you to “buy” a meme by tapu on it, and also shows the number of purchases of this meme and the balance of money in your account. From the translator: by clicking the “Purchase Currency” button, I really thought: Did I enter the Apple ID on the simulator?



... but he remembered that my credit card was not attached to my US account. :) Russian would say the price in rubles.

In general, everything is simple. There is a "game currency", and you (like a cracker) do not want to give real money for it. Our goal is to get more memes without pressing the “Purchase Currency” button.

We have roughly understood what the application is doing, let's take a deeper look. What else can we learn?

The class-dump-z utility will display all the declarations that it can get from the executable file. Download the latest version of the utility (for example, 0.2a), unpack the archive. In the terminal, go to the class-dump-z_0.2a/mac_x86/ . There is a class-dump-z executable file, install it, for example, by copying it to /usr/bin/ :

 sudo cp class-dump-z /usr/bin/ 

Go to the iOS simulator folder: (instead of 7.0.3 - your version)

 cd ~/Library/Application\ Support/iPhone\ Simulator/7.0.3/Applications/ 

Here are all the applications that you run in the simulator. There may be many of them. How to find Meme Collector?

Option 1. If you just launched the Meme Collector, then it lies in the folder with the newest modification date. Just go into it:

 cd `ls -tr | tail -1` 
What is this magic?
  • The ls command returns the contents of a folder. The "-tr" flag sorts by time: the newest folder will be the last in the list.
  • This entire list is input to the tail command. It takes some amount of data from the end. In this case, exactly one line (the flag "-n 1" or simply "-1").
  • Next, the cd command goes to this newest folder.

Option 2. Take and find:

 find . -name "Meme Collector" 

In my case, the folder is called 9A72F266-8851-4A25-84E4-9CF8EFF95CD4 - hereinafter we will call it simply the "application folder". In it lies:

A bundle is a folder (namely a folder, yes, with the extension .app ), in which there are one or more executable files plus resources for them (pictures, sounds, digital signature, in general, anything, even other bundles ... read more ). Go to the main bundle folder:

 cd Meme Collector.app 

There is an executable file, which is called: Meme Collector (without extension). Let's look at what frameworks and shared libraries there are links to it. The standard otool utility will help otool :

 otool -L "Meme Collector" 

And that's what we see:

 Meme Collector: /System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration (compatibility version 1.0.0, current version 615.0.0) /System/Library/Frameworks/MobileCoreServices.framework/MobileCoreServices (compatibility version 1.0.0, current version 51.0.0) /System/Library/Frameworks/Security.framework/Security (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/StoreKit.framework/StoreKit (compatibility version 1.0.0, current version 1.0.0) /System/Library/Frameworks/QuartzCore.framework/QuartzCore (compatibility version 1.2.0, current version 1.8.0) /System/Library/Frameworks/UIKit.framework/UIKit (compatibility version 1.0.0, current version 2903.23.0) /System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 1047.22.0) /System/Library/Frameworks/CoreGraphics.framework/CoreGraphics (compatibility version 64.0.0, current version 600.0.0) /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 227.0.0) /usr/lib/libSystem.dylib (compatibility version 1.0.0, current version 111.0.0) 

Mm, I wonder if the application uses the Store Kit framework - in-app purchases? Come on, go ahead. Run the class-dump-z utility:

 class-dump-z "Meme Collector" > ClassDump.txt 

And open the file in the standard goove editor:

 open ClassDump.txt 
Wow! Although there is, compared with the example from the original article (Xcode 4, iOS 6 SDK) there appeared some unpleasant moments like XXUnknownSuperclass , but still! We see not only the interface part, but also declarations of private methods, properties, and protocols.

Studying the dump classes of a serious project is often a tedious task. But it can give an amazing picture of the internal device of the application!

So, my young tracker! Find me all the singletons in the app.

hint
Signatons often have class method declarations with keywords: manager, shared, store.

If you meet an interesting singleton, learn all his methods.
(Apparently, "interesting" = "seems to be related to the logic of the application." - Note. Trans. )

Decision
Accurately found? Take a closer look at yourself. There are about four of them.

Yes all.
  • AFNetworking

  • MemeManager is an interesting singleton! He contains:
     @property(retain, nonatomic) AFHTTPClient* client; @property(readonly, assign, nonatomic) NSMutableArray* memes; +(id)sharedManager; -(void)memePurchased:(int)purchased; -(void)getMemeInformation; // ,  private- 


  • MoneyManager is also an interesting singleton:
     @property(readonly, assign, nonatomic) NSNumber* money; +(id)sharedManager; -(BOOL)saveState; // ,  private- -(void)loadState; // ,  private- -(BOOL)purchaseCurrency; -(BOOL)buyObject:(id)object; 


  • SVProgressHUD


Crackers often do what you just did — look for certain words in a class dump. For example, if they want to find out if there is logic in the application tied to a jailbreak device, then search by the words 'jailbroken', 'security', etc. may give a quick answer.

How to prevent this?


There are two news. I'll start with the good.

Apple does this for you automatically. When you send the app to the App Store, they encrypt your binaries using DRM technology called FairPlay . If you dump the class-dump-z'om encrypted binary, you will get ... gibberish.

The bad news: getting around this protection is pretty easy! The case for 10 minutes (manually), but still have the means to automate this process. In general, be sure your application will be decrypted and will see the names of all your classes, methods, protocols, etc.



Plist files: vulnerable!


We learned something about the application. Now look for all that is bad. Developers are prone to make mistakes. It is common for intruders to use these errors for their own purposes.

Mistakes ... Let's start with the most stupid! For example, how do you get the idea: use a .plist file to store critical information? Crackers always look at the plists: they are easy to see, and studying them can provide the key to the internal logic of the application. (Plist = property list, text file with serialized objects).

Let's see which plists we have?
(remember, we are still in the “Meme Collector.app” bundle folder)

 ls *.plist 

But what - two things:

 Info.plist MoneyDataStore.plist 

Let's see the first one - Info.plist:

 plutil -p Info.plist 

Result:

 { "DTSDKName" => "iphonesimulator7.0" "CFBundleName" => "Meme Collector" "CFBundleDevelopmentRegion" => "en" "CFBundleVersion" => "1.0" "DTPlatformName" => "iphonesimulator" …   … 

Nothing interesting, some general information. Okay. Well, and the second:

 plutil -p MoneyDataStore.plist 

And we see:

 { "userCurrency" => 108 } 

Funny! This .plist contains the userCurrency key with the same value that you just saw on the simulator screen. Does this mean that the application stores money in .plist? There is only one way to find out!

 open MoneyDataStore.plist 

Change the userCurrency value, for example, to 1234. Save and close the .plist file.

Let's go back to the simulator. Remove our application from RAM (as they say, "from multitasking").
Just in case the instruction.
The combination of the ⇧⌘H keys in the iOS simulator corresponds to pressing the Home button. Press this combination twice to show the multitasking screen, and flick the Meme Collector up to nowhere .

It seems he is not very pleased that it looks like:
In the future, when I say “restart the application”, I will mean this operation.

Run the application again. 1234 virtual tugriks at your disposal!
From the translator: I was waiting for more intrigue. It is never that easy! Although your test project write.

Custom settings: unsafe!


Well, you understand? Keeping important information in .plist is not a good idea. Now guess: what are the user settings ( NSUserDefaults )? Yeah, plist too! Physically, it lies at {App Directory}/Library/Preferences/{Bundle Identifier}.plist .

This is the place where developers often mistakenly feel safe. Not only freelancers: large corporations from time to time fall into this trap. Countless applications store important data in NSUserDefaults . Let's see what we prepared here Meme Collector?

From the terminal (we are still in Meme Collector.app, right?), Open the file:

 open ../Library/Preferences/com.selander.Meme-Collector.plist 

A simple exercise for you: using the methods mentioned above, modify NSUserDefaults to get a bunch of memes from the “YU No ...” series for free. Even if you have already guessed everything, I advise you to do it to consolidate.



But after all malefactors can get access to plist-files, even when the iOS-device is blocked - so where it is safe to store data? One solution is to store the data in NSUserDefaults in encrypted form. In this case (and not only. - Approx. K.. ) you need to check the data read from there for validity.

A bunch of keys: the best recipes


Another possible solution is to transfer important data from .plists to the iOS Keychain (Keychain). How to do it - it is written, for example, here .

A bunch of keys "raises the stakes" for the hacker. Attackers will not be able to pull anything off if the device is locked.

However, you shouldn’t rely solely on the Keychain alone! And that's why. The keychain is supported by Apple. (Well, you already understood everything, yes?) The information in it is encrypted with the user's password, which is usually a simple 4-digit numeric code. And this means that a brute force attack will take about twenty minutes. Having found out the password, it is easy to dump the entire keychain.

What to do? Some general recommendations:


Network: penetration testing


More hackers love to see how the application interacts with the network. The most stupid way to see if there is any work with the network on the device is to look for URLs in a binary.

While in the bundle folder (Meme Collector.app), type in the terminal:

 strings "Meme Collector" 

Stop where so much! The strings command goes through sections of a binary and prints all data elements that are similar to strings. Filter the noise:

 strings "Meme Collector" | grep http 

And, well, one line:

 http://version1.api.memegenerator.net/Generator_Select_ByUrlNameOrGeneratorID 

It seems that at some point the application turns to the meme generator for this urla. As a hacker, you would like to investigate this matter further by examining the network traffic of the application. To do this, we need a network monitor that intercepts all incoming and outgoing requests.

Charles, mentioned at the beginning of the article is a good option for such a study. Download it if you have not done it yet. Install and run.

Check that Charles catches network interaction with the iOS simulator (by launching Maps, or in Safari, type the URL). You will see how network requests will run in Charles. If this does not happen, make sure that the box is checked in the Proxy> Mac OS X Proxy menu.

By the way, Charles perfectly intercepts SSL traffic.
We will not do this because we did not see the HTTPS URLs at the output of the strings command. But this step is required for other applications that can use HTTPS. In the Proxy> Proxy Settings ...> SSL menu, you need to enable SSL proxy and add domains that need to intercept (and decrypt) HTTPS traffic. Until you do this, SSL will look something like this:


With Charles running, restart the Meme Collector. After launch, you should see three requests for version1.api.memegenerator.net version1.api.memegenerator.net by clicking on the triangle to the left of the url (see below). Three queries will open that have different GET parameters. For example, the first one has a GET parameter: urlName=Foul-Bachelor-Frog — this can be seen on the Request tab.

Select the Response tab and then JSON at the bottom. The server response, decrypted from JSON, is presented in the form of a beautiful label:



We see here many strings of the key-value type: heading ( displayName ), description ( description ), image URL ( imageUrl ) - in general, some information on this type of memes “Four Bachelor Frog” from the GET parameter.

What happens next? The application does the same thing three times: an HTTP request for url pictures, tries to download it from cdn.memegenerator.co , receives a 301th redirect to cdn.memegenerator.net and cdn.memegenerator.net from there.



It looks like what we saw in the app, right? Two other pictures were less fortunate this time, they did not wait for a response from the server (Charles reports this on the Overview tab) and therefore did not appear in the application.



And I don’t even see pictures requested!
When you restart the pictures can be taken from the simulator cache, Charles does not know this. Clear the cache and restart the application.

 rm -R Library/Caches/ 


So, with a certain probability we conclude: the application takes memes from this API and presents them in the form of paid content. And what if you try to change the URL in order to acquire some new content besides these three memes? It is unlikely that there is a check whether the application really receives from the server what the developer expected!

Are you already tired of these three memes? Well, let's try, is it possible to display and “buy” something new, say, “Success Kid”.

Select Charles from the menu: Tools> Rewrite . This feature allows you to intercept incoming / outgoing requests and modify them according to the rules that you set. Enable the checkbox Enable Rewrite . Rules are grouped into “sets”. Under the Sets list, click Add to add a new rule set. Optionally, rename (Name). We have created a set of rules, but it is still empty. Let's add a rule - in the Rules section there is an Add button, click it.



The Rewrite Rule window has opened. Change Type to “Modify Query Param” and complete two fields:




Click OK, OK. Restart the application ... Success! We can buy content that was previously unavailable.



Interesting: for this new meme a specific price is indicated. From where The application had to somehow determine the cost based on the JSON response.

Open the Response tab and look at the JSON that the server returns. What can determine the value of the price?

Try to find JSON-keys that can determine the cost of the meme in the application. Maybe it's generatorID, totalVotesScore, instancesCount, templatesCount or ranking. As an exercise for you: find the key that affects the cost of the meme.

To do this, go to Proxy> Breakpoints. Click Enable Breakpoints and click Add to add a new breakpoint. The Edit breakpoint window will appear, enter the following data in it:




Now restart the application. As soon as we receive a response from the server, a breakpoint will work. When this happens, click on the Edit Response tab, at the bottom select JSON:



Here you can manually modify the JSON response that will go to the application. Play around with these parameters and try to determine which keys affect the price displayed in the application. After changing the JSON response, click Execute to send the response. The application makes three requests to the API, so you will need to click Execute three times.

Found what key affects the price?
This is the ranking . The higher the ranking , the lower the price.

Important: act fast! AFNetworking has a timeout of 30 seconds. If you have intercepted the answer, but did not have time to make changes, AFNetworking will return a request timeout error and execute the corresponding handler in the code (which in this case does nothing). If you have time, restart the application and try again.

What's next?

You discovered hacking abilities and performed simplest penetration tests using the example of the file system and network interaction of a specific application. You have won simple plists and can even modify server responses.

Perhaps this knowledge will enhance the security of your iOS application ... a little bit. In the next part, we will delve much further into the bowels of the application, we will change its functionality! And while you're waiting for me to post the translation (until next Friday), you can try a lot of things on the topic of data storage in the application:



Comments on the translation or non-working examples can be sent to the mail dev @ x128.ru.

Source: https://habr.com/ru/post/199128/


All Articles