Sécurité et Powershell

Disponible depuis 2005, Powershell est installé et activé sur TOUTES les machines Windows. Ce langage de script très puissant, s’il peut être utilisé pour automatiser certaines tâches d’administration ou même pour s’amuser un peu, est aussi hélas de plus en plus un vecteur d’attaque pour les méchants virus d’Internet. Comment faire pour se protéger un peu ?

Le but de cet article n’est absolument pas de sécuriser complètement votre machine, c’est quasiment impossible. Mais compliquer un peu la tâche des auteurs de virus, c’est toujours ça de pris, non ?

Un peu de technique

Powershell, d’après cet excellent livre blanc de Symantec, est de plus en plus utilisé pour déposer des malwares sur les PC. Bien souvent, le vecteur de propagation utilise la ruse, ou le social engineering : vous recevez un mail avec une pièce jointe (souvent un document Word ou un fichier Excel) que vous ouvrez sans faire attention, vous activez les macros malgré l’avertissement présent, et pouf, vous voilà avec un virus. Cette méthode est la plus connue mais hélas elle fonctionne encore. Au boulot, nous recevons des dizaines, voire des centaines de mails similaires par jour, et même si la passerelle de messagerie en bloque beaucoup, un tout nouveau virus passera le filtre. Et si l’utilisateur est assez bête pour ouvrir un mail bizarre écrit en plus ou moins mauvais anglais avec une pièce jointe, la catastrophe n’est pas loin. Et déjà à plusieurs reprises, non seulement le PC de cet utilisateur s’est retrouvé vérolé et crypté de partout (il s’agit d’une variante du ransomware Locky), il a atteint via des partages réseaux (mais d’autres techniques sont possibles) des serveurs de fichiers, d’autres PC etc. Résultat, tout un site s’est retrouvé bloqué et isolé du réseau pendant deux jours, le temps de trouver un correctif et de scanner toutes les machines pour les nettoyer.

Un rappel

  • Ayez un antivirus à jour. Si vous avez un Mac ou êtes sous Linux, ne rêvez pas : il existe aussi des virus pour ces OS, et ils sont tout aussi néfastes que sous Windows. Ils sont simplement moins nombreux, la prédominance de Windows sur le marché en faisant une cible favorite depuis 20 ans (Linux a même gardé une faille de sécurité dans le kernel pendant 9 ans, seulement patchée récemment. Autant dire que la majorité des Linux est encore vulnérable… et comme on en trouve dans pas mal d’objets connectés, du NAS à l’ampoule qui change de couleur…). Windows Defender n’est pas le meilleur, mais il est gratuit et fait le job assez honorablement. Sinon, choisissez celui auquel vous faites le plus confiance. Chacun a ses défauts, tous sont des passoires plus ou moins efficaces, le prix ne fait pas la qualité… Je me garderai bien de vous en conseiller un en particulier.
  • Mettez votre machine à jour autant que possible. N’attendez pas qu’elle reboote toute seule lorsque des mises à jour de sécurité ont été installées.
  • Ne restez pas connecté avec un compte Administrateur de votre machine (ou pire, du domaine). Tout processus lancé avec ce compte hérite de vos droits, et les virus ne font pas exception à la règle. Si vous avez besoin des droits d’administration, n’ouvrez pas une session en tant qu’administrateur, mais lancez votre exécutable “En tant qu’administrateur” si ce n’est pas automatique. L’UAC (User Account Control) de Windows vous demandera le nom du compte administrateur et son mot de passe. Dès que vous quitterez le programme, vous vous retrouverez avec vos droits standard, et ce n’est pas plus mal. Quel besoin de lancer Word, Photoshop ou un jeu en tant qu’admin ? Aucun.
  • N’ouvrez pas les pièces jointes que des mails d’expéditeurs sûr et auxquels vous faites confiance. Au moindre doute, n’ouvrez pas la pièce jointe.
  • N’activez les macros Office qu’en cas d’absolue nécessité, et pour des fichiers dont vous êtes sûrs du contenu.
  • Utilisez des mots de passe forts (pas “123456” ou “password”. Sérieusement, arrêtez !)
  • N’allez pas sur des sites louches…
  • Faites des sauvegardes MULTIPLES de vos fichiers importants que vous stockerez HORS réseau.
  • Trust no one. The truth is out there. I want to believe.
  • Je pourrais faire une liste de 15 km de long avec ce qu’il faut faire ou non, mais ce n’est pas le but de cet article non plus…

Powershell et les ExecutionPolicies

Si vous avez lu la série d’articles sur DédéAmp et notamment sa première partie, vous avez du remarquer que je vous faisais exécuter cette commande :

Set-ExecutionPolicy Unrestricted

Est-ce mal ? Moui. Est-ce que la sécurité de votre machine est compromise ? Un peu. Est-ce que vous devez me tuer ? Non.

Pourquoi ? Parce qu’il fallait faire tourner DédéAmp, un script qui vient d’internet (et si vous ne me faites pas confiance, vous avez raison) qu’aurait rejeté Powershell. En effet, la stratégie d’exécution (ExecutionPolicy) par défaut est RemoteSigned, autrement qu’il faut qu’un script venant d’internet soit signé (et DédéAmp ne l’est pas).

Est-ce une mesure de sécurité ? Non. Microsoft le dit : l’ExecutionPolicy n’en est pas une, cela évite que vous cliquiez et exécutez par inadvertance le premier script Powershell qui traîne et c’est tout. Cela ne protègera EN RIEN votre machine.

Regardons un peu les possibilités qui nous sont offertes en tapant la commande suivante :

PS C:\scripts> Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser    Unrestricted
 LocalMachine       AllSigned

Le Scope, c’est la porté (ou l’étendue) de la stratégie d’exécution. On peut voir dans cet exemple que pour l’utilisateur actuel (CurrentUser, autrement dit vous), c’est sur Unrestricted : vous pouvez exécuter TOUS les scripts, d’où qu’ils proviennent, et sans qu’ils aient besoin d’être signés. Par contre, pour le scope LocalMachine, il faut que TOUS les scripts soient signés (avec un certificat) par une autorité à laquelle vous faites confiance (Microsoft en a déjà sélectionné toute une tripotée pour vous, pas d’inquiétude).

Pour MachinePolicy et UserPolicy, ces valeurs sont indéfinies (undefined) sur ma machine, qui ne fait pas partie d’un domaine ActiveDirectory, et donc sur laquelle aucune stratégie de sécurité ne s’applique (en dehors des stratégies locales, mais ne compliquons pas les choses).

Tout d’abord, on peut améliorer un peu les choses. Lancez Powershell en tant qu’administrateur et tapez la commande suivante :

PS C:\scripts> Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned

L’idée est que pour le scope CurrentUser, on applique la stratégie RemoteSigned (les scripts venant d’internet (ou du réseau, car ça vaut aussi pour ceux qui se trouvent sur des partages) doivent être signés). C’est déjà mieux, et on est revenus à la configuration par défaut.

Mais patatras, DédéAmp ne fonctionne plus. La preuve si vous le lancez :

PS C:\scripts> .\dedeamp.ps1
.\dedeamp.ps1 : Impossible de charger le fichier C:\scripts\dedeamp.ps1. Le fichier C:\scripts\dedeamp.ps1 n’est pas signé numériquement. 
Vous ne pouvez pas exécuter ce script sur le système actuel. Pour plus d’informations sur l’exécution de scripts et la définition de stratégies d’exécution, 
voir la rubrique about_Execution_Policies à l’adresse https://go.microsoft.com/fwlink/?LinkID=135170.
Au caractère Ligne:1 : 1
+ .\dedeamp.ps1
+ ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : Erreur de sécurité : (:) [], PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess

Le message d’erreur étant écrit en rouge, déjà ça fait peur. Mais ce n’est rien de grave : Powershell a bloqué DédéAmp parce qu’il vient d’Internet et qu’il n’est pas signé, il fait son job, tout va bien.

Mais que faire si vous tenez absolument à lancer DédéAmp ? Il existe pour cela trois possibilités :

  • Changer de nouveau l’ExecutionPolicy à Unrestricted. Oui mais non, on ne va pas faire ça, l’autre fois c’était juste pour gagner un peu de temps.
  • Me demander de signer DédéAmp avec un certificat signé par une autorité de confiance. Je veux bien, mais vous me payez le certificat, c’est pas gratuit, hein. Sinon, vous pouvez VOUS-MEME signer DédéAmp avec VOTRE certificat. Pas bête, surtout que ce n’est pas très très compliqué. Ou que je fournisse un certificat autosigné que vous auriez vous-même ajouté à votre liste de certificats approuvés. Mouais, et le jour où je vous envoie un script signé mais qui détruit votre machine, il s’exécutera sans coup férir, et sans le moindre avertissement. Je le disais en rappel : trust no one, même pas moi.
  • Ou bypasser l’ExecutionPolicy temporairement, le temps d’une session Powershell.

Bypasser l’ExecutionPolicy

Cela consiste tout simplement à lancer une session Powershell un peu différemment, avec un paramètre :

powershell –ExecutionPolicy Bypass

La fenêtre Powershell va s’ouvrir et vous pourrez ainsi, dans cette session, ouvrir et exécuter tous les scripts Powershell que vous voulez, même ceux qui viennent d’Internet et qui ne sont pas signés, comme DédéAmp. Mais vous serez le seul responsable de ce qui vous arrive si jamais vous lancez n’importe quoi, vous êtes prévenu.

Comme je le disais plus haut, vu qu’on peut la bypasser, l’ExecutionPolicy ne protège que des clics intempestifs, mais de rien d’autre. De plus, les auteurs de malwares ont bien d’autres techniques – cf le livre blanc de Symantec dont je parlais au début – pour lancer Powershell a votre insu, et faire leurs petites saloperies en douce. Donc, techniquement, je n’ai en rien compromis la sécurité de votre machine.

Cela dit, cette histoire de bypass s’avère pratique pour lancer un script auquel vous faites confiance (parce que vous avez lu le code source) de manière ponctuelle, sauf pour autant laisser la porte grande ouverte avec Unrestricted. C’est déjà un peu.

Signer le code

Cela va servir pour DédéAmp (vous allez le signer avec votre propre certificat pour l’exécuter sur votre machine) – après tout vous avez vu tout le code source, et je l’ai expliqué en long, en large et en travers – mais aussi vos futurs scripts.

Signer le code, cela consiste d’abord à générer un certificat (auto-signé). Pour cela, nous allons lancer la commande suivante dans Powershell :

New-SelfSignedCertificate -DnsName lenomdevotremachine -Type CodeSigning

Remplacez évidemment “lenomdevotremachine” par le nom de votre machine, si possible par son FQDN (Fully Qualified Domain Name) si elle en a un. Si vous n’êtes pas dans un domaine ActiveDirectory, il y a de fortes chances que ce soit “lenomdevotremachine.WORKGROUP”, mais vérifiez tout de même. Et si vous ne comprenez rien à cette phrase, pas grave, oubliez le FQDN.

Une fois la commande exécutée, vous obtiendrez quelque chose comme ceci :

PS C:\Scripts> New-SelfSignedCertificate -DnsName nova.laserforce.local -Type CodeSigning

   PSParentPath : Microsoft.PowerShell.Security\Certificate::LocalMachine\MY

Thumbprint                                Subject                                                                                                            
----------                                -------                                                                                                            
C960FE3FDC90BFAC6C1932824C3C7958D10615B64  CN=nova.laserforce.local

(ma machine s’appelle bien nova.laserforce.local, mais l’empreinte (thumbprint) est fausse, je l’ai modifiée, hein).

Ce certificat est stocké sur votre machine, il va pouvoir bientôt servir à signer votre code. Mais auparavant, il faut lui faire confiance.

Pour cela, faites un clic droit sur le menu Démarrer et sélectionnez l’option Exécuter, et tapez la commande suivante :

certmgr.msc

Cela va lancer la console du Gestionnaire de Certificats, qui ressemble à ceci :

Oh le joli gestionnaire de certificats !

Et allez, encore un truc qui a l’air compliqué… mais qui ne l’est pas tant que ça, pour autant qu’on apprenne à le connaître un peu. Développez l’arborescence “Autorités de certification intermédiaires” (elle est surlignée sur la capture d’écran ci-dessus) puis “Certificats”. Dans la partie droite de la fenêtre, cherchez le certificat qui porte le nom de votre machine, et double-cliquez dessus :

Trouvé !

Double-cliquez dessus : vous pouvez voir que vous ne lui faites pas confiance…

Oh ben flûte alors, c’est ballot.

On va faire ce qui est indiqué, à savoir déplacer ce certificat dans le “magasin d’autorités de certification de la racine de confiance” à tes souhaits. Pour cela, glisser ce certificat de la partie droite de la fenêtre vers l’arborescence “Autorités de certifications racines de confiance / Certificats” :

Ça s’appelle un glisser-déposer dans le jargon.

Et là paf, un avertissement de sécurité :

Croyez-le ou non, je n’ai jamais reçu d’averto, ni au collège ni au lycée…

Évidemment, cliquez sur Oui, c’est votre certificat, hein, à moins de ne pas vous faire confiance parce que vous êtes schizophrène, je ne vois aucune raison de cliquer sur autre chose que Oui.

Miraculos, votre certificat a fait des petits et vous lui faites désormais confiance (votre certificat, c’est celui dont le rôle est “Signature de code”).

Un miracle plus crédible que la naissance de Jésus.

Le certificat étant installé, on va pouvoir s’en servir pour signer DédéAmp, mais également tous vos autres scripts si le coeur vous en dit. Pour cela, on retourne à Powershell et on tape ceci :

Set-AuthenticodeSignature C:\Scripts\dedeamp.ps1 @(gci Cert:\LocalMachine\My -DnsName nova.laserforce.local -codesigning)[0]

(vous remplacez nova.laserforce.local par le nom de votre machine hein, et dedeamp.ps1 par le nom de votre script, vous êtes grands maintenant).

Résultat de cette commande :

    Répertoire : C:\Scripts

SignerCertificate                         Status                                                    Path                                                     
-----------------                         ------                                                    ----                                                     
0BFAC6B453824C3C7958D10615B64C960F13FDC9  Valid                                                     dedeamp.ps1

(j’ai changé le SignerCertificate, ne rêvez pas, vils pirates).

Si vous lancez désormais votre éditeur préféré ou PowerShell ISE et que vous ouvrez dedeamp.ps1, regardez tout en bas du script : une série de commentaires a été ajoutée à la fin :

J’en ai enlevé un gros bout pour la capture d’écran, pas la peine de recopier… 😉

Et voilà, dedeamp.ps1 est signé ! Donc même avec l’ExecutionPolicy RemoteSigned (ou AllSigned), vous pouvez désormais le lancer ! Pour vos autres scripts à signer, il vous suffira de relancer la commande Set-AuthenticodeSignature avec les mêmes paramètres, à l’exception du nom du script.

Il reste toutefois une étape. Lancez DédéAmp :

PS C:\scripts> .\dedeamp.ps1

La boîte de dialogue suivante va apparaître :

Il faut faire un choix difficile. C’est la vie.

  • Si vous êtes idiot, vous cliquerez sur Ne jamais exécuter.
  • Si vous êtes simplement étourdi, sur Ne pas exécuter
  • Si vous le sentez bien mais que c’est juste pour voir, sur Exécuter une fois
  • Et si vous êtes au top de la confiance (et je rappelle à tout hasard que c’est vous qui avez signé le script), sur Toujours exécuter

Conclusion

Votre PC n’est pas plus sécurisé qu’avant, mais au moins maintenant vous savez créer des certificats avec Powershell et signer des scripts, et c’est plutôt pas mal ! Portez-vous bien et tchüss !

 

 

 

2 commentaires

    1. En effet @gootsy, par défaut tous les scripts Powershell sont interdits, sauf sur Windows Server 2012 R2 (RemoteSigned). A noter aussi pour être exhaustif qu’il y a DEUX versions de Powershell (et de l’ISE) : 32 (x86) et 64 (x64) bits, et que les ExecutionPolicies ne sont pas communes…

Répondre à gootsy Annuler la réponse

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.