Article invité - Ludovic Cornac : Comment nous sécurisons nos postes utilisateurs

Aujourd'hui je laisse mon blog à mon collègue Ludovic Cornac, qui s'occupe de l'administration des serveurs et des postes utilisateurs dans la société Sothis


En tant que responsable du support informatique, et de l'installation des postes utilisateurs dans ma société, je dois faire en sorte que mes utilisateurs travaillent le plus efficacement possible, dans un contexte sécurisé.

Pour simplifier le déploiement et la maintenance des postes, nous avons mis en place un système de bureau virtuel (ou Desktop as a service). Nous sommes dans le cas d’un serveur hébergé Windows 2012R2 ou les utilisateurs s’y connectent en TSE.

Leurs boites mails ainsi que tous les logiciels de gestions leurs sont accessible sur ce même serveur. Celui-ci est protégé avec un Anti-virus System Center 2012 Endpoint Protection (antivirus de Microsoft).
Mais malgré cela nous ne sommes pas passé au travers de "ransomware".

Nous avons eu principalement beaucoup de mails "parasite" proposant des archives avec des scripts .js ou des fichiers Word avec des macros.
Une fois ces fichiers exécutés, les dossiers ou l'utilisateur possède des droits d’écriture sur le serveur sont chiffrés et certains ransomwares demandent des droits d’administrateur pour attaquer le reste du système notamment des répertoires ou l’user classique n’a pas accès le lecteur C: par exemple.

Une rançon est demandée en échange pour déchiffrer ces fichiers, sans aucune garantie. Dans le cadre professionnel c’est très ennuyeux c’est souvent plusieurs milliers de fichiers de données qui sont cryptés et qui rendent les documents illisibles ou les logiciels de gestions tout simplement inutilisable. C'est pourquoi nous avons du agir contre ces menaces.

Paramètres de sécurité

Blocage des fichiers dangereux

La première solution est d’administrer les options de sécurité d’Office via GPO, ce qui n’est pas possible par défaut.
Nous allons expliquer comment faire pour les versions d’Office 2010, 2013 et 2016.

Pour voir apparaitre dans les GPOs les paramètres pour Office il faut ajouter des fichiers ADMX. Ils sont disponibles sur le site de Microsoft :

Télécharger le contenu, se rendre sur le serveur appliquant les GPOs.
Extraire l’archive, récupérer le contenu et le coller dans : C:\Windows\PolicyDefinitions

Définitions des GPOs

Attention lors de la copie de ne pas remplacer des fichiers déjà existants.
Ouvrir gpedit.msc (Exemple avec Office 2010 mais même chose pour Office 2013 et 2016)

Configuration Utilisateur -> Stratégie -> Modèles d’administration -> Microsoft Outlook 2010 -> Options Outlook -> Sécurité -> Centre de gestion de confidentialité

GPO Office

Cliquer sur Mode de sécurité Outlook -> Activé (Utiliser la stratégie Groupe de sécurité Outlook)

Mode de sécurité Outlook

Configuration Utilisateur -> Stratégie -> Modèles d’administration -> Microsoft Outlook 2010 -> Sécurité -> Paramètre du formulaire de sécurité -> Sécurité par pièce jointes.

Extensions à bloquer niveau 1

Liste à bloquer pour le niveau 1 : (Tous les fichiers de cette liste seront complètement bloqués par Outlook)

Cette liste permet de bloquer tous les fichiers avec l'extensions suivantes: ceux-ci ne pourront être ni éxecutés ni enregistrés

JS;BAT;CMD;PY;PS;PS1;REG;DOTM;DOT;XLT;XLST;EXE;COM;DLL;MSI;SCR;VBS;VBA;VB

Extensions à bloquer niveau 2

Liste à bloquer pour le niveau 2 : (Tous les fichiers de cette liste, auront un message d’avertissement avant d’ouvrir le fichier en permettant à l’utilisateur d’enregistrer le fichier)

DOC;DOCX;XLS;XLSX;ZIP;RAR;7ZIP

Association de fichiers via GPO

On a configuré Outlook pour empêcher les fichiers dangereux d'arriver par e-mail, mais ils risquent toujours d'arriver par d'autres moyens.

Le but maintenant est d’ouvrir les fichiers .js (et d’autres…) avec Notepad pour éviter que l’utilisateur exécute des scripts et donc des virus.

Ouvrir gpedit.msc
Configuration Utilisateur -> Préférences Paramètres du Panneau de configuration -> Options des dossiers.

Nouvelle association de fichier
Associer .bat au Notepad

Faire pareil pour les extensions suivantes : bat, cmd, js, ps, ps1, py, vba, vbs.

Macro Word

En dehors des fichiers .js et autres fichiers directement exécutables, la principale source de contamination vient des Macro Office.

Un utilisateur qui ouvrait un fichier Word ou Excel était directement exposé, suite à l'activation de toutes les macros dans les paramètres de Word et Excel, de plus le mode protégé était complètement désactivé.
L'utilisateur pouvait donc ouvrir un fichier Word ou Excel, depuis un accès réseau, un mail Outlook ou depuis les téléchargements Internet.

La meilleure chose à faire est de les désactiver totalement - et ne pas laisser la possibilité à l'utilisateur de l'activer (on sait tous comment ça se passe, ils cliquent sans lire). Ça se fait toujours par GPO :
Configuration Utilisateur -> Stratégie -> Modèles d’administration -> Microsoft Word 2010 -> Options Word -> Sécurité -> Centre de gestion de confidentialité

blocage macros

Mais pour nous cela aurait posé problème car nous possédons un logiciel de gestion qui a besoin des macros Word pour fonctionner.
Nous avons donc plutôt sélectionné l'option "Désactiver tous sauf les macros signées numériquement", et contacté le développeur de l'outil de gestion pour lui demander de signer leur plugin : maintenant nos macros fonctionnent, et nous sommes quand même protégés des macros non signées.

Stratégie de backup

La dernière chose à faire - probablement la plus importante, est de faire en sorte d'avoir toujours des sauvegardes, parce que malgré nos précautions, on n'est jamais totalement à l'abris.

Nous avons décidé de renforcer notre stratégie de backup - avant on utilisait une réplication de machine virtuelle entre 2 serveurs Datacenter OVH. La restauration prenait énormement de temps et l'administration des sauvegardes ou des restaurations est assez limité.

Nous utilisons maintenant Veeam Backup & Replication qui coûte 650€ par hôte Hyper-V dans sa version standard (suffisante dans notre cas).

Nous avons des sauvegardes quotidiennes et hebdomadaires en fonction de nos serveurs et de leurs risques et expositions aux dangers, avec ce nouvel outil de sauvegarde, sur des sauvegardes quotidienne nous sommes en capacité de restaurer rapidement, en fonction de la taille du disque, un disque dur spécifique. Par exemple, un serveur attaqué par le virus locky à endommagé principalement le disque de donnée et non l'OS (car l'utilisateur ne possède pas les droits dessus) nous pouvons donc choisir de restaurer le disque de donnée F: à une heure H et un jour J.
Il suffit ensuite d'éteindre la VM et de remplacer notre VHDX et le tour est joué.

Hsts : oublions le http non sécurisé

Maintenant que Let's Encrypt est disponible, et fonctionne bien, nous n'avons plus d'excuse pour ne pas chiffrer nos sites webs. Pour ceux qui l'auraient loupé, la procédure pour activer https sur IIS est dispo dans un précédent article.

Aujourd'hui il est temps d'oublier http pour de bon. Nous allons voir comment configurer IIS pour rediriger correctement nos visiteurs.

Redirection HTTP vers HTTPS

Normalement, une fois configuré correctement, votre site IIS a 2 bindings : un en http, et un en https, pour le même nom d'hôte.

La première chose à faire, la plus évidente, est de faire une redirection de chaque requête http vers la même requête https. Pour faire ça, on va utiliser le module URL Rewrite.

Une fois le module installé, ajoutez un fichier de configuration web.config -ou modifiez l'existant- et ajoutez dans la section configuration/system.webServer :

<rewrite>
    <rules>
        <rule name="http to https" stopProcessing="true">
            <match url="(.*)" />
            <conditions>
                <add input="{HTTPS}" pattern="off" />
            </conditions>
            <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" />
        </rule>
    </rules>
</rewrite>

La règle est en 3 parties :

  • match : on utilise (.*) pour intercepter toutes les urls
  • conditions : on ajoute une condition, la requête ne doit pas être https (on ne veut rediriger que les requêtes http)
  • action : on définit l'url de redirection

Et ça suffit, à partir de maintenant toutes les requêtes http seront redirigées (code http 301 - redirection permanente) vers la page https correspondante. Attention, à vous maintenant de faire attention à ne plus avoir de liens internes http dans votre site, sous peine de doubler toutes les requêtes.

HSTS : pour informer le navigateur de n'utiliser que https

Cette redirection que nous avons mis en place nous permets de nous assurer que le site web ne sera accessible que en https. Mais on a un petit soucis : on a une première requête de redirection qui est faite en http. On aura donc cette requête inutile à chaque fois, si votre visiteur a mis votre site en favoris avec l'adresse http.

Pour éviter ça, il existe un moyen de dire au navigateur de se connecter systématiquement en https pour le domaine. Il suffit d'ajouter un en-tête HTTP Strict Transport Security (HSTS) à la requête.

Transport-Security: "max-age=31536000"

Ce simple en-tête permet de dire au navigateur de pas faire de requête http sur le domaine pendant x secondes (ici 31536000, soit un an), et d'appeller la requête en https à la place. Vous pouvez aussi activer HSTS pour le domaine en cours et pour les sous-domaine, en ajoutant includeSubDomains

Transport-Security: "max-age=31536000; includeSubDomains"

Pour activer cet en-tête dans IIS, il suffit de modifier le fichier web.config: pour ajouter un customHeader, toujours dans dans la section configuration/system.webServer :

<httpProtocol>
    <customHeaders>
        <add name="Strict-Transport-Security" value="max-age=31536000; includeSubDomains"/>
    </customHeaders>
</httpProtocol>

Attention, même si cet en-tête est défini ici pour être envoyé systématiquement, il ne sera pris en compte par le navigateur que s'il est défini dans une requête https. C'est pour ça que la redirection qu'on a définie reste indispensable.

Maintenant tout est en place, IIS est configuré pour rediriger correctement les requêtes http vers https, et demander au navigateur de ne plus faire de requête http. Voici donc toute la configuration à ajouter à votre web.config :

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <httpProtocol>
            <customHeaders>
                <add name="Strict-Transport-Security" value="max-age=31536000; includeSubDomains"/>
            </customHeaders>
        </httpProtocol>
        <rewrite>
            <rules>
                <rule name="http to https" stopProcessing="true">
                    <match url="(.*)" />
                    <conditions>
                        <add input="{HTTPS}" pattern="off" />
                    </conditions>
                    <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

Précharger son site dans le navigateur

Ce dernier point est vraiment facultatif, mais si vous voulez vraiment ne plus recevoir la moindre requête http sur votre serveur, il faudra passer par là. Il est possible de s'enregistrer directement dans les navigateurs pour que hsts soit activé, avant même que l'utilisateur n'ait visité votre site. Pour s'ajouter à la liste des sites webs https only, directement dans le code source des navigateurs, il faudra vous enregistrer sur cette page.

Attention, pour pouvoir vous enregistrer, il y a plusieurs contraintes :

  • Vous devez avoir activé https, et avoir un certificat valide
  • Toutes les requêtes http doivent être redirigées en https
  • https doit être activé pour le domaine ET tous ses sous-domaines

Il faut aussi que l'en-tête HSTS contienne includeSubDomains et preload, pour certifier que la demande d'intégration à la liste preload vienne bien du propriétaire du site.

Transport-Security: "max-age=31536000; includeSubDomains, preload"

Voilà, tout est bon ? Si vous êtes sûr de vous, vous pouvez vous lancer. Sachez juste que l'ajout à la liste peut prendre plusieurs semaines - la validation est faite manuellement, et l'acceptation n'est pas garantie. Faites aussi très attention : vous pouvez essayer de sortir de la liste, mais ça peut aussi être très long. Si pour une raison quelconque vous ne pouvez plus faire de https sur ce domaine, votre site sera totalement inaccessible.

Création d'un helper pouvant contenir du HTML

Depuis le tout début, ASP.NET MVC fournit des helpers permettant de créer des liens vers des actions ou des routes particulières. Et depuis le tout début, ces helpers n'autorisent rien d'autre que du texte. Si on veut mettre du html, il ne faut pas utiliser ces helpers (ou faire d'immondes bidouilles)

La solution la plus simple est de créer un simple lien html, en utilisant le Helper Url

<a href="@Url.Action("Index")"><img src="image.png"/></a>

Mais malheureusement, ceci n'est pas possible lorsqu'on veut créer des liens Ajax.

Vu que MVC est open-source, j'ai décidé d'aller voir un peu comment sont fait ces helpers, et d'en créer un nouveau, sur le modèle du BeginForm, permettant d'insérer du HTML dans un lien.
Le package MvcHtmlLink - permettant de créer des liens avec du html - est disponibles sur NuGet ; le code source et une mini doc sont sur GitHub

Le fonctionnement est simple : il faut créer un object IDisposable. Dans son constructeur on génère le tag d'ouverture, et dans le Dispose le tag de fermeture. Lorsqu'on l'utilise dans une vue Razor MVC avec un using, le html écrit entre les accolades sera donc au milieu de notre tag html.

@using (Html.BeginActionLink("Index", new { Id = 1 }, new { @class = "some-css-class" }))
{
    <span>Html link</span>
}

va générer :

<a class="some-css-class" href="/Home/Index/1">Mvc RouteLink with params</a>

Pour faire ça, j'ai créé une classe HtmlLink :

public class HtmlLink : IDisposable
{
    private readonly ViewContext _viewContext;

    public HtmlLink(ViewContext viewContext, string targetUrl)
    {
        _viewContext = viewContext;         
        _viewContext.Writer.Write("<a href=\"" + targetUrl + "\">");
        // Ici le lien doit être créé correctement, les attributs html et les options Ajax
    }

    public void Dispose()
    {
        _viewContext.Writer.Write("</a>");
    }
}

Cette classe doit recevoir le ViewContext d'ASP.NET MVC, c'est ce qui va permettre d'écrire dans la page.
La façon dont est générée le lien est reprise du code d'ASP.NET, et est visible sur GitHub.

Pour pouvoir ensuite utiliser cette classe, on va créer les helpers. Pour qu'ils soient plus facile d'accès, on va les créer sous forme de méthodes d'extension de la classe HtmlHelper, et dans le même namespace, afin qu'elles apparraissent sur l'objet @Html et @Ajax des vues MVC.

namespace System.Web.Mvc.Html
{
    public static class HtmlLinkHelper
    {
        public static HtmlLink BeginActionLink(this HtmlHelper htmlHelper, string actionName, string controllerName)
        {
            string targerUrl = UrlHelper.GenerateUrl(null, actionName, controllerName, null, htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, true);
            return new HtmlLink(htmlHelper, targetUrl);
        }

        public static HtmlLink BeginRouteLink(this HtmlHelper htmlHelper, string routeName)
        {
            string targerUrl = UrlHelper.GenerateUrl(null, routeName, null, null, htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, true);
            return new HtmlLink(htmlHelper, targetUrl);
        }
    }
}

Je n'ai mis que deux exemples pour illustrer le principe, mais il faut créer toutes les différentes surcharges.

Cette fois c'est bon, notre helper peut être utilisé dans nos vues.

Si vous souhaitez créer des helpers de ce type, vous voyez donc que ce n'est pas compliqué, si vous souhaitez juste utiliser ces méthodes BeginActionLink ou BeginRouteLink, vous avez juste à référencer le package NuGet