In 2014, QuarksLab was missioned by OpenITP [1] to audit the iOS application ChatSecure and to identify any weakness that could lead to information leakage or any other risk that could impact the user.
Introduction
The context
Back in February 2014, QuarksLab was missioned by OpenITP [1] to audit the iOS application ChatSecure and to identify any weakness that could lead to information leakage or any other risk that could impact the user. To sum up OpenITP, here is a quote from their website: "OpenITP improves and increases the distribution of open source anti-surveillance and anti-censorship tools by providing the communities behind these tools with many kinds of support." In our particular case, OpenITP funded the audit of ChatSecure. What could be a better help for an information security app? Obviously, there were time and financial constraints, but we did our best to identify most issues to assist in improving the security level of the app. 3 security researchers worked on the subject for approximately 20 days:
Sébastien Kaczmarek (@deesse_k): Cryptography assessment
Nicolas Grégoire (@Agarri_FR): XML fuzzing
Cyril Cattiaux (@pod2g): Application security
The audited version was ChatSecure iOS v2.2. The full report is available at the end of this blogpost.
Methodology
Evaluating the anti-surveillance security of an instant messaging application is not an easy task considering the huge attack surface that the reviewer has to cover. Here are some common possible weaknesses:
app should not let users trick other users into believing they are discussing with a trusted contact while talking to somebody else (prevent spoofing)
app should not let users trick other users into doing dangerous actions (prevent phishing)
app should not let users inject scripts into conversations (prevent XSS)
network protocols used should not let an attacker intercept and modify the discussion (prevent man-in-the-middle)
communication should not be readable by an attacker either active or passive over the network (prevent surveillance)
app should not let attackers execute code or access private data remotely (prevent control)
app should not let traces of conversations and private data accessible to other apps, to a connected computer, to a thief, or a forensic engineer
And these were only examples of all the possible attack scenarios... To be effective in the time constraint, we divided the work into different areas:
automated code audit of the whole project
human code audit of critical components
forensics of credentials and messages
cryptography protocol audit
man-in-the-middle attacks feasibility
XMPP protocol audit and fuzzing
If it was not complex enough, ChatSecure managed multiple transport protocols at that time: AIM, XMPP Google, XMPP Facebook and XMPP Jabber.
Findings
Our findings and conclusions on ChatSecure were surprising. Even though the application was coded with encryption and security in mind, developers (at that time) did not succeed in visualizing all the possible attacks they needed to defend against. We will not cover everything that we found in this blog article, as it would be a complete rewrite of our report, but we will try to organize problems in great categories.
Protocol weaknesses and user unawareness
The biggest problem with ChatSecure 2.2 is that it tried to handle multiple protocols, each being implemented in different sub-modules. We sumed up the differences in the next table:
AIM is obviously the concern here, but not only because it is not encrypted: the idea of ChatSecure at that time was to handle the maximum number of protocols and protect the communication with an additional layer of encryption, as of Adium on Mac for example. Adium let you concentrate all your accounts coming from 15 different services in a single app, and use the Off-the-Record (OTR) messaging standard on top of them to secure the communication. Is OTR over many protocols a good design choice for a secure messaging app? Here at QuarksLab, we think that it is not. OTR has been designed with security in mind, but when it is used over weak protocols, and when fingerprint verification is not sufficiently enforced, man-in-the-middle is still possible. Moreover, multiplying protocols means extending the attack surface and is a bad design practice for any secure application. Now let me explain why being AIM compatible is a bad choice for any messaging application: the AIM protocol does not authenticate the server, and the traffic is unencrypted, which means that an attacker on the network can impersonate the AIM server, being in a man-in-the-middle position. OK, but why is it important at all considering the whole communication is encrypted on top of the AIM protocol by OTR? There are multiple answers:
the fake server can intercept and spoof the user's buddy list
the fake server is in strong position to try man-in-the-middle attacks on the OTR protocol
the fake server can forge unattended packets
In the particular case of ChatSecure, here is what we found in addition:
the AIM protocol implementation was prone to multiple memory corruptions
the AIM protocol implementation included "debugging" commands in the message parser, probably left by the developer :-(
These commands did let a remote user with a simple message (using any AIM app) read the buddy list of a remote ChatSecure user, add/remove buddies, force a disconnect and even more fancy stuff...
Conclusion: limit the attack surface if you intend to code a secure application by limiting its functionalities. The more code, the more risks.
Another problem related to all these protocols is the user unwareness of their weaknesses. Although ChatSecure's Facebook and Google XMPP implementations both rely on a certificate pinned secure connections (Facebook and Google certificates bundled with the app) , the Jabber XMPP one did not enforce STARTTLS. The user should be aware that if he wants a really secure connection so that no attacker could be in position of, as with AIM, intercept metadata and forge packets, he has to connect to a STARTTLS compatible server. Using ChatSecure 2.2, the user adds Facebook, Google, Jabber, or AIM accounts without knowing if the server he is communicating with can be trusted and differences between protocols secureness. Either way, even if Facebook or Google servers are authenticated for sure (because of certificate pinning), who knows if some malicious user is not hacking these servers? That's why I am now continuing with the interresting part. Is ChatSecure OTR implementation a fortress?
ChatSecure's OTR
Quote from wikipedia (wikipedia OTR): "Off-the-Record Messaging (OTR) is a cryptographic protocol that provides encryption for instant messaging conversations. OTR uses a combination of AES symmetric-key algorithm with 128 bits key length, the Diffie–Hellman key exchange with 1536 bits group size, and the SHA-1 hash function. In addition to authentication and encryption, OTR provides forward secrecy and malleable encryption." Cryptographically wise, OTR is a really strong protocol with excellent features, particularly the perfect forward secrecy and deniable authentication. Cryptographers Ian Goldberg and Nikita Borisov behind OTR even provided a C implementation in a library for simple integration into instant messaging apps: libotr. ChatSecure depends on libotr, and a wrapper library has been written in Objective-C for the occasion: OTRKit. So, OTR is secure, but as most asymetric key communication, it is vulnerable to man-in-the-middle attacks: remember our talk on iMessage? Libotr provides 2 ways to authenticate the other user (and verify nobody is in the way):
Fingerprint verification of the DSA key of the remote party
SMP is not implemented in ChatSecure and the fingerprint verification was messy and partial, let me explain why. The most important thing in a secure communication is to be assured that you are talking to the right person, and ChatSecure provides a verification process for that:
you click on the padlock icon, and it shows the expected fingerprint of the remote user and yours.
your contact does the same
in another secure channel (GPG mail, iMessage, or best, in person) both double check the fingerprints
communication is now verified, the padlock has a little checkmark in addition to being locked
Issues:
ChatSecure v2.2 tends to forget about the verification status and you have to do the operation at every new discussion with the same user
The padlock is small, and if you do not pay attention, you are not warned nor encouraged to do the verification process
OTR is not even tried automatically by default, user have to manually force it (this behavior is overridable in the settings pane)
A user can still send you unencrypted (non OTR) messages even if ChatSecure considers the communication as secure
Remote user can decide to stop OTR and continue unencrypted, ChatSecure will just write a very small status text in the message window saying that the secure chat session has been ended
If the fingerprint of the remote party is different than last time, no warning pops. The communication is just not verified, as usual anyway, because ChatSecure v2.2 forgets about the verification state
So basically, to be certain that the communication with your contact is safe you would need to do, each discussion with him:
manually click on the padlock to activate OTR
verify the communication using another "secure" channel (quotes because this channel could obviously be man-in-the-middled)
watch the padlock and the microscopic status change text before reading or writing any message
And still, somebody could be in the middle and could send you unencrypted messages as if he would be your contact without you noticing. Sketchy implementation, isn't it?
Other issues
We found other potential problems when we audited ChatSecure, especially in the way credentials, metadata and messages were handled and recorded on the filesystem. We will not cover every vulnerability found in this article, so we strongly recommend reading the exhaustive report.
Conclusion
Developping a secure instant messaging application is a tough task. Secure messaging does not only rely on using strong cryptography:
the attack surface should be limited to the maximum so that nobody can take control and for example execute remote code instead of trying to break the cryptography
the user must be guided on how to verify the communication properly and be warned if everything goes wrong
the user should be encouraged to upgrade to the last version of the application and of his operating system
Also, thinking that OTR can protect you on any kind of channel is totally wrong. If a man-in-the-middle position is gained by an attacker because the underlying protocol is unsecure (AIM, XMPP without TLS, untrusted XMPP server, etc.), he can attempt to modify your buddy list, to disconnect the OTR communication and revert back to unsecure, forge unattended network packets, etc. Is ChatSecure v2.2 a secure instant messaging application? No. However, ChatSecure v3.0 is in the way and a lot of our findings and comments have been integrated, examples:
removal of AIM support
TLS required for all XMPP connections
message archiving with SQLCipher (encrypted database)
warning on insecure iOS versions
But what would be the ultimately secure IM application? An application that does not try to be compatible with existing services, and that would rethink everything from the ground up. No XMPP support (attack surface is huge), only one secure transport protocol, OTR like cryptography on top of it, and a clear and manageable list of fingerprints. If you do know one application that meets all these conditions, feel free to let us know, in the comments section below.
[1] | (1, 2) [dead] https://openitp.org |