Vol de Données Confidentielles au SRC

Ces derniers temps, les vols de données informatiques confidentielles ont souvent fait les grands titres des médias helvétiques, principalement dans le contexte du vol de données bancaires. La semaine passée, c’est le Service de Renseignement de la Confédération qui a confessé qu’un de ses employés, apparemment un informaticien ayant des fonctions d’administrateur système, avait été arrêté juste avant qu’il ne soit en position de vendre au plus offrant des montagnes de données ayant trait au secret-défense helvétique.

Ironie du sort, c’est en voulant ouvrir un compte à numéro dans la filiale bernoise (!) d’une banque helvétique (!!) que l’employé malhonnête s’est fait remarquer, puis dénoncer aux services compétents. Les mécanismes de détection de cas de blanchiment d’argent de cette banque semblent donc avoir été efficaces, au moins dans ce cas-là.

Cela me donne l’opportunité de commenter certains aspects avec l’œil du spécialiste en sécurité informatique.

[caveat emptor]: je ne possède évidemment pas plus d’information sur cette affaire que ce qui a paru dans les médias ces derniers jours. J’ai également remarqué que les explications données dans la Sonntagszeitung de ce dimanche et dans le Matin Dimanche comportaient quelques différences. Je pars donc du principe que les informations publiques reflètent la réalité.

Source des Données et Contrôle d’Accès

La Sonntagszeitung mentionne que l’employé était responsable du système de stockage sur lesquels les analystes du SRC stockent leurs rapports et les informations annexes, en plus d’avoir accès à un réseau de partage d’information sécurisé avec d’autres services de renseignements étrangers:

Er war zuständig für die Datenspeicher, auf denen die Mitarbeiter Informationen zur Bedrohungslage der Schweiz und ihre Analysen speichern. […] Er hatte auch Zugriff auf das speziell gesicherte Netzwerk, über das ausländische Geheimdienste wie der deutsche BND oder die amerikanische CIA ihre Informationen senden.

Les informations mémorisées dans ce système de stockage ont clairement une valeur inestimable. Ce système de stockage n’a cependant pas été la cible de l’employé. Peut-être ne possédait-il pas tous les droits d’accès nécessaires, l’information étant chiffrée. Peut-être ce système de stockage était-il bien protégé et surveillé. On ne le sera probablement jamais. D’après la Sonntagszeitung, l’employé a plutôt copié le contenu du serveur de messagerie, plus d’autres données annexes devant lui permettre d’accéder aux informations sensibles chez lui:

In seinem Büro im dritten Stock des Nachrichtendienstes kopiert der Informatiker zunächst den gesamten Mailserver des NDB innerhalb des speziell gesicherten internen SILAN-Netzes. Damit gelangt er auch an Mails des militärischen Nachrichtendienstes (Mil ND) und der Führungs- und Unterstützungsbasis der Armee (FUB). […]

Mit den Mails gelangt er an unzählige Anhänge: vertrauliche Berichte an den Bundesrat, geheime Berichte ausländischer Polizei- und Nachrichtendienste über Terroristen, Waffenhändler und laufende nachrichtendienstliche Operationen. Das Mail-System ist gegen aussen abgeschottet, deshalb ist es nicht verschlüsselt. Im internen Mail-Verkehr spiegeln sich mehrere Jahre Schweizer Geheimdienstarbeit. Neben dem Mail-Server kopiert er auch das Verzeichnis seiner Abteilung und Zugangsinformationen und Passwörter – damit er das Material zu Hause überhaupt sichten kann.

Comme l’indique très bien l’article, le trésor se trouve dans les pièces attachées: comme dans toute organisation, les employés du SRC utilisent leur messagerie pour échanger sur leurs rapports, les discuter, les affiner, bref, travailler.

La phrase qui me plaît le plus est mise en évidence ci-dessus: la messagerie n’était pas chiffrée, étant donné qu’elle est isolée de l’extérieur. Le lien de cause à effet est donné par le journaliste, mais je devine qu’il ne doit pas être loin de la vérité. Cette constatation est à mettre en lumière avec le fait bien connu dans le monde de la sécurité informatique que deux tiers à trois quarts des attaques sont perpétrées par des insiders.

Dans le but de protéger un système IT, il est possible de mettre en œuvre un certain nombre de mesures techniques visant à se protéger contre les attaques internes, principalement envers les employés disposant de droits étendus sur les systèmes qu’ils administrent: chiffrement des données, que cela soit au niveau système de fichiers, des entrées d’une base de données ou de la messagerie, par exemple, ou encore partage de secret k-out-of-n, etc.

Cependant, il est également bien connu que ces mesures techniques ne peuvent pas résoudre tous les problèmes de sécurité, ceci étant d’autant plus vrai si l’on souhaite que les utilisateurs soient capables de travailler dans des conditions acceptables tout en respectant un budget raisonnable.

Monitoring et Mécanismes d’Alerte, ou: Quis custodiet ipsos custodes?

Une composante essentielle de toute stratégie de sécurité visant à se protéger contre des attaques internes est le monitoring et la remontée d’alertes. Partant du principe que la sécurité à 100% n’existe pas, on souhaitera au moins détecter le plus rapidement possible une intrusion ou une fuite de données, dans le but d’y mettre fin et d’en réduire les impacts le plus rapidement possible.

Une condition nécessaire pour qu’un système de surveillance fasse correctement son boulot est qu’il soit administré indépendamment, bref qu’une séparation des rôles soit implémentée. La Sonntagszeitung mentionne que l’employé connaissait la façon de ne pas réveiller ce système d’alerte, tandis que le Matin Dimanche nous apprend «qu’au moins un script [de surveillance ?] a été modifié».

Sécurité Physique

Une autre composante de la sécurité générale d’un système IT est sa sécurité physique. S’il est possible de voler physiquement des disques durs contenant des informations confidentielles simplement en entrant dans une salle de calcul, toutes les mesures mentionnées ci-dessous sont vouées à l’échec. Apparemment, cet employé avait la possibilité, peut-être même la permission d’entrer et de sortir avec des disques durs externes dans son sac à dos, ce qui suggère que les procédures en relation avec la sécurité physique de ces données confidentielles laissent pour le moins à désirer.

Gestion des Ressources Humaines

Finalement, on touche au nœud de l’affaire: cet employé était manifestement un employé «à problèmes»: absentéisme fréquent et prolongé, soupçon de mobbing par les collègues et son chef, etc.

Une certaine confiance dans ses employés est inévitable au fonctionnement de toute organisation, et cela a souvent été relevé par les (ex-)dirigeants du SRC. Néanmoins, une mauvaise gestion des ressources humaines peut facilement accélérer, voir encourager un employé aigri à commettre l’irréparable. A posteriori, cela semble révéler un dysfonctionnement majeur entre les personnes responsables de la gestion des ressources humaines et celles responsables de la sécurité des données.

En conclusion

L’enquête parlementaire livrera probablement ses conclusions d’ici quelques mois, et les responsabilités vis-à-vis de ce fiasco devront être définies. Je ne serais pas surpris que soient mentionnées les coupes budgétaires récurrentes et autres manques de moyens à disposition du SRC pour mener à bien sa mission, l’argent restant encore et toujours le nerf de la guerre.

Le côté positif de cette affaire est la (relative) transparence avec laquelle le SRC a communiqué sur cette triste affaire: cela aura au moins le mérite de sensibiliser encore un peu plus, s’il en était besoin, les entreprises et les administrations suisses quant à la problématique du vol de données en particulier, et de la sécurité informatique en général.

 

Microsoft and SSE2 Intrinsics, or: How to Drive a Cryptographer Mad

When you implement cryptographic algorithms, especially fast implementations, you work often with the Intel MMX/SSEx/AVX/AVX2 instructions sets. Recently, I lost a bit of time spotting a rather difficult-to-find bug. The moral of the story could be: never, ever neglect the compiler warnings!

Here is the context: my implementation was working on Mac OS X and Linux, when compiled in 32-bit and 64-bit modes, with gcc and CLANG/LLVM. This code made a heavy use of SSE intrinsics. Quite happily, I handed my code to the person responsible to compile, test and integrate it into a Microsoft environment, and of course, the code was not working anymore…

The cause was the way I used the  _mm_slli_epi64 (). This intrinsics represents the PSLLQ machine instruction which, given a 128-bit SSE register, shifts the left and right parts of the register in an independent way to the left, inserting zero bits where required. Basically, this routine takes a 128-bit value and an int  representing the shift count, and it returns the resulting doubly-shifted 128-bit value.

Now, let’s have a look at the following code:

It does two things: it loads the 128-bit constant \mathtt{0xDEADBEEFDEADBEEFDEADBEEFDEADBEEF} into a register, and shifts the two 64-bit parts by … 64 positions. In other words, it’s a way (like many other ones) to clear the register; by the way, don’t ask me why I am using this kind of weird mechanism, it’s classified. Second, it outputs the result.

Here is the result on a *nix system, when compiled with gcc:

Now, let’s compile the same thing on Microsoft Visual Studio 10. The result is now

Obviously, the Microsoft compiler has transformed the 64 constant into a 0 one. Actually, it is even polite enough to mention it as a warning:

Disassembling the result effectively confirms this way to do:

So, who’s right ?! Glancing into Intel’s manuals, one learns the following:

Note that the shift count is an imm8 value, i.e., that it is encoded on 8 bits. It means that the shift count can be as large as 255 and this clearly contradicts the explanations given into the Microsoft Visual Studio 10 documentation. Further, one sees how is this instruction supposed to be implemented:

Clearly, the way how Microsoft’s compiler translates this intrinsic does not match the Intel specifications (I can hardly wait people explaining me why it’s a feature…).

Now, one can wonder why the Microsoft developers took this choice. An explanation is maybe the following: for the logical left shift instruction (SHL) operating on normal registers, a mask if effectively applied by the hardware on the shift count: However, it is not the case when in a SSE instruction set context.

Passwords Storage in a Nutshell

Recently, somebody leaked several millions of password hashes stolen to LinkedIn. Most security specialists have noticed with some surprise (or not…) that the hashes were not salted. In this post, I’d like to discuss how to store securely passwords in a database.

Let us assume that a website has to manage credential data of several users, that we will name u_i with 1 \leq i \leq \ell. Each user u_i possesses a password p_i allowing to authenticate him/herself. Of course, several users might share the same password. For the sake of concreteness, we will also assume that people choose passwords of at most 8 characters out of the set \mathtt{a-zA-Z0-9}. It means that an attacker willing to explore the whole passwords space will have at most

    \[62 + 62^2 + 62^3 + 62^4 + 62^5 + 62^6 + 62^7 + 62^8 \approx 2^{48}\]

different passwords to try.

We now discuss several ways to store the passwords in a database, from the least secure to the most secure one.

Storing Passwords in Clear

The least secure way consists in storing tuples (u_i, p_i) in the database. Unfortunately, any vulnerability of the web application allowing to dump the database (like an SQL injection) will reveal the passwords in clear. As people tend to use the same password on several websites, leaking credentials put at risk the access to those other websites as well.

Some developers like to store passwords in clear in order to give the possibility to their users to recover their password in case where they would have forgotten it. This is a bad decision: one should give a user the ability to reset his/her password, but not to recover it. Troy Hunt has written a nice blog post on the subject.

Hashing Passwords

The first step towards more security consists in hashing the passwords, i.e., applying a cryptographically secure hash function H(.) on the passwords, such as SHA-256 or SHA-512. LinkedIn implemented this solution, with help of SHA-1 (A a sidenote: this hash function is known to be sub-optimal in terms of security, as it is conjectured to be possible to compute a collision in  \approx 2^{64} steps instead of the expected 2^{80} ones; however, its security with respect to the recovery of first pre-images (i.e., inverting it) is still OK. Nevertheless, as of today, it is recommended to avoid SHA-1 for new systems, even if it is not necessary to urgently upgrade existing applications. Notice however that migrating SHA-1 to SHA-256 or SHA-512 can be considered as a good security practice).

Hashing passwords, however, is not sufficient, as an adversary could perform the following attack, named a dictionary attack: first, he selects a set of passwords that are the most likely to be chosen by the users, hashes them, and store the pairs (p_i, H(p_i)), sorted by the H(p_i) values, in a giant database. This phase of the attack can be performed off-line, and needs to be done only once. The off-line phase costs about 2^t hashes and 2^t memory cells for 2^t different passwords. The second step is immediate: given a password hash, one does a single lookup into the giant database, and one immediately recovers the password if it is stored into the database. Hence, the on-line phase costs only 1 hash evaluation and one database query, so it’s lightning fast. For a password space of size 2^{48}, the off-line phase would cost 2^{48} hash evaluations, which is easily tractable in 2012 using common hardware. The storage requirements are however less easy to deal with: one needs around 16\times2^{48} = 2^{52} bytes of storage, which represents \frac{2^{52}}{2^{11}\times2^{30}} = 2^{11}, i.e., more than 2000 drives of 2\,\mathrm{TB} each.

A second, more interesting possibility for an attacker consists in mounting an attack exploiting a time-memory trade-off, i.e., building rainbow tables: during the off-line phase of the attack, the attacker computes a set of tables that cost him 2^t hash evaluations and 2^{2t/3} memory cells. Once this step, which has to be done only a single time, has been performed, recovering a password costs only 2^{2t/3}  hash computations. Hence, a time-memory trade-off allows to trade some memory, which is typically a costly resource, with cheaper hash evaluations. For 2^{48} passwords, it means that the adversary will spend in th order of 2^{48} hash evaluations for building tables costing around 2^{32} memory cells, and once this step is done, cracking a password will require only about 2^{32} hash evaluations. Here, the figures are a bit less precise, as they heavily depend on the optimizations used in the implementation of the rainbow tables. However, one can note that it is definitely possible to mount this attack in practice given even a small hardware budget.

Hashing and Salting Passwords

In order to thwart dictionary attacks and time-memory trade-offs, one usually salts the passwords. Basically, salting a password means that you compute a hash value which depends on the password and on a salt, which is a non-secret random value of sufficient length, e.g, 32 or 64 bits. Concretely, for each user-password pair (u_i, p_i), you generate at random a salt value s_i, and you store the triple (u_i, s_i, H(p_i||s_i)) in the database, where || denotes the concatenation.

Salting passwords has two crucial consequences: first, two colliding passwords will not collide in the database, as long as the respective salts do not collide. Second, an attacker willing to mount a dictionary or a time-memory trade-off attack does not know the salt in advance, so it must build dictionaries or tables for every possible salt. Consequently, the time and memory complexities are multiplied by the possible number of salt values: given 2^s possible different salt values, dictionary attacks and time-memory trade-offs will require 2^{t+s} and 2^{\frac{2t}{3}+s} memory cells, respectively, as well as2^{t+s} hash evaluations during the off-line phase. Two crucial assumptions on the salt values for a salting scheme to be efficient are the following: salt values must be random in a cryptographic sense (they must be unpredictable for the attacker), and they must come out of a set of sufficient cardinality, i.e., 2-bit salt values won’t do the job. Coming back to our space of 2^{48} passwords, even a 32-bit salt will render dictionary and time-memory trade-offs unpractical.

Using Iterated Hash Functions

Given a database of properly hashed and salted passwords, the attacker can still mount a brute-force attack. It means that, given a triple (u_i, s_i, H(p_i||s_i)), the attacker will try every possible candidate password one after the other until it finds the good one. Moreover, this attack can easily be parallelized on multiple CPU or GPU cores. Given a space of 2^{48} possible passwords, the attacker will have to invest 2^{48} hash evaluations in the worst case, and 2^{47} in average.

To slow down an attacker, one can apply several iterations of the hash functions on the password, instead of a single one. For instance, one could marry the PBKDF2 key derivation mechanism with a hash function such as SHA-256, and fix the number of iterations such that hashing a password takes half a second on a modern CPU core, for instance. Hence, an attacker will be only able to compute two hashes per second on a core, instead of several millions.

Using Memory-Hungry Iterated Hash Functions

Eventually, brute-forcing passwords can be considerably accelerated with help of a dedicated ASIC or FPGAs. In order to raise the costs for an (already quite-powerful) adversary, people have noted that memory is considerably more expensive than computational power. Starting from this observation, one can use hashing mechanisms that have been designed to need significantly more memory than a common hash function. For instance, the BSD hacker Colin Percival has designed the scrypt key derivation function with the goal of better resisting brute-force attacks implemented in hardware. An older, but more popular and widespread scheme, is bcrypt. It has been designed by Niels Provos and David Mazières.

Users are the Weakest Link

It is well-known that users tend to pick easy-to-remember passwords, hence passwords having a small entropy. Consequently, it is important to remember that if your password database leaks, the adversary can face two very different situations:

  • She/he is willing to crack at least one password out of the list, but which one is not important. In that case, even using very resistant password hashing schemes will not help you a lot, as it is very likely that at least one password is very weak. Enforcing a strong password policy is then a good step in the proper direction, however, it is often delicate to define the good trade-off between security and user friendliness.
  • She/he is willing to crack a precise password: here, using a good scheme can help you, provided the precise password is not too weak.

As a conclusion, developers can take some technical measures in order to make their password-based authentication mechanism more resistant, however, a good defense-in-depth strategy consists in considering the password hashes as sensitive data, and do everything possible to protect them from being leaked!