Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Facebook, SnapChat, or Gmail iOS apps prevent Fiddler decrypting their https traffic?

I tried to use Fiddler to capture some iOS apps traffic, ex: Facebook, SnapChat, Gmail, and Instagram.

Instagram is not using https so I can get all the traffic and see the cookies I sent out but Fiddler cannot decrypt other three apps. It only shows something like this:

A SSLv3-compatible ClientHello handshake was found. Fiddler extracted the parameters below. Version: 3.3 (TLS/1.2) Random: 54 3F 49 C4 20 08 09 BC A8 84 24 92 08 BF B4 38 39 C9 BB 1C B2 7B 95 6A 39 34 E7 AC FE 0F 62 67 SessionID: empty Extensions: server_name graph.facebook.com elliptic_curves

Could anyone help me understand how they do this so I can use the same technology to protect my app.

like image 625
Sheep Avatar asked Oct 16 '14 04:10

Sheep


2 Answers

Your question revolves around preventing HTTPS man in the middle (MITM) attacks against iOS applications. Using Fiddler or other HTTPS proxies is a form of naive MITM attack that, unfortunately, often works.

HTTP is built on top of a secure transport protocol called TLS (and before that, SSL). The connection is encrypted using public and private keys between trusted parties. And that is where things tend to go wrong. The concept of trust is central to the security of TLS and SSL before it. The server your application connects to provides cryptographic credentials that must be evaluated to establish trust.

Think of this like a passport or driver's license. In most cases, the license checks out. Then you get one with the name McLovin. If you don't actually look at the name, date of birth, number, photo, hologram, etc. you may just blindly trust that McLovin is who they say they are. And then you're in trouble.

Don't trust McLovin.

McLovin

Most applications trust McLovin :(

To protect your application against these kinds of attacks you should implement a more strict set of crendential and trust evaluations. Apple has a tech note, Technote 2232: HTTPS Trust Evaluation that details this quite well.

A good start is to implement SSL Pinning. Pinning checks the credential of the remote host against a known value - all or part of that certificate. The iOS application has some copy of that certificate, and when connecting to that host checks the credential the host provides against this "known good" certificate. Some applications just check the meta information, others attempt to checksum the certificate (AFNetworking does this), and others perform a full trust evaluation using the known good certificate against the credential. Apple details this process in the WWDC 2014 session Building Apps for Enterprise and Education. If the remote host is not using the expected credentials, the connection is aborted. There is no traffic for an attacker to intercept. If your server's certificate changes often this can be a problem - which is one of several reasons its preferred to check the server's public key instead of meta information or a hash. Unfortunately, some server administrators change public keys often. Some think this is more secure. It's not.

Now, obviously this requires the iOS application to have a copy of the "good" certificate, or some part of it. You can include the certificate in your application, or implement your own method of key exchange. Secure key exchange has long been the subject of cryptographic research and is not something to be taken lightly. Including the certificate in your application is the solution most people use. You may decide it's important to secure this certificate from someone who may have compromised or jailbroken the device. You have a number of different options for doing so. Obviously you could include it as a resource, and encrypt that. You can also include it directly within the application binary, which can be much more difficult for an attacker to access. This can be done by using the xxd tool with Xcode, as a script build phase or as a build rule. Obviously, you can implement additional protection on top of that.

If the device has been compromised or the application has been tampered with it's possible the "known good" credential has been altered. This is where the iOS application sandbox can work to your advantage. You can detect many of these scenarios by implementing receipt validation for your application. Assuming your application is being distributed through an Apple channel such as the iOS App Store, when it's installed it includes a receipt. That can be validated, and that can be used to implement tamper-proofing for many common scenarios.

These are all methods that can be implemented in the client to protect communications over HTTPS from MITM attacks. The server can also expose the client in many more ways, and the server should be regularly audited for vulnerabilies. Use only known strong cryptographic algorithms, stay up to date with current public vulnerabilities, etc.

Of course, if your application is something that can connect to random HTTPS services you have no control over, like a web browser, your options are more limited. In those cases, the best you can do when a remote host's credentials are in doubt is give the user the choice to trust or not trust the credentials. On iOS there is no UI for doing so provided by the system frameworks, that would be something your application would have to implement.

This is only one, small facet of securing an iOS application, but your question was specific about man in the middle attacks.

like image 123
quellish Avatar answered Nov 16 '22 08:11

quellish


The way in which Fiddler can decrypt HTTPS traffic is by using their own certificate. However, when Facebook/Snapchat/Gmail detects that the certificate is not trusted by the system (and in cases will be more strict and limit the certificates within the trusted, so a third party trusted cert might be rejected), it will refuse to connect with the cert.

Fiddler can generate certs for the iOS to accept and install onto the system, but you first need to follow these instructions:

  1. Install CertMaker
  2. Generate the certificate from fiddler, it should then be on your desktop
  3. Visit the certificate from your Safari browser (Safari only, others will not work)
  4. Install the certificate

From this, you should then be able to sniff traffic from these applications.

So to answer the question again, it's not that they're preventing, it's common for SSL applications to deny responses from the server if the server provides an untrusted certificate. What Fiddler does, is spoof the part of the certificate with its so that when you are communicating over SSL, Fiddler can then use its cert to decrypt your traffic.

To answer the second part of your question, please check out this question for details. Essentially, you can force the user to use a specific certification and thus prevent the user from using installed certs.

However, they can still get around this -- just in a bit more sneaky way, but guided, this is on the client side, anything goes.

like image 24
Dave Chen Avatar answered Nov 16 '22 07:11

Dave Chen