22/12/2024

CybersécuritéLogiciels

PsExec : un outil incontournable pour les sysadmins

I. Présentation

Dans ce tutoriel, nous allons apprendre à utiliser PsExec, un outil gratuit de la suite Sysinternals qui permet d'exécuter des tâches d'administration à distance à partir de la ligne de commande. C'est un outil très puissant, qui existait déjà avant que PowerShell ne soit inventé, et qui continue de représenter aujourd'hui une solution intéressante lorsqu'il s'agit d'interagir à distance avec une ou plusieurs machines.

Ce premier article sur PsExec se concentre sur l'utilisation de l'outil en lui-même. Après avoir présenté PsExec un peu plus dans le détails, nous verrons comment l'installer et comment l'utiliser à travers différents exemples concrets ! Un second article sera mis en ligne pour vous donner quelques pistes afin de bloquer l'usage de PsExec.

II. Qu'est-ce que PsExec ?

PsExec est un outil (psexec.exe) qui permet d'exécuter des commandes ou des programmes à distance sur une machine (ou en local), que ce soit un poste de travail ou un serveur. Gratuit, il appartient à la famille PSTools de la suite Sysinternals, qui est connue et reconnue ! Cet outil a traversé les différentes générations de systèmes Windows donc il est compatible aussi bien avec Windows XP qu'avec Windows 11 et les différentes versions de Windows Server.

Pour utiliser PsExec, il faut l'installer sur sa machine Windows, en local, mais il n'est pas nécessaire de l'installer sur l'hôte distant. Un avantage. Que ce soit pour exécuter une simple commande telle que "ipconfig", "ping" ou encore "hostname", ou ouvrir une console PowerShell sur l'hôte distant via "powershell.exe", PsExec sera là pour vous aider. Cet outil fonctionne dans un environnement Active Directory, mais également en groupe de travail.

Comme nous allons le voir, il est très simple d'utilisation. Bien qu'il soit très pratique pour les administrateurs système, il ne faut pas ignorer une chose : il peut-être utilisé à des fins malveillantes, comme PowerShell vous allez me dire qui est de plus en plus utilisé par les logiciels malveillants. Concernant PsExec, il est utilisé par certains ransomwares comme Ryuk et Maze qui l'utilisent pour réaliser des mouvements latéraux sur une infrastructure compromise. D'ailleurs, sur le référentiel ATT&CK du MITRE, il y a plusieurs techniques basées sur PsExec qui sont référencées.

III. Quelle est la différence avec PowerShell ?

Même si aujourd'hui il y a PowerShell, et qu'avec PowerShell on peut exécuter des commandes à distance et ouvrir une session PowerShell à distance sur une machine, PsExec reste une solution intéressante. La raison principale c'est la manière dont PsExec va interagir avec la machine distante pour s'y connecter, en comparaison de PowerShell. En effet, PowerShell s'appuie sur WinRM ce qui implique une configuration au préalable.

PsExec quant à lui s'appuie sur le partage administratif "admin$" de Windows. Lors de l'exécution d'une commande via PsExec, il peut y avoir une petite latence le temps que PsExec se mette en place. Pour être précis, voici comment il fonctionne :

1 - Il crée un fichier nommé "PSEXESVC.exe" dans "C:\Windows" sur l'hôte distant

2 - Il crée et démarre un processus nommé PsExec sur le serveur distant

3 - Il exécute la commande ou le programme via un processus parent nommé "PSEXESVC.exe" et visible sur l'hôte distant

4 - À la fin de l'exécution, il arrête et supprime son service, ainsi que le fichier "PSEXESVC.exe"

Par ailleurs, dans certains environnements où d'anciennes versions de Windows sont utilisées, PsExec sera avantageux, car il fonctionne avec toutes les versions contrairement à PowerShell qui n'est pas présent sur toutes les versions de Windows (ou avec des versions variées).

Utiliser PsExec ne veut pas dire ne pas utiliser PowerShell, car on peut utiliser PowerShell au travers de PsExec. D'ailleurs, c'est peut-être la solution idéale en termes d'interopérabilité.

IV. Prérequis de PsExec

Bien qu'il soit possible d'utiliser PsExec en local, l'intérêt est surtout de l'utiliser pour interagir avec des machines distantes. Dans ce cas, quelques prérequis sont à connaître :

  • Le pare-feu doit autoriser les accès sur le port 445/TCP, correspondant au groupe de règles "Partage de fichiers et d’imprimantes"
    • Ce sera forcément le cas sur un contrôleur de domaine (accès au SYSVOL), sur un serveur de fichiers, etc...
    • Cette règle est activée sur le profil "domaine" du pare-feu pour les ordinateurs membre du domaine Active Directory

  • Le partage administratif "admin$" de Windows doit être actif, ce qui est le cas par défaut sur toutes les installations de Windows

  • Vous connaissez des identifiants de connexion sur l'hôte distant ou vous disposez d'un compte avec suffisamment de privilèges au niveau du domaine Active Directory
  • PsExec ne fonctionne qu'entre des hôtes Windows

Autant vous dire que les prérequis ne sont pas très effrayants.

V. Télécharger et installer PsExec

PsExec est disponible dans le package Sysinternals Suite disponible à partir du Microsoft Store de Windows, mais cela signifie que tous les outils de la suite seront installés sur votre machine. Si cette méthode vous intéresse, rendez-vous sur le Microsoft Store afin de l'installer par ce biais.

Sinon, l'outil PsExec est disponible sur le site de Microsoft dans un package nommé "PsTools" qui contient une vingtaine d'outils. Voici le lien pour le télécharger :

Suite au téléchargement, vous obtenez une archive ZIP avec l'ensemble des fichiers. Il suffit de copier-coller le contenu de cette archive vers le répertoire de votre choix. Pour cet exemple, ce sera dans le répertoire "C:\PsTools" de ma machine Windows. À partir de là, PsExec est utilisable à partir de la ligne de commande.

Installer PsExec

 

VI. Ajouter PsExec à la variable d'environnement PATH

Actuellement, PsExec est déjà prêt à l'utilisation, mais il sera nécessaire de se positionner dans le dossier "C:\PsTools" afin de pouvoir l'appeler. Si l'on souhaite que ce soit plus pratique et que Windows trouve l'exécutable dès que l'on exécute la commande "psexec", il faut ajuster la variable d'environnement PATH de la machine locale.

Tout d'abord, ouvrez les propriétés du système grâce au raccourci "sysdm.cpl" à exécuter dans la zone de recherche de Windows ou le menu "Exécuter". Ensuite, cliquez sur l'onglet "Paramètre système avancés" (1), cliquez sur "Variables d'environnement..." (2) afin d'ouvrir la fenêtre de gestion de ces variables. Dans "Variables système", sélectionnez "Path" (3) puis cliquez sur "Modifier" (4).

Cliquez sur le bouton "Nouveau" (1) pour ajouter une nouvelle valeur à cette variable d'environnement et ajoutez le chemin du dossier où se situe l'exécutable de PsExec, à savoir "C:\PsTools" (2) dans mon cas. Validez avec "OK" (3) et validez également les autres fenêtres.

Si vous ouvrez une Invite de commande ou une console PowerShell et que vous appelez PsExec, cela va fonctionner, peu importe le dossier où vous êtes positionné au niveau du prompt. Pour la première fois, il faudra valider les termes de la licence en cliquant sur "Agree". La commande ci-dessous permet d'accepter automatiquement la licence :

psexec /accepteula

Vous êtes prêt à utiliser PsExec, donc passons aux exemples.

VII. Exemples d'utilisation de PsExec

A. Premiers pas avec PsExec

Avant d'exécuter notre première commande, sachez que PsExec s'utilise selon le modèle suivant :

psexec \\<nom de l'ordinateur> <commande à exécuter>

Même si l'on peut ajouter également des arguments, nous allons commencer par utiliser cette syntaxe basique. Par exemple, nous pouvons exécuter la commande "ipconfig" sur l'hôte SRV-ADDS-01 pour récupérer sa configuration IP à distance. Ce qui donne :

psexec \\srv-adds-01 ipconfig

À partir de la machine distante où est installé PsExec, je parviens à récupérer la configuration IP de ce serveur. Si j'exécute la commande "ipconfig" sur mon hôte local, on peut voir que l'adresse IP n'est pas la même.

Note : lorsque PsExec retourne le code d'erreur 0, cela signifie que la commande s'est correctement exécutée.

Il est possible de cibler plusieurs ordinateurs avec une seule et même commande. Par exemple, on peut exécuter "ipconfig" sur deux serveurs différents :

PsExec \\srv-adds-01,srv-apps ipconfig

Voici le résultat obtenu :

PsExec sur plusieurs machines

B. Ouvrir une console PowerShell à distance via PsExec

Nous venons de voir comment exécuter une simple commande et obtenir le résultat dans la console. Néanmoins, on peut aussi ouvrir une console PowerShell sur l'hôte distant et agir dans cette commande. Dans ce cas, on va tout simplement préciser "powershell.exe" comme ceci :

psexec \\srv-adds-01 powershell.exe

Une fois que la connexion est établie, le prompt qui s'affiche correspond à l'hôte distant. D'ailleurs, si j'exécute la commande "hostname", c'est bien "SRV-ADDS-01" qui s'affiche et si je regarde quel est l'utilisateur connecté, c'est l'utilisateur de mon hôte local. La commande "whoami" me permet de voir quel est l'utilisateur associé à ce processus.

Utiliser PowerShell via PsExec

Si je me connecte sur l'hôte SRV-ADDS-01 et que je regarde le Gestionnaire des tâches, je remarque deux processus :

  • PSEXESVC.exe correspondant à PsExec en lui-même, sur l'hôte distant (malgré qu'il ne soit pas installé sur cet hôte)
  • powershell.exe correspondant au processus lancé par PsExec et qui tourne avec mon utilisateur "admin.fb"

C. PsExec : comment utiliser le compte SYSTEM ou un utilisateur spécifique ?

Actuellement, PsExec exécute nos commandes en utilisant le compte avec lequel je suis connecté sur ma machine locale, à savoir "IT-Connect\fb.admin". C'est normal, c'est son comportement par défaut.

PsExec offre la possibilité d'utiliser le compte "NT AUTHORITY\SYSTEM" qui est un compte avec des privilèges très élevés (encore plus élevés que le compte Administrateur) ou de préciser un couple utilisateur/mot de passe.

Tout d'abord, en ajoutant l'option "-s" on peut élever ses privilèges pour utiliser le compte SYSTEM :

psexec -s \\srv-adds-01 powershell.exe

Ainsi, la console PowerShell tourne avec le compte SYSTEM et la commande "whoami" me permet  de le vérifier. On voit la différence par rapport à l'exemple précédent.

PsExec avec le compte système

Dans le même esprit, on peut spécifier un nom d'utiliser et un mot de passe pour exécuter la commande "hostname" (ou un autre programme, un script, etc...) :

psexec \\srv-adds-01 hostname -u it-connect.local\administrateur -p MonSuperMotDePasse

Depuis le début, j'évoque l'exécution de commande sur un hôte ou plusieurs hôtes distants, mais PsExec fonctionne aussi très bien en local. Ainsi, on peut lancer un programme en local avec un utilisateur spécifique, voire même avec les droits SYSTEM. Par exemple, on peut ouvrir l'éditeur de Registre Windows avec les privilèges SYSTEM pour avoir les pleins pouvoirs sur la base de Regsitre.

psexec -s -i regedit

L'occasion de vous faire découvrir une nouvelle option nommée "-i" et qui permet d'exécuter la commande en mode interactif. Cela s'applique aussi sur une machine distante.

D. Exécuter un programme en mode interactif avec PsExec

À distance, vous pouvez exécuter un programme en mode interactif sur une machine, c'est-à-dire que l'interface du programme sera visible par l'utilisateur final. Pour cela, on peut utiliser l'option "-i" que l'on vient de voir précédemment, toujours en précisant le nom du programme derrière.

psexec \\srv-adds-01 -i notepad.exe

Dans certains cas, il est utile de préciser l'ID de session que l'on souhaite cibler. Il suffit de l'insérer entre l'option "-i" et le nom de la commande, comme ceci :

psexec \\srv-adds-01 -i 2 notepad.exe

E. PsExec : copier un programme vers un PC distant

L'option "-c" de PsExec permet de copier un programme vers l'hôte distant. Lorsque cette option est utilisée, il faut savoir que PsExec va chercher à l'exécuter, car c'est son fonctionnement par défaut. Par exemple, pour copier le fichier "C:\Partage\rustdesk.exe" de ma machine locale vers SRV-ADDS-01 et l'exécuter, voici la commande à utiliser :

psexec \\srv-adds-01 -c "C:\Partage\rustdesk.exe"

Je n'ai pas précisé de chemin sur le serveur cible, mais c'est normal, car le fichier sera copié temporairement dans le partage "admin$" de la machine cible.

F. Exécuter une commande PowerShell via PsExec

PsExec est capable d'exécuter des programmes et d'ouvrir une console PowerShell sur une machine distante, ce qui est relativement puissant. Dans certains cas, nous avons besoin d'exécuter une simple commande et d'en obtenir le résultat, sans pour autant obtenir une console sur l'hôte distant. La bonne nouvelle, c'est que PsExec permet d'exécuter une commande PowerShell sur l'hôte distant en appelant PowerShell et en ajoutant le paramètre "-Command" propre à l'appel de l'exécutable PowerShell.

Ainsi, pour exécuter la commande "Get-ChildItem C:\Partage\" sur SRV-ADDS-01, on utilisera cette commande :

psexec \\srv-adds-01 powershell -Command Get-ChildItem C:\Partage\

En retour, j'obtiens bien la liste du contenu du dossier "C:\Partage" !

PsExec PowerShell exemple

Pour exécuter un enchaînement de plusieurs commandes PowerShell, il faudra ruser autrement, car avec le paramètre -Command cela ne passera pas. Voici un exemple :

psexec \\srv-adds-01 powershell "Get-ChildItem C:\Partage\ODT_Exe;Get-ChildItem C:\Partage\ODT_Office"

On peut utiliser PsExec pour altérer la configuration d'une machine distante à l'aide de PowerShell afin de réaliser une tâche d'administration ! Ainsi, on peut, par exemple, changer le mode de démarrage d'un service en l'occurrence ici le service "Windows Update" :

psexec \\srv-adds-01 powershell -Command Set-Service -Name wuauserv -StartupType Automatic

G. Exécuter un script PowerShell avec PsExec

Pour exécuter un script, c'est le même principe que l'exemple précédent sauf que l'on va remplacer -Command par -File pour préciser le chemin vers le fichier PS1. En complément, on va jouer sur la politique d'exécution pour être sûr que le script s'exécute en ajoutant "-ExecutionPolicy Bypass". Même si c'est dangereux, on peut aller encore plus loin en ajoutant "-s" pour exécuter le script avec les droits SYSTEM sur l'hôte distant !

psexec \\srv-adds-01 powershell -File "\\PC-01\c$\Partage\script.ps1" -ExecutionPolicy Bypass

Dans l'exemple ci-dessus, vous pouvez constater que j'utilise un chemin réseau : c'est important, car sinon le processus "powershell.exe" ne pourra pas trouver le script si j'utilise un chemin local (à moins qu'il dispose du fichier en local). C'est différent de l'exécution d'un programme avec l'option "-c" où le programme est copié dans "admin$" avant d'être exécuté.

Ce script, nommé "script.ps1" crée un simple fichier texte à la racine du "C" sur la machine distante. Voici son code :

New-Item -ItemType File -Path "C:\fichier-psexec.txt" -Value "Demo IT-Connect"

Cette méthode fonctionne très bien ! C'est à la fois très puissant et très dangereux, car on peut exécuter ce que l'on veut comme script PowerShell !

PsExec script PowerShell

H. Cibler une liste d'ordinateurs Active Directory avec PsExec

Précédemment, nous avons qu'il était possible de cibler plusieurs machines en spécifiant leur nom. Pour aller plus loin, nous pouvons nous appuyer sur l'Active Directory pour obtenir une liste d'ordinateurs à cibler puisqu'il contient la liste des ordinateurs (et serveurs) membres du domaine.

À partir de PowerShell et du module Active Directory, nous pouvons obtenir la liste des ordinateurs du domaine avec le cmdlet Get-ADComputer (le module doit être installé sur la machine où il y a PsExec). La commande ci-dessous retourne le nom de tous les objets ordinateurs du domaine qui sont sous la racine "OU=PC,DC=it-connect,DC=local" :

(Get-ADComputer -Filter * -SearchBase "OU=PC,DC=it-connect,DC=local").Name

On peut utiliser cette commande via PsExec pour créer une liste de machines à cibler, il faut simplement que l'on crée une liste de noms séparés par une virgule afin de respecter les attentes de PsExec : un petit -Join et le tour est joué ! Ainsi, si l'on veut exécuter la commande "ipconfig" sur l'ensemble des machines de l'AD (selon la liste récupérée), voici la commande :

psexec "\\$((Get-ADComputer -Filter * -SearchBase "OU=PC,DC=it-connect,DC=local").Name -Join ',')" ipconfig

La console retourne le résultat pour chaque machine, tour à tour. Si une machine est hors ligne, une erreur est retournée.

PsExec liste d'ordinateurs de l'Active Directory

VIII. Conclusion

Nous venons de voir comment installer et utiliser PsExec pour interagir avec une ou plusieurs machines distantes. Suite à la lecture de cet article et aux différents tests que vous avez pu mener de votre côté, je pense que vous avez pris conscience de la puissance de cet outil.

Pour exécuter des commandes à distance sur les machines, il faut utiliser un compte qui dispose d'un niveau de droit suffisant : un utilisateur lambda ne pourra pas utiliser PsExec pour exécuter des actions avec des privilèges élevés, que ce soit en local ou à distance (notamment, car il n'aura pas accès à admin$ et qu'il ne pourra pas créer le service PsExec) à moins de connaître l'identifiant et le mot de passe (ou le hash) d'un compte administrateur et de l'utiliser avec les options "-u" et "-p".

Alors que certains vont en faire un allier au quotidien, d'autres vont souhaiter le bloquer. D'ailleurs, suite à la lecture de cet article, vous avez peut-être déjà identifié quelques pistes pour vous débarrasser de PsExec ? Le prochain article sera dédié aux différentes méthodes possibles pour bloquer PsExec.

author avatar
Florian BURNEL Co-founder of IT-Connect
Ingénieur système et réseau, cofondateur d'IT-Connect et Microsoft MVP "Cloud and Datacenter Management". Je souhaite partager mon expérience et mes découvertes au travers de mes articles. Généraliste avec une attirance particulière pour les solutions Microsoft et le scripting. Bonne lecture.
Partagez cet article Partager sur Twitter Partager sur Facebook Partager sur Linkedin Envoyer par mail

3 commentaires sur “PsExec : un outil incontournable pour les sysadmins

  • Bonjour,
    Tout d’abord merci pour cet article, qui est à l’image du site, très utile.
    J’ai une question bête, mais quelque chose m’a interpelé dans ta vidéo : qu’est ce que tu utilises pour avoir des bureaux à distance et des fenêtres PowerShell avec des onglets ? Je trouve cela bien pratique ^^

    Répondre
    • Hello,
      Pour les consoles PowerShell, c’est l’application Windows Terminal proposée par Microsoft 🙂
      Et pour les connexions Bureau à distance, c’est Royal TS (payant) où tu peux avoir tes connexions RDP, Web, SSH, etc… dans une même interface. Dans le même style en open source, tu as mRemoteNG, sinon Remote Desktop Manager de chez Devolutions (dans sa version gratuite).
      A+
      Florian

      Répondre

Laisser un commentaire

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.