Compilez vos scripts

I. Présentation

 

A. Introduction

 

Je publie cet article dans le but de vous sensibiliser aux rudiments de la sécurité en matière de script. En effet, si vous êtes comme moi amateur de petits outillages réalisés en Powershell, en vbs ou même en batch, vous vous êtes probablement heurté à cette question dès lors que vous vouliez les diffuser.

Même si je n’ai pas la prétention de le comparer à de « vraies applications » compilées, le « scripting » est vraiment très pratique et beaucoup plus simple à mettre en œuvre surtout lorsqu’on n’a pas l’âme d’un développeur, comme moi. Toutefois, hormis une relative lenteur, l’inconvénient majeur est au cœur du concept de « scripting », c’est-à-dire un tandem constitué d’un  interpréteur et d’un ensemble d’instructions ou de commande.

A partir de ce constat, n’importe qui peut consulter ou modifier ce contenu, ce qui présente implicitement un risque majeur, dès lors qu’il est distribué à des tiers (de confiance ou pas).

 

B. Compiler les scripts

 

Heureusement, il est possible de limiter cette exposition en procédant à une compilation  du code via des outils spécialisés. Ceci n’aura pas pour conséquence de rivaliser avec une véritable application, ni d’améliorer les performances d’exécution mais le code source ne sera plus visible, du moins pour le quidam…

Restez vigilant, ce genre de compilation ne vous met pas à l’abri des recherches brutes que l’on peut effectuer avec des éditeurs ou outils spécialisés, tels que Strings (sysinternals), XVI32, ultraedit, reshack, et bien d’autre encore.

Evitez donc d’y stocker des données sensibles, comme des mots de passe, surtout en un seul bloc, comme par exemple  <$Password = « C0mp!eX »>.

 

II. Les fichiers Batch

 

a. Démonstration

Bien, le décor étant planté, je vais commencer par vous présenter une technique, certes un peu vieillissante mais pas obsolète (Tiens, j’ai déjà entendu ça – Terminator Genesis 😀 ).

Prenons pour l’exemple, un batch chargé de renommer, réactiver le compte d’administrateur local intégré et de changer son mot de passe. Je vais au plus simple car ce langage de commande devient très rapidement complexe dès que l’on sort des sentiers battus.

Au besoin, vous  trouverez de nombreux exemples sur l’excellent site http://www.robvanderwoude.com/batchfiles.php

@echo off
whoami /groups|findstr S-1-16-12288 > nul
if %errorlevel%==0 (echo Le compte actuel "%userdomain%\%USERNAME%" dispose du niveau de privilEges requis) else goto notAdmin
wmic useraccount where "SID like '%-500' and LocalAccount ='true'" call rename AdminLocal > nul
net user AdminLocal Pa$$w0rd > nul
net user AdminLocal /active:yes > nul
echo Le compte d'administrateur a EtE rEactivE, renommE et son mot de passe changE.
goto fin
:notAdmin
echo Le compte actuel "%userdomain%\%USERNAME%" ne dispose pas du niveau de privilEges requis. (cf UAC)
:fin

Dans cet exemple, il est évident que n’importe quel quidam va découvrir le mot de passe renseigné. Pour masquer ce contenu franchement explicite, nous allons faire appel à l’excellent outil « Batch Compiler », gratuit de surcroit, que vous pouvez télécharger ici. http://sourceforge.net/projects/batchcompiler/

Une fois installé, il suffit de lancer le raccourci « Batch Compiler » qui nécessite un niveau de privilèges Administrateur. Je ne m’attarderais pas sur les possibilités de cet outil qui mériterait un article à part entière, mais son utilisation est plutôt simple et intuitive. L’éditeur fournit également une documentation et des exemples. Donc, après avoir chargé le batch précité, utilisez le menu « Build » puis « Compile script… »

Compil-image1

Batch Compiler – Compile script…

Dans la fenêtre de compilation, vous pouvez choisir de nombreux paramètres, tels que le nom de l’exécutable, l’ajout d’une icône, d’informations diverses.

Compil-image2

Batch Compiler – Privileges

Notez que vous pouvez également agir sur la visibilité du script – ‘Normal’ pour afficher l’invité de commande, ou ‘Hidden’ dans le cas contraire (les affichages de type « echo » n’apparaîtront pas.) ainsi que sur le niveau de privilège requis pour l’exécution. (Ce qui pourrait décharger le script de faire ce contrôle – lignes 2-3).

Une fois les valeurs saisies, cliquez sur le bouton situé en bas à droite.

Une fenêtre de débogage apparait puis la compilation se lance et après quelques secondes, notre exécutable est prêt, et en plus il est fonctionnel 😀 .

b. Mon avis sur la question …

Cet outil a bien évolué depuis ses débuts car en analysant son contenu via ‘strings’ ou un éditeur hexadécimal, je ne retrouve aucune trace du mot de passe initial. Ceci est probablement lié à l’utilisation d’un mécanisme d’encodage intrinsèque lors de la compilation.

Je pense honnêtement que cette protection des batches est assez dissuasive pour la plupart des cas, mais rien ne vous empêche de pousser la sécurité encore plus loin…

 

III. Les scripts VBScript

 

a. Démonstration

Ce langage de script particulièrement répandu sert principalement à produire des scripts .VBS, généralement plus élaborés que les batches. L’interprétation d’exécution est assurée par les moteurs « cscript.exe » en mode commande ou « wscript.exe » en mode fenêtré par défaut.

Depuis l’origine, Microsoft fournit un encodeur (screnc.exe) permettant de masquer le contenu d’un script, qui portera alors l’extension .VBE.

Par exemple, le script « RenAdmin.vbs » suivant :

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colAccounts = objWMIService.ExecQuery _
    ("Select * From Win32_UserAccount Where LocalAccount = TRUE")
For Each objAccount in colAccounts
    If Left (objAccount.SID, 6) = "S-1-5-" and Right(objAccount.SID, 4) = "-500" Then
        strLocalAdmin = objAccount.Name
    End If
Next
Set objUser = GetObject("WinNT://" & strComputer & "/" & strLocalAdmin & ", user")
' Mot de passe affecté à l'administrateur local intégré en clair
objUser.SetPassword "Pa$$w0rd"
objUser.SetInfo
WScript.Echo "Le mot de passe de " & strLocalAdmin & " a été modifié."

Après un passage dans l’encodeur de Microsoft :

Screnc.exe  RenAdmin.vbs RenAdmin.vbe

Si vous ouvrez le fichier « RenAdmin.vbe » avec le bloc-note, vous pourrez constater que le résultat est parfaitement illisible.

Mais cet encodage n’affecte aucunement son exécution. (L’interpréteur WSH n’utilise aucune clé privée, et se contente d’inverser l’algorithme d’encodage). Toutefois, en cherchant un peu sur la toile, et du fait que l’encodage utilisé soit réversible, il est relativement aisé de trouver un outil qui fera la conversion inverse, et affichera le code source original.

b. Mon avis sur la question …

J’aurais donc tendance à laisser cette technique de coté à moins de la combiner un outil tel que « Batch Compiler » que nous venons d’évoquer. Lors de la démonstration précédente, vous avez peut être remarqué la présence du bouton « Add Resources… » dans la fenêtre du compilateur. Cette fonctionnalité très intéressante permet d’intégrer des fichiers supplémentaires dans votre exécutable, y compris d’autres scripts :-D.

Il nous suffit donc de faire un nouveau projet de batch, en y intégrant par exemple un test d’architecture processeur et le choix automatique de l’interpréteur pour l’exécution de notre script .vbe.

Rem - Utilisation du moteur vbscript 32 bits
if "%PROCESSOR_ARCHITECTURE%"=="x86" goto x86
:amd64
 %windir%\sysWOW64\cscript //b "%myfiles%\set-LAdminPassword.vbe"
 goto fin
:x86
 %windir%\system32\cscript //b "%myfiles%\set-LAdminPassword.vbe"
:fin

Notez simplement qu’il faut utiliser la variable « %myfiles% » pour référencer chemin d’appel de ces fichiers durant l’exécution. Peu importe l’emplacement des fichiers (resources) lors de l’import, ils seront intégrés à plat (sans arborescence) dans l’exécutable.

Une fois le script saisi, dans la fenêtre du compilateur, cliquez sur « Add Resources… » puis sur le second bouton « Add Resource… » afin de sélectionner le script .vbe (ou vbs, selon votre degré de paranoïa), cochez la case « Don’t show extracting » puis cliquez sur le bouton « Done »

Compil-image3

Batch Compiler – Add resources…

Choisissez le mode « Hidden » et « Administrator », cliquez sur le bouton de compilation, et c’est terminé.

 

IV. Powershell

 

a. Introduction

Vous commencez peut être à me connaitre (sans prétention), sur ce sujet, je suis un afficionado de la première heure. Je vous avoue qu’il m’arrive encore de faire appel aux batches et vbscript, car Powershell n’est pas adapté à toutes les situations. Mais si nous revenons à notre propos, je souhaite attirer votre attention sur les mécanismes de sécurité inhérents aux environnements Powershell.

Parmi les différents composants de protection, je vais simplement relever les plus flagrants

  • L’utilisation de l’applet de commande « Get-Credential »
  • L’objet « SecureString »
  • Le passage d’une commande ou script encodé à l’interpréteur Powershell.exe

 

b. Démonstration

 

En général, lors de vos débuts en Powershell, on vous montre la simplicité de stockage des données sensibles  au sein d’objets spécialisés et « sécurisés ».

$cred = Get-Credential -Credential "Domain\User"

$Priv = Read-Host "Entrez un code :" -AsSecureString

$command = 'dir "c:\\program files" '
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
powershell.exe -encodedCommand $encodedCommand 

Si nous regardons maintenant le type des variables de cet exemple, soit $cred, $Priv et $encodedCommand, voici ce que nous obtenons

PS D:\> $cred.GetType().Name
PSCredential

PS D:\> $cred.password.GetType().Name
SecureString 

PS D:\> $Priv.GetType().name
SecureString 

PS D:\> $encodedCommand.GetType().name
String

PS D:\> $encodedCommand
ZABpAHIAIAAiAGMAOgBcAFwAcAByAG8AZwByAGEAbQAgAGYAaQBsAGUAcwAiACAA 

Pour les 2 premiers objets, il  s’agit de chaines sécurisées « SecureString » dont le contenu ne peut pas être affiché par défaut… Pour le 3eme objet, il s’agit d’une chaine simple « String », issue de l’encodage des octets de la chaine $command.

En fait, vous allez remarquer que la sécurité des « SecureString » en Powershell est très relative. En effet, le secret tient dans le petit bout de code suivant :

write "Entrez un mot de passe quelconque"
$Demo = Get-Credential -Credential "Domain\User"
write "Le mot de passe semble protégé: " $demo.Password
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Demo.Password)
$PlainPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
write "Et pourtant, le voici : $PlainPassword"  

Concernant la chaine encodée, il suffit de faire l’opération inverse

$Revert = [Convert]::FromBase64String($encodedCommand) 
[String]::Join("",[System.Text.Encoding]::Unicode.GetChars($Revert)) 

Donc, maintenant que vous avez constaté la fragilité de ces encodages dits « symétriques ou réversibles », et surtout lorsque tout ou partie du code est visible, vous comprendrez qu’il faille redoubler de précaution lors du stockage des données sensibles.

Pour palier ce genre de contrainte, le plus judicieux consisterait à utiliser des mécanismes de chiffrement asymétriques ou typiquement des certificats à clé publique,  mais sans recourir systématiquement  à ce genre d’artillerie lourde, une compilation de vos scripts vous permettra d’apporter une protection acceptable pour vos usages courants.

La liste suivante n’est certainement pas exhaustive, mais je vous propose mes favoris…..

1. PS2EXE (CodePlex – Ingo Karstein)

 

Initialement cet outil était gracieusement proposé sur le site https://ps2exe.codeplex.com/ mais est dorénavant disponible ici : https://gallery.technet.microsoft.com/PS2EXE-Convert-PowerShell-9e4e07f1 et toujours gratuit sous licence « Microsoft Public License (Ms-PL) »

Son usage est simplissime. Après avoir téléchargé le .zip puis extrait dans un dossier (sans oublier de débloquer les fichiers .bat et .ps1), il vous suffira d’ouvrir une session Powershell (Eh oui, l’outil est un script .ps1 dont vous pouvez consulter le contenu si cela vous chante, comme de l’OpenSource 😀 )

Entrez simplement une commande du genre

.\ps2exe.ps1 -inputfile .\MonScript.ps1 -outputFile .\MonScript.exe -runtime20

Au besoin, consultez l’aide pour afficher les autres commutateurs disponibles, tel que le choix d’architecture ou la version de runtime souhaitée.

 

2. Powershell Studio (Sapien)

 

Si vous êtes plutôt du genre à créer de jolies interfaces graphiques, je vous conseille  « Powershell Studio » de Sapien, qui a défaut d’être gratuit, propose une évaluation de 45 jours.

Parmi les très nombreuses capacités de cet outil, vous trouverez un module de compilation qui permettra d’obtenir un exécutable pratiquement autonome.

 

3. Batch Compiler (Encore lui 😀 )

 

Je pense que vous avez compris le principe, toujours le même. Autrement dit, vous saisissez un script du genre :

powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -File "%myfiles%\Decrypt.ps1"

Vous ajoutez ensuite votre script Powershell « .PS1 » via le bouton « Add resources… » puis vous compilez le tout…

 

 

V. Conclusion

 

Une fois de plus, je précise que cet article n’a qu’une vocation pédagogique de sensibilisation aux règles élémentaires de sécurité.  Quoi que nous fassions, ces informations sont (et seront) présentes sur la toile et ce n’est pas en se voilant la face que l’on pourra protéger nos informations sensibles.

Les protections par mot de passe (utilisant des clés symétriques) sont aujourd’hui dépassées et le stockage des informations sensibles peut rapidement être compromis. A défaut de mieux, il faut impérativement les conserver en lieu sûr et redoubler de vigilance pour les stockages isolés et physiquement accessibles.

Maintenant, c’est à vous de choisir, mais au moins, je vous aurais prévenu.

 

Christophe.

2 Commentaires

  1. Sylvain

    Bon article, mais le produit Batch Compiler n’est pas totalement gratuit. Il faut acheter une licence pour le distribuer, sinon il y a un message d’avertissement.
    Cordialement

    Répondre
    1. Christophe

      Exact, je n’avais pas remarqué ce détail et je pense que c’est lié au fait qu’il est développé à partir du produit « Advanced BAT to EXE Converter » qui intègre cette contrainte. Mais en cherchant un peu (pas nécessairement sur radins.com 🙂 ) on peut trouver une version préliminaire 1.0.0 qui fait pratiquement le même taf sans cette restriction de distribution. Et il y a aussi d’autres alternatives telles que http://www.f2ko.de/de/b2e.php v2.3.x (attention aux versions virussées) ou Quick Batch File Compiler, mais c’est aussi un shareware ($74.95 Business License) ou du coté PowerEXEBuilder (l’adaptation de batch en Powershell est une chose généralement assez facile)

      Répondre

Laisser un commentaire

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